@burdenoff/microfe-subscriberbot 2026.710.1 → 2026.715.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/index.js +4 -3
- package/dist/subscriberbot/admin/AdminDashboardPage.d.ts +4 -0
- package/dist/subscriberbot/admin/AdminDashboardPage.d.ts.map +1 -0
- package/dist/subscriberbot/admin/AdminDashboardPage.js +268 -0
- package/dist/subscriberbot/admin/AdminDashboardPage.js.map +1 -0
- package/dist/subscriberbot/admin/AdminRoot.d.ts +9 -0
- package/dist/subscriberbot/admin/AdminRoot.d.ts.map +1 -0
- package/dist/subscriberbot/admin/AdminRoot.js +23 -0
- package/dist/subscriberbot/admin/AdminRoot.js.map +1 -0
- package/dist/subscriberbot/admin/index.d.ts +7 -0
- package/dist/subscriberbot/admin/index.d.ts.map +1 -0
- package/dist/subscriberbot/admin/index.js +2 -0
- package/dist/subscriberbot/hooks/index.js +1 -0
- package/dist/subscriberbot/index.d.ts +1 -0
- package/dist/subscriberbot/index.d.ts.map +1 -1
- package/dist/subscriberbot/index.js +2 -0
- package/dist/subscriberbot/services/createSandboxAssistantTransport.d.ts +11 -0
- package/dist/subscriberbot/services/createSandboxAssistantTransport.d.ts.map +1 -1
- package/dist/subscriberbot/services/createSandboxAssistantTransport.js +8 -114
- package/dist/subscriberbot/services/createSandboxAssistantTransport.js.map +1 -1
- package/package.json +3 -3
- package/dist/subscriberbot/services/assistantApi.d.ts +0 -66
- package/dist/subscriberbot/services/assistantApi.d.ts.map +0 -1
- package/dist/subscriberbot/services/assistantApi.js +0 -260
- package/dist/subscriberbot/services/assistantApi.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -2,7 +2,8 @@ import { SubscriberBotProvider as e, useSubscriberBot as t } from "./subscriberb
|
|
|
2
2
|
import { cn as n } from "./subscriberbot/utils/cn.js";
|
|
3
3
|
import { formatCurrency as r, formatDate as i, formatDateTime as a, formatEnumLabel as o, formatIntervalSuffix as s, formatNumber as c, formatRelativeTime as l } from "./subscriberbot/utils/formatters.js";
|
|
4
4
|
import { SubscriberBotRoot as u } from "./subscriberbot/SubscriberBotRoot.js";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
5
|
+
import { AdminRoot as d } from "./subscriberbot/admin/AdminRoot.js";
|
|
6
|
+
import { useSubscriberBotStore as f } from "./subscriberbot/store/subscriberbotStore.js";
|
|
7
|
+
import { useSandboxAssistantTransport as p } from "./subscriberbot/services/createSandboxAssistantTransport.js";
|
|
7
8
|
import "./subscriberbot/index.js";
|
|
8
|
-
export { e as SubscriberBotProvider, u as SubscriberBotRoot, n as cn, r as formatCurrency, i as formatDate, a as formatDateTime, o as formatEnumLabel, s as formatIntervalSuffix, c as formatNumber, l as formatRelativeTime,
|
|
9
|
+
export { d as AdminRoot, e as SubscriberBotProvider, u as SubscriberBotRoot, n as cn, r as formatCurrency, i as formatDate, a as formatDateTime, o as formatEnumLabel, s as formatIntervalSuffix, c as formatNumber, l as formatRelativeTime, p as useSandboxAssistantTransport, t as useSubscriberBot, f as useSubscriberBotStore };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AdminDashboardPage.d.ts","sourceRoot":"","sources":["../../../src/subscriberbot/admin/AdminDashboardPage.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAY,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AA8E1C,eAAO,MAAM,kBAAkB,EAAE,EAoPhC,CAAC"}
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
import { PageLayout as e } from "../components/PageLayout.js";
|
|
2
|
+
import { formatDate as t } from "../utils/formatters.js";
|
|
3
|
+
import { StatusBadge as n } from "../components/StatusBadge.js";
|
|
4
|
+
import { useProviders as r, useUpdateProvider as i } from "../hooks/useSubscriberBotApi.js";
|
|
5
|
+
import "../hooks/index.js";
|
|
6
|
+
import { useState as a } from "react";
|
|
7
|
+
import { CheckCircle2 as o, Plug as s, Settings2 as c, Store as l } from "lucide-react";
|
|
8
|
+
import { jsx as u, jsxs as d } from "react/jsx-runtime";
|
|
9
|
+
import { Button as f, Card as p, CardContent as m, CardDescription as h, CardHeader as g, CardTitle as _, EmptyState as v, Spinner as y, Table as b, TableBody as x, TableCell as S, TableHead as C, TableHeader as w, TableRow as T, Tabs as E, TabsContent as D, TabsList as O, TabsTrigger as k } from "@burdenoff/fe-libs/ui";
|
|
10
|
+
//#region src/subscriberbot/admin/AdminDashboardPage.tsx
|
|
11
|
+
var A = [{
|
|
12
|
+
id: "adapter-placeholder-1",
|
|
13
|
+
name: "Stripe Billing Adapter",
|
|
14
|
+
kind: "BILLING",
|
|
15
|
+
submittedAt: "2026-07-10T08:30:00Z",
|
|
16
|
+
status: "pending"
|
|
17
|
+
}, {
|
|
18
|
+
id: "adapter-placeholder-2",
|
|
19
|
+
name: "Chargebee Sync Adapter",
|
|
20
|
+
kind: "BILLING",
|
|
21
|
+
submittedAt: "2026-07-12T14:22:00Z",
|
|
22
|
+
status: "pending"
|
|
23
|
+
}], j = [{
|
|
24
|
+
id: "listing-placeholder-1",
|
|
25
|
+
title: "Premium SaaS Bundle",
|
|
26
|
+
provider: "ExampleSoft",
|
|
27
|
+
reportedAt: "2026-07-14T09:15:00Z",
|
|
28
|
+
reason: "Misleading pricing"
|
|
29
|
+
}, {
|
|
30
|
+
id: "listing-placeholder-2",
|
|
31
|
+
title: "Newsletter Pro",
|
|
32
|
+
provider: "MailMaster",
|
|
33
|
+
reportedAt: "2026-07-13T16:40:00Z",
|
|
34
|
+
reason: "Trademark concern"
|
|
35
|
+
}], M = () => {
|
|
36
|
+
let [M, N] = a("providers"), { data: P, isLoading: F } = r({ pagination: { limit: 50 } }), I = i(), L = (e) => {
|
|
37
|
+
I.mutate({
|
|
38
|
+
id: e,
|
|
39
|
+
input: { status: "VERIFIED" }
|
|
40
|
+
});
|
|
41
|
+
}, R = (e) => {
|
|
42
|
+
I.mutate({
|
|
43
|
+
id: e,
|
|
44
|
+
input: { status: "DEPRECATED" }
|
|
45
|
+
});
|
|
46
|
+
}, z = P?.items ?? [];
|
|
47
|
+
return /* @__PURE__ */ u(e, {
|
|
48
|
+
title: "SubscriberBot Admin",
|
|
49
|
+
description: "Provider registry curation, adapter approvals, and marketplace moderation.",
|
|
50
|
+
children: /* @__PURE__ */ d(E, {
|
|
51
|
+
value: M,
|
|
52
|
+
onValueChange: N,
|
|
53
|
+
className: "w-full",
|
|
54
|
+
children: [
|
|
55
|
+
/* @__PURE__ */ d(O, {
|
|
56
|
+
className: "mb-4 grid w-full grid-cols-3 sm:w-auto sm:inline-flex",
|
|
57
|
+
children: [
|
|
58
|
+
/* @__PURE__ */ d(k, {
|
|
59
|
+
value: "providers",
|
|
60
|
+
className: "gap-2",
|
|
61
|
+
children: [/* @__PURE__ */ u(c, { size: 16 }), "Provider Registry"]
|
|
62
|
+
}),
|
|
63
|
+
/* @__PURE__ */ d(k, {
|
|
64
|
+
value: "adapters",
|
|
65
|
+
className: "gap-2",
|
|
66
|
+
children: [/* @__PURE__ */ u(s, { size: 16 }), "Adapter Approvals"]
|
|
67
|
+
}),
|
|
68
|
+
/* @__PURE__ */ d(k, {
|
|
69
|
+
value: "marketplace",
|
|
70
|
+
className: "gap-2",
|
|
71
|
+
children: [/* @__PURE__ */ u(l, { size: 16 }), "Marketplace Moderation"]
|
|
72
|
+
})
|
|
73
|
+
]
|
|
74
|
+
}),
|
|
75
|
+
/* @__PURE__ */ u(D, {
|
|
76
|
+
value: "providers",
|
|
77
|
+
children: /* @__PURE__ */ d(p, { children: [/* @__PURE__ */ d(g, { children: [/* @__PURE__ */ u(_, { children: "Provider registry" }), /* @__PURE__ */ u(h, { children: "Curate the global provider catalog. Verify submitted providers or deprecate stale entries." })] }), /* @__PURE__ */ u(m, { children: F ? /* @__PURE__ */ u("div", {
|
|
78
|
+
className: "flex min-h-[200px] items-center justify-center",
|
|
79
|
+
children: /* @__PURE__ */ u(y, { size: "lg" })
|
|
80
|
+
}) : z.length === 0 ? /* @__PURE__ */ u(v, {
|
|
81
|
+
icon: /* @__PURE__ */ u(l, { className: "size-6 text-action-primary-bg" }),
|
|
82
|
+
title: "No providers yet",
|
|
83
|
+
description: "Once providers are created or claimed they will appear here for curation."
|
|
84
|
+
}) : /* @__PURE__ */ u("div", {
|
|
85
|
+
className: "overflow-x-auto",
|
|
86
|
+
children: /* @__PURE__ */ d(b, { children: [/* @__PURE__ */ u(w, { children: /* @__PURE__ */ d(T, { children: [
|
|
87
|
+
/* @__PURE__ */ u(C, { children: "Name" }),
|
|
88
|
+
/* @__PURE__ */ u(C, { children: "Category" }),
|
|
89
|
+
/* @__PURE__ */ u(C, { children: "Status" }),
|
|
90
|
+
/* @__PURE__ */ u(C, { children: "Created" }),
|
|
91
|
+
/* @__PURE__ */ u(C, {
|
|
92
|
+
className: "text-right",
|
|
93
|
+
children: "Actions"
|
|
94
|
+
})
|
|
95
|
+
] }) }), /* @__PURE__ */ u(x, { children: z.map((e) => /* @__PURE__ */ d(T, { children: [
|
|
96
|
+
/* @__PURE__ */ u(S, {
|
|
97
|
+
className: "font-medium text-text-primary",
|
|
98
|
+
children: e.name
|
|
99
|
+
}),
|
|
100
|
+
/* @__PURE__ */ u(S, {
|
|
101
|
+
className: "text-text-secondary",
|
|
102
|
+
children: e.category
|
|
103
|
+
}),
|
|
104
|
+
/* @__PURE__ */ u(S, { children: /* @__PURE__ */ u(n, { status: e.status }) }),
|
|
105
|
+
/* @__PURE__ */ u(S, {
|
|
106
|
+
className: "text-text-secondary",
|
|
107
|
+
children: t(e.createdAt)
|
|
108
|
+
}),
|
|
109
|
+
/* @__PURE__ */ u(S, {
|
|
110
|
+
className: "text-right",
|
|
111
|
+
children: /* @__PURE__ */ d("div", {
|
|
112
|
+
className: "flex justify-end gap-2",
|
|
113
|
+
children: [e.status !== "VERIFIED" && /* @__PURE__ */ d(f, {
|
|
114
|
+
size: "sm",
|
|
115
|
+
variant: "outline",
|
|
116
|
+
onClick: () => L(e.id),
|
|
117
|
+
disabled: I.isPending,
|
|
118
|
+
children: [/* @__PURE__ */ u(o, {
|
|
119
|
+
size: 14,
|
|
120
|
+
className: "mr-1"
|
|
121
|
+
}), "Verify"]
|
|
122
|
+
}), e.status !== "DEPRECATED" && /* @__PURE__ */ u(f, {
|
|
123
|
+
size: "sm",
|
|
124
|
+
variant: "secondary",
|
|
125
|
+
onClick: () => R(e.id),
|
|
126
|
+
disabled: I.isPending,
|
|
127
|
+
children: "Deprecate"
|
|
128
|
+
})]
|
|
129
|
+
})
|
|
130
|
+
})
|
|
131
|
+
] }, e.id)) })] })
|
|
132
|
+
}) })] })
|
|
133
|
+
}),
|
|
134
|
+
/* @__PURE__ */ u(D, {
|
|
135
|
+
value: "adapters",
|
|
136
|
+
children: /* @__PURE__ */ d(p, { children: [/* @__PURE__ */ d(g, { children: [/* @__PURE__ */ u(_, { children: "Adapter approvals" }), /* @__PURE__ */ u(h, { children: "Review submitted integration adapters before they are published to the SubscriberBot adapter marketplace." })] }), /* @__PURE__ */ d(m, { children: [/* @__PURE__ */ d("div", {
|
|
137
|
+
className: "mb-4 rounded-md border border-status-warning-border bg-status-warning-bg-subtle p-3 text-sm text-status-warning-text",
|
|
138
|
+
children: [
|
|
139
|
+
"Backend query not yet implemented. Wire",
|
|
140
|
+
/* @__PURE__ */ u("code", {
|
|
141
|
+
className: "mx-1 rounded bg-bg-sunken px-1 py-0.5 font-mono text-text-primary",
|
|
142
|
+
children: "subListAdapterSubmissions"
|
|
143
|
+
}),
|
|
144
|
+
"from ",
|
|
145
|
+
/* @__PURE__ */ u("code", {
|
|
146
|
+
className: "font-mono",
|
|
147
|
+
children: "wspace-subscriberbot-svc"
|
|
148
|
+
}),
|
|
149
|
+
" to replace the placeholder rows below."
|
|
150
|
+
]
|
|
151
|
+
}), /* @__PURE__ */ u("div", {
|
|
152
|
+
className: "overflow-x-auto",
|
|
153
|
+
children: /* @__PURE__ */ d(b, { children: [/* @__PURE__ */ u(w, { children: /* @__PURE__ */ d(T, { children: [
|
|
154
|
+
/* @__PURE__ */ u(C, { children: "Adapter" }),
|
|
155
|
+
/* @__PURE__ */ u(C, { children: "Kind" }),
|
|
156
|
+
/* @__PURE__ */ u(C, { children: "Submitted" }),
|
|
157
|
+
/* @__PURE__ */ u(C, { children: "Status" }),
|
|
158
|
+
/* @__PURE__ */ u(C, {
|
|
159
|
+
className: "text-right",
|
|
160
|
+
children: "Actions"
|
|
161
|
+
})
|
|
162
|
+
] }) }), /* @__PURE__ */ u(x, { children: A.map((e) => /* @__PURE__ */ d(T, { children: [
|
|
163
|
+
/* @__PURE__ */ u(S, {
|
|
164
|
+
className: "font-medium text-text-primary",
|
|
165
|
+
children: e.name
|
|
166
|
+
}),
|
|
167
|
+
/* @__PURE__ */ u(S, {
|
|
168
|
+
className: "text-text-secondary",
|
|
169
|
+
children: e.kind
|
|
170
|
+
}),
|
|
171
|
+
/* @__PURE__ */ u(S, {
|
|
172
|
+
className: "text-text-secondary",
|
|
173
|
+
children: t(e.submittedAt)
|
|
174
|
+
}),
|
|
175
|
+
/* @__PURE__ */ u(S, { children: /* @__PURE__ */ u(n, { status: e.status }) }),
|
|
176
|
+
/* @__PURE__ */ u(S, {
|
|
177
|
+
className: "text-right",
|
|
178
|
+
children: /* @__PURE__ */ d("div", {
|
|
179
|
+
className: "flex justify-end gap-2",
|
|
180
|
+
children: [/* @__PURE__ */ u(f, {
|
|
181
|
+
size: "sm",
|
|
182
|
+
variant: "outline",
|
|
183
|
+
disabled: !0,
|
|
184
|
+
children: "Approve"
|
|
185
|
+
}), /* @__PURE__ */ u(f, {
|
|
186
|
+
size: "sm",
|
|
187
|
+
variant: "secondary",
|
|
188
|
+
disabled: !0,
|
|
189
|
+
children: "Reject"
|
|
190
|
+
})]
|
|
191
|
+
})
|
|
192
|
+
})
|
|
193
|
+
] }, e.id)) })] })
|
|
194
|
+
})] })] })
|
|
195
|
+
}),
|
|
196
|
+
/* @__PURE__ */ u(D, {
|
|
197
|
+
value: "marketplace",
|
|
198
|
+
children: /* @__PURE__ */ d(p, { children: [/* @__PURE__ */ d(g, { children: [/* @__PURE__ */ u(_, { children: "Marketplace moderation" }), /* @__PURE__ */ u(h, { children: "Review reported marketplace listings and take moderation actions." })] }), /* @__PURE__ */ d(m, { children: [/* @__PURE__ */ d("div", {
|
|
199
|
+
className: "mb-4 rounded-md border border-status-warning-border bg-status-warning-bg-subtle p-3 text-sm text-status-warning-text",
|
|
200
|
+
children: [
|
|
201
|
+
"Backend query not yet implemented. Wire",
|
|
202
|
+
/* @__PURE__ */ u("code", {
|
|
203
|
+
className: "mx-1 rounded bg-bg-sunken px-1 py-0.5 font-mono text-text-primary",
|
|
204
|
+
children: "subListMarketplaceReports"
|
|
205
|
+
}),
|
|
206
|
+
"from ",
|
|
207
|
+
/* @__PURE__ */ u("code", {
|
|
208
|
+
className: "font-mono",
|
|
209
|
+
children: "wspace-subscriberbot-svc"
|
|
210
|
+
}),
|
|
211
|
+
" to replace the placeholder rows below."
|
|
212
|
+
]
|
|
213
|
+
}), /* @__PURE__ */ u("div", {
|
|
214
|
+
className: "overflow-x-auto",
|
|
215
|
+
children: /* @__PURE__ */ d(b, { children: [/* @__PURE__ */ u(w, { children: /* @__PURE__ */ d(T, { children: [
|
|
216
|
+
/* @__PURE__ */ u(C, { children: "Listing" }),
|
|
217
|
+
/* @__PURE__ */ u(C, { children: "Provider" }),
|
|
218
|
+
/* @__PURE__ */ u(C, { children: "Reported" }),
|
|
219
|
+
/* @__PURE__ */ u(C, { children: "Reason" }),
|
|
220
|
+
/* @__PURE__ */ u(C, {
|
|
221
|
+
className: "text-right",
|
|
222
|
+
children: "Actions"
|
|
223
|
+
})
|
|
224
|
+
] }) }), /* @__PURE__ */ u(x, { children: j.map((e) => /* @__PURE__ */ d(T, { children: [
|
|
225
|
+
/* @__PURE__ */ u(S, {
|
|
226
|
+
className: "font-medium text-text-primary",
|
|
227
|
+
children: e.title
|
|
228
|
+
}),
|
|
229
|
+
/* @__PURE__ */ u(S, {
|
|
230
|
+
className: "text-text-secondary",
|
|
231
|
+
children: e.provider
|
|
232
|
+
}),
|
|
233
|
+
/* @__PURE__ */ u(S, {
|
|
234
|
+
className: "text-text-secondary",
|
|
235
|
+
children: t(e.reportedAt)
|
|
236
|
+
}),
|
|
237
|
+
/* @__PURE__ */ u(S, {
|
|
238
|
+
className: "text-text-secondary",
|
|
239
|
+
children: e.reason
|
|
240
|
+
}),
|
|
241
|
+
/* @__PURE__ */ u(S, {
|
|
242
|
+
className: "text-right",
|
|
243
|
+
children: /* @__PURE__ */ d("div", {
|
|
244
|
+
className: "flex justify-end gap-2",
|
|
245
|
+
children: [/* @__PURE__ */ u(f, {
|
|
246
|
+
size: "sm",
|
|
247
|
+
variant: "outline",
|
|
248
|
+
disabled: !0,
|
|
249
|
+
children: "Dismiss"
|
|
250
|
+
}), /* @__PURE__ */ u(f, {
|
|
251
|
+
size: "sm",
|
|
252
|
+
variant: "destructive",
|
|
253
|
+
disabled: !0,
|
|
254
|
+
children: "Remove"
|
|
255
|
+
})]
|
|
256
|
+
})
|
|
257
|
+
})
|
|
258
|
+
] }, e.id)) })] })
|
|
259
|
+
})] })] })
|
|
260
|
+
})
|
|
261
|
+
]
|
|
262
|
+
})
|
|
263
|
+
});
|
|
264
|
+
};
|
|
265
|
+
//#endregion
|
|
266
|
+
export { M as AdminDashboardPage };
|
|
267
|
+
|
|
268
|
+
//# sourceMappingURL=AdminDashboardPage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AdminDashboardPage.js","names":[],"sources":["../../../src/subscriberbot/admin/AdminDashboardPage.tsx"],"sourcesContent":["/**\n * SubscriberBot Admin Dashboard\n * @module subscriberbot/admin\n *\n * Product-specific admin surface mounted inside `admin-app`. It exposes the\n * three governance operations requested for SubscriberBot:\n * 1. Provider registry curation (real — wires `subListProviders` / `subUpdateProvider`).\n * 2. Adapter approval queue (placeholder — backend query does not exist yet).\n * 3. Marketplace moderation queue (placeholder — backend query does not exist yet).\n */\n\nimport { useState, type FC } from 'react';\nimport {\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n EmptyState,\n Spinner,\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n} from '@burdenoff/fe-libs/ui';\nimport { CheckCircle2, Plug, Settings2, Store } from 'lucide-react';\n\nimport { PageLayout } from '../components/PageLayout';\nimport { StatusBadge } from '../components/StatusBadge';\nimport { useProviders, useUpdateProvider } from '../hooks';\nimport { formatDate } from '../utils/formatters';\nimport type { SubProvider } from '../types';\n\n// Placeholder rows for surfaces that don't have a backend query yet.\n// These are intentionally typed as read-only data so the UI is structured\n// and the next engineer can swap in a real React-Query hook.\nconst PLACEHOLDER_ADAPTERS: Array<{\n id: string;\n name: string;\n kind: string;\n submittedAt: string;\n status: 'pending' | 'approved' | 'rejected';\n}> = [\n {\n id: 'adapter-placeholder-1',\n name: 'Stripe Billing Adapter',\n kind: 'BILLING',\n submittedAt: '2026-07-10T08:30:00Z',\n status: 'pending',\n },\n {\n id: 'adapter-placeholder-2',\n name: 'Chargebee Sync Adapter',\n kind: 'BILLING',\n submittedAt: '2026-07-12T14:22:00Z',\n status: 'pending',\n },\n];\n\nconst PLACEHOLDER_LISTINGS: Array<{\n id: string;\n title: string;\n provider: string;\n reportedAt: string;\n reason: string;\n}> = [\n {\n id: 'listing-placeholder-1',\n title: 'Premium SaaS Bundle',\n provider: 'ExampleSoft',\n reportedAt: '2026-07-14T09:15:00Z',\n reason: 'Misleading pricing',\n },\n {\n id: 'listing-placeholder-2',\n title: 'Newsletter Pro',\n provider: 'MailMaster',\n reportedAt: '2026-07-13T16:40:00Z',\n reason: 'Trademark concern',\n },\n];\n\nexport const AdminDashboardPage: FC = () => {\n const [activeTab, setActiveTab] = useState('providers');\n const { data: providersData, isLoading: providersLoading } = useProviders({\n pagination: { limit: 50 },\n });\n const updateProvider = useUpdateProvider();\n\n const handleVerify = (id: string) => {\n updateProvider.mutate({ id, input: { status: 'VERIFIED' } });\n };\n\n const handleDeprecate = (id: string) => {\n updateProvider.mutate({ id, input: { status: 'DEPRECATED' } });\n };\n\n const providers = providersData?.items ?? [];\n\n return (\n <PageLayout\n title=\"SubscriberBot Admin\"\n description=\"Provider registry curation, adapter approvals, and marketplace moderation.\"\n >\n <Tabs value={activeTab} onValueChange={setActiveTab} className=\"w-full\">\n <TabsList className=\"mb-4 grid w-full grid-cols-3 sm:w-auto sm:inline-flex\">\n <TabsTrigger value=\"providers\" className=\"gap-2\">\n <Settings2 size={16} />\n Provider Registry\n </TabsTrigger>\n <TabsTrigger value=\"adapters\" className=\"gap-2\">\n <Plug size={16} />\n Adapter Approvals\n </TabsTrigger>\n <TabsTrigger value=\"marketplace\" className=\"gap-2\">\n <Store size={16} />\n Marketplace Moderation\n </TabsTrigger>\n </TabsList>\n\n {/* Provider registry curation — backed by real GraphQL queries. */}\n <TabsContent value=\"providers\">\n <Card>\n <CardHeader>\n <CardTitle>Provider registry</CardTitle>\n <CardDescription>\n Curate the global provider catalog. Verify submitted providers or\n deprecate stale entries.\n </CardDescription>\n </CardHeader>\n <CardContent>\n {providersLoading ? (\n <div className=\"flex min-h-[200px] items-center justify-center\">\n <Spinner size=\"lg\" />\n </div>\n ) : providers.length === 0 ? (\n <EmptyState\n icon={<Store className=\"size-6 text-action-primary-bg\" />}\n title=\"No providers yet\"\n description=\"Once providers are created or claimed they will appear here for curation.\"\n />\n ) : (\n <div className=\"overflow-x-auto\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>Name</TableHead>\n <TableHead>Category</TableHead>\n <TableHead>Status</TableHead>\n <TableHead>Created</TableHead>\n <TableHead className=\"text-right\">Actions</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {providers.map((provider: SubProvider) => (\n <TableRow key={provider.id}>\n <TableCell className=\"font-medium text-text-primary\">\n {provider.name}\n </TableCell>\n <TableCell className=\"text-text-secondary\">\n {provider.category}\n </TableCell>\n <TableCell>\n <StatusBadge status={provider.status} />\n </TableCell>\n <TableCell className=\"text-text-secondary\">\n {formatDate(provider.createdAt)}\n </TableCell>\n <TableCell className=\"text-right\">\n <div className=\"flex justify-end gap-2\">\n {provider.status !== 'VERIFIED' && (\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => handleVerify(provider.id)}\n disabled={updateProvider.isPending}\n >\n <CheckCircle2 size={14} className=\"mr-1\" />\n Verify\n </Button>\n )}\n {provider.status !== 'DEPRECATED' && (\n <Button\n size=\"sm\"\n variant=\"secondary\"\n onClick={() => handleDeprecate(provider.id)}\n disabled={updateProvider.isPending}\n >\n Deprecate\n </Button>\n )}\n </div>\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n )}\n </CardContent>\n </Card>\n </TabsContent>\n\n {/* Adapter approval queue — placeholder until backend exists. */}\n <TabsContent value=\"adapters\">\n <Card>\n <CardHeader>\n <CardTitle>Adapter approvals</CardTitle>\n <CardDescription>\n Review submitted integration adapters before they are published to\n the SubscriberBot adapter marketplace.\n </CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"mb-4 rounded-md border border-status-warning-border bg-status-warning-bg-subtle p-3 text-sm text-status-warning-text\">\n Backend query not yet implemented. Wire\n <code className=\"mx-1 rounded bg-bg-sunken px-1 py-0.5 font-mono text-text-primary\">\n subListAdapterSubmissions\n </code>\n from <code className=\"font-mono\">wspace-subscriberbot-svc</code> to replace\n the placeholder rows below.\n </div>\n <div className=\"overflow-x-auto\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>Adapter</TableHead>\n <TableHead>Kind</TableHead>\n <TableHead>Submitted</TableHead>\n <TableHead>Status</TableHead>\n <TableHead className=\"text-right\">Actions</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {PLACEHOLDER_ADAPTERS.map((adapter) => (\n <TableRow key={adapter.id}>\n <TableCell className=\"font-medium text-text-primary\">\n {adapter.name}\n </TableCell>\n <TableCell className=\"text-text-secondary\">{adapter.kind}</TableCell>\n <TableCell className=\"text-text-secondary\">\n {formatDate(adapter.submittedAt)}\n </TableCell>\n <TableCell>\n <StatusBadge status={adapter.status} />\n </TableCell>\n <TableCell className=\"text-right\">\n <div className=\"flex justify-end gap-2\">\n <Button size=\"sm\" variant=\"outline\" disabled>\n Approve\n </Button>\n <Button size=\"sm\" variant=\"secondary\" disabled>\n Reject\n </Button>\n </div>\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n </CardContent>\n </Card>\n </TabsContent>\n\n {/* Marketplace moderation — placeholder until backend exists. */}\n <TabsContent value=\"marketplace\">\n <Card>\n <CardHeader>\n <CardTitle>Marketplace moderation</CardTitle>\n <CardDescription>\n Review reported marketplace listings and take moderation actions.\n </CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"mb-4 rounded-md border border-status-warning-border bg-status-warning-bg-subtle p-3 text-sm text-status-warning-text\">\n Backend query not yet implemented. Wire\n <code className=\"mx-1 rounded bg-bg-sunken px-1 py-0.5 font-mono text-text-primary\">\n subListMarketplaceReports\n </code>\n from <code className=\"font-mono\">wspace-subscriberbot-svc</code> to replace\n the placeholder rows below.\n </div>\n <div className=\"overflow-x-auto\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>Listing</TableHead>\n <TableHead>Provider</TableHead>\n <TableHead>Reported</TableHead>\n <TableHead>Reason</TableHead>\n <TableHead className=\"text-right\">Actions</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {PLACEHOLDER_LISTINGS.map((listing) => (\n <TableRow key={listing.id}>\n <TableCell className=\"font-medium text-text-primary\">\n {listing.title}\n </TableCell>\n <TableCell className=\"text-text-secondary\">{listing.provider}</TableCell>\n <TableCell className=\"text-text-secondary\">\n {formatDate(listing.reportedAt)}\n </TableCell>\n <TableCell className=\"text-text-secondary\">{listing.reason}</TableCell>\n <TableCell className=\"text-right\">\n <div className=\"flex justify-end gap-2\">\n <Button size=\"sm\" variant=\"outline\" disabled>\n Dismiss\n </Button>\n <Button size=\"sm\" variant=\"destructive\" disabled>\n Remove\n </Button>\n </div>\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n </CardContent>\n </Card>\n </TabsContent>\n </Tabs>\n </PageLayout>\n );\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
import { SubscriberBotRootProps } from '../types';
|
|
3
|
+
|
|
4
|
+
export interface SubscriberBotAdminRootProps extends SubscriberBotRootProps {
|
|
5
|
+
/** Workspace-scoped token supplied by `admin-app` for workspace gateway calls. */
|
|
6
|
+
workspaceToken?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare const AdminRoot: FC<SubscriberBotAdminRootProps>;
|
|
9
|
+
//# sourceMappingURL=AdminRoot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AdminRoot.d.ts","sourceRoot":"","sources":["../../../src/subscriberbot/admin/AdminRoot.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAGhC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAYvD,MAAM,WAAW,2BAA4B,SAAQ,sBAAsB;IACzE,kFAAkF;IAClF,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,eAAO,MAAM,SAAS,EAAE,EAAE,CAAC,2BAA2B,CAarD,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { SubscriberBotProvider as e } from "../context/SubscriberBotContext.js";
|
|
2
|
+
import "../context/index.js";
|
|
3
|
+
import { AdminDashboardPage as t } from "./AdminDashboardPage.js";
|
|
4
|
+
import { QueryClient as n, QueryClientProvider as r } from "@tanstack/react-query";
|
|
5
|
+
import { jsx as i } from "react/jsx-runtime";
|
|
6
|
+
//#region src/subscriberbot/admin/AdminRoot.tsx
|
|
7
|
+
var a = new n({ defaultOptions: { queries: {
|
|
8
|
+
staleTime: 60 * 1e3,
|
|
9
|
+
retry: 1
|
|
10
|
+
} } }), o = (n) => {
|
|
11
|
+
let { workspaceToken: o, ...s } = n;
|
|
12
|
+
return /* @__PURE__ */ i(r, {
|
|
13
|
+
client: a,
|
|
14
|
+
children: /* @__PURE__ */ i(e, {
|
|
15
|
+
...s,
|
|
16
|
+
children: /* @__PURE__ */ i(t, {})
|
|
17
|
+
})
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
//#endregion
|
|
21
|
+
export { o as AdminRoot };
|
|
22
|
+
|
|
23
|
+
//# sourceMappingURL=AdminRoot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AdminRoot.js","names":[],"sources":["../../../src/subscriberbot/admin/AdminRoot.tsx"],"sourcesContent":["/**\n * SubscriberBot Admin Root\n * @module subscriberbot/admin\n *\n * Host-contract entry point for the SubscriberBot admin surface inside\n * `admin-app`. Mirrors the provider/query-client setup of `SubscriberBotRoot`\n * but does not register product-shell navigation items.\n */\n\nimport type { FC } from 'react';\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query';\nimport { SubscriberBotProvider } from '../context';\nimport type { SubscriberBotRootProps } from '../types';\nimport { AdminDashboardPage } from './AdminDashboardPage';\n\nconst adminQueryClient = new QueryClient({\n defaultOptions: {\n queries: {\n staleTime: 60 * 1000,\n retry: 1,\n },\n },\n});\n\nexport interface SubscriberBotAdminRootProps extends SubscriberBotRootProps {\n /** Workspace-scoped token supplied by `admin-app` for workspace gateway calls. */\n workspaceToken?: string;\n}\n\nexport const AdminRoot: FC<SubscriberBotAdminRootProps> = (props) => {\n // `workspaceToken` is consumed by the host shell's `GatewayRoute` / graphql\n // transport context; it is not forwarded to the product context, which only\n // expects the standard microfrontend root props.\n const { workspaceToken: _workspaceToken, ...providerProps } = props;\n\n return (\n <QueryClientProvider client={adminQueryClient}>\n <SubscriberBotProvider {...providerProps}>\n <AdminDashboardPage />\n </SubscriberBotProvider>\n </QueryClientProvider>\n );\n};\n"],"mappings":";;;;;;AAeA,IAAM,IAAmB,IAAI,EAAY,EACvC,gBAAgB,EACd,SAAS;CACP,WAAW,KAAK;CAChB,OAAO;CACR,EACF,EACF,CAAC,EAOW,KAA8C,MAAU;CAInE,IAAM,EAAE,gBAAgB,GAAiB,GAAG,MAAkB;AAE9D,QACE,kBAAC,GAAD;EAAqB,QAAQ;YAC3B,kBAAC,GAAD;GAAuB,GAAI;aACzB,kBAAC,GAAD,EAAsB,CAAA;GACA,CAAA;EACJ,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/subscriberbot/admin/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import "./useSubscriberBotApi.js";
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* @module subscriberbot
|
|
4
4
|
*/
|
|
5
5
|
export { SubscriberBotRoot } from './SubscriberBotRoot';
|
|
6
|
+
export { AdminRoot } from './admin';
|
|
6
7
|
export type { SubscriberBotRootProps, NavItem, FooterItem, MicrofrontendRootProps, ViewMode, SubProvider, SubPlan, SubRelationship, SubEntitlement, SubAsset, SubRenewalEvent, SubInboxMessage, SubInvoice, SubPaymentInstrument, SubCommunicationChannel, SubAiAgent, SubPolicy, SubWorkflow, SubPageInfo, SubConnection, PaginationInput, } from './types';
|
|
7
8
|
export { SubscriberBotProvider, useSubscriberBot } from './context';
|
|
8
9
|
export { useSubscriberBotStore } from './store';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/subscriberbot/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAGxD,YAAY,EACV,sBAAsB,EACtB,OAAO,EACP,UAAU,EACV,sBAAsB,EACtB,QAAQ,EAER,WAAW,EACX,OAAO,EACP,eAAe,EACf,cAAc,EACd,QAAQ,EACR,eAAe,EACf,eAAe,EACf,UAAU,EACV,oBAAoB,EACpB,uBAAuB,EACvB,UAAU,EACV,SAAS,EACT,WAAW,EAEX,WAAW,EACX,aAAa,EACb,eAAe,GAChB,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAGpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAGhD,OAAO,EACL,4BAA4B,EAC5B,KAAK,kBAAkB,GACxB,MAAM,4CAA4C,CAAC;AAGpD,OAAO,EAAE,EAAE,EAAE,MAAM,YAAY,CAAC;AAChC,OAAO,EACL,cAAc,EACd,UAAU,EACV,cAAc,EACd,kBAAkB,EAClB,YAAY,EACZ,eAAe,EACf,oBAAoB,GACrB,MAAM,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/subscriberbot/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAGxD,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAGpC,YAAY,EACV,sBAAsB,EACtB,OAAO,EACP,UAAU,EACV,sBAAsB,EACtB,QAAQ,EAER,WAAW,EACX,OAAO,EACP,eAAe,EACf,cAAc,EACd,QAAQ,EACR,eAAe,EACf,eAAe,EACf,UAAU,EACV,oBAAoB,EACpB,uBAAuB,EACvB,UAAU,EACV,SAAS,EACT,WAAW,EAEX,WAAW,EACX,aAAa,EACb,eAAe,GAChB,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAGpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAGhD,OAAO,EACL,4BAA4B,EAC5B,KAAK,kBAAkB,GACxB,MAAM,4CAA4C,CAAC;AAGpD,OAAO,EAAE,EAAE,EAAE,MAAM,YAAY,CAAC;AAChC,OAAO,EACL,cAAc,EACd,UAAU,EACV,cAAc,EACd,kBAAkB,EAClB,YAAY,EACZ,eAAe,EACf,oBAAoB,GACrB,MAAM,oBAAoB,CAAC"}
|
|
@@ -3,6 +3,8 @@ import "./utils/cn.js";
|
|
|
3
3
|
import "./utils/formatters.js";
|
|
4
4
|
import "./context/index.js";
|
|
5
5
|
import "./SubscriberBotRoot.js";
|
|
6
|
+
import "./admin/AdminRoot.js";
|
|
7
|
+
import "./admin/index.js";
|
|
6
8
|
import "./store/subscriberbotStore.js";
|
|
7
9
|
import "./store/index.js";
|
|
8
10
|
import "./services/createSandboxAssistantTransport.js";
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* subscriberbot adapter for the shared fe-libs AssistantWidget transport.
|
|
3
|
+
*
|
|
4
|
+
* The sandbox lifecycle + poll/stream loop now lives in
|
|
5
|
+
* `@burdenoff/fe-libs/shared/assistant` (one implementation for all products);
|
|
6
|
+
* this is a thin wrapper. The exported name/shape are unchanged so app-shell
|
|
7
|
+
* imports don't move. The public return type is a LOCALLY-declared structural
|
|
8
|
+
* mirror — never re-export fe-libs types (vite-plugin-dts path rewriting).
|
|
9
|
+
*/
|
|
1
10
|
interface AssistantSendArgs {
|
|
2
11
|
prompt: string;
|
|
3
12
|
onProgress: (partialText: string) => void;
|
|
@@ -7,6 +16,8 @@ export interface AssistantTransport {
|
|
|
7
16
|
sendPrompt: (args: AssistantSendArgs) => Promise<{
|
|
8
17
|
text: string;
|
|
9
18
|
}>;
|
|
19
|
+
prewarm?: (level?: 'probe' | 'full') => void;
|
|
20
|
+
suspend?: () => void;
|
|
10
21
|
}
|
|
11
22
|
export declare function useSandboxAssistantTransport(): AssistantTransport;
|
|
12
23
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createSandboxAssistantTransport.d.ts","sourceRoot":"","sources":["../../../src/subscriberbot/services/createSandboxAssistantTransport.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"createSandboxAssistantTransport.d.ts","sourceRoot":"","sources":["../../../src/subscriberbot/services/createSandboxAssistantTransport.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,UAAU,iBAAiB;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnE,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,KAAK,IAAI,CAAC;IAC7C,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,wBAAgB,4BAA4B,IAAI,kBAAkB,CAMjE"}
|
|
@@ -1,120 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { useCallback as l, useMemo as u, useRef as d } from "react";
|
|
4
|
-
import { useGatewayClient as f } from "@burdenoff/fe-libs/shared/graphql";
|
|
5
|
-
import { useAuthToken as p } from "@burdenoff/fe-libs/shared/providers/shell";
|
|
1
|
+
import { gatherPageContext as e } from "../utils/pageContext.js";
|
|
2
|
+
import { useSandboxAssistantTransport as t } from "@burdenoff/fe-libs/shared/assistant";
|
|
6
3
|
//#region src/subscriberbot/services/createSandboxAssistantTransport.ts
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
let r = sessionStorage.getItem("bf-active-profile");
|
|
13
|
-
if (!r) return "";
|
|
14
|
-
let i = localStorage.getItem(`bf-p-${r}-context`);
|
|
15
|
-
return i ? JSON.parse(i)[e] ?? "" : "";
|
|
16
|
-
} catch {
|
|
17
|
-
return "";
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
function y() {
|
|
21
|
-
return new URLSearchParams(window.location.search).get("workspace") ?? v("workspaceId");
|
|
22
|
-
}
|
|
23
|
-
function b() {
|
|
24
|
-
return new URLSearchParams(window.location.search).get("org") ?? v("organizationId");
|
|
25
|
-
}
|
|
26
|
-
function x(e) {
|
|
27
|
-
return e.info?.time?.created ?? 0;
|
|
28
|
-
}
|
|
29
|
-
function S(e) {
|
|
30
|
-
return (e ?? []).filter((e) => e.type === "text" && typeof e.text == "string").map((e) => e.text?.trim() ?? "").filter(Boolean).join("\n");
|
|
31
|
-
}
|
|
32
|
-
function C(e) {
|
|
33
|
-
return (e ?? []).filter((e) => e.type === "tool" && e.tool).map((e) => {
|
|
34
|
-
let t = e.state?.status ?? "running", n = e.tool ?? "tool";
|
|
35
|
-
return t === "completed" ? `Completed: ${n}` : t === "failed" ? `Failed: ${n}` : `Running: ${n}`;
|
|
4
|
+
function n() {
|
|
5
|
+
return t({
|
|
6
|
+
product: "subscriberbot",
|
|
7
|
+
gatherPageContext: e,
|
|
8
|
+
enableCredits: !0
|
|
36
9
|
});
|
|
37
10
|
}
|
|
38
|
-
function w(e, t) {
|
|
39
|
-
let n = e.filter((e) => e.info?.role === "assistant" && x(e) >= t).sort((e, t) => x(e) - x(t));
|
|
40
|
-
if (n.length === 0) return {
|
|
41
|
-
content: "Thinking…",
|
|
42
|
-
done: !1
|
|
43
|
-
};
|
|
44
|
-
let r = n[n.length - 1], i = S(r.parts), a = C(r.parts);
|
|
45
|
-
return {
|
|
46
|
-
content: [i, ...a].filter(Boolean).join("\n\n") || "Thinking…",
|
|
47
|
-
done: !!r.info?.time?.completed && (!!i || a.length > 0)
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
function T(e) {
|
|
51
|
-
return e.replace(/(Authorization\s*:\s*Bearer\s+)[^\s\n]+/gi, "$1[REDACTED]").replace(/(X-Workspace-Authorization\s*:\s*Bearer\s+)[^\s\n]+/gi, "$1[REDACTED]").replace(/\beyJ[A-Za-z0-9_-]+\.[A-Za-z0-9._-]+\.[A-Za-z0-9._-]+\b/g, "[REDACTED_JWT]").replace(/\bsk-ant-[A-Za-z0-9-]+\b/g, "[REDACTED_API_KEY]");
|
|
52
|
-
}
|
|
53
|
-
function E(e) {
|
|
54
|
-
let t = e instanceof Error ? e.message.toLowerCase() : String(e).toLowerCase();
|
|
55
|
-
return t.includes("rate limit exceeded") || t.includes("unauthorized") || t.includes("k8s api error 401") ? !1 : [
|
|
56
|
-
"sandbox not found",
|
|
57
|
-
"sandbox is not running",
|
|
58
|
-
"sandbox service not available yet",
|
|
59
|
-
"sandbox failed",
|
|
60
|
-
"sandbox startup timed out",
|
|
61
|
-
"assistant service did not become healthy",
|
|
62
|
-
"proxy error: 404",
|
|
63
|
-
"proxy error: 502",
|
|
64
|
-
"proxy error: 503"
|
|
65
|
-
].some((e) => t.includes(e));
|
|
66
|
-
}
|
|
67
|
-
function D() {
|
|
68
|
-
let v = f("workspace"), { getAccessToken: x, getWorkspaceToken: S, userId: C } = p(), D = d(null), O = d(null), k = l(async (n, i) => {
|
|
69
|
-
let a = D.current;
|
|
70
|
-
if (!a) {
|
|
71
|
-
if (a = await r(v, n, m, i), !a) {
|
|
72
|
-
if (!x()) throw Error("API Calls mode requires an authenticated session. Please sign in again.");
|
|
73
|
-
a = await e(v, m, n, i);
|
|
74
|
-
}
|
|
75
|
-
await s(v, a, n, i), await o(v, a, n, i), D.current = a;
|
|
76
|
-
}
|
|
77
|
-
let c = O.current;
|
|
78
|
-
return c || (c = (await t(v, a, n, m, i)).sessionId, O.current = c), {
|
|
79
|
-
sandboxId: a,
|
|
80
|
-
sessionId: c
|
|
81
|
-
};
|
|
82
|
-
}, [v, x]), A = l(async ({ prompt: e, onProgress: t, signal: r }) => {
|
|
83
|
-
let o = y();
|
|
84
|
-
if (!o) throw Error("The assistant needs an active workspace. Open a workspace and try again.");
|
|
85
|
-
let s = {
|
|
86
|
-
accessToken: x(),
|
|
87
|
-
workspaceToken: S(),
|
|
88
|
-
userId: C,
|
|
89
|
-
organizationId: b()
|
|
90
|
-
}, l = async (u) => {
|
|
91
|
-
try {
|
|
92
|
-
let { sandboxId: l, sessionId: u } = await k(o, s), d = Date.now();
|
|
93
|
-
await a(v, l, o, u, e, m, c(), s);
|
|
94
|
-
let f = Date.now() + h, p = Date.now(), y = w([], d);
|
|
95
|
-
for (; Date.now() < f;) {
|
|
96
|
-
if (r.aborted) throw Error("Cancelled");
|
|
97
|
-
if (y = w(await i(v, l, o, u, s, 50), d), t(T(y.content)), y.done) break;
|
|
98
|
-
Date.now() - p > _ && (await n(v, l, o, 600, s).catch(() => void 0), p = Date.now()), await new Promise((e) => setTimeout(e, g));
|
|
99
|
-
}
|
|
100
|
-
if (!y.done) throw Error("The assistant timed out while responding. Please try again.");
|
|
101
|
-
return { text: T(y.content) };
|
|
102
|
-
} catch (e) {
|
|
103
|
-
if (u === 1 && E(e)) return D.current = null, O.current = null, l(2);
|
|
104
|
-
throw e;
|
|
105
|
-
}
|
|
106
|
-
};
|
|
107
|
-
return l(1);
|
|
108
|
-
}, [
|
|
109
|
-
v,
|
|
110
|
-
k,
|
|
111
|
-
x,
|
|
112
|
-
S,
|
|
113
|
-
C
|
|
114
|
-
]);
|
|
115
|
-
return u(() => ({ sendPrompt: A }), [A]);
|
|
116
|
-
}
|
|
117
11
|
//#endregion
|
|
118
|
-
export {
|
|
12
|
+
export { n as useSandboxAssistantTransport };
|
|
119
13
|
|
|
120
14
|
//# sourceMappingURL=createSandboxAssistantTransport.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createSandboxAssistantTransport.js","names":[],"sources":["../../../src/subscriberbot/services/createSandboxAssistantTransport.ts"],"sourcesContent":["import { useCallback, useMemo, useRef } from 'react';\nimport { useGatewayClient } from '@burdenoff/fe-libs/shared/graphql';\nimport { useAuthToken } from '@burdenoff/fe-libs/shared/providers/shell';\nimport {\n createAssistantSandbox,\n createAssistantSession,\n extendAssistantSandboxTTL,\n findExistingSandbox,\n getAssistantMessages,\n sendAssistantPromptAsync,\n waitForAssistantServiceReady,\n waitForSandboxReady,\n type AssistantRawMessage,\n type AssistantSandboxAuthContext,\n} from '#subscriberbot/services/assistantApi';\nimport { gatherPageContext } from '#subscriberbot/utils/pageContext';\nimport type { AssistantMode } from '#subscriberbot/types/assistant';\n\ninterface AssistantSendArgs {\n prompt: string;\n onProgress: (partialText: string) => void;\n signal: AbortSignal;\n}\n\nexport interface AssistantTransport {\n sendPrompt: (args: AssistantSendArgs) => Promise<{ text: string }>;\n}\n\nconst MODE: AssistantMode = 'assistant';\nconst STREAM_BUDGET_MS = 180_000;\nconst POLL_INTERVAL_MS = 1500;\nconst TTL_EXTEND_INTERVAL_MS = 30_000;\n\nfunction getProfileContextValue(key: 'workspaceId' | 'organizationId'): string {\n try {\n const activeContextKey =\n key === 'workspaceId'\n ? 'burdenoff-active-context-workspace'\n : 'burdenoff-active-context-organization';\n const activeContextValue = localStorage.getItem(activeContextKey);\n if (activeContextValue) return activeContextValue;\n\n const activeProfileId = sessionStorage.getItem('bf-active-profile');\n if (!activeProfileId) return '';\n const raw = localStorage.getItem(`bf-p-${activeProfileId}-context`);\n if (!raw) return '';\n const context = JSON.parse(raw) as { workspaceId?: string; organizationId?: string };\n return context[key] ?? '';\n } catch {\n return '';\n }\n}\n\nfunction getWorkspaceId(): string {\n const params = new URLSearchParams(window.location.search);\n return params.get('workspace') ?? getProfileContextValue('workspaceId');\n}\n\nfunction getOrganizationId(): string {\n const params = new URLSearchParams(window.location.search);\n return params.get('org') ?? getProfileContextValue('organizationId');\n}\n\nfunction getRawMessageCreatedAt(message: AssistantRawMessage): number {\n return message.info?.time?.created ?? 0;\n}\n\nfunction getAssistantText(parts: AssistantRawMessage['parts']): string {\n return (parts ?? [])\n .filter((part) => part.type === 'text' && typeof part.text === 'string')\n .map((part) => part.text?.trim() ?? '')\n .filter(Boolean)\n .join('\\n');\n}\n\nfunction getToolProgress(parts: AssistantRawMessage['parts']): string[] {\n return (parts ?? [])\n .filter((part) => part.type === 'tool' && part.tool)\n .map((part) => {\n const status = part.state?.status ?? 'running';\n const tool = part.tool ?? 'tool';\n if (status === 'completed') return `Completed: ${tool}`;\n if (status === 'failed') return `Failed: ${tool}`;\n return `Running: ${tool}`;\n });\n}\n\nfunction buildProgress(\n messages: AssistantRawMessage[],\n sinceMs: number\n): { content: string; done: boolean } {\n const relevant = messages\n .filter(\n (message) => message.info?.role === 'assistant' && getRawMessageCreatedAt(message) >= sinceMs\n )\n .sort((left, right) => getRawMessageCreatedAt(left) - getRawMessageCreatedAt(right));\n\n if (relevant.length === 0) return { content: 'Thinking…', done: false };\n\n const latest = relevant[relevant.length - 1]!;\n const text = getAssistantText(latest.parts);\n const toolProgress = getToolProgress(latest.parts);\n const content = [text, ...toolProgress].filter(Boolean).join('\\n\\n') || 'Thinking…';\n\n return {\n content,\n done: Boolean(latest.info?.time?.completed) && (Boolean(text) || toolProgress.length > 0),\n };\n}\n\nfunction sanitize(response: string): string {\n return response\n .replace(/(Authorization\\s*:\\s*Bearer\\s+)[^\\s\\n]+/gi, '$1[REDACTED]')\n .replace(/(X-Workspace-Authorization\\s*:\\s*Bearer\\s+)[^\\s\\n]+/gi, '$1[REDACTED]')\n .replace(/\\beyJ[A-Za-z0-9_-]+\\.[A-Za-z0-9._-]+\\.[A-Za-z0-9._-]+\\b/g, '[REDACTED_JWT]')\n .replace(/\\bsk-ant-[A-Za-z0-9-]+\\b/g, '[REDACTED_API_KEY]');\n}\n\nfunction isRecoverable(error: unknown): boolean {\n const message =\n error instanceof Error ? error.message.toLowerCase() : String(error).toLowerCase();\n if (\n message.includes('rate limit exceeded') ||\n message.includes('unauthorized') ||\n message.includes('k8s api error 401')\n ) {\n return false;\n }\n return [\n 'sandbox not found',\n 'sandbox is not running',\n 'sandbox service not available yet',\n 'sandbox failed',\n 'sandbox startup timed out',\n 'assistant service did not become healthy',\n 'proxy error: 404',\n 'proxy error: 502',\n 'proxy error: 503',\n ].some((fragment) => message.includes(fragment));\n}\n\nexport function useSandboxAssistantTransport(): AssistantTransport {\n const apollo = useGatewayClient('workspace');\n const { getAccessToken, getWorkspaceToken, userId } = useAuthToken();\n\n const sandboxIdRef = useRef<string | null>(null);\n const sessionIdRef = useRef<string | null>(null);\n\n const ensureRuntime = useCallback(\n async (\n workspaceId: string,\n authContext: AssistantSandboxAuthContext\n ): Promise<{ sandboxId: string; sessionId: string }> => {\n let sandboxId = sandboxIdRef.current;\n if (!sandboxId) {\n sandboxId = await findExistingSandbox(apollo, workspaceId, MODE, authContext);\n if (!sandboxId) {\n if (!getAccessToken()) {\n throw new Error(\n 'API Calls mode requires an authenticated session. Please sign in again.'\n );\n }\n sandboxId = await createAssistantSandbox(apollo, MODE, workspaceId, authContext);\n }\n await waitForSandboxReady(apollo, sandboxId, workspaceId, authContext);\n await waitForAssistantServiceReady(apollo, sandboxId, workspaceId, authContext);\n sandboxIdRef.current = sandboxId;\n }\n\n let sessionId = sessionIdRef.current;\n if (!sessionId) {\n const result = await createAssistantSession(\n apollo,\n sandboxId,\n workspaceId,\n MODE,\n authContext\n );\n sessionId = result.sessionId;\n sessionIdRef.current = sessionId;\n }\n\n return { sandboxId, sessionId };\n },\n [apollo, getAccessToken]\n );\n\n const sendPrompt = useCallback(\n async ({ prompt, onProgress, signal }: AssistantSendArgs): Promise<{ text: string }> => {\n const workspaceId = getWorkspaceId();\n if (!workspaceId) {\n throw new Error('The assistant needs an active workspace. Open a workspace and try again.');\n }\n const authContext: AssistantSandboxAuthContext = {\n accessToken: getAccessToken(),\n workspaceToken: getWorkspaceToken(),\n userId,\n organizationId: getOrganizationId(),\n };\n\n const run = async (attempt: 1 | 2): Promise<{ text: string }> => {\n try {\n const { sandboxId, sessionId } = await ensureRuntime(workspaceId, authContext);\n\n const startedAt = Date.now();\n await sendAssistantPromptAsync(\n apollo,\n sandboxId,\n workspaceId,\n sessionId,\n prompt,\n MODE,\n gatherPageContext(),\n authContext\n );\n\n const timeoutAt = Date.now() + STREAM_BUDGET_MS;\n let lastTtlExtensionAt = Date.now();\n let progress = buildProgress([], startedAt);\n\n while (Date.now() < timeoutAt) {\n if (signal.aborted) throw new Error('Cancelled');\n\n const messages = await getAssistantMessages(\n apollo,\n sandboxId,\n workspaceId,\n sessionId,\n authContext,\n 50\n );\n progress = buildProgress(messages, startedAt);\n onProgress(sanitize(progress.content));\n if (progress.done) break;\n\n if (Date.now() - lastTtlExtensionAt > TTL_EXTEND_INTERVAL_MS) {\n await extendAssistantSandboxTTL(\n apollo,\n sandboxId,\n workspaceId,\n 600,\n authContext\n ).catch(() => undefined);\n lastTtlExtensionAt = Date.now();\n }\n\n await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));\n }\n\n if (!progress.done) {\n throw new Error('The assistant timed out while responding. Please try again.');\n }\n\n return { text: sanitize(progress.content) };\n } catch (error) {\n if (attempt === 1 && isRecoverable(error)) {\n sandboxIdRef.current = null;\n sessionIdRef.current = null;\n return run(2);\n }\n throw error;\n }\n };\n\n return run(1);\n },\n [apollo, ensureRuntime, getAccessToken, getWorkspaceToken, userId]\n );\n\n return useMemo<AssistantTransport>(() => ({ sendPrompt }), [sendPrompt]);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"createSandboxAssistantTransport.js","names":[],"sources":["../../../src/subscriberbot/services/createSandboxAssistantTransport.ts"],"sourcesContent":["/**\n * subscriberbot adapter for the shared fe-libs AssistantWidget transport.\n *\n * The sandbox lifecycle + poll/stream loop now lives in\n * `@burdenoff/fe-libs/shared/assistant` (one implementation for all products);\n * this is a thin wrapper. The exported name/shape are unchanged so app-shell\n * imports don't move. The public return type is a LOCALLY-declared structural\n * mirror — never re-export fe-libs types (vite-plugin-dts path rewriting).\n */\n\nimport { useSandboxAssistantTransport as useSharedTransport } from '@burdenoff/fe-libs/shared/assistant';\nimport { gatherPageContext } from '#subscriberbot/utils/pageContext';\n\ninterface AssistantSendArgs {\n prompt: string;\n onProgress: (partialText: string) => void;\n signal: AbortSignal;\n}\n\nexport interface AssistantTransport {\n sendPrompt: (args: AssistantSendArgs) => Promise<{ text: string }>;\n prewarm?: (level?: 'probe' | 'full') => void;\n suspend?: () => void;\n}\n\nexport function useSandboxAssistantTransport(): AssistantTransport {\n return useSharedTransport({\n product: 'subscriberbot',\n gatherPageContext: gatherPageContext,\n enableCredits: true,\n });\n}\n"],"mappings":";;;AAyBA,SAAgB,IAAmD;AACjE,QAAO,EAAmB;EACxB,SAAS;EACU;EACnB,eAAe;EAChB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@burdenoff/microfe-subscriberbot",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.715.1",
|
|
4
4
|
"description": "Burdenoff SubscriberBot Microfrontend",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"@apollo/client": "^4.0.11",
|
|
47
|
-
"@burdenoff/fe-libs": "2026.
|
|
47
|
+
"@burdenoff/fe-libs": "2026.713.6",
|
|
48
48
|
"@tanstack/react-query": "^5.90.16",
|
|
49
49
|
"clsx": "^2.1.1",
|
|
50
50
|
"graphql": "^16.12.0",
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
"access": "restricted"
|
|
91
91
|
},
|
|
92
92
|
"overrides": {
|
|
93
|
-
"@burdenoff/fe-libs": "2026.
|
|
93
|
+
"@burdenoff/fe-libs": "2026.713.6",
|
|
94
94
|
"lodash": ">=4.17.21",
|
|
95
95
|
"lodash-es": ">=4.17.21",
|
|
96
96
|
"dompurify": ">=3.3.4",
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { ApolloClient } from '@apollo/client';
|
|
2
|
-
import { AssistantArtifact, AssistantMode } from '../types/assistant';
|
|
3
|
-
import { PageContext } from '../utils/pageContext';
|
|
4
|
-
|
|
5
|
-
export interface AssistantPromptResult {
|
|
6
|
-
response: string;
|
|
7
|
-
tokens?: {
|
|
8
|
-
input: number;
|
|
9
|
-
output: number;
|
|
10
|
-
};
|
|
11
|
-
artifacts?: AssistantArtifact[];
|
|
12
|
-
}
|
|
13
|
-
export interface AssistantRawMessagePart {
|
|
14
|
-
type?: string;
|
|
15
|
-
text?: string;
|
|
16
|
-
tool?: string;
|
|
17
|
-
state?: {
|
|
18
|
-
status?: string;
|
|
19
|
-
input?: unknown;
|
|
20
|
-
output?: unknown;
|
|
21
|
-
raw?: unknown;
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
export interface AssistantRawMessage {
|
|
25
|
-
info?: {
|
|
26
|
-
id?: string;
|
|
27
|
-
role?: string;
|
|
28
|
-
providerID?: string;
|
|
29
|
-
modelID?: string;
|
|
30
|
-
tokens?: {
|
|
31
|
-
input: number;
|
|
32
|
-
output: number;
|
|
33
|
-
};
|
|
34
|
-
time?: {
|
|
35
|
-
created?: number;
|
|
36
|
-
completed?: number;
|
|
37
|
-
};
|
|
38
|
-
};
|
|
39
|
-
parts?: AssistantRawMessagePart[];
|
|
40
|
-
}
|
|
41
|
-
export interface AssistantSandboxAuthContext {
|
|
42
|
-
accessToken?: string | null;
|
|
43
|
-
workspaceToken?: string | null;
|
|
44
|
-
userId?: string | null;
|
|
45
|
-
organizationId?: string | null;
|
|
46
|
-
}
|
|
47
|
-
export interface AssistantSessionInfo {
|
|
48
|
-
id: string;
|
|
49
|
-
mode: string;
|
|
50
|
-
}
|
|
51
|
-
export interface DownloadedAssistantArtifact {
|
|
52
|
-
filename: string;
|
|
53
|
-
mimeType: string;
|
|
54
|
-
contentBase64: string;
|
|
55
|
-
}
|
|
56
|
-
export declare function findExistingSandbox(_apollo: ApolloClient, workspaceId: string, mode: AssistantMode, authContext?: AssistantSandboxAuthContext): Promise<string | null>;
|
|
57
|
-
export declare function createAssistantSandbox(_apollo: ApolloClient, mode: AssistantMode, workspaceId: string, authContext?: AssistantSandboxAuthContext): Promise<string>;
|
|
58
|
-
export declare function waitForSandboxReady(_apollo: ApolloClient, sandboxId: string, workspaceId: string, authContext?: AssistantSandboxAuthContext, maxWaitMs?: number, onProgress?: (message: string) => void): Promise<void>;
|
|
59
|
-
export declare function waitForAssistantServiceReady(apollo: ApolloClient, sandboxId: string, workspaceId: string, authContext?: AssistantSandboxAuthContext, maxWaitMs?: number, onProgress?: (message: string) => void): Promise<void>;
|
|
60
|
-
export declare function createAssistantSession(apollo: ApolloClient, sandboxId: string, workspaceId: string, mode: AssistantMode, authContext?: AssistantSandboxAuthContext): Promise<{
|
|
61
|
-
sessionId: string;
|
|
62
|
-
}>;
|
|
63
|
-
export declare function sendAssistantPromptAsync(apollo: ApolloClient, sandboxId: string, workspaceId: string, sessionId: string, prompt: string, mode: AssistantMode, pageContext?: PageContext, authContext?: AssistantSandboxAuthContext): Promise<void>;
|
|
64
|
-
export declare function getAssistantMessages(apollo: ApolloClient, sandboxId: string, workspaceId: string, sessionId: string, authContext?: AssistantSandboxAuthContext, limit?: number): Promise<AssistantRawMessage[]>;
|
|
65
|
-
export declare function extendAssistantSandboxTTL(_apollo: ApolloClient, sandboxId: string, workspaceId: string, additionalSeconds?: number, authContext?: AssistantSandboxAuthContext): Promise<void>;
|
|
66
|
-
//# sourceMappingURL=assistantApi.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"assistantApi.d.ts","sourceRoot":"","sources":["../../../src/subscriberbot/services/assistantApi.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,260 +0,0 @@
|
|
|
1
|
-
import { gql as e } from "@apollo/client";
|
|
2
|
-
import { print as t } from "graphql";
|
|
3
|
-
//#region src/subscriberbot/services/assistantApi.ts
|
|
4
|
-
var n = "burdenoffregistry.azurecr.io", r = "alpha-delegated-auth-v11", i = "sandbox-app-client-headers-v1", a = e`
|
|
5
|
-
mutation CreateSandbox($input: CreateSandboxInput!) {
|
|
6
|
-
createSandbox(input: $input) {
|
|
7
|
-
id
|
|
8
|
-
name
|
|
9
|
-
status
|
|
10
|
-
network {
|
|
11
|
-
internalUrl
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
`, o = e`
|
|
16
|
-
query GetSandbox($id: ID!, $context: ContextInput!) {
|
|
17
|
-
getSandbox(id: $id, context: $context) {
|
|
18
|
-
id
|
|
19
|
-
status
|
|
20
|
-
errorMessage
|
|
21
|
-
network {
|
|
22
|
-
internalUrl
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
`, s = e`
|
|
27
|
-
query GetActiveSandboxes($context: ContextInput!) {
|
|
28
|
-
getActiveSandboxes(context: $context) {
|
|
29
|
-
id
|
|
30
|
-
name
|
|
31
|
-
status
|
|
32
|
-
metadata
|
|
33
|
-
template
|
|
34
|
-
createdBy
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
`, c = e`
|
|
38
|
-
mutation ProxySandboxRequest($input: ProxySandboxRequestInput!) {
|
|
39
|
-
proxySandboxRequest(input: $input) {
|
|
40
|
-
status
|
|
41
|
-
body
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
`, l = e`
|
|
45
|
-
mutation ExtendSandboxTtl($id: ID!, $additionalSeconds: Int!, $context: ContextInput!) {
|
|
46
|
-
extendSandboxTTL(id: $id, additionalSeconds: $additionalSeconds, context: $context) {
|
|
47
|
-
id
|
|
48
|
-
expiresAt
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
`;
|
|
52
|
-
function u(e) {
|
|
53
|
-
switch (e) {
|
|
54
|
-
case "api-calls": return r;
|
|
55
|
-
default: return r;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
function d(e) {
|
|
59
|
-
return `${n}/wspace/ai-assistant-${e === "assistant" ? "api-calls" : e}:${u(e)}`;
|
|
60
|
-
}
|
|
61
|
-
function f(e) {
|
|
62
|
-
switch (e) {
|
|
63
|
-
case "api-calls": return {
|
|
64
|
-
cpuRequest: "150m",
|
|
65
|
-
cpuLimit: "750m",
|
|
66
|
-
memoryRequest: "384Mi",
|
|
67
|
-
memoryLimit: "1536Mi"
|
|
68
|
-
};
|
|
69
|
-
default: return {
|
|
70
|
-
cpuRequest: "150m",
|
|
71
|
-
cpuLimit: "750m",
|
|
72
|
-
memoryRequest: "384Mi",
|
|
73
|
-
memoryLimit: "1536Mi"
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
function p(e) {
|
|
78
|
-
let t = e.metadata?.assistantMode;
|
|
79
|
-
if (t === "assistant" || t === "api-calls") return t;
|
|
80
|
-
let n = e.name ?? "";
|
|
81
|
-
return n.startsWith("ai-assistant-api-calls-") ? "api-calls" : n.startsWith("ai-assistant-assistant-") ? "assistant" : null;
|
|
82
|
-
}
|
|
83
|
-
function m(e, t) {
|
|
84
|
-
let n = {};
|
|
85
|
-
return t?.accessToken && (n.authorization = `Bearer ${t.accessToken}`), t?.workspaceToken && (n["x-workspace-authorization"] = `Bearer ${t.workspaceToken}`), e && (n["x-workspace-id"] = e), t?.userId && (n["x-actor-id"] = t.userId, n["x-actor-type"] = "user"), t?.organizationId && (n["x-org-id"] = t.organizationId), Object.keys(n).length > 0 ? { headers: n } : void 0;
|
|
86
|
-
}
|
|
87
|
-
function h(e, t) {
|
|
88
|
-
return {
|
|
89
|
-
workspaceId: e,
|
|
90
|
-
...t?.organizationId ? { custom: { organizationId: t.organizationId } } : {}
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
async function g(e) {
|
|
94
|
-
let n = await fetch("/workspaces/graphql", {
|
|
95
|
-
method: "POST",
|
|
96
|
-
headers: {
|
|
97
|
-
"Content-Type": "application/json",
|
|
98
|
-
...m(e.workspaceId, e.authContext)?.headers ?? {}
|
|
99
|
-
},
|
|
100
|
-
body: JSON.stringify({
|
|
101
|
-
query: t(e.document),
|
|
102
|
-
variables: e.variables
|
|
103
|
-
})
|
|
104
|
-
}), r = await n.json().catch(() => null);
|
|
105
|
-
if (!n.ok) {
|
|
106
|
-
let e = r?.errors?.map((e) => e.message).join(", "), t = Error(e || `Sandbox GraphQL HTTP ${n.status}`);
|
|
107
|
-
throw t.statusCode = n.status, t.result = r ?? void 0, t;
|
|
108
|
-
}
|
|
109
|
-
if (!r) throw Error("Sandbox GraphQL returned empty response");
|
|
110
|
-
if (r.errors?.length) throw Error(r.errors.map((e) => e.message).join(", "));
|
|
111
|
-
if (!r.data) throw Error("Sandbox GraphQL returned no data");
|
|
112
|
-
return r.data;
|
|
113
|
-
}
|
|
114
|
-
async function _(e, t, n, r) {
|
|
115
|
-
return ((await g({
|
|
116
|
-
document: s,
|
|
117
|
-
variables: { context: h(t, r) },
|
|
118
|
-
workspaceId: t,
|
|
119
|
-
authContext: r
|
|
120
|
-
})).getActiveSandboxes ?? []).find((e) => (e.status === "RUNNING" || e.status === "PROVISIONING" || e.status === "PENDING") && e.template === "AI_BUILDER" && p(e) === n && (!r?.userId || e.createdBy === r.userId) && e.metadata?.authStrategy === i && e.metadata?.imageTag === u(n))?.id ?? null;
|
|
121
|
-
}
|
|
122
|
-
async function v(e, t, n, r) {
|
|
123
|
-
let o = f(t), s = [
|
|
124
|
-
{
|
|
125
|
-
name: "AI_ASSISTANT_MODE",
|
|
126
|
-
value: t
|
|
127
|
-
},
|
|
128
|
-
{
|
|
129
|
-
name: "HOSTNAME",
|
|
130
|
-
value: "0.0.0.0"
|
|
131
|
-
},
|
|
132
|
-
{
|
|
133
|
-
name: "WORKSPACE_ID",
|
|
134
|
-
value: n
|
|
135
|
-
},
|
|
136
|
-
{
|
|
137
|
-
name: "AI_ASSISTANT_PRODUCT",
|
|
138
|
-
value: "subscriberbot"
|
|
139
|
-
}
|
|
140
|
-
], c = await g({
|
|
141
|
-
document: a,
|
|
142
|
-
variables: { input: {
|
|
143
|
-
name: `ai-assistant-${t}-${Date.now()}`,
|
|
144
|
-
description: `AI Assistant sandbox (${t} mode)`,
|
|
145
|
-
template: "AI_BUILDER",
|
|
146
|
-
mode: "DEPLOYMENT",
|
|
147
|
-
containers: [{
|
|
148
|
-
name: "ai-assistant",
|
|
149
|
-
image: d(t),
|
|
150
|
-
ports: [{
|
|
151
|
-
containerPort: 8080,
|
|
152
|
-
name: "http"
|
|
153
|
-
}],
|
|
154
|
-
env: s
|
|
155
|
-
}],
|
|
156
|
-
resources: {
|
|
157
|
-
cpuRequest: o.cpuRequest,
|
|
158
|
-
cpuLimit: o.cpuLimit,
|
|
159
|
-
memoryRequest: o.memoryRequest,
|
|
160
|
-
memoryLimit: o.memoryLimit
|
|
161
|
-
},
|
|
162
|
-
ttlSeconds: 600,
|
|
163
|
-
metadata: {
|
|
164
|
-
assistantMode: t,
|
|
165
|
-
assistantOwnerUserId: r?.userId ?? null,
|
|
166
|
-
assistantOrganizationId: r?.organizationId ?? null,
|
|
167
|
-
authStrategy: i,
|
|
168
|
-
imageTag: u(t)
|
|
169
|
-
},
|
|
170
|
-
context: h(n, r)
|
|
171
|
-
} },
|
|
172
|
-
workspaceId: n,
|
|
173
|
-
authContext: r
|
|
174
|
-
});
|
|
175
|
-
if (!c?.createSandbox?.id) throw Error("createSandbox returned empty response");
|
|
176
|
-
return c.createSandbox.id;
|
|
177
|
-
}
|
|
178
|
-
async function y(e, t, n, r, i = 3e5, a) {
|
|
179
|
-
let s = Date.now();
|
|
180
|
-
for (; Date.now() - s < i;) {
|
|
181
|
-
let e = await g({
|
|
182
|
-
document: o,
|
|
183
|
-
variables: {
|
|
184
|
-
id: t,
|
|
185
|
-
context: h(n, r)
|
|
186
|
-
},
|
|
187
|
-
workspaceId: n,
|
|
188
|
-
authContext: r
|
|
189
|
-
}), i = e?.getSandbox?.status, c = e?.getSandbox?.errorMessage;
|
|
190
|
-
if (i === "RUNNING") return;
|
|
191
|
-
if (i === "FAILED" || i === "STOPPED" || i === "EXPIRED") throw Error(c ? `Sandbox ${i.toLowerCase()}: ${c}` : `Sandbox ${i.toLowerCase()}`);
|
|
192
|
-
let l = Math.max(1, Math.round((Date.now() - s) / 1e3));
|
|
193
|
-
a?.(`Starting assistant environment... (${l}s)`), await new Promise((e) => setTimeout(e, 2e3));
|
|
194
|
-
}
|
|
195
|
-
throw Error("Sandbox startup timed out");
|
|
196
|
-
}
|
|
197
|
-
async function b(e, t, n, r, i, a, o) {
|
|
198
|
-
let s = (await g({
|
|
199
|
-
document: c,
|
|
200
|
-
variables: { input: {
|
|
201
|
-
sandboxId: t,
|
|
202
|
-
path: r,
|
|
203
|
-
method: i,
|
|
204
|
-
body: a,
|
|
205
|
-
context: h(n, o)
|
|
206
|
-
} },
|
|
207
|
-
workspaceId: n,
|
|
208
|
-
authContext: o
|
|
209
|
-
})).proxySandboxRequest;
|
|
210
|
-
if (!s || s.status >= 400) {
|
|
211
|
-
let e = s?.body;
|
|
212
|
-
throw Error(e?.error ?? `Proxy error: ${s?.status ?? "unknown"}`);
|
|
213
|
-
}
|
|
214
|
-
return s.body;
|
|
215
|
-
}
|
|
216
|
-
async function x(e, t, n, r, i = 9e4, a) {
|
|
217
|
-
let o = Date.now();
|
|
218
|
-
for (; Date.now() - o < i;) {
|
|
219
|
-
try {
|
|
220
|
-
await b(e, t, n, "/health", "GET", void 0, r);
|
|
221
|
-
return;
|
|
222
|
-
} catch (e) {
|
|
223
|
-
let t = e instanceof Error ? e.message : String(e);
|
|
224
|
-
if (!/proxy error: 502|proxy error: 503|proxy error: 404|service not available/i.test(t)) throw e;
|
|
225
|
-
}
|
|
226
|
-
let i = Math.max(1, Math.round((Date.now() - o) / 1e3));
|
|
227
|
-
a?.(`Connecting to assistant... (${i}s)`), await new Promise((e) => setTimeout(e, 2e3));
|
|
228
|
-
}
|
|
229
|
-
throw Error("Assistant service did not become healthy before timeout");
|
|
230
|
-
}
|
|
231
|
-
async function S(e, t, n, r, i) {
|
|
232
|
-
return { sessionId: (await b(e, t, n, "/sessions", "POST", { mode: r }, i)).session.id };
|
|
233
|
-
}
|
|
234
|
-
async function C(e, t, n, r, i, a, o, s) {
|
|
235
|
-
let c = {
|
|
236
|
-
mode: a,
|
|
237
|
-
prompt: i,
|
|
238
|
-
pageContext: o ?? void 0
|
|
239
|
-
};
|
|
240
|
-
await b(e, t, n, `/sessions/${r}/prompt-async`, "POST", c, s);
|
|
241
|
-
}
|
|
242
|
-
async function w(e, t, n, r, i, a = 50) {
|
|
243
|
-
return (await b(e, t, n, `/sessions/${r}/messages?limit=${a}`, "GET", void 0, i)).messages ?? [];
|
|
244
|
-
}
|
|
245
|
-
async function T(e, t, n, r = 600, i) {
|
|
246
|
-
await g({
|
|
247
|
-
document: l,
|
|
248
|
-
variables: {
|
|
249
|
-
id: t,
|
|
250
|
-
additionalSeconds: r,
|
|
251
|
-
context: h(n, i)
|
|
252
|
-
},
|
|
253
|
-
workspaceId: n,
|
|
254
|
-
authContext: i
|
|
255
|
-
});
|
|
256
|
-
}
|
|
257
|
-
//#endregion
|
|
258
|
-
export { v as createAssistantSandbox, S as createAssistantSession, T as extendAssistantSandboxTTL, _ as findExistingSandbox, w as getAssistantMessages, C as sendAssistantPromptAsync, x as waitForAssistantServiceReady, y as waitForSandboxReady };
|
|
259
|
-
|
|
260
|
-
//# sourceMappingURL=assistantApi.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"assistantApi.js","names":[],"sources":["../../../src/subscriberbot/services/assistantApi.ts"],"sourcesContent":["import { type ApolloClient, gql } from '@apollo/client';\nimport { print, type DocumentNode } from 'graphql';\nimport type { AssistantArtifact, AssistantMode } from '#subscriberbot/types/assistant';\nimport type { PageContext } from '#subscriberbot/utils/pageContext';\n\nconst HARBOR_REGISTRY = 'burdenoffregistry.azurecr.io';\nconst DEFAULT_IMAGE_TAG = import.meta.env.VITE_APP_ENV === 'prod' ? 'prod' : 'alpha';\nconst API_CALLS_IMAGE_TAG =\n import.meta.env.VITE_APP_ENV === 'prod' ? 'prod' : 'alpha-delegated-auth-v11';\nconst ASSISTANT_API_AUTH_STRATEGY = 'sandbox-app-client-headers-v1';\n\nconst CreateSandboxDocument = gql`\n mutation CreateSandbox($input: CreateSandboxInput!) {\n createSandbox(input: $input) {\n id\n name\n status\n network {\n internalUrl\n }\n }\n }\n`;\n\nconst GetSandboxDocument = gql`\n query GetSandbox($id: ID!, $context: ContextInput!) {\n getSandbox(id: $id, context: $context) {\n id\n status\n errorMessage\n network {\n internalUrl\n }\n }\n }\n`;\n\nconst GetActiveSandboxesDocument = gql`\n query GetActiveSandboxes($context: ContextInput!) {\n getActiveSandboxes(context: $context) {\n id\n name\n status\n metadata\n template\n createdBy\n }\n }\n`;\n\nconst ProxySandboxRequestDocument = gql`\n mutation ProxySandboxRequest($input: ProxySandboxRequestInput!) {\n proxySandboxRequest(input: $input) {\n status\n body\n }\n }\n`;\n\nconst ExtendSandboxTtlDocument = gql`\n mutation ExtendSandboxTtl($id: ID!, $additionalSeconds: Int!, $context: ContextInput!) {\n extendSandboxTTL(id: $id, additionalSeconds: $additionalSeconds, context: $context) {\n id\n expiresAt\n }\n }\n`;\n\nfunction getImageTagForMode(mode: AssistantMode): string {\n switch (mode) {\n case 'api-calls':\n return API_CALLS_IMAGE_TAG;\n case 'assistant':\n default:\n return API_CALLS_IMAGE_TAG;\n }\n}\n\nfunction getImageForMode(mode: AssistantMode): string {\n const imageMode = mode === 'assistant' ? 'api-calls' : mode;\n return `${HARBOR_REGISTRY}/wspace/ai-assistant-${imageMode}:${getImageTagForMode(mode)}`;\n}\n\nfunction getResourcesForMode(mode: AssistantMode): {\n cpuRequest: string;\n cpuLimit: string;\n memoryRequest: string;\n memoryLimit: string;\n} {\n switch (mode) {\n case 'api-calls':\n return {\n cpuRequest: '150m',\n cpuLimit: '750m',\n memoryRequest: '384Mi',\n memoryLimit: '1536Mi',\n };\n case 'assistant':\n default:\n return {\n cpuRequest: '150m',\n cpuLimit: '750m',\n memoryRequest: '384Mi',\n memoryLimit: '1536Mi',\n };\n }\n}\n\nfunction resolveSandboxAssistantMode(sandbox: {\n metadata: Record<string, unknown> | null;\n name?: string | null;\n}): AssistantMode | null {\n const metadataMode = sandbox.metadata?.assistantMode;\n if (metadataMode === 'assistant' || metadataMode === 'api-calls') {\n return metadataMode;\n }\n\n const name = sandbox.name ?? '';\n if (name.startsWith('ai-assistant-api-calls-')) return 'api-calls';\n if (name.startsWith('ai-assistant-assistant-')) return 'assistant';\n return null;\n}\n\nexport interface AssistantPromptResult {\n response: string;\n tokens?: { input: number; output: number };\n artifacts?: AssistantArtifact[];\n}\n\nexport interface AssistantRawMessagePart {\n type?: string;\n text?: string;\n tool?: string;\n state?: {\n status?: string;\n input?: unknown;\n output?: unknown;\n raw?: unknown;\n };\n}\n\nexport interface AssistantRawMessage {\n info?: {\n id?: string;\n role?: string;\n providerID?: string;\n modelID?: string;\n tokens?: { input: number; output: number };\n time?: {\n created?: number;\n completed?: number;\n };\n };\n parts?: AssistantRawMessagePart[];\n}\n\nexport interface AssistantSandboxAuthContext {\n accessToken?: string | null;\n workspaceToken?: string | null;\n userId?: string | null;\n organizationId?: string | null;\n}\n\nexport interface AssistantSessionInfo {\n id: string;\n mode: string;\n}\n\ninterface GraphQLResponse<TData> {\n data?: TData;\n errors?: Array<{ message: string }>;\n}\n\nexport interface DownloadedAssistantArtifact {\n filename: string;\n mimeType: string;\n contentBase64: string;\n}\n\ninterface ProxyResponse {\n proxySandboxRequest: {\n status: number;\n body: Record<string, unknown>;\n };\n}\n\nfunction getGatewayRequestContext(\n workspaceId: string,\n authContext?: AssistantSandboxAuthContext\n): { headers?: Record<string, string> } | undefined {\n const headers: Record<string, string> = {};\n\n if (authContext?.accessToken) {\n headers.authorization = `Bearer ${authContext.accessToken}`;\n }\n\n if (authContext?.workspaceToken) {\n headers['x-workspace-authorization'] = `Bearer ${authContext.workspaceToken}`;\n }\n\n if (workspaceId) {\n headers['x-workspace-id'] = workspaceId;\n }\n\n if (authContext?.userId) {\n headers['x-actor-id'] = authContext.userId;\n headers['x-actor-type'] = 'user';\n }\n\n if (authContext?.organizationId) {\n headers['x-org-id'] = authContext.organizationId;\n }\n\n return Object.keys(headers).length > 0 ? { headers } : undefined;\n}\n\nfunction buildSandboxContextInput(\n workspaceId: string,\n authContext?: AssistantSandboxAuthContext\n): Record<string, unknown> {\n return {\n workspaceId,\n ...(authContext?.organizationId\n ? {\n custom: {\n organizationId: authContext.organizationId,\n },\n }\n : {}),\n };\n}\n\nasync function executeSandboxGraphQL<TData>(params: {\n document: DocumentNode;\n variables: Record<string, unknown>;\n workspaceId: string;\n authContext?: AssistantSandboxAuthContext;\n}): Promise<TData> {\n const response = await fetch('/workspaces/graphql', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(getGatewayRequestContext(params.workspaceId, params.authContext)?.headers ?? {}),\n },\n body: JSON.stringify({\n query: print(params.document),\n variables: params.variables,\n }),\n });\n\n const result = (await response.json().catch(() => null)) as GraphQLResponse<TData> | null;\n\n if (!response.ok) {\n const messages = result?.errors?.map((error: { message: string }) => error.message).join(', ');\n const httpError = new Error(messages || `Sandbox GraphQL HTTP ${response.status}`) as Error & {\n statusCode?: number;\n result?: unknown;\n };\n httpError.statusCode = response.status;\n httpError.result = result ?? undefined;\n throw httpError;\n }\n\n if (!result) {\n throw new Error('Sandbox GraphQL returned empty response');\n }\n\n if (result.errors?.length) {\n throw new Error(result.errors.map((error: { message: string }) => error.message).join(', '));\n }\n\n if (!result.data) {\n throw new Error('Sandbox GraphQL returned no data');\n }\n\n return result.data;\n}\n\nexport async function findExistingSandbox(\n _apollo: ApolloClient,\n workspaceId: string,\n mode: AssistantMode,\n authContext?: AssistantSandboxAuthContext\n): Promise<string | null> {\n const data = await executeSandboxGraphQL<{\n getActiveSandboxes: Array<{\n id: string;\n name: string;\n status: string;\n metadata: Record<string, unknown> | null;\n template: string;\n createdBy: string;\n }>;\n }>({\n document: GetActiveSandboxesDocument,\n variables: { context: buildSandboxContextInput(workspaceId, authContext) },\n workspaceId,\n authContext,\n });\n const sandboxes = data.getActiveSandboxes ?? [];\n\n return (\n sandboxes.find(\n (s) =>\n (s.status === 'RUNNING' || s.status === 'PROVISIONING' || s.status === 'PENDING') &&\n s.template === 'AI_BUILDER' &&\n resolveSandboxAssistantMode(s) === mode &&\n (!authContext?.userId || s.createdBy === authContext.userId) &&\n s.metadata?.authStrategy === ASSISTANT_API_AUTH_STRATEGY &&\n s.metadata?.imageTag === getImageTagForMode(mode)\n )?.id ?? null\n );\n}\n\nexport async function createAssistantSandbox(\n _apollo: ApolloClient,\n mode: AssistantMode,\n workspaceId: string,\n authContext?: AssistantSandboxAuthContext\n): Promise<string> {\n const resources = getResourcesForMode(mode);\n const env = [\n { name: 'AI_ASSISTANT_MODE', value: mode },\n { name: 'HOSTNAME', value: '0.0.0.0' },\n { name: 'WORKSPACE_ID', value: workspaceId },\n { name: 'AI_ASSISTANT_PRODUCT', value: 'subscriberbot' },\n ];\n\n const data = await executeSandboxGraphQL<{ createSandbox: { id: string } }>({\n document: CreateSandboxDocument,\n variables: {\n input: {\n name: `ai-assistant-${mode}-${Date.now()}`,\n description: `AI Assistant sandbox (${mode} mode)`,\n template: 'AI_BUILDER',\n mode: 'DEPLOYMENT',\n containers: [\n {\n name: 'ai-assistant',\n image: getImageForMode(mode),\n ports: [{ containerPort: 8080, name: 'http' }],\n env,\n },\n ],\n resources: {\n cpuRequest: resources.cpuRequest,\n cpuLimit: resources.cpuLimit,\n memoryRequest: resources.memoryRequest,\n memoryLimit: resources.memoryLimit,\n },\n ttlSeconds: 600,\n metadata: {\n assistantMode: mode,\n assistantOwnerUserId: authContext?.userId ?? null,\n assistantOrganizationId: authContext?.organizationId ?? null,\n authStrategy: ASSISTANT_API_AUTH_STRATEGY,\n imageTag: getImageTagForMode(mode),\n },\n context: buildSandboxContextInput(workspaceId, authContext),\n },\n },\n workspaceId,\n authContext,\n });\n\n if (!data?.createSandbox?.id) {\n throw new Error('createSandbox returned empty response');\n }\n return data.createSandbox.id;\n}\n\nexport async function waitForSandboxReady(\n _apollo: ApolloClient,\n sandboxId: string,\n workspaceId: string,\n authContext?: AssistantSandboxAuthContext,\n maxWaitMs = 300_000,\n onProgress?: (message: string) => void\n): Promise<void> {\n const start = Date.now();\n while (Date.now() - start < maxWaitMs) {\n const data = await executeSandboxGraphQL<{\n getSandbox: { status?: string; errorMessage?: string } | null;\n }>({\n document: GetSandboxDocument,\n variables: { id: sandboxId, context: buildSandboxContextInput(workspaceId, authContext) },\n workspaceId,\n authContext,\n });\n const status = data?.getSandbox?.status;\n const errorMessage = data?.getSandbox?.errorMessage as string | undefined;\n if (status === 'RUNNING') return;\n if (status === 'FAILED' || status === 'STOPPED' || status === 'EXPIRED') {\n throw new Error(\n errorMessage\n ? `Sandbox ${status.toLowerCase()}: ${errorMessage}`\n : `Sandbox ${status.toLowerCase()}`\n );\n }\n const elapsedSeconds = Math.max(1, Math.round((Date.now() - start) / 1000));\n onProgress?.(`Starting assistant environment... (${elapsedSeconds}s)`);\n await new Promise((r) => setTimeout(r, 2000));\n }\n throw new Error('Sandbox startup timed out');\n}\n\nasync function proxyToSandbox(\n _apollo: ApolloClient,\n sandboxId: string,\n workspaceId: string,\n path: string,\n method: string,\n body?: unknown,\n authContext?: AssistantSandboxAuthContext\n): Promise<Record<string, unknown>> {\n const result = await executeSandboxGraphQL<ProxyResponse>({\n document: ProxySandboxRequestDocument,\n variables: {\n input: {\n sandboxId,\n path,\n method,\n body,\n context: buildSandboxContextInput(workspaceId, authContext),\n },\n },\n workspaceId,\n authContext,\n });\n\n const proxyResult = result.proxySandboxRequest;\n if (!proxyResult || proxyResult.status >= 400) {\n const errBody = proxyResult?.body as Record<string, unknown> | undefined;\n throw new Error(\n (errBody?.error as string) ?? `Proxy error: ${proxyResult?.status ?? 'unknown'}`\n );\n }\n\n return proxyResult.body;\n}\n\nexport async function waitForAssistantServiceReady(\n apollo: ApolloClient,\n sandboxId: string,\n workspaceId: string,\n authContext?: AssistantSandboxAuthContext,\n maxWaitMs = 90_000,\n onProgress?: (message: string) => void\n): Promise<void> {\n const startedAt = Date.now();\n\n while (Date.now() - startedAt < maxWaitMs) {\n try {\n await proxyToSandbox(\n apollo,\n sandboxId,\n workspaceId,\n '/health',\n 'GET',\n undefined,\n authContext\n );\n return;\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (\n !/proxy error: 502|proxy error: 503|proxy error: 404|service not available/i.test(message)\n ) {\n throw error;\n }\n }\n\n const elapsedSeconds = Math.max(1, Math.round((Date.now() - startedAt) / 1000));\n onProgress?.(`Connecting to assistant... (${elapsedSeconds}s)`);\n\n await new Promise((resolve) => setTimeout(resolve, 2000));\n }\n\n throw new Error('Assistant service did not become healthy before timeout');\n}\n\nexport async function createAssistantSession(\n apollo: ApolloClient,\n sandboxId: string,\n workspaceId: string,\n mode: AssistantMode,\n authContext?: AssistantSandboxAuthContext\n): Promise<{ sessionId: string }> {\n const body = await proxyToSandbox(\n apollo,\n sandboxId,\n workspaceId,\n '/sessions',\n 'POST',\n { mode },\n authContext\n );\n const session = body.session as Record<string, unknown>;\n return { sessionId: session.id as string };\n}\n\nexport async function sendAssistantPromptAsync(\n apollo: ApolloClient,\n sandboxId: string,\n workspaceId: string,\n sessionId: string,\n prompt: string,\n mode: AssistantMode,\n pageContext?: PageContext,\n authContext?: AssistantSandboxAuthContext\n): Promise<void> {\n const requestBody = {\n mode,\n prompt,\n pageContext: pageContext ?? undefined,\n };\n\n await proxyToSandbox(\n apollo,\n sandboxId,\n workspaceId,\n `/sessions/${sessionId}/prompt-async`,\n 'POST',\n requestBody,\n authContext\n );\n}\n\nexport async function getAssistantMessages(\n apollo: ApolloClient,\n sandboxId: string,\n workspaceId: string,\n sessionId: string,\n authContext?: AssistantSandboxAuthContext,\n limit = 50\n): Promise<AssistantRawMessage[]> {\n const body = await proxyToSandbox(\n apollo,\n sandboxId,\n workspaceId,\n `/sessions/${sessionId}/messages?limit=${limit}`,\n 'GET',\n undefined,\n authContext\n );\n\n return (body.messages as AssistantRawMessage[] | undefined) ?? [];\n}\n\nexport async function extendAssistantSandboxTTL(\n _apollo: ApolloClient,\n sandboxId: string,\n workspaceId: string,\n additionalSeconds = 600,\n authContext?: AssistantSandboxAuthContext\n): Promise<void> {\n await executeSandboxGraphQL<{ extendSandboxTTL: { id: string } }>({\n document: ExtendSandboxTtlDocument,\n variables: {\n id: sandboxId,\n additionalSeconds,\n context: buildSandboxContextInput(workspaceId, authContext),\n },\n workspaceId,\n authContext,\n });\n}\n"],"mappings":"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"}
|