@burdenoff/microfe-crewfoundry 2026.710.5 → 2026.716.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/crewfoundry/pages/DashboardDashboardPagePage.js +4 -4
- package/dist/crewfoundry/pages/HiringCandidatesPagePage.js +3 -3
- package/dist/crewfoundry/pages/HrLeaveManagementPagePage.js +4 -4
- package/dist/crewfoundry/pages/HrPayrollPagePage.js +3 -3
- package/dist/crewfoundry/pages/LearningCoursesPagePage.js +3 -3
- package/dist/services/createSandboxAssistantTransport.d.ts +8 -24
- package/dist/services/createSandboxAssistantTransport.d.ts.map +1 -1
- package/dist/services/createSandboxAssistantTransport.js +8 -114
- package/dist/services/createSandboxAssistantTransport.js.map +1 -1
- package/dist/stories/RatingStars.stories.d.ts +10 -0
- package/dist/stories/RatingStars.stories.d.ts.map +1 -0
- package/dist/stories/SkillBar.stories.d.ts +10 -0
- package/dist/stories/SkillBar.stories.d.ts.map +1 -0
- package/dist/stories/StatCard.stories.d.ts +10 -0
- package/dist/stories/StatCard.stories.d.ts.map +1 -0
- package/package.json +15 -4
- package/dist/services/assistantApi.d.ts +0 -75
- package/dist/services/assistantApi.d.ts.map +0 -1
- package/dist/services/assistantApi.js +0 -273
- package/dist/services/assistantApi.js.map +0 -1
|
@@ -12,8 +12,8 @@ import { Activity as c, Briefcase as l, Calendar as u, FolderPlus as re, Plus as
|
|
|
12
12
|
import { useNavigate as oe } from "react-router-dom";
|
|
13
13
|
import { jsx as p, jsxs as m } from "react/jsx-runtime";
|
|
14
14
|
import { AuroraBackground as se, Badge as h, Button as g, Card as _, CardContent as v, CardHeader as y, CardTitle as b, DropdownMenu as ce, DropdownMenuContent as le, DropdownMenuItem as x, DropdownMenuLabel as ue, DropdownMenuSeparator as S, DropdownMenuTrigger as C, GradientText as de, IllustratedEmptyState as w, NextSteps as fe, PagePurpose as pe, Pagination as me } from "@burdenoff/fe-libs/ui";
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
15
|
+
import { usePagination as he } from "@burdenoff/fe-libs/shared/hooks";
|
|
16
|
+
import { useGlobalUi as ge } from "@burdenoff/fe-libs/shared/providers/shell";
|
|
17
17
|
import { useI18n as _e } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
18
18
|
//#region src/crewfoundry/pages/DashboardDashboardPagePage.tsx
|
|
19
19
|
function T(e) {
|
|
@@ -49,7 +49,7 @@ var ve = [
|
|
|
49
49
|
"hired"
|
|
50
50
|
];
|
|
51
51
|
function O() {
|
|
52
|
-
let { t: r } = _e(), O = oe(), { showToast: k } =
|
|
52
|
+
let { t: r } = _e(), O = oe(), { showToast: k } = ge(), { currentUser: A } = e(), { employees: j, jobPostings: M, interviews: N, leaveRequests: P, projects: F, candidates: I, announcements: L, updateLeaveRequest: ye } = t(), [R, z] = s(null), [be, xe] = s({}), Se = A?.name || [A?.firstName, A?.lastName].filter(Boolean).join(" ") || A?.email || "Manager", B = async (e, t) => {
|
|
53
53
|
z(e);
|
|
54
54
|
try {
|
|
55
55
|
await ye(e, {
|
|
@@ -98,7 +98,7 @@ function O() {
|
|
|
98
98
|
let e = /* @__PURE__ */ new Map();
|
|
99
99
|
for (let t of j) e.set(`${t.firstName} ${t.lastName}`.trim().toLowerCase(), t.avatar);
|
|
100
100
|
return e;
|
|
101
|
-
}, [j]), K = [...N].filter((e) => e.status === "scheduled").sort((e, t) => `${e.date} ${e.time}`.localeCompare(`${t.date} ${t.time}`)), q = K.slice(0, 5), J = o(() => [...L].sort((e, t) => e.isPinned === t.isPinned ? t.createdAt.localeCompare(e.createdAt) : e.isPinned ? -1 : 1), [L]), Y = J.slice(0, 4), X = [...P].sort((e, t) => e.status === "pending" && t.status !== "pending" ? -1 : t.status === "pending" && e.status !== "pending" ? 1 : t.startDate.localeCompare(e.startDate)), { page: Z, pageSize: Q, offset: $, setPage: Pe } =
|
|
101
|
+
}, [j]), K = [...N].filter((e) => e.status === "scheduled").sort((e, t) => `${e.date} ${e.time}`.localeCompare(`${t.date} ${t.time}`)), q = K.slice(0, 5), J = o(() => [...L].sort((e, t) => e.isPinned === t.isPinned ? t.createdAt.localeCompare(e.createdAt) : e.isPinned ? -1 : 1), [L]), Y = J.slice(0, 4), X = [...P].sort((e, t) => e.status === "pending" && t.status !== "pending" ? -1 : t.status === "pending" && e.status !== "pending" ? 1 : t.startDate.localeCompare(e.startDate)), { page: Z, pageSize: Q, offset: $, setPage: Pe } = he({ initialPageSize: 6 }), Fe = X.slice($, $ + Q);
|
|
102
102
|
return /* @__PURE__ */ m("div", {
|
|
103
103
|
className: "space-y-6 p-6",
|
|
104
104
|
children: [
|
|
@@ -11,8 +11,8 @@ import { useMemo as u, useState as d } from "react";
|
|
|
11
11
|
import { ArrowRightLeft as f, LayoutGrid as p, Pencil as m, Plus as h, Search as g, Table2 as _, Trash2 as v } from "lucide-react";
|
|
12
12
|
import { jsx as y, jsxs as b } from "react/jsx-runtime";
|
|
13
13
|
import { Badge as x, Button as S, CardContent as C, DropdownMenu as w, DropdownMenuContent as T, DropdownMenuItem as E, DropdownMenuLabel as D, DropdownMenuSeparator as O, DropdownMenuTrigger as k, GlassCard as A, GradientText as j, IllustratedEmptyState as M, Input as N, PagePurpose as P, Pagination as F, ResponsiveTable as te } from "@burdenoff/fe-libs/ui";
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
14
|
+
import { usePagination as ne } from "@burdenoff/fe-libs/shared/hooks";
|
|
15
|
+
import { useGlobalUi as re } from "@burdenoff/fe-libs/shared/providers/shell";
|
|
16
16
|
//#region src/crewfoundry/pages/HiringCandidatesPagePage.tsx
|
|
17
17
|
var I = [
|
|
18
18
|
{
|
|
@@ -286,7 +286,7 @@ var H = [
|
|
|
286
286
|
}
|
|
287
287
|
];
|
|
288
288
|
function U() {
|
|
289
|
-
let { showToast: n } =
|
|
289
|
+
let { showToast: n } = re(), { candidates: i, addCandidate: s, updateCandidate: c, removeCandidate: l } = e(), [f, x] = d(""), [w, T] = d("board"), [E, D] = d("all"), { page: O, pageSize: k, offset: I, setPage: V } = ne({ initialPageSize: 25 }), [U, G] = d(!1), [K, q] = d(null), [J, Y] = d(null), X = async (e) => {
|
|
290
290
|
await s({
|
|
291
291
|
id: ee(),
|
|
292
292
|
...B(e)
|
|
@@ -10,8 +10,8 @@ import { useMemo as u, useState as d } from "react";
|
|
|
10
10
|
import { Calendar as f, CheckCircle as p, ChevronLeft as m, ChevronRight as h, Clock as g, XCircle as _ } from "lucide-react";
|
|
11
11
|
import { jsx as v, jsxs as y } from "react/jsx-runtime";
|
|
12
12
|
import { Badge as b, Button as x, Card as S, CardContent as C, CardDescription as w, CardHeader as T, CardTitle as E, GradientText as D, PagePurpose as O, Pagination as ee, ResponsiveTable as te } from "@burdenoff/fe-libs/ui";
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
13
|
+
import { usePagination as k } from "@burdenoff/fe-libs/shared/hooks";
|
|
14
|
+
import { useAuth as A, useGlobalUi as j } from "@burdenoff/fe-libs/shared/providers/shell";
|
|
15
15
|
//#region src/crewfoundry/pages/HrLeaveManagementPagePage.tsx
|
|
16
16
|
var ne = [
|
|
17
17
|
{
|
|
@@ -182,7 +182,7 @@ function z({ leaveRequests: e, monthCursor: t, onPrev: n, onNext: r }) {
|
|
|
182
182
|
})] });
|
|
183
183
|
}
|
|
184
184
|
function B() {
|
|
185
|
-
let { leaveRequests: m, employees: h, addLeaveRequest: N, updateLeaveRequest: F } = e(), { showToast: I } =
|
|
185
|
+
let { leaveRequests: m, employees: h, addLeaveRequest: N, updateLeaveRequest: F } = e(), { showToast: I } = j(), { currentUser: L } = A(), B = o(), [V, H] = d("requests"), U = u(() => new Map(h.map((e) => [e.id, e])), [h]), [W, G] = d(() => {
|
|
186
186
|
let e = m.filter((e) => e.status === "approved" || e.status === "pending").map((e) => R(e.startDate)).sort(), t = e[e.length - 1];
|
|
187
187
|
if (t) {
|
|
188
188
|
let [e, n] = t.split("-").map(Number);
|
|
@@ -254,7 +254,7 @@ function B() {
|
|
|
254
254
|
}, [m]), oe = u(() => {
|
|
255
255
|
let e = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
256
256
|
return m.filter((t) => t.status === "approved" && t.startDate <= e && t.endDate >= e).length;
|
|
257
|
-
}, [m]), Z = u(() => [...m].sort((e, t) => t.startDate.localeCompare(e.startDate)), [m]), Q =
|
|
257
|
+
}, [m]), Z = u(() => [...m].sort((e, t) => t.startDate.localeCompare(e.startDate)), [m]), Q = k({ initialPageSize: 10 }), se = Z.slice(Q.offset, Q.offset + Q.pageSize), ce = [
|
|
258
258
|
{
|
|
259
259
|
key: "employee",
|
|
260
260
|
header: "Employee",
|
|
@@ -10,8 +10,8 @@ import { useMemo as u, useState as d } from "react";
|
|
|
10
10
|
import { CalendarClock as ee, CheckCircle as f, DollarSign as te, Download as ne, Play as re, Plus as p, Users as m } from "lucide-react";
|
|
11
11
|
import { Fragment as h, jsx as g, jsxs as _ } from "react/jsx-runtime";
|
|
12
12
|
import { Badge as v, Button as y, Card as b, CardContent as x, CardDescription as ie, CardHeader as S, CardTitle as C, GlassCard as w, GradientText as ae, PagePurpose as oe, Pagination as T, ResponsiveTable as E, Separator as se } from "@burdenoff/fe-libs/ui";
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
13
|
+
import { usePagination as ce } from "@burdenoff/fe-libs/shared/hooks";
|
|
14
|
+
import { useGlobalUi as le } from "@burdenoff/fe-libs/shared/providers/shell";
|
|
15
15
|
//#region src/crewfoundry/pages/HrPayrollPagePage.tsx
|
|
16
16
|
var ue = [
|
|
17
17
|
{
|
|
@@ -67,7 +67,7 @@ var ue = [
|
|
|
67
67
|
return `${O[a]} 1, ${o}`;
|
|
68
68
|
};
|
|
69
69
|
function k() {
|
|
70
|
-
let { payrollRecords: D, employees: O, addPayrollRecord: k, updatePayrollRecord: A } = e(), { showToast: j } =
|
|
70
|
+
let { payrollRecords: D, employees: O, addPayrollRecord: k, updatePayrollRecord: A } = e(), { showToast: j } = le(), M = u(() => [...new Set(D.map((e) => e.period))], [D]), [N, P] = d(""), F = a(), [I, L] = d(!1), [R, z] = d(!1), { page: B, pageSize: V, offset: H, setPage: U } = ce({ initialPageSize: 10 }), W = N || M[0] || "", fe = u(() => new Map(O.map((e) => [e.id, e])), [O]), G = u(() => O.map((e) => ({
|
|
71
71
|
label: `${e.firstName} ${e.lastName}`,
|
|
72
72
|
value: e.id
|
|
73
73
|
})), [O]), pe = u(() => [
|
|
@@ -10,8 +10,8 @@ import { BarChart3 as l, Briefcase as u, Code2 as d, GraduationCap as f, Megapho
|
|
|
10
10
|
import { useNavigate as b } from "react-router-dom";
|
|
11
11
|
import { jsx as x, jsxs as S } from "react/jsx-runtime";
|
|
12
12
|
import { Badge as C, Button as w, CardContent as T, CardHeader as E, GlassCard as D, GradientText as O, IllustratedEmptyState as k, Input as A, PagePurpose as j, Pagination as M } from "@burdenoff/fe-libs/ui";
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
13
|
+
import { usePagination as N } from "@burdenoff/fe-libs/shared/hooks";
|
|
14
|
+
import { useGlobalUi as P } from "@burdenoff/fe-libs/shared/providers/shell";
|
|
15
15
|
//#region src/crewfoundry/pages/LearningCoursesPagePage.tsx
|
|
16
16
|
var F = [
|
|
17
17
|
{
|
|
@@ -115,7 +115,7 @@ function R(e) {
|
|
|
115
115
|
return e === "beginner" ? "secondary" : e === "intermediate" ? "default" : "destructive";
|
|
116
116
|
}
|
|
117
117
|
function z() {
|
|
118
|
-
let { courses: n, addCourse: l, enrollCourse: u } = e(), { showToast: d } =
|
|
118
|
+
let { courses: n, addCourse: l, enrollCourse: u } = e(), { showToast: d } = P(), f = b(), [p, m] = c(""), [v, z] = c("all"), [B, V] = c(null), H = a(), { page: U, pageSize: W, offset: G, setPage: K } = N({ initialPageSize: 12 }), q = s(() => {
|
|
119
119
|
let e = /* @__PURE__ */ new Map();
|
|
120
120
|
for (let t of n) {
|
|
121
121
|
let n = t.category.trim() || "Uncategorized";
|
|
@@ -1,24 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* crewfoundry adapter for the shared fe-libs AssistantWidget transport.
|
|
3
3
|
*
|
|
4
|
-
* The
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* behalf using their workspace token, contextual to the current screen (via
|
|
10
|
-
* `gatherPageContext`).
|
|
11
|
-
*/
|
|
12
|
-
/**
|
|
13
|
-
* Locally-defined mirror of the fe-libs `AssistantTransport` contract.
|
|
14
|
-
*
|
|
15
|
-
* We intentionally do NOT import the type from `@burdenoff/fe-libs` here:
|
|
16
|
-
* microfe's tsconfig maps `@burdenoff/fe-libs/*` to fe-libs *source*, so
|
|
17
|
-
* vite-plugin-dts would rewrite a cross-package type used in this hook's
|
|
18
|
-
* public signature to a broken source-relative path in the emitted `.d.ts`.
|
|
19
|
-
* Structural typing makes this shape assignable to fe-libs' `AssistantTransport`
|
|
20
|
-
* at the call site (crewfoundry-app's AppShell), which is where compatibility
|
|
21
|
-
* is enforced — drift there fails the app type-check.
|
|
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).
|
|
22
9
|
*/
|
|
23
10
|
interface AssistantSendArgs {
|
|
24
11
|
prompt: string;
|
|
@@ -29,12 +16,9 @@ export interface AssistantTransport {
|
|
|
29
16
|
sendPrompt: (args: AssistantSendArgs) => Promise<{
|
|
30
17
|
text: string;
|
|
31
18
|
}>;
|
|
19
|
+
prewarm?: (level?: 'probe' | 'full') => void;
|
|
20
|
+
suspend?: () => void;
|
|
32
21
|
}
|
|
33
|
-
/**
|
|
34
|
-
* Returns a memoized `AssistantTransport` wired to the CrewFoundry sandbox
|
|
35
|
-
* `api-calls` agent. The sandbox + session are cached in refs so follow-up
|
|
36
|
-
* turns reuse the warm environment for the lifetime of the host shell.
|
|
37
|
-
*/
|
|
38
22
|
export declare function useSandboxAssistantTransport(): AssistantTransport;
|
|
39
23
|
export {};
|
|
40
24
|
//# sourceMappingURL=createSandboxAssistantTransport.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createSandboxAssistantTransport.d.ts","sourceRoot":"","sources":["../../src/services/createSandboxAssistantTransport.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"createSandboxAssistantTransport.d.ts","sourceRoot":"","sources":["../../src/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/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: "crewfoundry",
|
|
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/services/createSandboxAssistantTransport.ts"],"sourcesContent":["/**\n * CrewFoundry adapter for the shared fe-libs AssistantWidget.\n *\n * The floating widget (fe-libs, Layer 1) is backend-agnostic — it calls an\n * injected `AssistantTransport`. This hook builds a transport that reuses the\n * existing sandbox `api-calls` agent: it provisions/reuses a sandbox, opens a\n * session, dispatches the prompt async, then polls for the streamed answer.\n * The agent introspects the GraphQL schema and performs API calls on the user's\n * behalf using their workspace token, contextual to the current screen (via\n * `gatherPageContext`).\n */\n\nimport { 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 './assistantApi';\nimport { gatherPageContext } from '@/utils/pageContext';\nimport type { AssistantMode } from '@/types/assistant';\n\n/**\n * Locally-defined mirror of the fe-libs `AssistantTransport` contract.\n *\n * We intentionally do NOT import the type from `@burdenoff/fe-libs` here:\n * microfe's tsconfig maps `@burdenoff/fe-libs/*` to fe-libs *source*, so\n * vite-plugin-dts would rewrite a cross-package type used in this hook's\n * public signature to a broken source-relative path in the emitted `.d.ts`.\n * Structural typing makes this shape assignable to fe-libs' `AssistantTransport`\n * at the call site (crewfoundry-app's AppShell), which is where compatibility\n * is enforced — drift there fails the app type-check.\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\n// ── Context helpers (mirror AssistantChatArea's resolution) ──────────\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\n// ── Message-progress helpers (pure; mirror AssistantChatArea) ────────\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\n/**\n * Returns a memoized `AssistantTransport` wired to the CrewFoundry sandbox\n * `api-calls` agent. The sandbox + session are cached in refs so follow-up\n * turns reuse the warm environment for the lifetime of the host shell.\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 // A stale/expired sandbox or session is recoverable — drop the warm\n // refs and retry once from a clean runtime.\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/services/createSandboxAssistantTransport.ts"],"sourcesContent":["/**\n * crewfoundry 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 '@/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: 'crewfoundry',\n gatherPageContext: gatherPageContext,\n enableCredits: true,\n });\n}\n"],"mappings":";;;AAyBA,SAAgB,IAAmD;AACjE,QAAO,EAAmB;EACxB,SAAS;EACU;EACnB,eAAe;EAChB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { RatingStars } from '../crewfoundry/components/viz/RatingStars';
|
|
3
|
+
|
|
4
|
+
declare const meta: Meta<typeof RatingStars>;
|
|
5
|
+
export default meta;
|
|
6
|
+
type Story = StoryObj<typeof meta>;
|
|
7
|
+
export declare const Default: Story;
|
|
8
|
+
export declare const WithValueAndCount: Story;
|
|
9
|
+
export declare const FullRating: Story;
|
|
10
|
+
//# sourceMappingURL=RatingStars.stories.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RatingStars.stories.d.ts","sourceRoot":"","sources":["../../src/stories/RatingStars.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,2CAA2C,CAAC;AAExE,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,WAAW,CAMlC,CAAC;AAEF,eAAe,IAAI,CAAC;AAEpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,OAAO,EAAE,KAIrB,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,KAQ/B,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,KAMxB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { SkillBar } from '../crewfoundry/components/viz/SkillBar';
|
|
3
|
+
|
|
4
|
+
declare const meta: Meta<typeof SkillBar>;
|
|
5
|
+
export default meta;
|
|
6
|
+
type Story = StoryObj<typeof meta>;
|
|
7
|
+
export declare const Default: Story;
|
|
8
|
+
export declare const WithLevelLabel: Story;
|
|
9
|
+
export declare const LowProficiency: Story;
|
|
10
|
+
//# sourceMappingURL=SkillBar.stories.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SkillBar.stories.d.ts","sourceRoot":"","sources":["../../src/stories/SkillBar.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,wCAAwC,CAAC;AAElE,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,QAAQ,CAM/B,CAAC;AAEF,eAAe,IAAI,CAAC;AAEpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,OAAO,EAAE,KAMrB,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,KAM5B,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,KAO5B,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { StatCard } from '../crewfoundry/components/viz/StatCard';
|
|
3
|
+
|
|
4
|
+
declare const meta: Meta<typeof StatCard>;
|
|
5
|
+
export default meta;
|
|
6
|
+
type Story = StoryObj<typeof meta>;
|
|
7
|
+
export declare const Default: Story;
|
|
8
|
+
export declare const WithDelta: Story;
|
|
9
|
+
export declare const WithSparkline: Story;
|
|
10
|
+
//# sourceMappingURL=StatCard.stories.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StatCard.stories.d.ts","sourceRoot":"","sources":["../../src/stories/StatCard.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,QAAQ,EAAE,MAAM,wCAAwC,CAAC;AAElE,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,QAAQ,CAM/B,CAAC;AAEF,eAAe,IAAI,CAAC;AAEpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,OAAO,EAAE,KAMrB,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,KASvB,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,KAW3B,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@burdenoff/microfe-crewfoundry",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.716.1",
|
|
4
4
|
"description": "Burdenoff CrewFoundry Microfrontend",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -40,11 +40,14 @@
|
|
|
40
40
|
"switch:local": "bun scripts/deps-mode.ts local",
|
|
41
41
|
"switch:check": "bun scripts/deps-mode.ts check",
|
|
42
42
|
"prepare": "lefthook install || true",
|
|
43
|
-
"format:check": "prettier --check \"src/**/*.{ts,tsx}\""
|
|
43
|
+
"format:check": "prettier --check \"src/**/*.{ts,tsx}\"",
|
|
44
|
+
"storybook": "storybook dev -p 6006",
|
|
45
|
+
"build-storybook": "storybook build",
|
|
46
|
+
"test:storybook": "test-storybook"
|
|
44
47
|
},
|
|
45
48
|
"dependencies": {
|
|
46
49
|
"@apollo/client": "^4.0.11",
|
|
47
|
-
"@burdenoff/fe-libs": "2026.
|
|
50
|
+
"@burdenoff/fe-libs": "2026.713.6",
|
|
48
51
|
"@tanstack/react-query": "^5.90.16",
|
|
49
52
|
"clsx": "^2.1.1",
|
|
50
53
|
"graphql": "^16.10.0",
|
|
@@ -81,7 +84,15 @@
|
|
|
81
84
|
"typescript": "^5.9.0",
|
|
82
85
|
"typescript-eslint": "^8.54.0",
|
|
83
86
|
"vite": "8.0.8",
|
|
84
|
-
"vite-plugin-dts": "3.9.1"
|
|
87
|
+
"vite-plugin-dts": "3.9.1",
|
|
88
|
+
"@storybook/addon-essentials": "^8.6.0",
|
|
89
|
+
"@storybook/addon-interactions": "^8.6.0",
|
|
90
|
+
"@storybook/react": "^8.6.0",
|
|
91
|
+
"@storybook/react-vite": "^8.6.0",
|
|
92
|
+
"@storybook/test": "^8.6.0",
|
|
93
|
+
"@storybook/test-runner": "0.22.0",
|
|
94
|
+
"@tailwindcss/vite": "^4.3.2",
|
|
95
|
+
"storybook": "^8.6.0"
|
|
85
96
|
},
|
|
86
97
|
"peerDependencies": {
|
|
87
98
|
"@apollo/client": "^4.0.11",
|
|
@@ -1,75 +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 getAssistantSession(apollo: ApolloClient, sandboxId: string, workspaceId: string, sessionId: string, authContext?: AssistantSandboxAuthContext): Promise<AssistantSessionInfo>;
|
|
64
|
-
export declare function sendAssistantPrompt(apollo: ApolloClient, sandboxId: string, workspaceId: string, sessionId: string, prompt: string, mode: AssistantMode, pageContext?: PageContext, authContext?: AssistantSandboxAuthContext): Promise<AssistantPromptResult>;
|
|
65
|
-
export declare function sendAssistantPromptAsync(apollo: ApolloClient, sandboxId: string, workspaceId: string, sessionId: string, prompt: string, mode: AssistantMode, pageContext?: PageContext, authContext?: AssistantSandboxAuthContext): Promise<void>;
|
|
66
|
-
export declare function getAssistantMessages(apollo: ApolloClient, sandboxId: string, workspaceId: string, sessionId: string, authContext?: AssistantSandboxAuthContext, limit?: number): Promise<AssistantRawMessage[]>;
|
|
67
|
-
export declare function checkAssistantAiCredits(_apollo: ApolloClient, workspaceId: string, authContext?: AssistantSandboxAuthContext): Promise<boolean>;
|
|
68
|
-
export declare function reportAssistantAiTokenUsage(_apollo: ApolloClient, workspaceId: string, sessionId: string, messageId: string, model: string | undefined, tokens: {
|
|
69
|
-
input: number;
|
|
70
|
-
output: number;
|
|
71
|
-
}, authContext?: AssistantSandboxAuthContext): Promise<void>;
|
|
72
|
-
export declare function getAssistantArtifacts(apollo: ApolloClient, sandboxId: string, workspaceId: string, sessionId: string, authContext?: AssistantSandboxAuthContext): Promise<AssistantArtifact[]>;
|
|
73
|
-
export declare function downloadAssistantArtifact(apollo: ApolloClient, sandboxId: string, workspaceId: string, sessionId: string, artifactPath: string, authContext?: AssistantSandboxAuthContext): Promise<DownloadedAssistantArtifact>;
|
|
74
|
-
export declare function extendAssistantSandboxTTL(_apollo: ApolloClient, sandboxId: string, workspaceId: string, additionalSeconds?: number, authContext?: AssistantSandboxAuthContext): Promise<void>;
|
|
75
|
-
//# sourceMappingURL=assistantApi.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"assistantApi.d.ts","sourceRoot":"","sources":["../../src/services/assistantApi.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,273 +0,0 @@
|
|
|
1
|
-
import { print as e } from "graphql";
|
|
2
|
-
import { gql as t } from "@apollo/client";
|
|
3
|
-
//#region src/services/assistantApi.ts
|
|
4
|
-
var n = "burdenoffregistry.azurecr.io", r = "alpha", i = "alpha-delegated-auth-v11", a = "sandbox-app-client-headers-v1";
|
|
5
|
-
function o(e) {
|
|
6
|
-
switch (e) {
|
|
7
|
-
case "general": return r;
|
|
8
|
-
case "assistant":
|
|
9
|
-
case "api-calls": return i;
|
|
10
|
-
default: return i;
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
function s(e) {
|
|
14
|
-
return `${n}/wspace/ai-assistant-${e === "assistant" ? "api-calls" : e}:${o(e)}`;
|
|
15
|
-
}
|
|
16
|
-
function c(e) {
|
|
17
|
-
switch (e) {
|
|
18
|
-
case "general": return {
|
|
19
|
-
cpuRequest: "100m",
|
|
20
|
-
cpuLimit: "500m",
|
|
21
|
-
memoryRequest: "256Mi",
|
|
22
|
-
memoryLimit: "1Gi"
|
|
23
|
-
};
|
|
24
|
-
case "assistant":
|
|
25
|
-
case "api-calls": return {
|
|
26
|
-
cpuRequest: "150m",
|
|
27
|
-
cpuLimit: "750m",
|
|
28
|
-
memoryRequest: "384Mi",
|
|
29
|
-
memoryLimit: "1536Mi"
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
function l(e) {
|
|
34
|
-
let t = e.metadata?.assistantMode;
|
|
35
|
-
if (t === "assistant" || t === "general" || t === "api-calls") return t;
|
|
36
|
-
let n = e.name ?? "";
|
|
37
|
-
return n.startsWith("ai-assistant-api-calls-") ? "api-calls" : n.startsWith("ai-assistant-general-") ? "general" : n.startsWith("ai-assistant-assistant-") ? "assistant" : null;
|
|
38
|
-
}
|
|
39
|
-
var u = t`
|
|
40
|
-
mutation CreateSandbox($input: CreateSandboxInput!) {
|
|
41
|
-
createSandbox(input: $input) {
|
|
42
|
-
id
|
|
43
|
-
name
|
|
44
|
-
status
|
|
45
|
-
network {
|
|
46
|
-
internalUrl
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
`, d = t`
|
|
51
|
-
query GetSandbox($id: ID!, $context: ContextInput!) {
|
|
52
|
-
getSandbox(id: $id, context: $context) {
|
|
53
|
-
id
|
|
54
|
-
status
|
|
55
|
-
errorMessage
|
|
56
|
-
network {
|
|
57
|
-
internalUrl
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
`, f = t`
|
|
62
|
-
query GetActiveSandboxes($context: ContextInput!) {
|
|
63
|
-
getActiveSandboxes(context: $context) {
|
|
64
|
-
id
|
|
65
|
-
name
|
|
66
|
-
status
|
|
67
|
-
metadata
|
|
68
|
-
template
|
|
69
|
-
createdBy
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
`, p = t`
|
|
73
|
-
mutation ProxySandboxRequest($input: ProxySandboxRequestInput!) {
|
|
74
|
-
proxySandboxRequest(input: $input) {
|
|
75
|
-
status
|
|
76
|
-
body
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
`, m = t`
|
|
80
|
-
mutation ExtendSandboxTtl($id: ID!, $additionalSeconds: Int!, $context: ContextInput!) {
|
|
81
|
-
extendSandboxTTL(id: $id, additionalSeconds: $additionalSeconds, context: $context) {
|
|
82
|
-
id
|
|
83
|
-
expiresAt
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
`;
|
|
87
|
-
t`
|
|
88
|
-
mutation CheckAiCredits {
|
|
89
|
-
checkAiCredits
|
|
90
|
-
}
|
|
91
|
-
`, t`
|
|
92
|
-
mutation ReportAiTokenUsage($input: ReportAiTokenUsageInput!) {
|
|
93
|
-
reportAiTokenUsage(input: $input)
|
|
94
|
-
}
|
|
95
|
-
`;
|
|
96
|
-
function h(e, t) {
|
|
97
|
-
let n = {};
|
|
98
|
-
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;
|
|
99
|
-
}
|
|
100
|
-
function g(e, t) {
|
|
101
|
-
return {
|
|
102
|
-
workspaceId: e,
|
|
103
|
-
...t?.organizationId ? { custom: { organizationId: t.organizationId } } : {}
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
async function _(t) {
|
|
107
|
-
let n = await fetch("/workspaces/graphql", {
|
|
108
|
-
method: "POST",
|
|
109
|
-
headers: {
|
|
110
|
-
"Content-Type": "application/json",
|
|
111
|
-
...h(t.workspaceId, t.authContext)?.headers ?? {}
|
|
112
|
-
},
|
|
113
|
-
body: JSON.stringify({
|
|
114
|
-
query: e(t.document),
|
|
115
|
-
variables: t.variables
|
|
116
|
-
})
|
|
117
|
-
}), r = await n.json().catch(() => null);
|
|
118
|
-
if (!n.ok) {
|
|
119
|
-
let e = r?.errors?.map((e) => e.message).join(", "), t = Error(e || `Sandbox GraphQL HTTP ${n.status}`);
|
|
120
|
-
throw t.statusCode = n.status, t.result = r ?? void 0, t;
|
|
121
|
-
}
|
|
122
|
-
if (!r) throw Error("Sandbox GraphQL returned empty response");
|
|
123
|
-
if (r.errors?.length) throw Error(r.errors.map((e) => e.message).join(", "));
|
|
124
|
-
if (!r.data) throw Error("Sandbox GraphQL returned no data");
|
|
125
|
-
return r.data;
|
|
126
|
-
}
|
|
127
|
-
async function v(e, t, n, r) {
|
|
128
|
-
return ((await _({
|
|
129
|
-
document: f,
|
|
130
|
-
variables: { context: g(t, r) },
|
|
131
|
-
workspaceId: t,
|
|
132
|
-
authContext: r
|
|
133
|
-
})).getActiveSandboxes ?? []).find((e) => (e.status === "RUNNING" || e.status === "PROVISIONING" || e.status === "PENDING") && e.template === "AI_BUILDER" && l(e) === n && (!r?.userId || e.createdBy === r.userId) && e.metadata?.authStrategy === a && e.metadata?.imageTag === o(n))?.id ?? null;
|
|
134
|
-
}
|
|
135
|
-
async function y(e, t, n, r) {
|
|
136
|
-
let i = c(t), l = [
|
|
137
|
-
{
|
|
138
|
-
name: "AI_ASSISTANT_MODE",
|
|
139
|
-
value: t
|
|
140
|
-
},
|
|
141
|
-
{
|
|
142
|
-
name: "HOSTNAME",
|
|
143
|
-
value: "0.0.0.0"
|
|
144
|
-
},
|
|
145
|
-
{
|
|
146
|
-
name: "WORKSPACE_ID",
|
|
147
|
-
value: n
|
|
148
|
-
},
|
|
149
|
-
{
|
|
150
|
-
name: "AI_ASSISTANT_PRODUCT",
|
|
151
|
-
value: "crewfoundry"
|
|
152
|
-
}
|
|
153
|
-
], d = await _({
|
|
154
|
-
document: u,
|
|
155
|
-
variables: { input: {
|
|
156
|
-
name: `ai-assistant-${t}-${Date.now()}`,
|
|
157
|
-
description: `CrewFoundry AI Assistant sandbox (${t} mode)`,
|
|
158
|
-
template: "AI_BUILDER",
|
|
159
|
-
mode: "DEPLOYMENT",
|
|
160
|
-
containers: [{
|
|
161
|
-
name: "ai-assistant",
|
|
162
|
-
image: s(t),
|
|
163
|
-
ports: [{
|
|
164
|
-
containerPort: 8080,
|
|
165
|
-
name: "http"
|
|
166
|
-
}],
|
|
167
|
-
env: l
|
|
168
|
-
}],
|
|
169
|
-
resources: {
|
|
170
|
-
cpuRequest: i.cpuRequest,
|
|
171
|
-
cpuLimit: i.cpuLimit,
|
|
172
|
-
memoryRequest: i.memoryRequest,
|
|
173
|
-
memoryLimit: i.memoryLimit
|
|
174
|
-
},
|
|
175
|
-
ttlSeconds: 600,
|
|
176
|
-
metadata: {
|
|
177
|
-
assistantMode: t,
|
|
178
|
-
assistantOwnerUserId: r?.userId ?? null,
|
|
179
|
-
assistantOrganizationId: r?.organizationId ?? null,
|
|
180
|
-
authStrategy: a,
|
|
181
|
-
imageTag: o(t)
|
|
182
|
-
},
|
|
183
|
-
context: g(n, r)
|
|
184
|
-
} },
|
|
185
|
-
workspaceId: n,
|
|
186
|
-
authContext: r
|
|
187
|
-
});
|
|
188
|
-
if (!d?.createSandbox?.id) throw Error("createSandbox returned empty response");
|
|
189
|
-
return d.createSandbox.id;
|
|
190
|
-
}
|
|
191
|
-
async function b(e, t, n, r, i = 3e5, a) {
|
|
192
|
-
let o = Date.now();
|
|
193
|
-
for (; Date.now() - o < i;) {
|
|
194
|
-
let e = await _({
|
|
195
|
-
document: d,
|
|
196
|
-
variables: {
|
|
197
|
-
id: t,
|
|
198
|
-
context: g(n, r)
|
|
199
|
-
},
|
|
200
|
-
workspaceId: n,
|
|
201
|
-
authContext: r
|
|
202
|
-
}), i = e?.getSandbox?.status, s = e?.getSandbox?.errorMessage;
|
|
203
|
-
if (i === "RUNNING") return;
|
|
204
|
-
if (i === "FAILED" || i === "STOPPED" || i === "EXPIRED") throw Error(s ? `Sandbox ${i.toLowerCase()}: ${s}` : `Sandbox ${i.toLowerCase()}`);
|
|
205
|
-
let c = Math.max(1, Math.round((Date.now() - o) / 1e3));
|
|
206
|
-
a?.(`Starting assistant environment... (${c}s)`), await new Promise((e) => setTimeout(e, 2e3));
|
|
207
|
-
}
|
|
208
|
-
throw Error("Sandbox startup timed out");
|
|
209
|
-
}
|
|
210
|
-
async function x(e, t, n, r, i, a, o) {
|
|
211
|
-
let s = (await _({
|
|
212
|
-
document: p,
|
|
213
|
-
variables: { input: {
|
|
214
|
-
sandboxId: t,
|
|
215
|
-
path: r,
|
|
216
|
-
method: i,
|
|
217
|
-
body: a,
|
|
218
|
-
context: g(n, o)
|
|
219
|
-
} },
|
|
220
|
-
workspaceId: n,
|
|
221
|
-
authContext: o
|
|
222
|
-
})).proxySandboxRequest;
|
|
223
|
-
if (!s || s.status >= 400) {
|
|
224
|
-
let e = s?.body;
|
|
225
|
-
throw Error(e?.error ?? `Proxy error: ${s?.status ?? "unknown"}`);
|
|
226
|
-
}
|
|
227
|
-
return s.body;
|
|
228
|
-
}
|
|
229
|
-
async function S(e, t, n, r, i = 9e4, a) {
|
|
230
|
-
let o = Date.now();
|
|
231
|
-
for (; Date.now() - o < i;) {
|
|
232
|
-
try {
|
|
233
|
-
await x(e, t, n, "/health", "GET", void 0, r);
|
|
234
|
-
return;
|
|
235
|
-
} catch (e) {
|
|
236
|
-
let t = e instanceof Error ? e.message : String(e);
|
|
237
|
-
if (!/proxy error: 502|proxy error: 503|proxy error: 404|service not available/i.test(t)) throw e;
|
|
238
|
-
}
|
|
239
|
-
let i = Math.max(1, Math.round((Date.now() - o) / 1e3));
|
|
240
|
-
a?.(`Connecting to assistant... (${i}s)`), await new Promise((e) => setTimeout(e, 2e3));
|
|
241
|
-
}
|
|
242
|
-
throw Error("Assistant service did not become healthy before timeout");
|
|
243
|
-
}
|
|
244
|
-
async function C(e, t, n, r, i) {
|
|
245
|
-
return { sessionId: (await x(e, t, n, "/sessions", "POST", { mode: r }, i)).session.id };
|
|
246
|
-
}
|
|
247
|
-
async function w(e, t, n, r, i, a, o, s) {
|
|
248
|
-
let c = {
|
|
249
|
-
mode: a,
|
|
250
|
-
prompt: i,
|
|
251
|
-
pageContext: o ?? void 0
|
|
252
|
-
};
|
|
253
|
-
await x(e, t, n, `/sessions/${r}/prompt-async`, "POST", c, s);
|
|
254
|
-
}
|
|
255
|
-
async function T(e, t, n, r, i, a = 50) {
|
|
256
|
-
return (await x(e, t, n, `/sessions/${r}/messages?limit=${a}`, "GET", void 0, i)).messages ?? [];
|
|
257
|
-
}
|
|
258
|
-
async function E(e, t, n, r = 600, i) {
|
|
259
|
-
await _({
|
|
260
|
-
document: m,
|
|
261
|
-
variables: {
|
|
262
|
-
id: t,
|
|
263
|
-
additionalSeconds: r,
|
|
264
|
-
context: g(n, i)
|
|
265
|
-
},
|
|
266
|
-
workspaceId: n,
|
|
267
|
-
authContext: i
|
|
268
|
-
});
|
|
269
|
-
}
|
|
270
|
-
//#endregion
|
|
271
|
-
export { y as createAssistantSandbox, C as createAssistantSession, E as extendAssistantSandboxTTL, v as findExistingSandbox, T as getAssistantMessages, w as sendAssistantPromptAsync, S as waitForAssistantServiceReady, b as waitForSandboxReady };
|
|
272
|
-
|
|
273
|
-
//# sourceMappingURL=assistantApi.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"assistantApi.js","names":[],"sources":["../../src/services/assistantApi.ts"],"sourcesContent":["/**\n * AI Assistant API service for CrewFoundry.\n *\n * All requests go through the wspace-public-gateway (GraphQL Federation):\n * Frontend → wspace-public-gateway → wspace-sandbox-svc → ai-assistant\n *\n * Uses the host app's Apollo Client which already points to the gateway.\n */\n\nimport { type ApolloClient } from '@apollo/client';\nimport { print } from 'graphql';\nimport { gql } from '@apollo/client';\nimport type { AssistantArtifact, AssistantMode } from '@/types/assistant';\nimport type { PageContext } from '@/utils/pageContext';\n\n// ── Image registry ─────────────────────────────────────────────────\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\nfunction getImageTagForMode(mode: AssistantMode): string {\n switch (mode) {\n case 'general':\n return DEFAULT_IMAGE_TAG;\n case 'assistant':\n case 'api-calls':\n return API_CALLS_IMAGE_TAG;\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 'general':\n return {\n cpuRequest: '100m',\n cpuLimit: '500m',\n memoryRequest: '256Mi',\n memoryLimit: '1Gi',\n };\n case 'assistant':\n case 'api-calls':\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 === 'general' || 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-general-')) return 'general';\n if (name.startsWith('ai-assistant-assistant-')) return 'assistant';\n return null;\n}\n\n// ── GraphQL operations (inline so the MFE does not depend on generated files) ──\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\nconst CheckAiCreditsDocument = gql`\n mutation CheckAiCredits {\n checkAiCredits\n }\n`;\n\nconst ReportAiTokenUsageDocument = gql`\n mutation ReportAiTokenUsage($input: ReportAiTokenUsageInput!) {\n reportAiTokenUsage(input: $input)\n }\n`;\n\n// ── Types ───────────────────────────────────────────────────────────\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: ReturnType<typeof gql>;\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\n// ── Find existing sandbox for a mode ───────────────────────────────\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\n// ── Sandbox lifecycle ──────────────────────────────────────────────\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: 'crewfoundry' },\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: `CrewFoundry 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\n// ── Proxy calls to ai-assistant (via gateway → sandbox-svc) ───────\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\n// ── Session management ─────────────────────────────────────────────\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 getAssistantSession(\n apollo: ApolloClient,\n sandboxId: string,\n workspaceId: string,\n sessionId: string,\n authContext?: AssistantSandboxAuthContext\n): Promise<AssistantSessionInfo> {\n const body = await proxyToSandbox(\n apollo,\n sandboxId,\n workspaceId,\n `/sessions/${sessionId}`,\n 'GET',\n undefined,\n authContext\n );\n const session = body.session as Record<string, unknown> | undefined;\n\n return {\n id: (session?.id as string | undefined) ?? sessionId,\n mode: (body.mode as string | undefined) ?? 'unknown',\n };\n}\n\n// ── Send prompt ────────────────────────────────────────────────────\n\nexport async function sendAssistantPrompt(\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<AssistantPromptResult> {\n const requestBody = {\n mode,\n prompt,\n pageContext: pageContext\n ? {\n currentUrl: pageContext.currentUrl,\n currentPage: pageContext.currentPage,\n entityType: pageContext.entityType,\n entityId: pageContext.entityId,\n platform: pageContext.platform,\n version: pageContext.version,\n viewportSize: pageContext.viewportSize,\n }\n : undefined,\n };\n\n const body = await proxyToSandbox(\n apollo,\n sandboxId,\n workspaceId,\n `/sessions/${sessionId}/prompt`,\n 'POST',\n requestBody,\n authContext\n );\n\n const message = body.message as Record<string, unknown> | undefined;\n const tokens = message?.tokens as { input: number; output: number } | undefined;\n\n return { response: body.text as string, tokens };\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\n// ── AI credits (per-token metering) ────────────────────────────────\n\nexport async function checkAssistantAiCredits(\n _apollo: ApolloClient,\n workspaceId: string,\n authContext?: AssistantSandboxAuthContext\n): Promise<boolean> {\n const data = await executeSandboxGraphQL<{ checkAiCredits: boolean }>({\n document: CheckAiCreditsDocument,\n variables: {},\n workspaceId,\n authContext,\n });\n return data.checkAiCredits;\n}\n\nexport async function reportAssistantAiTokenUsage(\n _apollo: ApolloClient,\n workspaceId: string,\n sessionId: string,\n messageId: string,\n model: string | undefined,\n tokens: { input: number; output: number },\n authContext?: AssistantSandboxAuthContext\n): Promise<void> {\n const inputTokens = Math.max(0, Math.round(tokens.input ?? 0));\n const outputTokens = Math.max(0, Math.round(tokens.output ?? 0));\n if (inputTokens + outputTokens === 0) return;\n if (!model) return;\n\n await executeSandboxGraphQL<{ reportAiTokenUsage: boolean }>({\n document: ReportAiTokenUsageDocument,\n variables: {\n input: { sessionId, messageId, model, inputTokens, outputTokens },\n },\n workspaceId,\n authContext,\n });\n}\n\nexport async function getAssistantArtifacts(\n apollo: ApolloClient,\n sandboxId: string,\n workspaceId: string,\n sessionId: string,\n authContext?: AssistantSandboxAuthContext\n): Promise<AssistantArtifact[]> {\n const body = await proxyToSandbox(\n apollo,\n sandboxId,\n workspaceId,\n `/sessions/${sessionId}/artifacts`,\n 'GET',\n undefined,\n authContext\n );\n\n return ((body.artifacts as AssistantArtifact[] | undefined) ?? []).filter(\n (artifact) => !artifact.name.startsWith('.')\n );\n}\n\nexport async function downloadAssistantArtifact(\n apollo: ApolloClient,\n sandboxId: string,\n workspaceId: string,\n sessionId: string,\n artifactPath: string,\n authContext?: AssistantSandboxAuthContext\n): Promise<DownloadedAssistantArtifact> {\n const encodedPath = encodeURIComponent(artifactPath);\n const body = await proxyToSandbox(\n apollo,\n sandboxId,\n workspaceId,\n `/sessions/${sessionId}/artifacts/download?path=${encodedPath}`,\n 'GET',\n undefined,\n authContext\n );\n\n const artifact = body.artifact as Record<string, unknown> | undefined;\n if (!artifact) {\n throw new Error('Artifact download returned an empty response');\n }\n\n return {\n filename: artifact.filename as string,\n mimeType: artifact.mimeType as string,\n contentBase64: artifact.contentBase64 as string,\n };\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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"}
|