@burdenoff/microfe-botmanor 2026.1007.1 → 2026.1009.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/botlit/BotlitRoutes.js +58 -146
- package/dist/botlit/BotlitRoutes.js.map +1 -1
- package/dist/botlit/BotmanorRoot.js.map +1 -1
- package/dist/botlit/BotmanorRootInner.js +39 -67
- package/dist/botlit/BotmanorRootInner.js.map +1 -1
- package/dist/botlit/components/AssistantRuntimeSetupPanel.js +1 -1
- package/dist/botlit/components/AssistantRuntimeSetupPanel.js.map +1 -1
- package/dist/botlit/components/ModelRegistrationPanel.js +174 -0
- package/dist/botlit/components/ModelRegistrationPanel.js.map +1 -0
- package/dist/botlit/hooks/internal/workspaceGateway.js +1 -1
- package/dist/botlit/hooks/useAssistantRuntimeSetup.js +2 -2
- package/dist/botlit/hooks/useAssistantRuntimeSetup.js.map +1 -1
- package/dist/botlit/hooks/useBotWorkflow.js +56 -0
- package/dist/botlit/hooks/useBotWorkflow.js.map +1 -0
- package/dist/botlit/hooks/useLLMProviders.js +94 -50
- package/dist/botlit/hooks/useLLMProviders.js.map +1 -1
- package/dist/botlit/pages/AgentBuilderPage.js +206 -183
- package/dist/botlit/pages/AgentBuilderPage.js.map +1 -1
- package/dist/botlit/pages/BotWorkflowTab.js +33 -33
- package/dist/botlit/pages/BotWorkflowTab.js.map +1 -1
- package/dist/botlit/pages/KnowledgeBaseDetailPage.js +162 -145
- package/dist/botlit/pages/KnowledgeBaseDetailPage.js.map +1 -1
- package/dist/botlit/pages/SettingsPage.js +129 -66
- package/dist/botlit/pages/SettingsPage.js.map +1 -1
- package/dist/botlit/providers/BotlitProvider.js +30 -26
- package/dist/botlit/providers/BotlitProvider.js.map +1 -1
- package/dist/botlit/utils/embedding-models.js +36 -0
- package/dist/botlit/utils/embedding-models.js.map +1 -0
- package/dist/generated/wspace-operations.js +58 -36
- package/dist/generated/wspace-operations.js.map +1 -1
- package/package.json +1 -3
|
@@ -2,100 +2,72 @@ import { RouteLoader as e } from "./components/RouteLoader.js";
|
|
|
2
2
|
import { BotlitProvider as t } from "./providers/BotlitProvider.js";
|
|
3
3
|
import { BotlitRoutes as n } from "./BotlitRoutes.js";
|
|
4
4
|
import { WorkspaceRequired as r } from "./components/WorkspaceRequired.js";
|
|
5
|
-
import {
|
|
6
|
-
import { jsx as
|
|
7
|
-
import { useGatewayClient as
|
|
8
|
-
import { ApolloProvider as
|
|
9
|
-
import { QueryClient as
|
|
10
|
-
import { ErrorBoundary as
|
|
11
|
-
import { FeatureFlagProvider as
|
|
12
|
-
import { refetchStoreNodes as _, resetFluidGridsClient as v, resetFluidGridsConfig as y, resetGlobalStoreClient as b, setFluidGridsClient as x, setFluidGridsConfig as S, setGlobalStoreClient as C } from "@burdenoff/fluidgrids-fe-sdk";
|
|
5
|
+
import { useEffect as i, useState as a } from "react";
|
|
6
|
+
import { jsx as o, jsxs as s } from "react/jsx-runtime";
|
|
7
|
+
import { useGatewayClient as c } from "@burdenoff/fe-libs/shared/graphql";
|
|
8
|
+
import { ApolloProvider as l } from "@apollo/client/react";
|
|
9
|
+
import { QueryClient as u, QueryClientProvider as d } from "@tanstack/react-query";
|
|
10
|
+
import { ErrorBoundary as f } from "@burdenoff/fe-libs/shared/components";
|
|
11
|
+
import { FeatureFlagProvider as p } from "@burdenoff/fe-libs/shared/feature-flags";
|
|
13
12
|
//#region src/botlit/BotmanorRootInner.tsx
|
|
14
|
-
var
|
|
13
|
+
var m = 1e4, h = 2e3, g = new u({ defaultOptions: { queries: {
|
|
15
14
|
staleTime: 300 * 1e3,
|
|
16
15
|
retry: 1
|
|
17
|
-
} } }),
|
|
18
|
-
let
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}), M(!0)), () => {
|
|
22
|
-
v(), b();
|
|
23
|
-
}), [k, A]), a(() => {
|
|
24
|
-
if (j) return;
|
|
16
|
+
} } }), _ = (u) => {
|
|
17
|
+
let _ = c("workspace"), v = !!_, [y, b] = a(null), [x, S] = a(!1);
|
|
18
|
+
if (i(() => {
|
|
19
|
+
if (v) return;
|
|
25
20
|
let e = setTimeout(() => {
|
|
26
|
-
|
|
27
|
-
},
|
|
21
|
+
b("BotManor could not connect to the gateway. Please refresh the page or check your configuration.");
|
|
22
|
+
}, m);
|
|
28
23
|
return () => clearTimeout(e);
|
|
29
|
-
}, [
|
|
30
|
-
if (
|
|
31
|
-
let e = setTimeout(() =>
|
|
24
|
+
}, [v]), i(() => {
|
|
25
|
+
if (u.workspaceId) return;
|
|
26
|
+
let e = setTimeout(() => S(!0), h);
|
|
32
27
|
return () => clearTimeout(e);
|
|
33
|
-
}, [
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
if (p.apiGatewayUrl) return S({
|
|
39
|
-
apiGatewayUrl: p.apiGatewayUrl.endsWith("/") ? p.apiGatewayUrl.slice(0, -1) : p.apiGatewayUrl,
|
|
40
|
-
authToken: p.authToken,
|
|
41
|
-
workspaceId: p.workspaceId ?? "",
|
|
42
|
-
tenantId: p.tenantId,
|
|
43
|
-
productId: p.productId ?? w,
|
|
44
|
-
productName: p.productName ?? T,
|
|
45
|
-
onWorkflowSaved: (e) => R.current(e)
|
|
46
|
-
}), () => {
|
|
47
|
-
y();
|
|
48
|
-
};
|
|
49
|
-
}, [
|
|
50
|
-
p.apiGatewayUrl,
|
|
51
|
-
p.authToken,
|
|
52
|
-
p.workspaceId,
|
|
53
|
-
p.tenantId,
|
|
54
|
-
p.productId,
|
|
55
|
-
p.productName
|
|
56
|
-
]), !p.workspaceId) return F ? /* @__PURE__ */ l(r, {
|
|
57
|
-
basePath: p.basePath,
|
|
58
|
-
navigate: p.navigate
|
|
59
|
-
}) : /* @__PURE__ */ l(e, { label: "Loading your workspace…" });
|
|
60
|
-
if (!j) return N ? /* @__PURE__ */ l("div", {
|
|
28
|
+
}, [u.workspaceId]), !u.workspaceId) return x ? /* @__PURE__ */ o(r, {
|
|
29
|
+
basePath: u.basePath,
|
|
30
|
+
navigate: u.navigate
|
|
31
|
+
}) : /* @__PURE__ */ o(e, { label: "Loading your workspace…" });
|
|
32
|
+
if (!v) return y ? /* @__PURE__ */ o("div", {
|
|
61
33
|
className: "flex h-full min-h-[200px] w-full items-center justify-center p-6",
|
|
62
|
-
children: /* @__PURE__ */
|
|
34
|
+
children: /* @__PURE__ */ s("div", {
|
|
63
35
|
className: "text-center",
|
|
64
|
-
children: [/* @__PURE__ */
|
|
36
|
+
children: [/* @__PURE__ */ o("p", {
|
|
65
37
|
className: "mb-4 text-sm text-text-secondary",
|
|
66
|
-
children:
|
|
67
|
-
}), /* @__PURE__ */
|
|
38
|
+
children: y
|
|
39
|
+
}), /* @__PURE__ */ o("button", {
|
|
68
40
|
type: "button",
|
|
69
41
|
onClick: () => window.location.reload(),
|
|
70
42
|
className: "rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text transition-colors hover:bg-action-primary-bg-hover",
|
|
71
43
|
children: "Reload Page"
|
|
72
44
|
})]
|
|
73
45
|
})
|
|
74
|
-
}) : /* @__PURE__ */
|
|
75
|
-
let
|
|
76
|
-
...
|
|
77
|
-
children: /* @__PURE__ */
|
|
46
|
+
}) : /* @__PURE__ */ o(e, {});
|
|
47
|
+
let C = !!u.basePath, w = /* @__PURE__ */ o(t, {
|
|
48
|
+
...u,
|
|
49
|
+
children: /* @__PURE__ */ o(n, {})
|
|
78
50
|
});
|
|
79
|
-
return /* @__PURE__ */
|
|
80
|
-
fallback: /* @__PURE__ */
|
|
51
|
+
return /* @__PURE__ */ o(f, {
|
|
52
|
+
fallback: /* @__PURE__ */ o("div", {
|
|
81
53
|
className: "p-6 text-center text-text-secondary",
|
|
82
54
|
children: "Something went wrong loading BotManor. Please refresh the page."
|
|
83
55
|
}),
|
|
84
|
-
children: /* @__PURE__ */
|
|
56
|
+
children: /* @__PURE__ */ o(p, {
|
|
85
57
|
workspaceId: null,
|
|
86
58
|
gateway: "global",
|
|
87
59
|
defaultEnabled: !0,
|
|
88
|
-
children: /* @__PURE__ */
|
|
89
|
-
client:
|
|
90
|
-
children:
|
|
91
|
-
client:
|
|
92
|
-
children:
|
|
60
|
+
children: /* @__PURE__ */ o(d, {
|
|
61
|
+
client: g,
|
|
62
|
+
children: C ? w : /* @__PURE__ */ o(l, {
|
|
63
|
+
client: _,
|
|
64
|
+
children: w
|
|
93
65
|
})
|
|
94
66
|
})
|
|
95
67
|
})
|
|
96
68
|
});
|
|
97
69
|
};
|
|
98
70
|
//#endregion
|
|
99
|
-
export {
|
|
71
|
+
export { _ as BotmanorRootInner };
|
|
100
72
|
|
|
101
73
|
//# sourceMappingURL=BotmanorRootInner.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BotmanorRootInner.js","names":[],"sources":["../../src/botlit/BotmanorRootInner.tsx"],"sourcesContent":["/**\n * BotManor Root — implementation\n * @module botlit\n *\n * The heavy half of {@link BotmanorRoot}. Everything that pulls a large\n * dependency graph lives behind this module so the package entry point stays\n * small: `BotmanorRootInner` statically imports `BotlitRoutes`, which in turn\n * pulls the whole `@burdenoff/fluidgrids-fe-sdk` barrel (workflow builder,\n * @xyflow/react, framer-motion …). `BotmanorRoot` loads this module lazily and\n * paints a skeleton meanwhile, so the host never shows an empty content\n * region while that graph downloads.\n */\n\nimport type { FC } from 'react';\nimport { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query';\nimport { ApolloProvider } from '@apollo/client/react';\nimport { ErrorBoundary } from '@burdenoff/fe-libs/shared/components';\nimport { BotlitProvider } from './providers/BotlitProvider';\nimport { FeatureFlagProvider } from '@burdenoff/fe-libs/shared/feature-flags';\nimport { BotlitRoutes } from './BotlitRoutes';\nimport { RouteLoader } from './components/RouteLoader';\nimport { WorkspaceRequired } from './components/WorkspaceRequired';\nimport type { BotmanorRootProps } from './types';\n\n// FluidGrids SDK client injection (needed for workflow components)\nimport {\n setFluidGridsClient,\n resetFluidGridsClient,\n setFluidGridsConfig,\n resetFluidGridsConfig,\n setGlobalStoreClient,\n resetGlobalStoreClient,\n refetchStoreNodes,\n type WorkflowSavedResult,\n} from '@burdenoff/fluidgrids-fe-sdk';\n// Use the shared gateway Apollo clients from the shell\nimport { useGatewayClient } from '@burdenoff/fe-libs/shared/graphql';\n\n/**\n * Product identity handed to the FluidGrids SDK when the shell does not override it.\n * `botmanor` since the Botlit -> BotManor rename's Stage 5a; workflow\n * definitions stored under the legacy `botlit` were migrated, and the workflow\n * service matches either slug.\n */\nconst DEFAULT_PRODUCT_ID = 'botmanor';\nconst DEFAULT_PRODUCT_NAME = 'BotManor';\n\n/** How long to wait for the shell's gateway clients before showing an error. */\nconst CLIENT_READY_TIMEOUT_MS = 10_000;\n\n/**\n * How long to keep showing the loading skeleton before concluding that the\n * shell really has no active workspace.\n *\n * The shell resolves org/workspace asynchronously and passes `workspaceId=\"\"`\n * until it lands, which is indistinguishable from \"this user has no\n * workspace\". Without this settle window the guided zero state would flash on\n * every cold load — a get-started screen appearing and vanishing reads as a\n * broken page, which is exactly what this component exists to avoid.\n */\nconst WORKSPACE_SETTLE_MS = 2_000;\n\n// Create a query client for this microfrontend\nconst queryClient = new QueryClient({\n defaultOptions: {\n queries: {\n staleTime: 5 * 60 * 1000,\n retry: 1,\n },\n },\n});\n\nexport const BotmanorRootInner: FC<BotmanorRootProps> = (props) => {\n // NOTE: Navigation is now handled by the shell's NavRegistration.tsx\n // The shell manages all product submenu items in a centralized way\n\n // Get shell's Apollo clients (both workspace and global for FluidGrids SDK)\n const workspaceClient = useGatewayClient('workspace');\n const globalClient = useGatewayClient('global');\n const [clientReady, setClientReady] = useState(false);\n const [clientError, setClientError] = useState<string | null>(null);\n const [workspaceSettled, setWorkspaceSettled] = useState(false);\n\n // Inject Apollo clients into FluidGrids SDK (for workflow components).\n // This synchronizes external stores (module-level client singletons in the SDK)\n // with React's lifecycle. The setState call is intentional — it gates rendering\n // so children don't mount before the SDK clients are available.\n //\n // KNOWN TRADE-OFF (mirrors microfe-bigconsole): clientReady is NOT reset in\n // cleanup. When the client references change (e.g. token refresh) children keep\n // rendering against a briefly uninitialised SDK client until the effect re-runs.\n // That avoids a spinner flash mid-session; failed requests are retried by\n // Apollo/React Query.\n useEffect(() => {\n if (workspaceClient && globalClient) {\n setFluidGridsClient(workspaceClient);\n setGlobalStoreClient(globalClient);\n // Node definitions come from the global store — refresh them now that the\n // SDK has a client, otherwise the builder palette stays empty.\n void refetchStoreNodes().catch((error: unknown) => {\n console.warn('[BotManor] Failed to refresh FluidGrids store nodes', error);\n });\n setClientReady(true);\n }\n return () => {\n resetFluidGridsClient();\n resetGlobalStoreClient();\n };\n }, [workspaceClient, globalClient]);\n\n // Timeout fallback: if gateway clients are never provided (test env, shell\n // misconfiguration, auth failure before hydration), show an error rather than\n // spinning indefinitely.\n useEffect(() => {\n if (clientReady) return;\n const timer = setTimeout(() => {\n setClientError(\n 'BotManor could not connect to the gateway. Please refresh the page or check your configuration.'\n );\n }, CLIENT_READY_TIMEOUT_MS);\n return () => clearTimeout(timer);\n }, [clientReady]);\n\n // Give the shell a bounded window to resolve the active workspace before the\n // guided zero state is allowed to render. Cancelled the moment a workspace\n // arrives — a workspace that is already present never starts the timer.\n useEffect(() => {\n if (props.workspaceId) return;\n const timer = setTimeout(() => setWorkspaceSettled(true), WORKSPACE_SETTLE_MS);\n return () => clearTimeout(timer);\n }, [props.workspaceId]);\n\n // Hook point for syncing a saved workflow back into BotManor. BotManor keeps no\n // separate workflow record (unlike BigConsole), so there is nothing to write —\n // the bridge exists so a future sync can be added without re-initialising the SDK.\n const handleWorkflowSaved = useCallback((result: WorkflowSavedResult) => {\n if (import.meta.env.DEV) {\n console.info('[BotManor] Workflow saved', result.workflowKey, result.operation);\n }\n }, []);\n\n // Ref-forwarding: decouple the callback from the SDK config effect so that\n // workspaceClient reference changes don't trigger resetFluidGridsConfig() + re-init.\n const handleWorkflowSavedRef = useRef(handleWorkflowSaved);\n useLayoutEffect(() => {\n handleWorkflowSavedRef.current = handleWorkflowSaved;\n }, [handleWorkflowSaved]);\n\n // Configure FluidGrids SDK settings\n useEffect(() => {\n if (!props.apiGatewayUrl) return;\n\n const normalizedBase = props.apiGatewayUrl.endsWith('/')\n ? props.apiGatewayUrl.slice(0, -1)\n : props.apiGatewayUrl;\n\n setFluidGridsConfig({\n apiGatewayUrl: normalizedBase,\n authToken: props.authToken,\n workspaceId: props.workspaceId ?? '',\n tenantId: props.tenantId,\n // The SDK filters workflows by productId. It MUST be this product — falling\n // back to the shell's default ('workspaces') would leak another product's\n // workflows into BotManor.\n productId: props.productId ?? DEFAULT_PRODUCT_ID,\n productName: props.productName ?? DEFAULT_PRODUCT_NAME,\n // Stable wrapper via ref — avoids SDK re-init when workspaceClient changes reference\n onWorkflowSaved: (result: WorkflowSavedResult) => handleWorkflowSavedRef.current(result),\n });\n\n return () => {\n resetFluidGridsConfig();\n };\n }, [\n props.apiGatewayUrl,\n props.authToken,\n props.workspaceId,\n props.tenantId,\n props.productId,\n props.productName,\n ]);\n\n // Without a workspace every BotManor query is unscoped and every write is\n // rejected — guide the user instead of rendering empty lists. Until the\n // settle window elapses we cannot tell \"still resolving\" from \"none\", so we\n // keep the same skeleton the shell was already showing.\n if (!props.workspaceId) {\n if (!workspaceSettled) {\n return <RouteLoader label=\"Loading your workspace…\" />;\n }\n return <WorkspaceRequired basePath={props.basePath} navigate={props.navigate} />;\n }\n\n // Don't render until clients are ready (same pattern as microfe-bigconsole)\n if (!clientReady) {\n if (clientError) {\n return (\n <div className=\"flex h-full min-h-[200px] w-full items-center justify-center p-6\">\n <div className=\"text-center\">\n <p className=\"mb-4 text-sm text-text-secondary\">{clientError}</p>\n <button\n type=\"button\"\n onClick={() => window.location.reload()}\n className=\"rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text transition-colors hover:bg-action-primary-bg-hover\"\n >\n Reload Page\n </button>\n </div>\n </div>\n );\n }\n // Same skeleton as the lazy-chunk fallback, so the content region never\n // switches loading idioms between first paint and the page rendering.\n return <RouteLoader />;\n }\n\n const isIntegrated = !!props.basePath;\n\n const content = (\n <BotlitProvider {...props}>\n <BotlitRoutes />\n </BotlitProvider>\n );\n\n return (\n <ErrorBoundary\n fallback={\n <div className=\"p-6 text-center text-text-secondary\">\n Something went wrong loading BotManor. Please refresh the page.\n </div>\n }\n >\n <FeatureFlagProvider workspaceId={null} gateway=\"global\" defaultEnabled={true}>\n <QueryClientProvider client={queryClient}>\n {isIntegrated ? (\n content\n ) : (\n <ApolloProvider client={workspaceClient}>{content}</ApolloProvider>\n )}\n </QueryClientProvider>\n </FeatureFlagProvider>\n </ErrorBoundary>\n );\n};\n"],"mappings":";;;;;;;;;;;;;AA6CA,IAAM,IAAqB,YACrB,IAAuB,YAGvB,IAA0B,KAY1B,IAAsB,KAGtB,IAAc,IAAI,EAAY,EAClC,gBAAgB,EACd,SAAS;CACP,WAAW,MAAS;CACpB,OAAO;CACR,EACF,EACF,CAAC,EAEW,KAA4C,MAAU;CAKjE,IAAM,IAAkB,EAAiB,YAAY,EAC/C,IAAe,EAAiB,SAAS,EACzC,CAAC,GAAa,KAAkB,EAAS,GAAM,EAC/C,CAAC,GAAa,KAAkB,EAAwB,KAAK,EAC7D,CAAC,GAAkB,KAAuB,EAAS,GAAM;AA6C/D,CAjCA,SACM,KAAmB,MACrB,EAAoB,EAAgB,EACpC,EAAqB,EAAa,EAG7B,GAAmB,CAAC,OAAO,MAAmB;AACjD,UAAQ,KAAK,uDAAuD,EAAM;GAC1E,EACF,EAAe,GAAK,SAET;AAEX,EADA,GAAuB,EACvB,GAAwB;KAEzB,CAAC,GAAiB,EAAa,CAAC,EAKnC,QAAgB;AACd,MAAI,EAAa;EACjB,IAAM,IAAQ,iBAAiB;AAC7B,KACE,kGACD;KACA,EAAwB;AAC3B,eAAa,aAAa,EAAM;IAC/B,CAAC,EAAY,CAAC,EAKjB,QAAgB;AACd,MAAI,EAAM,YAAa;EACvB,IAAM,IAAQ,iBAAiB,EAAoB,GAAK,EAAE,EAAoB;AAC9E,eAAa,aAAa,EAAM;IAC/B,CAAC,EAAM,YAAY,CAAC;CAKvB,IAAM,IAAsB,GAAa,MAAgC,IAItE,EAAE,CAAC,EAIA,IAAyB,EAAO,EAAoB;AA2C1D,KA1CA,QAAsB;AACpB,IAAuB,UAAU;IAChC,CAAC,EAAoB,CAAC,EAGzB,QAAgB;AACT,QAAM,cAoBX,QAdA,EAAoB;GAClB,eALqB,EAAM,cAAc,SAAS,IAAI,GACpD,EAAM,cAAc,MAAM,GAAG,GAAG,GAChC,EAAM;GAIR,WAAW,EAAM;GACjB,aAAa,EAAM,eAAe;GAClC,UAAU,EAAM;GAIhB,WAAW,EAAM,aAAa;GAC9B,aAAa,EAAM,eAAe;GAElC,kBAAkB,MAAgC,EAAuB,QAAQ,EAAO;GACzF,CAAC,QAEW;AACX,MAAuB;;IAExB;EACD,EAAM;EACN,EAAM;EACN,EAAM;EACN,EAAM;EACN,EAAM;EACN,EAAM;EACP,CAAC,EAME,CAAC,EAAM,YAIT,QAHK,IAGE,kBAAC,GAAD;EAAmB,UAAU,EAAM;EAAU,UAAU,EAAM;EAAY,CAAA,GAFvE,kBAAC,GAAD,EAAa,OAAM,2BAA4B,CAAA;AAM1D,KAAI,CAAC,EAmBH,QAlBI,IAEA,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,KAAD;IAAG,WAAU;cAAoC;IAAgB,CAAA,EACjE,kBAAC,UAAD;IACE,MAAK;IACL,eAAe,OAAO,SAAS,QAAQ;IACvC,WAAU;cACX;IAEQ,CAAA,CACL;;EACF,CAAA,GAKH,kBAAC,GAAD,EAAe,CAAA;CAGxB,IAAM,IAAe,CAAC,CAAC,EAAM,UAEvB,IACJ,kBAAC,GAAD;EAAgB,GAAI;YAClB,kBAAC,GAAD,EAAgB,CAAA;EACD,CAAA;AAGnB,QACE,kBAAC,GAAD;EACE,UACE,kBAAC,OAAD;GAAK,WAAU;aAAsC;GAE/C,CAAA;YAGR,kBAAC,GAAD;GAAqB,aAAa;GAAM,SAAQ;GAAS,gBAAgB;aACvE,kBAAC,GAAD;IAAqB,QAAQ;cAC1B,IACC,IAEA,kBAAC,GAAD;KAAgB,QAAQ;eAAkB;KAAyB,CAAA;IAEjD,CAAA;GACF,CAAA;EACR,CAAA"}
|
|
1
|
+
{"version":3,"file":"BotmanorRootInner.js","names":[],"sources":["../../src/botlit/BotmanorRootInner.tsx"],"sourcesContent":["/**\n * BotManor Root — implementation\n * @module botlit\n *\n * Product pages live behind this lazy boundary. Workflow routes and SDK\n * lifecycle are owned by the app-shell WorkflowsRoot, shared with every host.\n */\n\nimport type { FC } from 'react';\nimport { useEffect, useState } from 'react';\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query';\nimport { ApolloProvider } from '@apollo/client/react';\nimport { ErrorBoundary } from '@burdenoff/fe-libs/shared/components';\nimport { BotlitProvider } from './providers/BotlitProvider';\nimport { FeatureFlagProvider } from '@burdenoff/fe-libs/shared/feature-flags';\nimport { BotlitRoutes } from './BotlitRoutes';\nimport { RouteLoader } from './components/RouteLoader';\nimport { WorkspaceRequired } from './components/WorkspaceRequired';\nimport type { BotmanorRootProps } from './types';\n\nimport { useGatewayClient } from '@burdenoff/fe-libs/shared/graphql';\n\n/** How long to wait for the shell's gateway clients before showing an error. */\nconst CLIENT_READY_TIMEOUT_MS = 10_000;\n\n/**\n * How long to keep showing the loading skeleton before concluding that the\n * shell really has no active workspace.\n *\n * The shell resolves org/workspace asynchronously and passes `workspaceId=\"\"`\n * until it lands, which is indistinguishable from \"this user has no\n * workspace\". Without this settle window the guided zero state would flash on\n * every cold load — a get-started screen appearing and vanishing reads as a\n * broken page, which is exactly what this component exists to avoid.\n */\nconst WORKSPACE_SETTLE_MS = 2_000;\n\n// Create a query client for this microfrontend\nconst queryClient = new QueryClient({\n defaultOptions: {\n queries: {\n staleTime: 5 * 60 * 1000,\n retry: 1,\n },\n },\n});\n\nexport const BotmanorRootInner: FC<BotmanorRootProps> = (props) => {\n // NOTE: Navigation is now handled by the shell's NavRegistration.tsx\n // The shell manages all product submenu items in a centralized way\n\n // Product operations use the shell's authenticated workspace gateway client.\n const workspaceClient = useGatewayClient('workspace');\n const clientReady = Boolean(workspaceClient);\n const [clientError, setClientError] = useState<string | null>(null);\n const [workspaceSettled, setWorkspaceSettled] = useState(false);\n\n // Timeout fallback: if gateway clients are never provided (test env, shell\n // misconfiguration, auth failure before hydration), show an error rather than\n // spinning indefinitely.\n useEffect(() => {\n if (clientReady) return;\n const timer = setTimeout(() => {\n setClientError(\n 'BotManor could not connect to the gateway. Please refresh the page or check your configuration.'\n );\n }, CLIENT_READY_TIMEOUT_MS);\n return () => clearTimeout(timer);\n }, [clientReady]);\n\n // Give the shell a bounded window to resolve the active workspace before the\n // guided zero state is allowed to render. Cancelled the moment a workspace\n // arrives — a workspace that is already present never starts the timer.\n useEffect(() => {\n if (props.workspaceId) return;\n const timer = setTimeout(() => setWorkspaceSettled(true), WORKSPACE_SETTLE_MS);\n return () => clearTimeout(timer);\n }, [props.workspaceId]);\n\n // Without a workspace every BotManor query is unscoped and every write is\n // rejected — guide the user instead of rendering empty lists. Until the\n // settle window elapses we cannot tell \"still resolving\" from \"none\", so we\n // keep the same skeleton the shell was already showing.\n if (!props.workspaceId) {\n if (!workspaceSettled) {\n return <RouteLoader label=\"Loading your workspace…\" />;\n }\n return <WorkspaceRequired basePath={props.basePath} navigate={props.navigate} />;\n }\n\n // Don't render until clients are ready (same pattern as microfe-bigconsole)\n if (!clientReady) {\n if (clientError) {\n return (\n <div className=\"flex h-full min-h-[200px] w-full items-center justify-center p-6\">\n <div className=\"text-center\">\n <p className=\"mb-4 text-sm text-text-secondary\">{clientError}</p>\n <button\n type=\"button\"\n onClick={() => window.location.reload()}\n className=\"rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text transition-colors hover:bg-action-primary-bg-hover\"\n >\n Reload Page\n </button>\n </div>\n </div>\n );\n }\n // Same skeleton as the lazy-chunk fallback, so the content region never\n // switches loading idioms between first paint and the page rendering.\n return <RouteLoader />;\n }\n\n const isIntegrated = !!props.basePath;\n\n const content = (\n <BotlitProvider {...props}>\n <BotlitRoutes />\n </BotlitProvider>\n );\n\n return (\n <ErrorBoundary\n fallback={\n <div className=\"p-6 text-center text-text-secondary\">\n Something went wrong loading BotManor. Please refresh the page.\n </div>\n }\n >\n <FeatureFlagProvider workspaceId={null} gateway=\"global\" defaultEnabled={true}>\n <QueryClientProvider client={queryClient}>\n {isIntegrated ? (\n content\n ) : (\n <ApolloProvider client={workspaceClient}>{content}</ApolloProvider>\n )}\n </QueryClientProvider>\n </FeatureFlagProvider>\n </ErrorBoundary>\n );\n};\n"],"mappings":";;;;;;;;;;;;AAuBA,IAAM,IAA0B,KAY1B,IAAsB,KAGtB,IAAc,IAAI,EAAY,EAClC,gBAAgB,EACd,SAAS;CACP,WAAW,MAAS;CACpB,OAAO;CACR,EACF,EACF,CAAC,EAEW,KAA4C,MAAU;CAKjE,IAAM,IAAkB,EAAiB,YAAY,EAC/C,IAAc,EAAQ,GACtB,CAAC,GAAa,KAAkB,EAAwB,KAAK,EAC7D,CAAC,GAAkB,KAAuB,EAAS,GAAM;AA4B/D,KAvBA,QAAgB;AACd,MAAI,EAAa;EACjB,IAAM,IAAQ,iBAAiB;AAC7B,KACE,kGACD;KACA,EAAwB;AAC3B,eAAa,aAAa,EAAM;IAC/B,CAAC,EAAY,CAAC,EAKjB,QAAgB;AACd,MAAI,EAAM,YAAa;EACvB,IAAM,IAAQ,iBAAiB,EAAoB,GAAK,EAAE,EAAoB;AAC9E,eAAa,aAAa,EAAM;IAC/B,CAAC,EAAM,YAAY,CAAC,EAMnB,CAAC,EAAM,YAIT,QAHK,IAGE,kBAAC,GAAD;EAAmB,UAAU,EAAM;EAAU,UAAU,EAAM;EAAY,CAAA,GAFvE,kBAAC,GAAD,EAAa,OAAM,2BAA4B,CAAA;AAM1D,KAAI,CAAC,EAmBH,QAlBI,IAEA,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,KAAD;IAAG,WAAU;cAAoC;IAAgB,CAAA,EACjE,kBAAC,UAAD;IACE,MAAK;IACL,eAAe,OAAO,SAAS,QAAQ;IACvC,WAAU;cACX;IAEQ,CAAA,CACL;;EACF,CAAA,GAKH,kBAAC,GAAD,EAAe,CAAA;CAGxB,IAAM,IAAe,CAAC,CAAC,EAAM,UAEvB,IACJ,kBAAC,GAAD;EAAgB,GAAI;YAClB,kBAAC,GAAD,EAAgB,CAAA;EACD,CAAA;AAGnB,QACE,kBAAC,GAAD;EACE,UACE,kBAAC,OAAD;GAAK,WAAU;aAAsC;GAE/C,CAAA;YAGR,kBAAC,GAAD;GAAqB,aAAa;GAAM,SAAQ;GAAS,gBAAgB;aACvE,kBAAC,GAAD;IAAqB,QAAQ;cAC1B,IACC,IAEA,kBAAC,GAAD;KAAgB,QAAQ;eAAkB;KAAyB,CAAA;IAEjD,CAAA;GACF,CAAA;EACR,CAAA"}
|
|
@@ -62,7 +62,7 @@ function c({ agentId: e, onConfigured: s }) {
|
|
|
62
62
|
}
|
|
63
63
|
},
|
|
64
64
|
children: "Configure assistant"
|
|
65
|
-
})] }) : /* @__PURE__ */ a("p", { children: "Create an active
|
|
65
|
+
})] }) : /* @__PURE__ */ a("p", { children: "Create an active BotManor Assistant Runtime connection in Integrations, then reload this page." }),
|
|
66
66
|
f && /* @__PURE__ */ a("p", {
|
|
67
67
|
role: m ? "alert" : "status",
|
|
68
68
|
children: f
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AssistantRuntimeSetupPanel.js","names":[],"sources":["../../../src/botlit/components/AssistantRuntimeSetupPanel.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { useAssistantRuntimeSetup } from '../hooks/useAssistantRuntimeSetup';\nimport { useBotlit } from '../providers/BotlitProvider';\nimport { Button } from './Button';\n\nexport function AssistantRuntimeSetupPanel({\n agentId,\n onConfigured,\n}: {\n agentId: string;\n onConfigured: () => void;\n}) {\n const { workspaceId, currentUser } = useBotlit();\n return (\n <ScopedSetupPanel\n key={`${workspaceId}:${currentUser?.id}:${agentId}`}\n agentId={agentId}\n onConfigured={onConfigured}\n />\n );\n}\n\nfunction ScopedSetupPanel({\n agentId,\n onConfigured,\n}: {\n agentId: string;\n onConfigured: () => void;\n}) {\n const { connections, configure } = useAssistantRuntimeSetup(agentId);\n const [selected, setSelected] = useState('');\n const [message, setMessage] = useState('');\n const [failed, setFailed] = useState(false);\n return (\n <section className=\"space-y-4 rounded-lg border border-border-default p-5\">\n <div>\n <h2 className=\"text-lg font-semibold\">Assistant setup</h2>\n <p className=\"text-sm text-text-secondary\">\n Connect this assistant to Fluidgrids for answers and recovery. Course teachers also\n receive content ingestion workflows.\n </p>\n </div>\n {connections.isPending ? (\n <p role=\"status\">Loading connections…</p>\n ) : connections.isError ? (\n <div role=\"alert\">\n <p>Connections could not be loaded. Check your access and try again.</p>\n <Button variant=\"outline\" onClick={() => void connections.refetch()}>\n Reload connections\n </Button>\n </div>\n ) : !connections.data?.length ? (\n <p>\n Create an active
|
|
1
|
+
{"version":3,"file":"AssistantRuntimeSetupPanel.js","names":[],"sources":["../../../src/botlit/components/AssistantRuntimeSetupPanel.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { useAssistantRuntimeSetup } from '../hooks/useAssistantRuntimeSetup';\nimport { useBotlit } from '../providers/BotlitProvider';\nimport { Button } from './Button';\n\nexport function AssistantRuntimeSetupPanel({\n agentId,\n onConfigured,\n}: {\n agentId: string;\n onConfigured: () => void;\n}) {\n const { workspaceId, currentUser } = useBotlit();\n return (\n <ScopedSetupPanel\n key={`${workspaceId}:${currentUser?.id}:${agentId}`}\n agentId={agentId}\n onConfigured={onConfigured}\n />\n );\n}\n\nfunction ScopedSetupPanel({\n agentId,\n onConfigured,\n}: {\n agentId: string;\n onConfigured: () => void;\n}) {\n const { connections, configure } = useAssistantRuntimeSetup(agentId);\n const [selected, setSelected] = useState('');\n const [message, setMessage] = useState('');\n const [failed, setFailed] = useState(false);\n return (\n <section className=\"space-y-4 rounded-lg border border-border-default p-5\">\n <div>\n <h2 className=\"text-lg font-semibold\">Assistant setup</h2>\n <p className=\"text-sm text-text-secondary\">\n Connect this assistant to Fluidgrids for answers and recovery. Course teachers also\n receive content ingestion workflows.\n </p>\n </div>\n {connections.isPending ? (\n <p role=\"status\">Loading connections…</p>\n ) : connections.isError ? (\n <div role=\"alert\">\n <p>Connections could not be loaded. Check your access and try again.</p>\n <Button variant=\"outline\" onClick={() => void connections.refetch()}>\n Reload connections\n </Button>\n </div>\n ) : !connections.data?.length ? (\n <p>\n Create an active BotManor Assistant Runtime connection in Integrations, then reload this\n page.\n </p>\n ) : (\n <>\n <label className=\"grid gap-2 text-sm font-medium\">\n Workflow connection\n <select\n className=\"h-10 rounded-md border border-border-default bg-bg-surface px-3\"\n value={selected}\n disabled={configure.isPending}\n onChange={(event) => {\n setSelected(event.target.value);\n setMessage('');\n }}\n >\n <option value=\"\">Choose a connection</option>\n {connections.data.map((connection) => (\n <option key={connection.id} value={connection.id}>\n {connection.name}\n </option>\n ))}\n </select>\n </label>\n <Button\n disabled={!selected}\n isLoading={configure.isPending}\n onClick={async () => {\n setMessage('');\n setFailed(false);\n try {\n const result = await configure.mutateAsync(selected);\n setMessage(\n result.ready\n ? 'Assistant configured and ready.'\n : 'Workflows configured. Activate the assistant and finish indexing its knowledge before using it.'\n );\n onConfigured();\n } catch {\n setFailed(true);\n setMessage(\n 'Setup could not be completed. Check the model, knowledge scope and your permissions, then try again.'\n );\n }\n }}\n >\n Configure assistant\n </Button>\n </>\n )}\n {message && <p role={failed ? 'alert' : 'status'}>{message}</p>}\n </section>\n );\n}\n"],"mappings":";;;;;;AAKA,SAAgB,EAA2B,EACzC,YACA,mBAIC;CACD,IAAM,EAAE,gBAAa,mBAAgB,GAAW;AAChD,QACE,kBAAC,GAAD;EAEW;EACK;EACd,EAHK,GAAG,EAAY,GAAG,GAAa,GAAG,GAAG,IAG1C;;AAIN,SAAS,EAAiB,EACxB,YACA,mBAIC;CACD,IAAM,EAAE,gBAAa,iBAAc,EAAyB,EAAQ,EAC9D,CAAC,GAAU,KAAe,EAAS,GAAG,EACtC,CAAC,GAAS,KAAc,EAAS,GAAG,EACpC,CAAC,GAAQ,KAAa,EAAS,GAAM;AAC3C,QACE,kBAAC,WAAD;EAAS,WAAU;YAAnB;GACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;IAAI,WAAU;cAAwB;IAAoB,CAAA,EAC1D,kBAAC,KAAD;IAAG,WAAU;cAA8B;IAGvC,CAAA,CACA,EAAA,CAAA;GACL,EAAY,YACX,kBAAC,KAAD;IAAG,MAAK;cAAS;IAAwB,CAAA,GACvC,EAAY,UACd,kBAAC,OAAD;IAAK,MAAK;cAAV,CACE,kBAAC,KAAD,EAAA,UAAG,qEAAqE,CAAA,EACxE,kBAAC,GAAD;KAAQ,SAAQ;KAAU,eAAe,KAAK,EAAY,SAAS;eAAE;KAE5D,CAAA,CACL;QACH,EAAY,MAAM,SAMrB,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,SAAD;IAAO,WAAU;cAAjB,CAAkD,uBAEhD,kBAAC,UAAD;KACE,WAAU;KACV,OAAO;KACP,UAAU,EAAU;KACpB,WAAW,MAAU;AAEnB,MADA,EAAY,EAAM,OAAO,MAAM,EAC/B,EAAW,GAAG;;eANlB,CASE,kBAAC,UAAD;MAAQ,OAAM;gBAAG;MAA4B,CAAA,EAC5C,EAAY,KAAK,KAAK,MACrB,kBAAC,UAAD;MAA4B,OAAO,EAAW;gBAC3C,EAAW;MACL,EAFI,EAAW,GAEf,CACT,CACK;OACH;OACR,kBAAC,GAAD;IACE,UAAU,CAAC;IACX,WAAW,EAAU;IACrB,SAAS,YAAY;AAEnB,KADA,EAAW,GAAG,EACd,EAAU,GAAM;AAChB,SAAI;AAOF,MALA,GADe,MAAM,EAAU,YAAY,EAAS,EAE3C,QACH,oCACA,kGACL,EACD,GAAc;aACR;AAEN,MADA,EAAU,GAAK,EACf,EACE,uGACD;;;cAGN;IAEQ,CAAA,CACR,EAAA,CAAA,GAjDH,kBAAC,KAAD,EAAA,UAAG,kGAGC,CAAA;GAgDL,KAAW,kBAAC,KAAD;IAAG,MAAM,IAAS,UAAU;cAAW;IAAY,CAAA;GACvD"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { useCreateLLMModel as e } from "../hooks/useLLMProviders.js";
|
|
2
|
+
import { Card as t, CardContent as n, CardHeader as r, CardTitle as i } from "./Card.js";
|
|
3
|
+
import { Button as a } from "./Button.js";
|
|
4
|
+
import { FormField as o, Input as s } from "./Input.js";
|
|
5
|
+
import { useState as c } from "react";
|
|
6
|
+
import { jsx as l, jsxs as u } from "react/jsx-runtime";
|
|
7
|
+
import { toast as d } from "sonner";
|
|
8
|
+
//#region src/botlit/components/ModelRegistrationPanel.tsx
|
|
9
|
+
function f({ providers: f, onCreated: p }) {
|
|
10
|
+
let { createModel: m, isCreating: h } = e(), [g, _] = c(""), [v, y] = c(""), [b, x] = c(""), [S, C] = c("answer"), [w, T] = c(""), [E, D] = c("8192"), [O, k] = c("2048"), [A, j] = c("0"), [M, N] = c("0"), P = f.filter((e) => e.isActive), F = P.find((e) => e.id === g), I = F?.type === "AWS_BEDROCK" ? b.trim() === "amazon.titan-embed-text-v2:0" : [
|
|
11
|
+
"OPENAI",
|
|
12
|
+
"AZURE_OPENAI",
|
|
13
|
+
"CUSTOM"
|
|
14
|
+
].includes(F?.type ?? ""), L = P.some((e) => e.id === g) && !!(v.trim() && b.trim()) && Number.isSafeInteger(Number(E)) && Number(E) > 0 && (S !== "embedding" || I && Number.isInteger(Number(w)) && Number(w) > 0 && Number(w) <= 16e3) && (S === "embedding" || Number.isSafeInteger(Number(O)) && Number(O) > 0) && (S === "embedding" ? [A] : [A, M]).every((e) => e.trim() !== "" && Number.isFinite(Number(e)) && Number(e) >= 0);
|
|
15
|
+
return /* @__PURE__ */ u(t, { children: [/* @__PURE__ */ l(r, { children: /* @__PURE__ */ l(i, { children: "Register model" }) }), /* @__PURE__ */ u(n, {
|
|
16
|
+
className: "space-y-4",
|
|
17
|
+
children: [
|
|
18
|
+
/* @__PURE__ */ l("p", {
|
|
19
|
+
className: "text-sm text-text-secondary",
|
|
20
|
+
children: "Register an answer or embedding model available through your provider. Model access and billing limits must already be configured."
|
|
21
|
+
}),
|
|
22
|
+
/* @__PURE__ */ l(o, {
|
|
23
|
+
label: "Model provider",
|
|
24
|
+
children: /* @__PURE__ */ u("select", {
|
|
25
|
+
"aria-label": "Model provider",
|
|
26
|
+
value: g,
|
|
27
|
+
onChange: (e) => {
|
|
28
|
+
_(e.target.value);
|
|
29
|
+
let t = P.find((t) => t.id === e.target.value);
|
|
30
|
+
T(t?.type === "AWS_BEDROCK" ? String(t.metadata?.embeddingDimensions ?? 1024) : "");
|
|
31
|
+
},
|
|
32
|
+
className: "h-10 w-full rounded-md border bg-bg-surface px-3",
|
|
33
|
+
children: [/* @__PURE__ */ l("option", {
|
|
34
|
+
value: "",
|
|
35
|
+
children: "Choose an active provider"
|
|
36
|
+
}), P.map((e) => /* @__PURE__ */ l("option", {
|
|
37
|
+
value: e.id,
|
|
38
|
+
children: e.name
|
|
39
|
+
}, e.id))]
|
|
40
|
+
})
|
|
41
|
+
}),
|
|
42
|
+
/* @__PURE__ */ l(o, {
|
|
43
|
+
label: "Model name",
|
|
44
|
+
children: /* @__PURE__ */ l(s, {
|
|
45
|
+
"aria-label": "Model name",
|
|
46
|
+
value: v,
|
|
47
|
+
maxLength: 255,
|
|
48
|
+
onChange: (e) => y(e.target.value)
|
|
49
|
+
})
|
|
50
|
+
}),
|
|
51
|
+
/* @__PURE__ */ l(o, {
|
|
52
|
+
label: "Provider model ID",
|
|
53
|
+
children: /* @__PURE__ */ l(s, {
|
|
54
|
+
"aria-label": "Provider model ID",
|
|
55
|
+
value: b,
|
|
56
|
+
maxLength: 255,
|
|
57
|
+
onChange: (e) => {
|
|
58
|
+
x(e.target.value);
|
|
59
|
+
let t = {
|
|
60
|
+
"text-embedding-3-small": 1536,
|
|
61
|
+
"text-embedding-3-large": 3072,
|
|
62
|
+
"text-embedding-ada-002": 1536
|
|
63
|
+
}[e.target.value.trim()];
|
|
64
|
+
t && T(String(t));
|
|
65
|
+
}
|
|
66
|
+
})
|
|
67
|
+
}),
|
|
68
|
+
/* @__PURE__ */ l(o, {
|
|
69
|
+
label: "Model purpose",
|
|
70
|
+
children: /* @__PURE__ */ u("select", {
|
|
71
|
+
"aria-label": "Model purpose",
|
|
72
|
+
value: S,
|
|
73
|
+
onChange: (e) => C(e.target.value),
|
|
74
|
+
className: "h-10 w-full rounded-md border bg-bg-surface px-3",
|
|
75
|
+
children: [/* @__PURE__ */ l("option", {
|
|
76
|
+
value: "answer",
|
|
77
|
+
children: "Answer generation"
|
|
78
|
+
}), /* @__PURE__ */ l("option", {
|
|
79
|
+
value: "embedding",
|
|
80
|
+
children: "Content embeddings"
|
|
81
|
+
})]
|
|
82
|
+
})
|
|
83
|
+
}),
|
|
84
|
+
S === "embedding" && /* @__PURE__ */ u(o, {
|
|
85
|
+
label: "Embedding dimensions",
|
|
86
|
+
children: [/* @__PURE__ */ l(s, {
|
|
87
|
+
"aria-label": "Embedding dimensions",
|
|
88
|
+
type: "number",
|
|
89
|
+
min: 1,
|
|
90
|
+
max: 16e3,
|
|
91
|
+
disabled: F?.type === "AWS_BEDROCK",
|
|
92
|
+
value: w,
|
|
93
|
+
onChange: (e) => T(e.target.value)
|
|
94
|
+
}), /* @__PURE__ */ l("p", {
|
|
95
|
+
className: "text-sm text-text-secondary",
|
|
96
|
+
children: "Use the vector size returned by this deployment. Supported: Titan Text Embeddings V2 and OpenAI-compatible embedding endpoints."
|
|
97
|
+
})]
|
|
98
|
+
}),
|
|
99
|
+
/* @__PURE__ */ l(o, {
|
|
100
|
+
label: "Context window",
|
|
101
|
+
children: /* @__PURE__ */ l(s, {
|
|
102
|
+
"aria-label": "Context window",
|
|
103
|
+
type: "number",
|
|
104
|
+
min: 1,
|
|
105
|
+
value: E,
|
|
106
|
+
onChange: (e) => D(e.target.value)
|
|
107
|
+
})
|
|
108
|
+
}),
|
|
109
|
+
S === "answer" && /* @__PURE__ */ l(o, {
|
|
110
|
+
label: "Maximum output tokens",
|
|
111
|
+
children: /* @__PURE__ */ l(s, {
|
|
112
|
+
"aria-label": "Maximum output tokens",
|
|
113
|
+
type: "number",
|
|
114
|
+
min: 1,
|
|
115
|
+
value: O,
|
|
116
|
+
onChange: (e) => k(e.target.value)
|
|
117
|
+
})
|
|
118
|
+
}),
|
|
119
|
+
/* @__PURE__ */ l(o, {
|
|
120
|
+
label: "Input price per million tokens",
|
|
121
|
+
children: /* @__PURE__ */ l(s, {
|
|
122
|
+
"aria-label": "Input price per million tokens",
|
|
123
|
+
type: "number",
|
|
124
|
+
min: 0,
|
|
125
|
+
step: "any",
|
|
126
|
+
value: A,
|
|
127
|
+
onChange: (e) => j(e.target.value)
|
|
128
|
+
})
|
|
129
|
+
}),
|
|
130
|
+
S === "answer" && /* @__PURE__ */ l(o, {
|
|
131
|
+
label: "Output price per million tokens",
|
|
132
|
+
children: /* @__PURE__ */ l(s, {
|
|
133
|
+
"aria-label": "Output price per million tokens",
|
|
134
|
+
type: "number",
|
|
135
|
+
min: 0,
|
|
136
|
+
step: "any",
|
|
137
|
+
value: M,
|
|
138
|
+
onChange: (e) => N(e.target.value)
|
|
139
|
+
})
|
|
140
|
+
}),
|
|
141
|
+
/* @__PURE__ */ l(a, {
|
|
142
|
+
disabled: !L,
|
|
143
|
+
isLoading: h,
|
|
144
|
+
onClick: async () => {
|
|
145
|
+
try {
|
|
146
|
+
await m({
|
|
147
|
+
providerId: g,
|
|
148
|
+
name: v.trim(),
|
|
149
|
+
modelId: b.trim(),
|
|
150
|
+
contextWindow: Number(E),
|
|
151
|
+
maxOutputTokens: S === "embedding" ? 0 : Number(O),
|
|
152
|
+
inputPricePerMToken: Number(A),
|
|
153
|
+
outputPricePerMToken: S === "embedding" ? 0 : Number(M),
|
|
154
|
+
supportsStreaming: S === "answer",
|
|
155
|
+
supportsFunctionCalling: !1,
|
|
156
|
+
supportsVision: !1,
|
|
157
|
+
metadata: {
|
|
158
|
+
purpose: S,
|
|
159
|
+
...S === "embedding" ? { embeddingDimensions: Number(w) } : {}
|
|
160
|
+
}
|
|
161
|
+
}), y(""), x(""), p(), d.success("Model registered.");
|
|
162
|
+
} catch (e) {
|
|
163
|
+
d.error(e instanceof Error ? e.message : "Model registration failed.");
|
|
164
|
+
}
|
|
165
|
+
},
|
|
166
|
+
children: "Register model"
|
|
167
|
+
})
|
|
168
|
+
]
|
|
169
|
+
})] });
|
|
170
|
+
}
|
|
171
|
+
//#endregion
|
|
172
|
+
export { f as ModelRegistrationPanel };
|
|
173
|
+
|
|
174
|
+
//# sourceMappingURL=ModelRegistrationPanel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ModelRegistrationPanel.js","names":[],"sources":["../../../src/botlit/components/ModelRegistrationPanel.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { toast } from 'sonner';\nimport { useCreateLLMModel, type LLMProviderRecord } from '../hooks/useLLMProviders';\nimport { Button } from './Button';\nimport { Card, CardContent, CardHeader, CardTitle } from './Card';\nimport { FormField, Input } from './Input';\n\nexport function ModelRegistrationPanel({\n providers,\n onCreated,\n}: {\n providers: LLMProviderRecord[];\n onCreated: () => void;\n}) {\n const { createModel, isCreating } = useCreateLLMModel();\n const [providerId, setProviderId] = useState('');\n const [name, setName] = useState('');\n const [modelId, setModelId] = useState('');\n const [purpose, setPurpose] = useState('answer');\n const [embeddingDimensions, setEmbeddingDimensions] = useState('');\n const [contextWindow, setContextWindow] = useState('8192');\n const [maxOutputTokens, setMaxOutputTokens] = useState('2048');\n const [inputPrice, setInputPrice] = useState('0');\n const [outputPrice, setOutputPrice] = useState('0');\n const activeProviders = providers.filter((provider) => provider.isActive);\n const selectedProvider = activeProviders.find((provider) => provider.id === providerId);\n const embeddingSupported =\n selectedProvider?.type === 'AWS_BEDROCK'\n ? modelId.trim() === 'amazon.titan-embed-text-v2:0'\n : ['OPENAI', 'AZURE_OPENAI', 'CUSTOM'].includes(selectedProvider?.type ?? '');\n const valid =\n activeProviders.some((provider) => provider.id === providerId) &&\n Boolean(name.trim() && modelId.trim()) &&\n Number.isSafeInteger(Number(contextWindow)) &&\n Number(contextWindow) > 0 &&\n (purpose !== 'embedding' ||\n (embeddingSupported &&\n Number.isInteger(Number(embeddingDimensions)) &&\n Number(embeddingDimensions) > 0 &&\n Number(embeddingDimensions) <= 16000)) &&\n (purpose === 'embedding' ||\n (Number.isSafeInteger(Number(maxOutputTokens)) && Number(maxOutputTokens) > 0)) &&\n (purpose === 'embedding' ? [inputPrice] : [inputPrice, outputPrice]).every(\n (value) => value.trim() !== '' && Number.isFinite(Number(value)) && Number(value) >= 0\n );\n return (\n <Card>\n <CardHeader>\n <CardTitle>Register model</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <p className=\"text-sm text-text-secondary\">\n Register an answer or embedding model available through your provider. Model access and\n billing limits must already be configured.\n </p>\n <FormField label=\"Model provider\">\n <select\n aria-label=\"Model provider\"\n value={providerId}\n onChange={(event) => {\n setProviderId(event.target.value);\n const provider = activeProviders.find((entry) => entry.id === event.target.value);\n setEmbeddingDimensions(\n provider?.type === 'AWS_BEDROCK'\n ? String(provider.metadata?.embeddingDimensions ?? 1024)\n : ''\n );\n }}\n className=\"h-10 w-full rounded-md border bg-bg-surface px-3\"\n >\n <option value=\"\">Choose an active provider</option>\n {activeProviders.map((provider) => (\n <option key={provider.id} value={provider.id}>\n {provider.name}\n </option>\n ))}\n </select>\n </FormField>\n <FormField label=\"Model name\">\n <Input\n aria-label=\"Model name\"\n value={name}\n maxLength={255}\n onChange={(event) => setName(event.target.value)}\n />\n </FormField>\n <FormField label=\"Provider model ID\">\n <Input\n aria-label=\"Provider model ID\"\n value={modelId}\n maxLength={255}\n onChange={(event) => {\n setModelId(event.target.value);\n const defaultDimensions: Record<string, number> = {\n 'text-embedding-3-small': 1536,\n 'text-embedding-3-large': 3072,\n 'text-embedding-ada-002': 1536,\n };\n const dimensions = defaultDimensions[event.target.value.trim()];\n if (dimensions) setEmbeddingDimensions(String(dimensions));\n }}\n />\n </FormField>\n <FormField label=\"Model purpose\">\n <select\n aria-label=\"Model purpose\"\n value={purpose}\n onChange={(event) => setPurpose(event.target.value)}\n className=\"h-10 w-full rounded-md border bg-bg-surface px-3\"\n >\n <option value=\"answer\">Answer generation</option>\n <option value=\"embedding\">Content embeddings</option>\n </select>\n </FormField>\n {purpose === 'embedding' && (\n <FormField label=\"Embedding dimensions\">\n <Input\n aria-label=\"Embedding dimensions\"\n type=\"number\"\n min={1}\n max={16000}\n disabled={selectedProvider?.type === 'AWS_BEDROCK'}\n value={embeddingDimensions}\n onChange={(event) => setEmbeddingDimensions(event.target.value)}\n />\n <p className=\"text-sm text-text-secondary\">\n Use the vector size returned by this deployment. Supported: Titan Text Embeddings V2\n and OpenAI-compatible embedding endpoints.\n </p>\n </FormField>\n )}\n <FormField label=\"Context window\">\n <Input\n aria-label=\"Context window\"\n type=\"number\"\n min={1}\n value={contextWindow}\n onChange={(event) => setContextWindow(event.target.value)}\n />\n </FormField>\n {purpose === 'answer' && (\n <FormField label=\"Maximum output tokens\">\n <Input\n aria-label=\"Maximum output tokens\"\n type=\"number\"\n min={1}\n value={maxOutputTokens}\n onChange={(event) => setMaxOutputTokens(event.target.value)}\n />\n </FormField>\n )}\n <FormField label=\"Input price per million tokens\">\n <Input\n aria-label=\"Input price per million tokens\"\n type=\"number\"\n min={0}\n step=\"any\"\n value={inputPrice}\n onChange={(event) => setInputPrice(event.target.value)}\n />\n </FormField>\n {purpose === 'answer' && (\n <FormField label=\"Output price per million tokens\">\n <Input\n aria-label=\"Output price per million tokens\"\n type=\"number\"\n min={0}\n step=\"any\"\n value={outputPrice}\n onChange={(event) => setOutputPrice(event.target.value)}\n />\n </FormField>\n )}\n <Button\n disabled={!valid}\n isLoading={isCreating}\n onClick={async () => {\n try {\n await createModel({\n providerId,\n name: name.trim(),\n modelId: modelId.trim(),\n contextWindow: Number(contextWindow),\n maxOutputTokens: purpose === 'embedding' ? 0 : Number(maxOutputTokens),\n inputPricePerMToken: Number(inputPrice),\n outputPricePerMToken: purpose === 'embedding' ? 0 : Number(outputPrice),\n supportsStreaming: purpose === 'answer',\n supportsFunctionCalling: false,\n supportsVision: false,\n metadata: {\n purpose,\n ...(purpose === 'embedding'\n ? { embeddingDimensions: Number(embeddingDimensions) }\n : {}),\n },\n });\n setName('');\n setModelId('');\n onCreated();\n toast.success('Model registered.');\n } catch (error) {\n toast.error(error instanceof Error ? error.message : 'Model registration failed.');\n }\n }}\n >\n Register model\n </Button>\n </CardContent>\n </Card>\n );\n}\n"],"mappings":"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"}
|
|
@@ -94,6 +94,6 @@ function f(e) {
|
|
|
94
94
|
]), d];
|
|
95
95
|
}
|
|
96
96
|
//#endregion
|
|
97
|
-
export { c as useWorkspaceId, f as useWorkspaceMutation, d as useWorkspaceQuery };
|
|
97
|
+
export { s as useWorkspaceClient, c as useWorkspaceId, f as useWorkspaceMutation, d as useWorkspaceQuery };
|
|
98
98
|
|
|
99
99
|
//# sourceMappingURL=workspaceGateway.js.map
|
|
@@ -5,7 +5,7 @@ import { useMutation as r, useQuery as i } from "@tanstack/react-query";
|
|
|
5
5
|
//#region src/botlit/hooks/useAssistantRuntimeSetup.ts
|
|
6
6
|
var a = t`
|
|
7
7
|
query AssistantWorkflowProvider {
|
|
8
|
-
getProviderByKey(key: "
|
|
8
|
+
getProviderByKey(key: "botmanor-runtime") {
|
|
9
9
|
id
|
|
10
10
|
}
|
|
11
11
|
}
|
|
@@ -74,7 +74,7 @@ function c(t) {
|
|
|
74
74
|
fetchPolicy: "no-cache"
|
|
75
75
|
})).data?.getConnections;
|
|
76
76
|
if (!r || r.items.length > 100) throw Error("Connections unavailable");
|
|
77
|
-
for (let e of r.items) e.workspaceId === l && e.status === "ACTIVE" && e.provider.key === "
|
|
77
|
+
for (let e of r.items) e.workspaceId === l && e.status === "ACTIVE" && e.provider.key === "botmanor-runtime" && e.authMethod?.authType === "WORKSPACE_APP_TOKEN" && e.authMethod.isEnabled && e.authMethod.isConfigured && t.push({
|
|
78
78
|
id: e.id,
|
|
79
79
|
name: e.name
|
|
80
80
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAssistantRuntimeSetup.js","names":[],"sources":["../../../src/botlit/hooks/useAssistantRuntimeSetup.ts"],"sourcesContent":["import { gql } from '@apollo/client';\nimport { useMutation, useQuery } from '@tanstack/react-query';\nimport { useGatewayClient } from '@burdenoff/fe-libs/shared/graphql';\nimport { useBotlit } from '../providers/BotlitProvider';\n\ninterface Connection {\n id: string;\n name: string;\n workspaceId: string | null;\n status: string;\n provider: { key: string };\n authMethod: { authType: string; isEnabled: boolean; isConfigured: boolean } | null;\n}\nexport interface AssistantRuntimeConfiguration {\n agentId: string;\n courseId: string | null;\n inferenceWorkflowId: string;\n recoveryWorkflowId: string;\n recoveryScheduleId: string;\n ingestionWorkflowId: string | null;\n protocolVersion: number;\n ready: boolean;\n}\nconst PROVIDER = gql`\n query AssistantWorkflowProvider {\n getProviderByKey(key: \"
|
|
1
|
+
{"version":3,"file":"useAssistantRuntimeSetup.js","names":[],"sources":["../../../src/botlit/hooks/useAssistantRuntimeSetup.ts"],"sourcesContent":["import { gql } from '@apollo/client';\nimport { useMutation, useQuery } from '@tanstack/react-query';\nimport { useGatewayClient } from '@burdenoff/fe-libs/shared/graphql';\nimport { useBotlit } from '../providers/BotlitProvider';\n\ninterface Connection {\n id: string;\n name: string;\n workspaceId: string | null;\n status: string;\n provider: { key: string };\n authMethod: { authType: string; isEnabled: boolean; isConfigured: boolean } | null;\n}\nexport interface AssistantRuntimeConfiguration {\n agentId: string;\n courseId: string | null;\n inferenceWorkflowId: string;\n recoveryWorkflowId: string;\n recoveryScheduleId: string;\n ingestionWorkflowId: string | null;\n protocolVersion: number;\n ready: boolean;\n}\nconst PROVIDER = gql`\n query AssistantWorkflowProvider {\n getProviderByKey(key: \"botmanor-runtime\") {\n id\n }\n }\n`;\nconst CONNECTIONS = gql`\n query AssistantWorkflowConnections($providerId: ID!, $offset: Int!) {\n getConnections(\n filter: { providerId: $providerId, status: ACTIVE }\n pagination: { limit: 100, offset: $offset }\n ) {\n hasMore\n items {\n id\n name\n workspaceId\n status\n provider {\n key\n }\n authMethod {\n authType\n isEnabled\n isConfigured\n }\n }\n }\n }\n`;\nconst CONFIGURE = gql`\n mutation ConfigureAssistantRuntime($agentId: ID!, $connectionId: ID!) {\n configureAssistantRuntime(agentId: $agentId, connectionId: $connectionId) {\n agentId\n courseId\n inferenceWorkflowId\n recoveryWorkflowId\n recoveryScheduleId\n ingestionWorkflowId\n protocolVersion\n ready\n }\n }\n`;\n\nexport function useAssistantRuntimeSetup(agentId: string) {\n const client = useGatewayClient('workspace');\n const { workspaceId, currentUser } = useBotlit();\n const connections = useQuery({\n queryKey: ['botmanor-assistant-connections', workspaceId, currentUser?.id],\n enabled: Boolean(workspaceId && currentUser?.id),\n retry: false,\n queryFn: async () => {\n const provider = await client.query<{ getProviderByKey: { id: string } | null }>({\n query: PROVIDER,\n fetchPolicy: 'no-cache',\n });\n const providerId = provider.data?.getProviderByKey?.id;\n if (!providerId) return [];\n const result: Array<{ id: string; name: string }> = [];\n for (let offset = 0; offset < 500; offset += 100) {\n const page = await client.query<{\n getConnections: { hasMore: boolean; items: Connection[] };\n }>({\n query: CONNECTIONS,\n variables: { providerId, offset },\n fetchPolicy: 'no-cache',\n });\n const data = page.data?.getConnections;\n if (!data || data.items.length > 100) throw new Error('Connections unavailable');\n for (const connection of data.items) {\n if (\n connection.workspaceId === workspaceId &&\n connection.status === 'ACTIVE' &&\n connection.provider.key === 'botmanor-runtime' &&\n connection.authMethod?.authType === 'WORKSPACE_APP_TOKEN' &&\n connection.authMethod.isEnabled &&\n connection.authMethod.isConfigured\n )\n result.push({ id: connection.id, name: connection.name });\n }\n if (!data.hasMore) return result;\n }\n throw new Error('Connection list exceeds the supported limit');\n },\n });\n const configure = useMutation({\n mutationKey: ['botmanor-assistant-runtime', workspaceId, currentUser?.id, agentId],\n retry: false,\n mutationFn: async (connectionId: string) => {\n if (!workspaceId || !currentUser?.id) throw new Error('Sign in to configure an assistant');\n const result = await client.mutate<{\n configureAssistantRuntime: AssistantRuntimeConfiguration;\n }>({\n mutation: CONFIGURE,\n variables: { agentId, connectionId },\n });\n const configured = result.data?.configureAssistantRuntime;\n if (\n !configured ||\n configured.agentId !== agentId ||\n configured.protocolVersion !== 2 ||\n !configured.inferenceWorkflowId ||\n !configured.recoveryWorkflowId ||\n !configured.recoveryScheduleId ||\n typeof configured.ready !== 'boolean'\n )\n throw new Error('Runtime configuration unavailable');\n return configured;\n },\n });\n return { connections, configure };\n}\n"],"mappings":";;;;;AAuBA,IAAM,IAAW,CAAG;;;;;;GAOd,IAAc,CAAG;;;;;;;;;;;;;;;;;;;;;;;GAwBjB,IAAY,CAAG;;;;;;;;;;;;;;AAerB,SAAgB,EAAyB,GAAiB;CACxD,IAAM,IAAS,EAAiB,YAAY,EACtC,EAAE,gBAAa,mBAAgB,GAAW;AAgEhD,QAAO;EAAE,aA/DW,EAAS;GAC3B,UAAU;IAAC;IAAkC;IAAa,GAAa;IAAG;GAC1E,SAAS,GAAQ,KAAe,GAAa;GAC7C,OAAO;GACP,SAAS,YAAY;IAKnB,IAAM,KAJW,MAAM,EAAO,MAAmD;KAC/E,OAAO;KACP,aAAa;KACd,CAAC,EAC0B,MAAM,kBAAkB;AACpD,QAAI,CAAC,EAAY,QAAO,EAAE;IAC1B,IAAM,IAA8C,EAAE;AACtD,SAAK,IAAI,IAAS,GAAG,IAAS,KAAK,KAAU,KAAK;KAQhD,IAAM,KAPO,MAAM,EAAO,MAEvB;MACD,OAAO;MACP,WAAW;OAAE;OAAY;OAAQ;MACjC,aAAa;MACd,CAAC,EACgB,MAAM;AACxB,SAAI,CAAC,KAAQ,EAAK,MAAM,SAAS,IAAK,OAAU,MAAM,0BAA0B;AAChF,UAAK,IAAM,KAAc,EAAK,MAC5B,CACE,EAAW,gBAAgB,KAC3B,EAAW,WAAW,YACtB,EAAW,SAAS,QAAQ,sBAC5B,EAAW,YAAY,aAAa,yBACpC,EAAW,WAAW,aACtB,EAAW,WAAW,gBAEtB,EAAO,KAAK;MAAE,IAAI,EAAW;MAAI,MAAM,EAAW;MAAM,CAAC;AAE7D,SAAI,CAAC,EAAK,QAAS,QAAO;;AAE5B,UAAU,MAAM,8CAA8C;;GAEjE,CAAC;EA0BoB,WAzBJ,EAAY;GAC5B,aAAa;IAAC;IAA8B;IAAa,GAAa;IAAI;IAAQ;GAClF,OAAO;GACP,YAAY,OAAO,MAAyB;AAC1C,QAAI,CAAC,KAAe,CAAC,GAAa,GAAI,OAAU,MAAM,oCAAoC;IAO1F,IAAM,KANS,MAAM,EAAO,OAEzB;KACD,UAAU;KACV,WAAW;MAAE;MAAS;MAAc;KACrC,CAAC,EACwB,MAAM;AAChC,QACE,CAAC,KACD,EAAW,YAAY,KACvB,EAAW,oBAAoB,KAC/B,CAAC,EAAW,uBACZ,CAAC,EAAW,sBACZ,CAAC,EAAW,sBACZ,OAAO,EAAW,SAAU,UAE5B,OAAU,MAAM,oCAAoC;AACtD,WAAO;;GAEV,CAAC;EAC+B"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { useBotlit as e } from "../providers/BotlitProvider.js";
|
|
2
|
+
import { useCallback as t } from "react";
|
|
3
|
+
import { gql as n } from "@apollo/client";
|
|
4
|
+
import { useGatewayClient as r } from "@burdenoff/fe-libs/shared/graphql";
|
|
5
|
+
import { useQuery as i } from "@apollo/client/react";
|
|
6
|
+
//#region src/botlit/hooks/useBotWorkflow.ts
|
|
7
|
+
var a = n`
|
|
8
|
+
query BotWorkflowDefinition($id: ID!) {
|
|
9
|
+
workflowDefinition(id: $id) {
|
|
10
|
+
id
|
|
11
|
+
workflowKey
|
|
12
|
+
version
|
|
13
|
+
name
|
|
14
|
+
status
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
`, o = n`
|
|
18
|
+
mutation CreateBotWorkflow($input: CreateWorkflowDefinitionInput!) {
|
|
19
|
+
createWorkflowDefinition(input: $input) {
|
|
20
|
+
id
|
|
21
|
+
workflowKey
|
|
22
|
+
version
|
|
23
|
+
name
|
|
24
|
+
status
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
`;
|
|
28
|
+
function s(e, t) {
|
|
29
|
+
let n = r("workspace"), { data: o, loading: s } = i(a, {
|
|
30
|
+
client: n ?? void 0,
|
|
31
|
+
variables: { id: t },
|
|
32
|
+
skip: !t || !n,
|
|
33
|
+
fetchPolicy: "network-only"
|
|
34
|
+
});
|
|
35
|
+
return {
|
|
36
|
+
workflow: s ? null : o?.workflowDefinition ?? null,
|
|
37
|
+
loading: s
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
function c() {
|
|
41
|
+
let { productId: n } = e(), i = r("workspace");
|
|
42
|
+
return { createWorkflow: t(async (e) => {
|
|
43
|
+
if (!i) throw Error("Workspace gateway is unavailable");
|
|
44
|
+
return (await i.mutate({
|
|
45
|
+
mutation: o,
|
|
46
|
+
variables: { input: {
|
|
47
|
+
...e,
|
|
48
|
+
context: { productId: n || "botmanor" }
|
|
49
|
+
} }
|
|
50
|
+
})).data?.createWorkflowDefinition ?? null;
|
|
51
|
+
}, [i, n]) };
|
|
52
|
+
}
|
|
53
|
+
//#endregion
|
|
54
|
+
export { s as useBotWorkflowDefinition, c as useCreateBotWorkflow };
|
|
55
|
+
|
|
56
|
+
//# sourceMappingURL=useBotWorkflow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useBotWorkflow.js","names":[],"sources":["../../../src/botlit/hooks/useBotWorkflow.ts"],"sourcesContent":["import { gql } from '@apollo/client';\nimport { useCallback } from 'react';\nimport { useQuery } from '@apollo/client/react';\nimport { useBotlit } from '../providers/BotlitProvider';\nimport { useGatewayClient } from '@burdenoff/fe-libs/shared/graphql';\n\ninterface BotWorkflowDefinition {\n id: string;\n workflowKey: string;\n version: string;\n name: string;\n status: string;\n}\n\nconst GET_WORKFLOW = gql`\n query BotWorkflowDefinition($id: ID!) {\n workflowDefinition(id: $id) {\n id\n workflowKey\n version\n name\n status\n }\n }\n`;\nconst CREATE_WORKFLOW = gql`\n mutation CreateBotWorkflow($input: CreateWorkflowDefinitionInput!) {\n createWorkflowDefinition(input: $input) {\n id\n workflowKey\n version\n name\n status\n }\n }\n`;\n\n/** Product-side binding does not initialize the shared builder's SDK singleton. */\nexport function useBotWorkflowDefinition(_key: undefined, id?: string) {\n const client = useGatewayClient('workspace');\n const { data, loading } = useQuery<{ workflowDefinition: BotWorkflowDefinition | null }>(\n GET_WORKFLOW,\n {\n client: client ?? undefined,\n variables: { id },\n skip: !id || !client,\n fetchPolicy: 'network-only',\n }\n );\n return { workflow: loading ? null : (data?.workflowDefinition ?? null), loading };\n}\n\nexport function useCreateBotWorkflow() {\n const { productId } = useBotlit();\n const client = useGatewayClient('workspace');\n const createWorkflow = useCallback(\n async (input: {\n workflowKey: string;\n version: string;\n name: string;\n description?: string;\n definitionJson: unknown;\n }) => {\n if (!client) throw new Error('Workspace gateway is unavailable');\n const result = await client.mutate<{ createWorkflowDefinition: BotWorkflowDefinition }>({\n mutation: CREATE_WORKFLOW,\n variables: { input: { ...input, context: { productId: productId || 'botmanor' } } },\n });\n return result.data?.createWorkflowDefinition ?? null;\n },\n [client, productId]\n );\n return { createWorkflow };\n}\n"],"mappings":";;;;;;AAcA,IAAM,IAAe,CAAG;;;;;;;;;;GAWlB,IAAkB,CAAG;;;;;;;;;;;AAa3B,SAAgB,EAAyB,GAAiB,GAAa;CACrE,IAAM,IAAS,EAAiB,YAAY,EACtC,EAAE,SAAM,eAAY,EACxB,GACA;EACE,QAAQ,KAAU,KAAA;EAClB,WAAW,EAAE,OAAI;EACjB,MAAM,CAAC,KAAM,CAAC;EACd,aAAa;EACd,CACF;AACD,QAAO;EAAE,UAAU,IAAU,OAAQ,GAAM,sBAAsB;EAAO;EAAS;;AAGnF,SAAgB,IAAuB;CACrC,IAAM,EAAE,iBAAc,GAAW,EAC3B,IAAS,EAAiB,YAAY;AAkB5C,QAAO,EAAE,gBAjBc,EACrB,OAAO,MAMD;AACJ,MAAI,CAAC,EAAQ,OAAU,MAAM,mCAAmC;AAKhE,UAJe,MAAM,EAAO,OAA4D;GACtF,UAAU;GACV,WAAW,EAAE,OAAO;IAAE,GAAG;IAAO,SAAS,EAAE,WAAW,KAAa,YAAY;IAAE,EAAE;GACpF,CAAC,EACY,MAAM,4BAA4B;IAElD,CAAC,GAAQ,EAAU,CACpB,EACwB"}
|