@burdenoff/microfe-botmanor 2026.927.2 → 2026.1006.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/components/AssistantChannelPanel.js +109 -0
- package/dist/botlit/components/AssistantChannelPanel.js.map +1 -0
- package/dist/botlit/components/AssistantRuntimeSetupPanel.js +76 -0
- package/dist/botlit/components/AssistantRuntimeSetupPanel.js.map +1 -0
- package/dist/botlit/components/AssistantWebsitePanel.js +196 -0
- package/dist/botlit/components/AssistantWebsitePanel.js.map +1 -0
- package/dist/botlit/components/KnowledgeSourceImportPanel.js +135 -0
- package/dist/botlit/components/KnowledgeSourceImportPanel.js.map +1 -0
- package/dist/botlit/hooks/useAssistantChannels.js +76 -0
- package/dist/botlit/hooks/useAssistantChannels.js.map +1 -0
- package/dist/botlit/hooks/useAssistantRuntimeSetup.js +112 -0
- package/dist/botlit/hooks/useAssistantRuntimeSetup.js.map +1 -0
- package/dist/botlit/hooks/useAssistantWebsites.js +85 -0
- package/dist/botlit/hooks/useAssistantWebsites.js.map +1 -0
- package/dist/botlit/hooks/useExecutions.js.map +1 -1
- package/dist/botlit/hooks/useKnowledgeSourceImports.js +86 -0
- package/dist/botlit/hooks/useKnowledgeSourceImports.js.map +1 -0
- package/dist/botlit/pages/AgentDetailPage.js +180 -158
- package/dist/botlit/pages/AgentDetailPage.js.map +1 -1
- package/dist/botlit/pages/ChatPage.js +58 -238
- package/dist/botlit/pages/ChatPage.js.map +1 -1
- package/dist/botlit/pages/KnowledgeBaseDetailPage.js +162 -160
- package/dist/botlit/pages/KnowledgeBaseDetailPage.js.map +1 -1
- package/dist/generated/global-types.js.map +1 -1
- package/dist/generated/wspace-operations.js +2 -2
- package/dist/generated/wspace-operations.js.map +1 -1
- package/dist/generated/wspace-types.js.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { useBotlit as e } from "../providers/BotlitProvider.js";
|
|
2
|
+
import { gql as t } from "@apollo/client";
|
|
3
|
+
import { useGatewayClient as n } from "@burdenoff/fe-libs/shared/graphql";
|
|
4
|
+
import { useMutation as r, useQuery as i, useQueryClient as a } from "@tanstack/react-query";
|
|
5
|
+
//#region src/botlit/hooks/useAssistantChannels.ts
|
|
6
|
+
var o = t`
|
|
7
|
+
query AssistantChannelPublications {
|
|
8
|
+
assistantChannelInstallations {
|
|
9
|
+
id
|
|
10
|
+
workspaceId
|
|
11
|
+
routeId
|
|
12
|
+
publicationId
|
|
13
|
+
enabled
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
`, s = t`
|
|
17
|
+
mutation ConfigureAssistantChannel($routeId: ID!, $publicationId: ID!) {
|
|
18
|
+
configureAssistantChannel(routeId: $routeId, publicationId: $publicationId) {
|
|
19
|
+
id
|
|
20
|
+
workspaceId
|
|
21
|
+
routeId
|
|
22
|
+
publicationId
|
|
23
|
+
enabled
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
`, c = t`
|
|
27
|
+
mutation DisableAssistantChannel($id: ID!) {
|
|
28
|
+
disableAssistantChannel(id: $id)
|
|
29
|
+
}
|
|
30
|
+
`;
|
|
31
|
+
function l() {
|
|
32
|
+
let t = n("workspace"), l = a(), { workspaceId: u, currentUser: d } = e(), f = [
|
|
33
|
+
"botmanor-assistant-channels",
|
|
34
|
+
u,
|
|
35
|
+
d?.id
|
|
36
|
+
];
|
|
37
|
+
return {
|
|
38
|
+
installations: i({
|
|
39
|
+
queryKey: f,
|
|
40
|
+
enabled: !!(u && d?.id),
|
|
41
|
+
retry: !1,
|
|
42
|
+
queryFn: async () => {
|
|
43
|
+
let e = (await t.query({
|
|
44
|
+
query: o,
|
|
45
|
+
fetchPolicy: "no-cache"
|
|
46
|
+
})).data?.assistantChannelInstallations;
|
|
47
|
+
if (!e || e.length > 100 || e.some((e) => e.workspaceId !== u)) throw Error("Channel publications unavailable");
|
|
48
|
+
return e;
|
|
49
|
+
}
|
|
50
|
+
}),
|
|
51
|
+
configure: r({
|
|
52
|
+
mutationFn: async (e) => {
|
|
53
|
+
let n = (await t.mutate({
|
|
54
|
+
mutation: s,
|
|
55
|
+
variables: e
|
|
56
|
+
})).data?.configureAssistantChannel;
|
|
57
|
+
if (!n || n.workspaceId !== u || n.routeId !== e.routeId || n.publicationId !== e.publicationId) throw Error("Channel publication unavailable");
|
|
58
|
+
return n;
|
|
59
|
+
},
|
|
60
|
+
onSuccess: () => l.invalidateQueries({ queryKey: f })
|
|
61
|
+
}),
|
|
62
|
+
disable: r({
|
|
63
|
+
mutationFn: async (e) => {
|
|
64
|
+
if (!(await t.mutate({
|
|
65
|
+
mutation: c,
|
|
66
|
+
variables: { id: e }
|
|
67
|
+
})).data?.disableAssistantChannel) throw Error("Channel revocation unavailable");
|
|
68
|
+
},
|
|
69
|
+
onSuccess: () => l.invalidateQueries({ queryKey: f })
|
|
70
|
+
})
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
//#endregion
|
|
74
|
+
export { l as useAssistantChannels };
|
|
75
|
+
|
|
76
|
+
//# sourceMappingURL=useAssistantChannels.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAssistantChannels.js","names":[],"sources":["../../../src/botlit/hooks/useAssistantChannels.ts"],"sourcesContent":["import { gql } from '@apollo/client';\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';\nimport { useGatewayClient } from '@burdenoff/fe-libs/shared/graphql';\nimport { useBotlit } from '../providers/BotlitProvider';\n\ninterface Installation {\n id: string;\n workspaceId: string;\n routeId: string;\n publicationId: string;\n enabled: boolean;\n}\nconst LIST = gql`\n query AssistantChannelPublications {\n assistantChannelInstallations {\n id\n workspaceId\n routeId\n publicationId\n enabled\n }\n }\n`;\nconst CONFIGURE = gql`\n mutation ConfigureAssistantChannel($routeId: ID!, $publicationId: ID!) {\n configureAssistantChannel(routeId: $routeId, publicationId: $publicationId) {\n id\n workspaceId\n routeId\n publicationId\n enabled\n }\n }\n`;\nconst DISABLE = gql`\n mutation DisableAssistantChannel($id: ID!) {\n disableAssistantChannel(id: $id)\n }\n`;\nexport function useAssistantChannels() {\n const client = useGatewayClient('workspace'),\n cache = useQueryClient(),\n { workspaceId, currentUser } = useBotlit();\n const key = ['botmanor-assistant-channels', workspaceId, currentUser?.id];\n const installations = useQuery({\n queryKey: key,\n enabled: Boolean(workspaceId && currentUser?.id),\n retry: false,\n queryFn: async () => {\n const response = await client.query<{ assistantChannelInstallations: Installation[] }>({\n query: LIST,\n fetchPolicy: 'no-cache',\n });\n const rows = response.data?.assistantChannelInstallations;\n if (!rows || rows.length > 100 || rows.some((row) => row.workspaceId !== workspaceId))\n throw new Error('Channel publications unavailable');\n return rows;\n },\n });\n const configure = useMutation({\n mutationFn: async (input: { routeId: string; publicationId: string }) => {\n const response = await client.mutate<{ configureAssistantChannel: Installation }>({\n mutation: CONFIGURE,\n variables: input,\n });\n const row = response.data?.configureAssistantChannel;\n if (\n !row ||\n row.workspaceId !== workspaceId ||\n row.routeId !== input.routeId ||\n row.publicationId !== input.publicationId\n )\n throw new Error('Channel publication unavailable');\n return row;\n },\n onSuccess: () => cache.invalidateQueries({ queryKey: key }),\n });\n const disable = useMutation({\n mutationFn: async (id: string) => {\n const response = await client.mutate<{ disableAssistantChannel: boolean }>({\n mutation: DISABLE,\n variables: { id },\n });\n if (!response.data?.disableAssistantChannel)\n throw new Error('Channel revocation unavailable');\n },\n onSuccess: () => cache.invalidateQueries({ queryKey: key }),\n });\n return { installations, configure, disable };\n}\n"],"mappings":";;;;;AAYA,IAAM,IAAO,CAAG;;;;;;;;;;GAWV,IAAY,CAAG;;;;;;;;;;GAWf,IAAU,CAAG;;;;;AAKnB,SAAgB,IAAuB;CACrC,IAAM,IAAS,EAAiB,YAAY,EAC1C,IAAQ,GAAgB,EACxB,EAAE,gBAAa,mBAAgB,GAAW,EACtC,IAAM;EAAC;EAA+B;EAAa,GAAa;EAAG;AA6CzE,QAAO;EAAE,eA5Ca,EAAS;GAC7B,UAAU;GACV,SAAS,GAAQ,KAAe,GAAa;GAC7C,OAAO;GACP,SAAS,YAAY;IAKnB,IAAM,KAJW,MAAM,EAAO,MAAyD;KACrF,OAAO;KACP,aAAa;KACd,CAAC,EACoB,MAAM;AAC5B,QAAI,CAAC,KAAQ,EAAK,SAAS,OAAO,EAAK,MAAM,MAAQ,EAAI,gBAAgB,EAAY,CACnF,OAAU,MAAM,mCAAmC;AACrD,WAAO;;GAEV,CAAC;EA8BsB,WA7BN,EAAY;GAC5B,YAAY,OAAO,MAAsD;IAKvE,IAAM,KAJW,MAAM,EAAO,OAAoD;KAChF,UAAU;KACV,WAAW;KACZ,CAAC,EACmB,MAAM;AAC3B,QACE,CAAC,KACD,EAAI,gBAAgB,KACpB,EAAI,YAAY,EAAM,WACtB,EAAI,kBAAkB,EAAM,cAE5B,OAAU,MAAM,kCAAkC;AACpD,WAAO;;GAET,iBAAiB,EAAM,kBAAkB,EAAE,UAAU,GAAK,CAAC;GAC5D,CAAC;EAYiC,SAXnB,EAAY;GAC1B,YAAY,OAAO,MAAe;AAKhC,QAAI,EAJa,MAAM,EAAO,OAA6C;KACzE,UAAU;KACV,WAAW,EAAE,OAAI;KAClB,CAAC,EACY,MAAM,wBAClB,OAAU,MAAM,iCAAiC;;GAErD,iBAAiB,EAAM,kBAAkB,EAAE,UAAU,GAAK,CAAC;GAC5D,CAAC;EAC0C"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { useBotlit as e } from "../providers/BotlitProvider.js";
|
|
2
|
+
import { gql as t } from "@apollo/client";
|
|
3
|
+
import { useGatewayClient as n } from "@burdenoff/fe-libs/shared/graphql";
|
|
4
|
+
import { useMutation as r, useQuery as i } from "@tanstack/react-query";
|
|
5
|
+
//#region src/botlit/hooks/useAssistantRuntimeSetup.ts
|
|
6
|
+
var a = t`
|
|
7
|
+
query AssistantWorkflowProvider {
|
|
8
|
+
getProviderByKey(key: "burdenoff") {
|
|
9
|
+
id
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
`, o = t`
|
|
13
|
+
query AssistantWorkflowConnections($providerId: ID!, $offset: Int!) {
|
|
14
|
+
getConnections(
|
|
15
|
+
filter: { providerId: $providerId, status: ACTIVE }
|
|
16
|
+
pagination: { limit: 100, offset: $offset }
|
|
17
|
+
) {
|
|
18
|
+
hasMore
|
|
19
|
+
items {
|
|
20
|
+
id
|
|
21
|
+
name
|
|
22
|
+
workspaceId
|
|
23
|
+
status
|
|
24
|
+
provider {
|
|
25
|
+
key
|
|
26
|
+
}
|
|
27
|
+
authMethod {
|
|
28
|
+
authType
|
|
29
|
+
isEnabled
|
|
30
|
+
isConfigured
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
`, s = t`
|
|
36
|
+
mutation ConfigureAssistantRuntime($agentId: ID!, $connectionId: ID!) {
|
|
37
|
+
configureAssistantRuntime(agentId: $agentId, connectionId: $connectionId) {
|
|
38
|
+
agentId
|
|
39
|
+
courseId
|
|
40
|
+
inferenceWorkflowId
|
|
41
|
+
recoveryWorkflowId
|
|
42
|
+
recoveryScheduleId
|
|
43
|
+
ingestionWorkflowId
|
|
44
|
+
protocolVersion
|
|
45
|
+
ready
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
`;
|
|
49
|
+
function c(t) {
|
|
50
|
+
let c = n("workspace"), { workspaceId: l, currentUser: u } = e();
|
|
51
|
+
return {
|
|
52
|
+
connections: i({
|
|
53
|
+
queryKey: [
|
|
54
|
+
"botmanor-assistant-connections",
|
|
55
|
+
l,
|
|
56
|
+
u?.id
|
|
57
|
+
],
|
|
58
|
+
enabled: !!(l && u?.id),
|
|
59
|
+
retry: !1,
|
|
60
|
+
queryFn: async () => {
|
|
61
|
+
let e = (await c.query({
|
|
62
|
+
query: a,
|
|
63
|
+
fetchPolicy: "no-cache"
|
|
64
|
+
})).data?.getProviderByKey?.id;
|
|
65
|
+
if (!e) return [];
|
|
66
|
+
let t = [];
|
|
67
|
+
for (let n = 0; n < 500; n += 100) {
|
|
68
|
+
let r = (await c.query({
|
|
69
|
+
query: o,
|
|
70
|
+
variables: {
|
|
71
|
+
providerId: e,
|
|
72
|
+
offset: n
|
|
73
|
+
},
|
|
74
|
+
fetchPolicy: "no-cache"
|
|
75
|
+
})).data?.getConnections;
|
|
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 === "burdenoff" && e.authMethod?.authType === "SERVICE_ACCOUNT" && e.authMethod.isEnabled && e.authMethod.isConfigured && t.push({
|
|
78
|
+
id: e.id,
|
|
79
|
+
name: e.name
|
|
80
|
+
});
|
|
81
|
+
if (!r.hasMore) return t;
|
|
82
|
+
}
|
|
83
|
+
throw Error("Connection list exceeds the supported limit");
|
|
84
|
+
}
|
|
85
|
+
}),
|
|
86
|
+
configure: r({
|
|
87
|
+
mutationKey: [
|
|
88
|
+
"botmanor-assistant-runtime",
|
|
89
|
+
l,
|
|
90
|
+
u?.id,
|
|
91
|
+
t
|
|
92
|
+
],
|
|
93
|
+
retry: !1,
|
|
94
|
+
mutationFn: async (e) => {
|
|
95
|
+
if (!l || !u?.id) throw Error("Sign in to configure an assistant");
|
|
96
|
+
let n = (await c.mutate({
|
|
97
|
+
mutation: s,
|
|
98
|
+
variables: {
|
|
99
|
+
agentId: t,
|
|
100
|
+
connectionId: e
|
|
101
|
+
}
|
|
102
|
+
})).data?.configureAssistantRuntime;
|
|
103
|
+
if (!n || n.agentId !== t || n.protocolVersion !== 2 || !n.inferenceWorkflowId || !n.recoveryWorkflowId || !n.recoveryScheduleId || typeof n.ready != "boolean") throw Error("Runtime configuration unavailable");
|
|
104
|
+
return n;
|
|
105
|
+
}
|
|
106
|
+
})
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
//#endregion
|
|
110
|
+
export { c as useAssistantRuntimeSetup };
|
|
111
|
+
|
|
112
|
+
//# sourceMappingURL=useAssistantRuntimeSetup.js.map
|
|
@@ -0,0 +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: \"burdenoff\") {\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 === 'burdenoff' &&\n connection.authMethod?.authType === 'SERVICE_ACCOUNT' &&\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,eAC5B,EAAW,YAAY,aAAa,qBACpC,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,85 @@
|
|
|
1
|
+
import { useBotlit as e } from "../providers/BotlitProvider.js";
|
|
2
|
+
import { gql as t } from "@apollo/client";
|
|
3
|
+
import { useGatewayClient as n } from "@burdenoff/fe-libs/shared/graphql";
|
|
4
|
+
import { useMutation as r, useQuery as i, useQueryClient as a } from "@tanstack/react-query";
|
|
5
|
+
//#region src/botlit/hooks/useAssistantWebsites.ts
|
|
6
|
+
var o = t`
|
|
7
|
+
query AssistantWebsites($agentId: ID!) {
|
|
8
|
+
assistantWebsiteInstallations(agentId: $agentId) {
|
|
9
|
+
id
|
|
10
|
+
workspaceId
|
|
11
|
+
agentId
|
|
12
|
+
name
|
|
13
|
+
allowedOrigins
|
|
14
|
+
approvedKnowledgeBaseIds
|
|
15
|
+
enabled
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
`, s = t`
|
|
19
|
+
mutation PublishAssistantWebsite($input: PublishAssistantWebsiteInput!) {
|
|
20
|
+
publishAssistantWebsite(input: $input) {
|
|
21
|
+
id
|
|
22
|
+
workspaceId
|
|
23
|
+
agentId
|
|
24
|
+
name
|
|
25
|
+
allowedOrigins
|
|
26
|
+
approvedKnowledgeBaseIds
|
|
27
|
+
enabled
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
`, c = t`
|
|
31
|
+
mutation DisableAssistantWebsite($id: ID!) {
|
|
32
|
+
disableAssistantWebsite(id: $id)
|
|
33
|
+
}
|
|
34
|
+
`;
|
|
35
|
+
function l(t) {
|
|
36
|
+
let l = n("workspace"), u = a(), { workspaceId: d, currentUser: f } = e(), p = [
|
|
37
|
+
"botmanor-assistant-websites",
|
|
38
|
+
d,
|
|
39
|
+
f?.id,
|
|
40
|
+
t
|
|
41
|
+
];
|
|
42
|
+
return {
|
|
43
|
+
installations: i({
|
|
44
|
+
queryKey: p,
|
|
45
|
+
enabled: !!(d && f?.id),
|
|
46
|
+
retry: !1,
|
|
47
|
+
queryFn: async () => {
|
|
48
|
+
let e = (await l.query({
|
|
49
|
+
query: o,
|
|
50
|
+
variables: { agentId: t },
|
|
51
|
+
fetchPolicy: "no-cache"
|
|
52
|
+
})).data?.assistantWebsiteInstallations;
|
|
53
|
+
if (!e || e.length > 100 || e.some((e) => e.workspaceId !== d || e.agentId !== t)) throw Error("Website publications unavailable");
|
|
54
|
+
return e;
|
|
55
|
+
}
|
|
56
|
+
}),
|
|
57
|
+
publish: r({
|
|
58
|
+
mutationFn: async (e) => {
|
|
59
|
+
let n = (await l.mutate({
|
|
60
|
+
mutation: s,
|
|
61
|
+
variables: { input: {
|
|
62
|
+
...e,
|
|
63
|
+
agentId: t
|
|
64
|
+
} }
|
|
65
|
+
})).data?.publishAssistantWebsite;
|
|
66
|
+
if (!n || n.workspaceId !== d || n.agentId !== t) throw Error("Website publication unavailable");
|
|
67
|
+
return n;
|
|
68
|
+
},
|
|
69
|
+
onSuccess: () => u.invalidateQueries({ queryKey: p })
|
|
70
|
+
}),
|
|
71
|
+
disable: r({
|
|
72
|
+
mutationFn: async (e) => {
|
|
73
|
+
if ((await l.mutate({
|
|
74
|
+
mutation: c,
|
|
75
|
+
variables: { id: e }
|
|
76
|
+
})).data?.disableAssistantWebsite !== !0) throw Error("Website revocation unavailable");
|
|
77
|
+
},
|
|
78
|
+
onSuccess: () => u.invalidateQueries({ queryKey: p })
|
|
79
|
+
})
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
//#endregion
|
|
83
|
+
export { l as useAssistantWebsites };
|
|
84
|
+
|
|
85
|
+
//# sourceMappingURL=useAssistantWebsites.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAssistantWebsites.js","names":[],"sources":["../../../src/botlit/hooks/useAssistantWebsites.ts"],"sourcesContent":["import { gql } from '@apollo/client';\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';\nimport { useGatewayClient } from '@burdenoff/fe-libs/shared/graphql';\nimport { useBotlit } from '../providers/BotlitProvider';\n\nexport interface AssistantWebsiteInstallation {\n id: string;\n workspaceId: string;\n agentId: string;\n name: string;\n allowedOrigins: string[];\n approvedKnowledgeBaseIds: string[];\n enabled: boolean;\n}\nconst LIST = gql`\n query AssistantWebsites($agentId: ID!) {\n assistantWebsiteInstallations(agentId: $agentId) {\n id\n workspaceId\n agentId\n name\n allowedOrigins\n approvedKnowledgeBaseIds\n enabled\n }\n }\n`;\nconst PUBLISH = gql`\n mutation PublishAssistantWebsite($input: PublishAssistantWebsiteInput!) {\n publishAssistantWebsite(input: $input) {\n id\n workspaceId\n agentId\n name\n allowedOrigins\n approvedKnowledgeBaseIds\n enabled\n }\n }\n`;\nconst DISABLE = gql`\n mutation DisableAssistantWebsite($id: ID!) {\n disableAssistantWebsite(id: $id)\n }\n`;\n\nexport function useAssistantWebsites(agentId: string) {\n const client = useGatewayClient('workspace'),\n cache = useQueryClient(),\n { workspaceId, currentUser } = useBotlit();\n const key = ['botmanor-assistant-websites', workspaceId, currentUser?.id, agentId];\n const installations = useQuery({\n queryKey: key,\n enabled: Boolean(workspaceId && currentUser?.id),\n retry: false,\n queryFn: async () => {\n const response = await client.query<{\n assistantWebsiteInstallations: AssistantWebsiteInstallation[];\n }>({ query: LIST, variables: { agentId }, fetchPolicy: 'no-cache' });\n const rows = response.data?.assistantWebsiteInstallations;\n if (\n !rows ||\n rows.length > 100 ||\n rows.some((row) => row.workspaceId !== workspaceId || row.agentId !== agentId)\n )\n throw new Error('Website publications unavailable');\n return rows;\n },\n });\n const publish = useMutation({\n mutationFn: async (input: {\n name: string;\n allowedOrigins: string[];\n approvedKnowledgeBaseIds: string[];\n }) => {\n const response = await client.mutate<{\n publishAssistantWebsite: AssistantWebsiteInstallation;\n }>({ mutation: PUBLISH, variables: { input: { ...input, agentId } } });\n const row = response.data?.publishAssistantWebsite;\n if (!row || row.workspaceId !== workspaceId || row.agentId !== agentId)\n throw new Error('Website publication unavailable');\n return row;\n },\n onSuccess: () => cache.invalidateQueries({ queryKey: key }),\n });\n const disable = useMutation({\n mutationFn: async (id: string) => {\n const response = await client.mutate<{ disableAssistantWebsite: boolean }>({\n mutation: DISABLE,\n variables: { id },\n });\n if (response.data?.disableAssistantWebsite !== true)\n throw new Error('Website revocation unavailable');\n },\n onSuccess: () => cache.invalidateQueries({ queryKey: key }),\n });\n return { installations, publish, disable };\n}\n"],"mappings":";;;;;AAcA,IAAM,IAAO,CAAG;;;;;;;;;;;;GAaV,IAAU,CAAG;;;;;;;;;;;;GAab,IAAU,CAAG;;;;;AAMnB,SAAgB,EAAqB,GAAiB;CACpD,IAAM,IAAS,EAAiB,YAAY,EAC1C,IAAQ,GAAgB,EACxB,EAAE,gBAAa,mBAAgB,GAAW,EACtC,IAAM;EAAC;EAA+B;EAAa,GAAa;EAAI;EAAQ;AA8ClF,QAAO;EAAE,eA7Ca,EAAS;GAC7B,UAAU;GACV,SAAS,GAAQ,KAAe,GAAa;GAC7C,OAAO;GACP,SAAS,YAAY;IAInB,IAAM,KAHW,MAAM,EAAO,MAE3B;KAAE,OAAO;KAAM,WAAW,EAAE,YAAS;KAAE,aAAa;KAAY,CAAC,EAC9C,MAAM;AAC5B,QACE,CAAC,KACD,EAAK,SAAS,OACd,EAAK,MAAM,MAAQ,EAAI,gBAAgB,KAAe,EAAI,YAAY,EAAQ,CAE9E,OAAU,MAAM,mCAAmC;AACrD,WAAO;;GAEV,CAAC;EA4BsB,SA3BR,EAAY;GAC1B,YAAY,OAAO,MAIb;IAIJ,IAAM,KAHW,MAAM,EAAO,OAE3B;KAAE,UAAU;KAAS,WAAW,EAAE,OAAO;MAAE,GAAG;MAAO;MAAS,EAAE;KAAE,CAAC,EACjD,MAAM;AAC3B,QAAI,CAAC,KAAO,EAAI,gBAAgB,KAAe,EAAI,YAAY,EAC7D,OAAU,MAAM,kCAAkC;AACpD,WAAO;;GAET,iBAAiB,EAAM,kBAAkB,EAAE,UAAU,GAAK,CAAC;GAC5D,CAAC;EAY+B,SAXjB,EAAY;GAC1B,YAAY,OAAO,MAAe;AAKhC,SAJiB,MAAM,EAAO,OAA6C;KACzE,UAAU;KACV,WAAW,EAAE,OAAI;KAClB,CAAC,EACW,MAAM,4BAA4B,GAC7C,OAAU,MAAM,iCAAiC;;GAErD,iBAAiB,EAAM,kBAAkB,EAAE,UAAU,GAAK,CAAC;GAC5D,CAAC;EACwC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useExecutions.js","names":[],"sources":["../../../src/botlit/hooks/useExecutions.ts"],"sourcesContent":["/**\n * Executions Hooks\n * @module botlit/hooks\n *\n * Backed by the live `listExecutions` / `getExecution` / `getExecutionMetrics`\n * operations plus the `createExecution` / `updateExecutionStatus` mutations on\n * wspace-botlit-svc.\n *\n * Note on filtering: `ExecutionFilterInput` accepts a SINGLE status and has no\n * free-text field, so multi-status selections and search are narrowed on the\n * client over the fetched page.\n */\n\nimport { useCallback, useMemo } from 'react';\nimport {\n CreateExecutionDocument,\n GetExecutionDocument,\n GetExecutionMetricsDocument,\n ListExecutionsDocument,\n UpdateExecutionStatusDocument,\n type CreateExecutionMutation,\n type GetExecutionMetricsQuery,\n type GetExecutionQuery,\n type ListExecutionsQuery,\n type UpdateExecutionStatusMutation,\n} from '../../generated/wspace-operations';\nimport type { CreateExecutionInput } from '../../generated/wspace-types';\nimport { buildMutationInput, fieldsOf, type GraphQLInput } from './internal/mutationInput';\nimport {\n useWorkspaceId,\n useWorkspaceMutation,\n useWorkspaceQuery,\n type QueryResult,\n} from './internal/workspaceGateway';\n\nconst LIST_LIMIT = 100;\n\nexport interface ExecutionRecord {\n id: string;\n status: string;\n type: string;\n input: string;\n output?: string | null;\n agentId?: string | null;\n appId?: string | null;\n conversationId?: string | null;\n cost?: number | null;\n duration?: number | null;\n tokensUsed?: number | null;\n errorCode?: string | null;\n errorMessage?: string | null;\n errorDetails?: Record<string, unknown> | null;\n metadata?: Record<string, unknown> | null;\n completedAt?: string | null;\n createdAt: string;\n workspaceId: string;\n}\n\nexport interface ExecutionMetricsRecord {\n executionId: string;\n cost: number;\n inputTokens: number;\n outputTokens: number;\n totalTokens: number;\n ragChunks: number;\n toolCalls: number;\n}\n\nexport interface ExecutionsFilter {\n search?: string;\n status?: string[];\n agentId?: string;\n appId?: string;\n conversationId?: string;\n type?: string;\n}\n\nexport interface ExecutionMetricsFilter {\n agentId?: string;\n appId?: string;\n startDate?: string;\n endDate?: string;\n}\n\nexport interface CreateExecutionVariables {\n input: GraphQLInput<CreateExecutionInput>;\n}\n\nconst CREATE_EXECUTION_FIELDS = fieldsOf<CreateExecutionInput>({\n agentId: true,\n appId: true,\n conversationId: true,\n input: true,\n metadata: true,\n type: true,\n workspaceId: true,\n});\n\nexport interface UpdateExecutionStatusVariables {\n id: string;\n status: string;\n output?: string;\n error?: Record<string, unknown>;\n}\n\n/** Terminal statuses that count as a successful run. */\nconst SUCCESS_STATUSES = new Set(['COMPLETED']);\n\nconst NO_EXECUTIONS: ExecutionRecord[] = [];\n\nexport const executionKeys = {\n all: ['executions'] as const,\n lists: () => [...executionKeys.all, 'list'] as const,\n list: (filter?: ExecutionsFilter) => [...executionKeys.lists(), filter] as const,\n details: () => [...executionKeys.all, 'detail'] as const,\n detail: (id: string) => [...executionKeys.details(), id] as const,\n metrics: () => [...executionKeys.all, 'metrics'] as const,\n};\n\nfunction matchesSearch(execution: ExecutionRecord, needle: string): boolean {\n return (\n execution.id.toLowerCase().includes(needle) ||\n (execution.agentId ?? '').toLowerCase().includes(needle) ||\n (execution.appId ?? '').toLowerCase().includes(needle) ||\n execution.input.toLowerCase().includes(needle)\n );\n}\n\nexport function useExecutions(filter?: ExecutionsFilter): QueryResult<ExecutionRecord[]> {\n const workspaceId = useWorkspaceId();\n const search = filter?.search?.trim().toLowerCase() ?? '';\n const statuses = filter?.status;\n const singleStatus = statuses?.length === 1 ? statuses[0] : undefined;\n const statusKey = statuses?.join(',') ?? '';\n const { agentId, appId, conversationId, type } = filter ?? {};\n\n const variables = useMemo(\n () => ({\n filters: {\n workspaceId,\n status: singleStatus,\n agentId,\n appId,\n conversationId,\n type,\n },\n pagination: { limit: LIST_LIMIT, offset: 0 },\n }),\n [workspaceId, singleStatus, agentId, appId, conversationId, type]\n );\n\n const select = useCallback(\n (data: ListExecutionsQuery | undefined): ExecutionRecord[] => {\n const rows: ExecutionRecord[] = data?.listExecutions ?? NO_EXECUTIONS;\n const wanted = statusKey ? new Set(statusKey.split(',')) : undefined;\n const narrowed =\n // A single status is already applied server-side.\n wanted && wanted.size > 1 ? rows.filter((row) => wanted.has(row.status)) : rows;\n return search ? narrowed.filter((row) => matchesSearch(row, search)) : narrowed;\n },\n [search, statusKey]\n );\n\n return useWorkspaceQuery<ListExecutionsQuery, ExecutionRecord[]>({\n document: ListExecutionsDocument,\n variables,\n select,\n fallback: NO_EXECUTIONS,\n enabled: Boolean(workspaceId),\n errorMessage: 'Failed to load executions',\n });\n}\n\nexport function useExecution(executionId: string | undefined): QueryResult<ExecutionRecord | null> {\n const variables = useMemo(() => ({ id: executionId ?? '' }), [executionId]);\n\n return useWorkspaceQuery<GetExecutionQuery, ExecutionRecord | null>({\n document: GetExecutionDocument,\n variables,\n select: (data) => data?.getExecution ?? null,\n fallback: null,\n enabled: Boolean(executionId),\n errorMessage: 'Failed to load execution',\n });\n}\n\n/**\n * Token/cost metrics for the workspace, optionally narrowed to an agent, app or\n * date window. Returns `null` when the service has nothing recorded yet.\n */\nexport function useExecutionMetrics(\n filter?: ExecutionMetricsFilter\n): QueryResult<ExecutionMetricsRecord | null> {\n const workspaceId = useWorkspaceId();\n const { agentId, appId, startDate, endDate } = filter ?? {};\n\n const variables = useMemo(\n () => ({ filter: { workspaceId, agentId, appId, startDate, endDate } }),\n [workspaceId, agentId, appId, startDate, endDate]\n );\n\n return useWorkspaceQuery<GetExecutionMetricsQuery, ExecutionMetricsRecord | null>({\n document: GetExecutionMetricsDocument,\n variables,\n select: (data) => data?.getExecutionMetrics ?? null,\n fallback: null,\n enabled: Boolean(workspaceId),\n errorMessage: 'Failed to load execution metrics',\n });\n}\n\nexport interface ExecutionRollup {\n total: number;\n succeeded: number;\n failed: number;\n successRate: number;\n avgDurationMs: number;\n totalCost: number;\n totalTokens: number;\n}\n\n/**\n * Rolls a list of executions up into the headline numbers shown above the table.\n * Derived purely from the rows that were actually loaded — no server aggregate\n * exists for this, so callers must label it as such.\n */\nexport function summariseExecutions(executions: readonly ExecutionRecord[]): ExecutionRollup {\n const total = executions.length;\n let succeeded = 0;\n let failed = 0;\n let durationSum = 0;\n let durationCount = 0;\n let totalCost = 0;\n let totalTokens = 0;\n\n for (const execution of executions) {\n if (SUCCESS_STATUSES.has(execution.status)) succeeded += 1;\n if (execution.status === 'FAILED' || execution.status === 'TIMEOUT') failed += 1;\n if (typeof execution.duration === 'number') {\n durationSum += execution.duration;\n durationCount += 1;\n }\n totalCost += execution.cost ?? 0;\n totalTokens += execution.tokensUsed ?? 0;\n }\n\n return {\n total,\n succeeded,\n failed,\n successRate: total > 0 ? succeeded / total : 0,\n avgDurationMs: durationCount > 0 ? durationSum / durationCount : 0,\n totalCost,\n totalTokens,\n };\n}\n\nexport function useCreateExecution() {\n return useWorkspaceMutation<CreateExecutionMutation, CreateExecutionVariables, ExecutionRecord>({\n document: CreateExecutionDocument,\n variables: ({ input }) => ({ input: buildMutationInput(input, CREATE_EXECUTION_FIELDS) }),\n select: (data) => data?.createExecution,\n errorMessage: 'Failed to start execution',\n });\n}\n\nexport function useUpdateExecutionStatus() {\n return useWorkspaceMutation<\n UpdateExecutionStatusMutation,\n UpdateExecutionStatusVariables,\n ExecutionRecord\n >({\n document: UpdateExecutionStatusDocument,\n variables: ({ id, status, output, error }) => ({ id, status, output, error }),\n select: (data) => data?.updateExecutionStatus,\n errorMessage: 'Failed to update execution status',\n });\n}\n"],"mappings":";;;;;AAmCA,IAAM,IAAa,KAqDb,IAA0B,EAA+B;CAC7D,SAAS;CACT,OAAO;CACP,gBAAgB;CAChB,OAAO;CACP,UAAU;CACV,MAAM;CACN,aAAa;CACd,CAAC,EAUI,IAAmB,IAAI,IAAI,CAAC,YAAY,CAAC,EAEzC,IAAmC,EAAE;AAW3C,SAAS,EAAc,GAA4B,GAAyB;AAC1E,QACE,EAAU,GAAG,aAAa,CAAC,SAAS,EAAO,KAC1C,EAAU,WAAW,IAAI,aAAa,CAAC,SAAS,EAAO,KACvD,EAAU,SAAS,IAAI,aAAa,CAAC,SAAS,EAAO,IACtD,EAAU,MAAM,aAAa,CAAC,SAAS,EAAO;;AAIlD,SAAgB,EAAc,GAA2D;CACvF,IAAM,IAAc,GAAgB,EAC9B,IAAS,GAAQ,QAAQ,MAAM,CAAC,aAAa,IAAI,IACjD,IAAW,GAAQ,QACnB,IAAe,GAAU,WAAW,IAAI,EAAS,KAAK,KAAA,GACtD,IAAY,GAAU,KAAK,IAAI,IAAI,IACnC,EAAE,YAAS,UAAO,mBAAgB,YAAS,KAAU,EAAE;AA6B7D,QAAO,EAA0D;EAC/D,UAAU;EACV,WA7BgB,SACT;GACL,SAAS;IACP;IACA,QAAQ;IACR;IACA;IACA;IACA;IACD;GACD,YAAY;IAAE,OAAO;IAAY,QAAQ;IAAG;GAC7C,GACD;GAAC;GAAa;GAAc;GAAS;GAAO;GAAgB;GAAK,CAClE;EAiBC,QAfa,GACZ,MAA6D;GAC5D,IAAM,IAA0B,GAAM,kBAAkB,GAClD,IAAS,IAAY,IAAI,IAAI,EAAU,MAAM,IAAI,CAAC,GAAG,KAAA,GACrD,IAEJ,KAAU,EAAO,OAAO,IAAI,EAAK,QAAQ,MAAQ,EAAO,IAAI,EAAI,OAAO,CAAC,GAAG;AAC7E,UAAO,IAAS,EAAS,QAAQ,MAAQ,EAAc,GAAK,EAAO,CAAC,GAAG;KAEzE,CAAC,GAAQ,EAAU,CACpB;EAMC,UAAU;EACV,SAAS,EAAQ;EACjB,cAAc;EACf,CAAC;;AAGJ,SAAgB,EAAa,GAAsE;AAGjG,QAAO,EAA6D;EAClE,UAAU;EACV,WAJgB,SAAe,EAAE,IAAI,KAAe,IAAI,GAAG,CAAC,EAAY,CAAC;EAKzE,SAAS,MAAS,GAAM,gBAAgB;EACxC,UAAU;EACV,SAAS,EAAQ;EACjB,cAAc;EACf,CAAC;;AA2CJ,SAAgB,EAAoB,GAAyD;CAC3F,IAAM,IAAQ,EAAW,QACrB,IAAY,GACZ,IAAS,GACT,IAAc,GACd,IAAgB,GAChB,IAAY,GACZ,IAAc;AAElB,MAAK,IAAM,KAAa,EAQtB,CAPI,EAAiB,IAAI,EAAU,OAAO,KAAE,KAAa,KACrD,EAAU,WAAW,YAAY,EAAU,WAAW,eAAW,KAAU,IAC3E,OAAO,EAAU,YAAa,aAChC,KAAe,EAAU,UACzB,KAAiB,IAEnB,KAAa,EAAU,QAAQ,GAC/B,KAAe,EAAU,cAAc;AAGzC,QAAO;EACL;EACA;EACA;EACA,aAAa,IAAQ,IAAI,IAAY,IAAQ;EAC7C,eAAe,IAAgB,IAAI,IAAc,IAAgB;EACjE;EACA;EACD;;AAGH,SAAgB,IAAqB;AACnC,QAAO,EAAyF;EAC9F,UAAU;EACV,YAAY,EAAE,gBAAa,EAAE,OAAO,EAAmB,GAAO,EAAwB,EAAE;EACxF,SAAS,MAAS,GAAM;EACxB,cAAc;EACf,CAAC"}
|
|
1
|
+
{"version":3,"file":"useExecutions.js","names":[],"sources":["../../../src/botlit/hooks/useExecutions.ts"],"sourcesContent":["/**\n * Executions Hooks\n * @module botlit/hooks\n *\n * Backed by the live `listExecutions` / `getExecution` / `getExecutionMetrics`\n * operations plus the `createExecution` / `updateExecutionStatus` mutations on\n * wspace-botlit-svc.\n *\n * Note on filtering: `ExecutionFilterInput` accepts a SINGLE status and has no\n * free-text field, so multi-status selections and search are narrowed on the\n * client over the fetched page.\n */\n\nimport { useCallback, useMemo } from 'react';\nimport {\n CreateExecutionDocument,\n GetExecutionDocument,\n GetExecutionMetricsDocument,\n ListExecutionsDocument,\n UpdateExecutionStatusDocument,\n type CreateExecutionMutation,\n type GetExecutionMetricsQuery,\n type GetExecutionQuery,\n type ListExecutionsQuery,\n type UpdateExecutionStatusMutation,\n} from '../../generated/wspace-operations';\nimport type { CreateExecutionInput, ExecutionStatus } from '../../generated/wspace-types';\nimport { buildMutationInput, fieldsOf, type GraphQLInput } from './internal/mutationInput';\nimport {\n useWorkspaceId,\n useWorkspaceMutation,\n useWorkspaceQuery,\n type QueryResult,\n} from './internal/workspaceGateway';\n\nconst LIST_LIMIT = 100;\n\nexport interface ExecutionRecord {\n id: string;\n status: string;\n type: string;\n input: string;\n output?: string | null;\n agentId?: string | null;\n appId?: string | null;\n conversationId?: string | null;\n cost?: number | null;\n duration?: number | null;\n tokensUsed?: number | null;\n errorCode?: string | null;\n errorMessage?: string | null;\n errorDetails?: Record<string, unknown> | null;\n metadata?: Record<string, unknown> | null;\n completedAt?: string | null;\n createdAt: string;\n workspaceId: string;\n}\n\nexport interface ExecutionMetricsRecord {\n executionId: string;\n cost: number;\n inputTokens: number;\n outputTokens: number;\n totalTokens: number;\n ragChunks: number;\n toolCalls: number;\n}\n\nexport interface ExecutionsFilter {\n search?: string;\n status?: string[];\n agentId?: string;\n appId?: string;\n conversationId?: string;\n type?: string;\n}\n\nexport interface ExecutionMetricsFilter {\n agentId?: string;\n appId?: string;\n startDate?: string;\n endDate?: string;\n}\n\nexport interface CreateExecutionVariables {\n input: GraphQLInput<CreateExecutionInput>;\n}\n\nconst CREATE_EXECUTION_FIELDS = fieldsOf<CreateExecutionInput>({\n agentId: true,\n appId: true,\n conversationId: true,\n input: true,\n metadata: true,\n type: true,\n workspaceId: true,\n});\n\nexport interface UpdateExecutionStatusVariables {\n id: string;\n status: ExecutionStatus;\n output?: string;\n error?: Record<string, unknown>;\n}\n\n/** Terminal statuses that count as a successful run. */\nconst SUCCESS_STATUSES = new Set(['COMPLETED']);\n\nconst NO_EXECUTIONS: ExecutionRecord[] = [];\n\nexport const executionKeys = {\n all: ['executions'] as const,\n lists: () => [...executionKeys.all, 'list'] as const,\n list: (filter?: ExecutionsFilter) => [...executionKeys.lists(), filter] as const,\n details: () => [...executionKeys.all, 'detail'] as const,\n detail: (id: string) => [...executionKeys.details(), id] as const,\n metrics: () => [...executionKeys.all, 'metrics'] as const,\n};\n\nfunction matchesSearch(execution: ExecutionRecord, needle: string): boolean {\n return (\n execution.id.toLowerCase().includes(needle) ||\n (execution.agentId ?? '').toLowerCase().includes(needle) ||\n (execution.appId ?? '').toLowerCase().includes(needle) ||\n execution.input.toLowerCase().includes(needle)\n );\n}\n\nexport function useExecutions(filter?: ExecutionsFilter): QueryResult<ExecutionRecord[]> {\n const workspaceId = useWorkspaceId();\n const search = filter?.search?.trim().toLowerCase() ?? '';\n const statuses = filter?.status;\n const singleStatus = statuses?.length === 1 ? statuses[0] : undefined;\n const statusKey = statuses?.join(',') ?? '';\n const { agentId, appId, conversationId, type } = filter ?? {};\n\n const variables = useMemo(\n () => ({\n filters: {\n workspaceId,\n status: singleStatus,\n agentId,\n appId,\n conversationId,\n type,\n },\n pagination: { limit: LIST_LIMIT, offset: 0 },\n }),\n [workspaceId, singleStatus, agentId, appId, conversationId, type]\n );\n\n const select = useCallback(\n (data: ListExecutionsQuery | undefined): ExecutionRecord[] => {\n const rows: ExecutionRecord[] = data?.listExecutions ?? NO_EXECUTIONS;\n const wanted = statusKey ? new Set(statusKey.split(',')) : undefined;\n const narrowed =\n // A single status is already applied server-side.\n wanted && wanted.size > 1 ? rows.filter((row) => wanted.has(row.status)) : rows;\n return search ? narrowed.filter((row) => matchesSearch(row, search)) : narrowed;\n },\n [search, statusKey]\n );\n\n return useWorkspaceQuery<ListExecutionsQuery, ExecutionRecord[]>({\n document: ListExecutionsDocument,\n variables,\n select,\n fallback: NO_EXECUTIONS,\n enabled: Boolean(workspaceId),\n errorMessage: 'Failed to load executions',\n });\n}\n\nexport function useExecution(executionId: string | undefined): QueryResult<ExecutionRecord | null> {\n const variables = useMemo(() => ({ id: executionId ?? '' }), [executionId]);\n\n return useWorkspaceQuery<GetExecutionQuery, ExecutionRecord | null>({\n document: GetExecutionDocument,\n variables,\n select: (data) => data?.getExecution ?? null,\n fallback: null,\n enabled: Boolean(executionId),\n errorMessage: 'Failed to load execution',\n });\n}\n\n/**\n * Token/cost metrics for the workspace, optionally narrowed to an agent, app or\n * date window. Returns `null` when the service has nothing recorded yet.\n */\nexport function useExecutionMetrics(\n filter?: ExecutionMetricsFilter\n): QueryResult<ExecutionMetricsRecord | null> {\n const workspaceId = useWorkspaceId();\n const { agentId, appId, startDate, endDate } = filter ?? {};\n\n const variables = useMemo(\n () => ({ filter: { workspaceId, agentId, appId, startDate, endDate } }),\n [workspaceId, agentId, appId, startDate, endDate]\n );\n\n return useWorkspaceQuery<GetExecutionMetricsQuery, ExecutionMetricsRecord | null>({\n document: GetExecutionMetricsDocument,\n variables,\n select: (data) => data?.getExecutionMetrics ?? null,\n fallback: null,\n enabled: Boolean(workspaceId),\n errorMessage: 'Failed to load execution metrics',\n });\n}\n\nexport interface ExecutionRollup {\n total: number;\n succeeded: number;\n failed: number;\n successRate: number;\n avgDurationMs: number;\n totalCost: number;\n totalTokens: number;\n}\n\n/**\n * Rolls a list of executions up into the headline numbers shown above the table.\n * Derived purely from the rows that were actually loaded — no server aggregate\n * exists for this, so callers must label it as such.\n */\nexport function summariseExecutions(executions: readonly ExecutionRecord[]): ExecutionRollup {\n const total = executions.length;\n let succeeded = 0;\n let failed = 0;\n let durationSum = 0;\n let durationCount = 0;\n let totalCost = 0;\n let totalTokens = 0;\n\n for (const execution of executions) {\n if (SUCCESS_STATUSES.has(execution.status)) succeeded += 1;\n if (execution.status === 'FAILED' || execution.status === 'TIMEOUT') failed += 1;\n if (typeof execution.duration === 'number') {\n durationSum += execution.duration;\n durationCount += 1;\n }\n totalCost += execution.cost ?? 0;\n totalTokens += execution.tokensUsed ?? 0;\n }\n\n return {\n total,\n succeeded,\n failed,\n successRate: total > 0 ? succeeded / total : 0,\n avgDurationMs: durationCount > 0 ? durationSum / durationCount : 0,\n totalCost,\n totalTokens,\n };\n}\n\nexport function useCreateExecution() {\n return useWorkspaceMutation<CreateExecutionMutation, CreateExecutionVariables, ExecutionRecord>({\n document: CreateExecutionDocument,\n variables: ({ input }) => ({ input: buildMutationInput(input, CREATE_EXECUTION_FIELDS) }),\n select: (data) => data?.createExecution,\n errorMessage: 'Failed to start execution',\n });\n}\n\nexport function useUpdateExecutionStatus() {\n return useWorkspaceMutation<\n UpdateExecutionStatusMutation,\n UpdateExecutionStatusVariables,\n ExecutionRecord\n >({\n document: UpdateExecutionStatusDocument,\n variables: ({ id, status, output, error }) => ({\n id,\n input: {\n status,\n output,\n // The subgraph takes the failure as a message plus a JSON detail blob\n // (UpdateExecutionStatusInput); pass the caller's object through whole.\n errorMessage: typeof error?.message === 'string' ? error.message : undefined,\n errorDetails: error,\n },\n }),\n select: (data) => data?.updateExecutionStatus,\n errorMessage: 'Failed to update execution status',\n });\n}\n"],"mappings":";;;;;AAmCA,IAAM,IAAa,KAqDb,IAA0B,EAA+B;CAC7D,SAAS;CACT,OAAO;CACP,gBAAgB;CAChB,OAAO;CACP,UAAU;CACV,MAAM;CACN,aAAa;CACd,CAAC,EAUI,IAAmB,IAAI,IAAI,CAAC,YAAY,CAAC,EAEzC,IAAmC,EAAE;AAW3C,SAAS,EAAc,GAA4B,GAAyB;AAC1E,QACE,EAAU,GAAG,aAAa,CAAC,SAAS,EAAO,KAC1C,EAAU,WAAW,IAAI,aAAa,CAAC,SAAS,EAAO,KACvD,EAAU,SAAS,IAAI,aAAa,CAAC,SAAS,EAAO,IACtD,EAAU,MAAM,aAAa,CAAC,SAAS,EAAO;;AAIlD,SAAgB,EAAc,GAA2D;CACvF,IAAM,IAAc,GAAgB,EAC9B,IAAS,GAAQ,QAAQ,MAAM,CAAC,aAAa,IAAI,IACjD,IAAW,GAAQ,QACnB,IAAe,GAAU,WAAW,IAAI,EAAS,KAAK,KAAA,GACtD,IAAY,GAAU,KAAK,IAAI,IAAI,IACnC,EAAE,YAAS,UAAO,mBAAgB,YAAS,KAAU,EAAE;AA6B7D,QAAO,EAA0D;EAC/D,UAAU;EACV,WA7BgB,SACT;GACL,SAAS;IACP;IACA,QAAQ;IACR;IACA;IACA;IACA;IACD;GACD,YAAY;IAAE,OAAO;IAAY,QAAQ;IAAG;GAC7C,GACD;GAAC;GAAa;GAAc;GAAS;GAAO;GAAgB;GAAK,CAClE;EAiBC,QAfa,GACZ,MAA6D;GAC5D,IAAM,IAA0B,GAAM,kBAAkB,GAClD,IAAS,IAAY,IAAI,IAAI,EAAU,MAAM,IAAI,CAAC,GAAG,KAAA,GACrD,IAEJ,KAAU,EAAO,OAAO,IAAI,EAAK,QAAQ,MAAQ,EAAO,IAAI,EAAI,OAAO,CAAC,GAAG;AAC7E,UAAO,IAAS,EAAS,QAAQ,MAAQ,EAAc,GAAK,EAAO,CAAC,GAAG;KAEzE,CAAC,GAAQ,EAAU,CACpB;EAMC,UAAU;EACV,SAAS,EAAQ;EACjB,cAAc;EACf,CAAC;;AAGJ,SAAgB,EAAa,GAAsE;AAGjG,QAAO,EAA6D;EAClE,UAAU;EACV,WAJgB,SAAe,EAAE,IAAI,KAAe,IAAI,GAAG,CAAC,EAAY,CAAC;EAKzE,SAAS,MAAS,GAAM,gBAAgB;EACxC,UAAU;EACV,SAAS,EAAQ;EACjB,cAAc;EACf,CAAC;;AA2CJ,SAAgB,EAAoB,GAAyD;CAC3F,IAAM,IAAQ,EAAW,QACrB,IAAY,GACZ,IAAS,GACT,IAAc,GACd,IAAgB,GAChB,IAAY,GACZ,IAAc;AAElB,MAAK,IAAM,KAAa,EAQtB,CAPI,EAAiB,IAAI,EAAU,OAAO,KAAE,KAAa,KACrD,EAAU,WAAW,YAAY,EAAU,WAAW,eAAW,KAAU,IAC3E,OAAO,EAAU,YAAa,aAChC,KAAe,EAAU,UACzB,KAAiB,IAEnB,KAAa,EAAU,QAAQ,GAC/B,KAAe,EAAU,cAAc;AAGzC,QAAO;EACL;EACA;EACA;EACA,aAAa,IAAQ,IAAI,IAAY,IAAQ;EAC7C,eAAe,IAAgB,IAAI,IAAc,IAAgB;EACjE;EACA;EACD;;AAGH,SAAgB,IAAqB;AACnC,QAAO,EAAyF;EAC9F,UAAU;EACV,YAAY,EAAE,gBAAa,EAAE,OAAO,EAAmB,GAAO,EAAwB,EAAE;EACxF,SAAS,MAAS,GAAM;EACxB,cAAc;EACf,CAAC"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { useBotlit as e } from "../providers/BotlitProvider.js";
|
|
2
|
+
import { gql as t } from "@apollo/client";
|
|
3
|
+
import { useGatewayClient as n } from "@burdenoff/fe-libs/shared/graphql";
|
|
4
|
+
import { useMutation as r, useQuery as i, useQueryClient as a } from "@tanstack/react-query";
|
|
5
|
+
//#region src/botlit/hooks/useKnowledgeSourceImports.ts
|
|
6
|
+
var o = t`
|
|
7
|
+
query KnowledgeSourceImports($knowledgeBaseId: ID!) {
|
|
8
|
+
knowledgeSourceImports(knowledgeBaseId: $knowledgeBaseId) {
|
|
9
|
+
id
|
|
10
|
+
knowledgeBaseId
|
|
11
|
+
title
|
|
12
|
+
status
|
|
13
|
+
failureCount
|
|
14
|
+
errorCode
|
|
15
|
+
documentId
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
`, s = t`
|
|
19
|
+
mutation QueueKnowledgeSource($input: QueueKnowledgeSourceInput!) {
|
|
20
|
+
queueKnowledgeSource(input: $input) {
|
|
21
|
+
id
|
|
22
|
+
knowledgeBaseId
|
|
23
|
+
title
|
|
24
|
+
status
|
|
25
|
+
failureCount
|
|
26
|
+
errorCode
|
|
27
|
+
documentId
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
`, c = t`
|
|
31
|
+
mutation RetryKnowledgeSourceImport($id: ID!) {
|
|
32
|
+
retryKnowledgeSourceImport(id: $id)
|
|
33
|
+
}
|
|
34
|
+
`;
|
|
35
|
+
function l(t) {
|
|
36
|
+
let l = n("workspace"), u = a(), { workspaceId: d, currentUser: f } = e(), p = [
|
|
37
|
+
"botmanor-knowledge-source-imports",
|
|
38
|
+
d,
|
|
39
|
+
f?.id,
|
|
40
|
+
t
|
|
41
|
+
];
|
|
42
|
+
return {
|
|
43
|
+
imports: i({
|
|
44
|
+
queryKey: p,
|
|
45
|
+
enabled: !!(d && f?.id && t),
|
|
46
|
+
retry: !1,
|
|
47
|
+
refetchInterval: (e) => e.state.data?.some((e) => ["READY", "PROCESSING"].includes(e.status)) ? 5e3 : !1,
|
|
48
|
+
queryFn: async () => {
|
|
49
|
+
let e = (await l.query({
|
|
50
|
+
query: o,
|
|
51
|
+
variables: { knowledgeBaseId: t },
|
|
52
|
+
fetchPolicy: "no-cache"
|
|
53
|
+
})).data?.knowledgeSourceImports;
|
|
54
|
+
if (!e || e.length > 100 || e.some((e) => e.knowledgeBaseId !== t)) throw Error("Knowledge imports unavailable");
|
|
55
|
+
return e;
|
|
56
|
+
}
|
|
57
|
+
}),
|
|
58
|
+
queue: r({
|
|
59
|
+
mutationFn: async (e) => {
|
|
60
|
+
let n = (await l.mutate({
|
|
61
|
+
mutation: s,
|
|
62
|
+
variables: { input: {
|
|
63
|
+
...e,
|
|
64
|
+
knowledgeBaseId: t
|
|
65
|
+
} }
|
|
66
|
+
})).data?.queueKnowledgeSource;
|
|
67
|
+
if (!n || n.knowledgeBaseId !== t) throw Error("Knowledge admission unavailable");
|
|
68
|
+
return n;
|
|
69
|
+
},
|
|
70
|
+
onSuccess: () => u.invalidateQueries({ queryKey: p })
|
|
71
|
+
}),
|
|
72
|
+
retry: r({
|
|
73
|
+
mutationFn: async (e) => {
|
|
74
|
+
if (!(await l.mutate({
|
|
75
|
+
mutation: c,
|
|
76
|
+
variables: { id: e }
|
|
77
|
+
})).data?.retryKnowledgeSourceImport) throw Error("Knowledge recovery unavailable");
|
|
78
|
+
},
|
|
79
|
+
onSuccess: () => u.invalidateQueries({ queryKey: p })
|
|
80
|
+
})
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
//#endregion
|
|
84
|
+
export { l as useKnowledgeSourceImports };
|
|
85
|
+
|
|
86
|
+
//# sourceMappingURL=useKnowledgeSourceImports.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useKnowledgeSourceImports.js","names":[],"sources":["../../../src/botlit/hooks/useKnowledgeSourceImports.ts"],"sourcesContent":["import { gql } from '@apollo/client';\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';\nimport { useGatewayClient } from '@burdenoff/fe-libs/shared/graphql';\nimport { useBotlit } from '../providers/BotlitProvider';\n\ninterface SourceImport {\n id: string;\n knowledgeBaseId: string;\n title: string;\n status: string;\n failureCount: number;\n errorCode: string | null;\n documentId: string | null;\n}\nexport interface SourceImportInput {\n clientRequestId: string;\n title: string;\n sourceUrl?: string;\n content?: string;\n}\nconst LIST = gql`\n query KnowledgeSourceImports($knowledgeBaseId: ID!) {\n knowledgeSourceImports(knowledgeBaseId: $knowledgeBaseId) {\n id\n knowledgeBaseId\n title\n status\n failureCount\n errorCode\n documentId\n }\n }\n`;\nconst QUEUE = gql`\n mutation QueueKnowledgeSource($input: QueueKnowledgeSourceInput!) {\n queueKnowledgeSource(input: $input) {\n id\n knowledgeBaseId\n title\n status\n failureCount\n errorCode\n documentId\n }\n }\n`;\nconst RETRY = gql`\n mutation RetryKnowledgeSourceImport($id: ID!) {\n retryKnowledgeSourceImport(id: $id)\n }\n`;\nexport function useKnowledgeSourceImports(knowledgeBaseId: string) {\n const client = useGatewayClient('workspace'),\n cache = useQueryClient(),\n { workspaceId, currentUser } = useBotlit();\n const key = ['botmanor-knowledge-source-imports', workspaceId, currentUser?.id, knowledgeBaseId];\n const imports = useQuery({\n queryKey: key,\n enabled: Boolean(workspaceId && currentUser?.id && knowledgeBaseId),\n retry: false,\n refetchInterval: (query) =>\n query.state.data?.some((row) => ['READY', 'PROCESSING'].includes(row.status)) ? 5000 : false,\n queryFn: async () => {\n const response = await client.query<{ knowledgeSourceImports: SourceImport[] }>({\n query: LIST,\n variables: { knowledgeBaseId },\n fetchPolicy: 'no-cache',\n });\n const rows = response.data?.knowledgeSourceImports;\n if (!rows || rows.length > 100 || rows.some((row) => row.knowledgeBaseId !== knowledgeBaseId))\n throw new Error('Knowledge imports unavailable');\n return rows;\n },\n });\n const queue = useMutation({\n mutationFn: async (input: SourceImportInput) => {\n const response = await client.mutate<{ queueKnowledgeSource: SourceImport }>({\n mutation: QUEUE,\n variables: { input: { ...input, knowledgeBaseId } },\n });\n const row = response.data?.queueKnowledgeSource;\n if (!row || row.knowledgeBaseId !== knowledgeBaseId)\n throw new Error('Knowledge admission unavailable');\n return row;\n },\n onSuccess: () => cache.invalidateQueries({ queryKey: key }),\n });\n const retry = useMutation({\n mutationFn: async (id: string) => {\n const response = await client.mutate<{ retryKnowledgeSourceImport: boolean }>({\n mutation: RETRY,\n variables: { id },\n });\n if (!response.data?.retryKnowledgeSourceImport)\n throw new Error('Knowledge recovery unavailable');\n },\n onSuccess: () => cache.invalidateQueries({ queryKey: key }),\n });\n return { imports, queue, retry };\n}\n"],"mappings":";;;;;AAoBA,IAAM,IAAO,CAAG;;;;;;;;;;;;GAaV,IAAQ,CAAG;;;;;;;;;;;;GAaX,IAAQ,CAAG;;;;;AAKjB,SAAgB,EAA0B,GAAyB;CACjE,IAAM,IAAS,EAAiB,YAAY,EAC1C,IAAQ,GAAgB,EACxB,EAAE,gBAAa,mBAAgB,GAAW,EACtC,IAAM;EAAC;EAAqC;EAAa,GAAa;EAAI;EAAgB;AA2ChG,QAAO;EAAE,SA1CO,EAAS;GACvB,UAAU;GACV,SAAS,GAAQ,KAAe,GAAa,MAAM;GACnD,OAAO;GACP,kBAAkB,MAChB,EAAM,MAAM,MAAM,MAAM,MAAQ,CAAC,SAAS,aAAa,CAAC,SAAS,EAAI,OAAO,CAAC,GAAG,MAAO;GACzF,SAAS,YAAY;IAMnB,IAAM,KALW,MAAM,EAAO,MAAkD;KAC9E,OAAO;KACP,WAAW,EAAE,oBAAiB;KAC9B,aAAa;KACd,CAAC,EACoB,MAAM;AAC5B,QAAI,CAAC,KAAQ,EAAK,SAAS,OAAO,EAAK,MAAM,MAAQ,EAAI,oBAAoB,EAAgB,CAC3F,OAAU,MAAM,gCAAgC;AAClD,WAAO;;GAEV,CAAC;EAyBgB,OAxBJ,EAAY;GACxB,YAAY,OAAO,MAA6B;IAK9C,IAAM,KAJW,MAAM,EAAO,OAA+C;KAC3E,UAAU;KACV,WAAW,EAAE,OAAO;MAAE,GAAG;MAAO;MAAiB,EAAE;KACpD,CAAC,EACmB,MAAM;AAC3B,QAAI,CAAC,KAAO,EAAI,oBAAoB,EAClC,OAAU,MAAM,kCAAkC;AACpD,WAAO;;GAET,iBAAiB,EAAM,kBAAkB,EAAE,UAAU,GAAK,CAAC;GAC5D,CAAC;EAYuB,OAXX,EAAY;GACxB,YAAY,OAAO,MAAe;AAKhC,QAAI,EAJa,MAAM,EAAO,OAAgD;KAC5E,UAAU;KACV,WAAW,EAAE,OAAI;KAClB,CAAC,EACY,MAAM,2BAClB,OAAU,MAAM,iCAAiC;;GAErD,iBAAiB,EAAM,kBAAkB,EAAE,UAAU,GAAK,CAAC;GAC5D,CAAC;EAC8B"}
|