@burdenoff/microfe-vibecontrols 2026.515.4 → 2026.515.5

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.
@@ -6,15 +6,15 @@ import { AssistantMessageList as p } from "./AssistantMessageList.js";
6
6
  import { AssistantModeSelector as m } from "./AssistantModeSelector.js";
7
7
  import { AssistantWelcome as h } from "./AssistantWelcome.js";
8
8
  import { gatherPageContext as ee } from "../../utils/pageContext.js";
9
- import { useCallback as g, useEffect as _, useRef as te } from "react";
10
- import { useGatewayClient as ne } from "@burdenoff/fe-libs/shared/graphql";
11
- import { useAuthToken as re } from "@burdenoff/fe-libs/shared/providers/shell";
12
- import { jsx as v, jsxs as y } from "react/jsx-runtime";
9
+ import { useCallback as g, useEffect as _, useRef as v } from "react";
10
+ import { useGatewayClient as y } from "@burdenoff/fe-libs/shared/graphql";
11
+ import { useAuthToken as b } from "@burdenoff/fe-libs/shared/providers/shell";
12
+ import { jsx as x, jsxs as S } from "react/jsx-runtime";
13
13
  //#region src/components/assistant/AssistantChatArea.tsx
14
- function b() {
14
+ function C() {
15
15
  return `${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
16
16
  }
17
- function x(e) {
17
+ function w(e) {
18
18
  try {
19
19
  let t = e === "workspaceId" ? "burdenoff-active-context-workspace" : "burdenoff-active-context-organization", n = localStorage.getItem(t);
20
20
  if (n) return n;
@@ -26,13 +26,13 @@ function x(e) {
26
26
  return "";
27
27
  }
28
28
  }
29
- function S() {
30
- return new URLSearchParams(window.location.search).get("workspace") ?? x("workspaceId");
29
+ function te() {
30
+ return new URLSearchParams(window.location.search).get("workspace") ?? w("workspaceId");
31
31
  }
32
- function C() {
33
- return new URLSearchParams(window.location.search).get("org") ?? x("organizationId");
32
+ function ne() {
33
+ return new URLSearchParams(window.location.search).get("org") ?? w("organizationId");
34
34
  }
35
- function ie(e) {
35
+ function re(e) {
36
36
  let t = e instanceof Error ? e.message.toLowerCase() : String(e).toLowerCase();
37
37
  return t.includes("rate limit exceeded") || t.includes("unauthorized") || t.includes("k8s api error 401") ? !1 : [
38
38
  "sandbox not found",
@@ -47,22 +47,9 @@ function ie(e) {
47
47
  "session mode mismatch"
48
48
  ].some((e) => t.includes(e));
49
49
  }
50
- function w(e) {
50
+ function T(e) {
51
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
52
  }
53
- var T = {
54
- action: "An Action is a reusable operation VibeControls can run against a target, vibe, session, or automation flow. Create one from VibeControls > Actions, choose the action type, configure the inputs and permissions, then save and run it from the relevant page.",
55
- component: "A Component represents a software unit such as a service, frontend, library, API, database, or infrastructure asset. Add one from VibeControls > Components, fill in the metadata, lifecycle, owner, language/framework, and tags, then attach it to catalogs or vibes as needed.",
56
- vibe: "A Vibe is a workspace project/repository context managed by VibeControls. Create one from VibeControls > Vibes, select the type and path, optionally attach an agent, then use its detail tabs for sessions, docs, catalogs, GitOps, and related resources.",
57
- session: "A Session is a managed terminal/workflow runtime connected to an agent. Open VibeControls > Sessions, create or start a session, then use terminal tabs to interact with it, share it, restart it, or bookmark a specific session tab from the URL.",
58
- target: "A Target is a machine or runtime endpoint that an agent can manage. Register or inspect targets from VibeControls > Targets & Agents, then use them for sessions, actions, tunnels, and vibe operations."
59
- };
60
- function ae(e) {
61
- let t = e.toLowerCase();
62
- if (!t.includes("vibecontrols") && !t.includes("vibe controls")) return null;
63
- let n = Object.keys(T).find((e) => RegExp(`\\b${e}s?\\b`).test(t));
64
- return n ? T[n] ?? null : null;
65
- }
66
53
  function E(e) {
67
54
  return e.info?.time?.created ?? 0;
68
55
  }
@@ -88,7 +75,7 @@ function k(e, t) {
88
75
  tokens: r.info?.tokens
89
76
  };
90
77
  }
91
- function oe(e) {
78
+ function A(e) {
92
79
  switch (e) {
93
80
  case "provisioning": return "Starting assistant environment...";
94
81
  case "connecting": return "Connecting to assistant...";
@@ -96,138 +83,67 @@ function oe(e) {
96
83
  default: return "";
97
84
  }
98
85
  }
99
- function se(e) {
100
- let t = e.toLowerCase();
101
- return t.includes("workspace") && (t.includes("access") || t.includes("authorized") || t.includes("list"));
102
- }
103
- function ce(e) {
104
- let t = e.toLowerCase();
105
- return t.includes("what api calls") || t.includes("what can you do") || t.includes("which api calls");
106
- }
107
- function le(e) {
108
- let t = e.toLowerCase();
109
- return t.includes("what is my name") || t.includes("my profile name");
110
- }
111
- function ue(e) {
112
- return e.match(/create\s+a\s+target\s+named\s+(.+)/i)?.[1]?.trim() ?? null;
113
- }
114
- function de() {
115
- try {
116
- let e = sessionStorage.getItem("bf-active-profile");
117
- if (!e) return {};
118
- let t = localStorage.getItem(`bf-p-${e}-user`);
119
- if (!t) return {};
120
- let n = JSON.parse(t);
121
- return {
122
- name: n.name || n.username || n.firstName,
123
- email: n.email
124
- };
125
- } catch {
126
- return {};
127
- }
128
- }
129
- function A(e) {
130
- return e.toLowerCase().trim() === "what can you do";
131
- }
132
86
  var j = () => {
133
- let x = e(), T = ne("workspace"), { getAccessToken: E, getWorkspaceToken: D, userId: O } = re(), { conversations: j, activeConversationId: M, mode: N, processingByConversationId: P, setMode: F, setConversationMode: I, setActiveConversation: L, createConversation: R, addMessage: z, updateMessage: B, patchMessage: V, setConversationProcessing: H, clearConversationProcessing: fe, setBackendSessionId: U, clearBackendSessionId: W, setSandbox: G, clearSandbox: K } = t(), q = j.find((e) => e.id === M)?.messages ?? [], J = M ? P[M] : void 0, pe = J?.messageId ?? null, me = J?.status === "provisioning" || J?.status === "connecting" || J?.status === "streaming", Y = g((e, t, n, r) => {
134
- H(e, n, t, null), r ? B(e, t, r) : B(e, t, oe(n));
135
- }, [H, B]), he = g(async (e) => {
136
- if (se(e)) {
137
- let e = S(), t = C();
138
- if (!e) return "No authorized workspace is attached to this assistant session yet.";
139
- let n = t ? `https://api.${t}.burdenoff.com/workspaces/graphql` : "";
140
- return `This assistant sandbox is authorized for 1 workspace:\n\n1. Current active workspace — ${e}${n ? `\n Public URL: ${n}` : ""}`;
141
- }
142
- if (le(e)) {
143
- let e = de();
144
- return !e.name && !e.email ? "I could not determine your profile name from the local session." : [e.name ? `Your profile name is ${e.name}.` : "", e.email ? `Your profile email is ${e.email}.` : ""].filter(Boolean).join("\n");
145
- }
146
- let t = ue(e);
147
- return t ? [
148
- `I can create the target "${t}", but I still need the target connection details before I can execute the mutation.`,
149
- "",
150
- "Please provide at least:",
151
- "- target type (SSH, RDP, VNC, or DIRECT)",
152
- "- host or IP address",
153
- "- port if it is not the default for that protocol",
154
- "- any credentials or auth method the target requires",
155
- "",
156
- `For example: create a target named ${t} using SSH at 10.0.0.15:22 with username ubuntu.`
157
- ].join("\n") : ce(e) ? [
158
- "I can query or mutate both Burdenoff GraphQL gateways on your behalf:",
159
- "",
160
- "- Global gateway: organizations, workspaces, apps, billing, notifications, store, support, and dev portal operations",
161
- "- Workspace gateway: workspace-scoped modules like vibecontrols, files, tags, conversations, calendar, sandbox, and related resources",
162
- "",
163
- "Ask me for a specific action like listing your workspaces, fetching a resource, or creating/updating something through the APIs."
164
- ].join("\n") : null;
165
- }, []), X = g(async (e, t) => e === "api-calls" ? he(t) : e === "general" && A(t) ? [
166
- "I can help explain VibeControls concepts, navigation, sessions, targets, tunnels, and platform workflows.",
167
- "",
168
- "I can also guide you through the UI, describe features, and help you understand how different parts of the product fit together."
169
- ].join("\n") : e === "vibe-plugins" && A(t) ? [
170
- "I can help design, generate, explain, and package Vibe Plugins.",
171
- "",
172
- "I can create plugin scaffolds, explain manifests and lifecycle hooks, and provide downloadable plugin artifacts for this session."
173
- ].join("\n") : ae(t) || null, [he]), Z = g(async (e, i, o, s, l) => {
87
+ let w = e(), E = y("workspace"), { getAccessToken: D, getWorkspaceToken: O, userId: j } = b(), { conversations: M, activeConversationId: N, mode: P, processingByConversationId: F, setMode: I, setConversationMode: L, setActiveConversation: R, createConversation: z, addMessage: B, updateMessage: V, patchMessage: H, setConversationProcessing: U, clearConversationProcessing: ie, setBackendSessionId: W, clearBackendSessionId: G, setSandbox: K, clearSandbox: q } = t(), J = M.find((e) => e.id === N)?.messages ?? [], Y = N ? F[N] : void 0, ae = Y?.messageId ?? null, oe = Y?.status === "provisioning" || Y?.status === "connecting" || Y?.status === "streaming", X = g((e, t, n, r) => {
88
+ U(e, n, t, null), r ? V(e, t, r) : V(e, t, A(n));
89
+ }, [U, V]), Z = g(async (e, i, o, s, l) => {
174
90
  let f = t.getState().sandboxesByMode[o]?.sandboxId ?? null;
175
91
  if (!f) {
176
- Y(e, i, "provisioning", "Looking for existing environment...");
177
- let t = await a(T, s, o, l);
178
- if (t) f = t, G(o, f, "provisioning"), Y(e, i, "provisioning", "Reusing assistant environment..."), await d(T, f, s, l, 3e5, (t) => Y(e, i, "provisioning", t)), await u(T, f, s, l, 9e4, (t) => Y(e, i, "connecting", t)), G(o, f, "running");
92
+ X(e, i, "provisioning", "Looking for existing environment...");
93
+ let t = await a(E, s, o, l);
94
+ if (t) f = t, K(o, f, "provisioning"), X(e, i, "provisioning", "Reusing assistant environment..."), await d(E, f, s, l, 3e5, (t) => X(e, i, "provisioning", t)), await u(E, f, s, l, 9e4, (t) => X(e, i, "connecting", t)), K(o, f, "running");
179
95
  else {
180
- if (o === "api-calls" && !E()) throw Error("API Calls mode requires an authenticated session. Please sign in again.");
181
- Y(e, i, "provisioning", "Starting assistant environment..."), G(o, null, "provisioning"), f = await n(T, o, s, l), G(o, f, "provisioning"), await d(T, f, s, l, 3e5, (t) => Y(e, i, "provisioning", t)), await u(T, f, s, l, 9e4, (t) => Y(e, i, "connecting", t)), G(o, f, "running");
96
+ if (o === "api-calls" && !D()) throw Error("API Calls mode requires an authenticated session. Please sign in again.");
97
+ X(e, i, "provisioning", "Starting assistant environment..."), K(o, null, "provisioning"), f = await n(E, o, s, l), K(o, f, "provisioning"), await d(E, f, s, l, 3e5, (t) => X(e, i, "provisioning", t)), await u(E, f, s, l, 9e4, (t) => X(e, i, "connecting", t)), K(o, f, "running");
182
98
  }
183
99
  }
184
100
  let p = t.getState().conversations.find((t) => t.id === e)?.backendSessionId ?? null;
185
101
  if (p) try {
186
- let e = await c(T, f, s, p, l);
102
+ let e = await c(E, f, s, p, l);
187
103
  if (e.mode !== o) throw Error(`Session mode mismatch: expected ${o}, received ${e.mode}`);
188
104
  } catch {
189
- W(e), p = null;
105
+ G(e), p = null;
190
106
  }
191
- return p || (Y(e, i, "connecting", "Preparing session..."), p = (await r(T, f, s, o, l)).sessionId, U(e, p)), {
107
+ return p || (X(e, i, "connecting", "Preparing session..."), p = (await r(E, f, s, o, l)).sessionId, W(e, p)), {
192
108
  sandboxId: f,
193
109
  sessionId: p
194
110
  };
195
111
  }, [
196
- T,
197
- W,
198
112
  E,
199
- U,
200
113
  G,
201
- Y
114
+ D,
115
+ W,
116
+ K,
117
+ X
202
118
  ]), Q = g(async (e) => {
203
- if (M) {
204
- let e = P[M]?.status;
119
+ if (N) {
120
+ let e = F[N]?.status;
205
121
  if (e === "provisioning" || e === "connecting" || e === "streaming") return;
206
122
  }
207
- let n = t.getState().mode, r = M, a = r ? t.getState().conversations.find((e) => e.id === r) : void 0;
208
- if (r ? a && a.mode !== n && (a.messages.length > 0 || a.backendSessionId) ? r = R(void 0, n) : a && a.mode !== n && I(r, n) : r = R(void 0, n), !r) return;
209
- let c = S(), u = {
210
- accessToken: E(),
211
- workspaceToken: D(),
212
- userId: O,
213
- organizationId: C()
123
+ let n = t.getState().mode, r = N, a = r ? t.getState().conversations.find((e) => e.id === r) : void 0;
124
+ if (r ? a && a.mode !== n && (a.messages.length > 0 || a.backendSessionId) ? r = z(void 0, n) : a && a.mode !== n && L(r, n) : r = z(void 0, n), !r) return;
125
+ let c = te(), u = {
126
+ accessToken: D(),
127
+ workspaceToken: O(),
128
+ userId: j,
129
+ organizationId: ne()
214
130
  }, d = {
215
- id: b(),
131
+ id: C(),
216
132
  role: "user",
217
133
  content: e,
218
134
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
219
135
  };
220
- z(r, d);
221
- let f = b();
222
- z(r, {
136
+ B(r, d);
137
+ let f = C();
138
+ B(r, {
223
139
  id: f,
224
140
  role: "assistant",
225
141
  content: "",
226
142
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
227
143
  });
228
144
  let p = (e, t, i, a) => {
229
- V(r, f, {
230
- content: w(e),
145
+ H(r, f, {
146
+ content: T(e),
231
147
  metadata: t?.length || i || a ? {
232
148
  artifacts: t,
233
149
  mode: n,
@@ -238,63 +154,48 @@ var j = () => {
238
154
  }, m = async (t = 1) => {
239
155
  try {
240
156
  let { sandboxId: t, sessionId: a } = await Z(r, f, n, c, u);
241
- Y(r, f, "streaming", "Thinking...");
157
+ X(r, f, "streaming", "Thinking...");
242
158
  let d = Date.now();
243
- await l(T, t, c, a, e, n, ee(), u);
159
+ await l(E, t, c, a, e, n, ee(), u);
244
160
  let m = k([], d), h = Date.now() + 18e4, g = Date.now();
245
- for (; Date.now() < h && (m = k(await s(T, t, c, a, u, 50), d), V(r, f, { content: w(m.content) }), !m.done);) Date.now() - g > 3e4 && (await i(T, t, c, 600, u).catch(() => void 0), g = Date.now()), await new Promise((e) => setTimeout(e, 1500));
161
+ for (; Date.now() < h && (m = k(await s(E, t, c, a, u, 50), d), H(r, f, { content: T(m.content) }), !m.done);) Date.now() - g > 3e4 && (await i(E, t, c, 600, u).catch(() => void 0), g = Date.now()), await new Promise((e) => setTimeout(e, 1500));
246
162
  if (!m.done) throw Error("Assistant response timed out while streaming progress");
247
- let _ = n === "vibe-plugins" ? await o(T, t, c, a, u).catch(() => []) : void 0;
248
- p(m.content, _, a, t), m.tokens && V(r, f, { tokens: m.tokens }), H(r, "complete", f, null);
163
+ let _ = n === "vibe-plugins" ? await o(E, t, c, a, u).catch(() => []) : void 0;
164
+ p(m.content, _, a, t), m.tokens && H(r, f, { tokens: m.tokens }), U(r, "complete", f, null);
249
165
  } catch (e) {
250
- if (t === 1 && ie(e)) return W(r), K(n), m(2);
166
+ if (t === 1 && re(e)) return G(r), q(n), m(2);
251
167
  throw e;
252
168
  }
253
169
  };
254
170
  try {
255
171
  if (!c) throw Error("Assistant backend is unavailable without an active workspace context.");
256
- {
257
- let t = await X(n, e);
258
- if (t) {
259
- p(t), H(r, "complete", f, null);
260
- return;
261
- }
262
- }
263
172
  await m();
264
- } catch (t) {
265
- let i = t instanceof Error ? t.message : "Something went wrong";
266
- {
267
- let t = await X(n, e).catch(() => null);
268
- if (t) {
269
- p(t), H(r, "complete", f, null);
270
- return;
271
- }
272
- }
273
- H(r, "error", f, i), B(r, f, `Sorry, an error occurred: ${i}. Please try again.`);
173
+ } catch (e) {
174
+ let t = e instanceof Error ? e.message : "Something went wrong";
175
+ U(r, "error", f, t), V(r, f, `Sorry, an error occurred: ${t}. Please try again.`);
274
176
  }
275
177
  }, [
178
+ N,
179
+ B,
180
+ E,
181
+ G,
182
+ q,
276
183
  M,
277
184
  z,
278
- T,
279
- W,
280
- K,
281
- j,
282
- R,
283
185
  Z,
284
- E,
285
186
  D,
286
- V,
287
- P,
288
- U,
289
- I,
187
+ O,
290
188
  H,
189
+ F,
190
+ W,
191
+ L,
192
+ U,
291
193
  X,
292
- Y,
293
- B,
294
- O
295
- ]), ge = g((e) => {
194
+ V,
195
+ j
196
+ ]), se = g((e) => {
296
197
  Q(e);
297
- }, [Q]), $ = te(Q);
198
+ }, [Q]), $ = v(Q);
298
199
  _(() => {
299
200
  $.current = Q;
300
201
  }, [Q]), _(() => {
@@ -306,40 +207,40 @@ var j = () => {
306
207
  }
307
208
  });
308
209
  }, []);
309
- let _e = g((e) => {
310
- let n = M ? t.getState().conversations.find((e) => e.id === M) : void 0;
210
+ let ce = g((e) => {
211
+ let n = N ? t.getState().conversations.find((e) => e.id === N) : void 0;
311
212
  if (n && (n.messages.length > 0 || n.backendSessionId)) {
312
213
  if (n.mode !== e) {
313
214
  let n = t.getState().conversations.find((n) => n.mode === e && n.messages.length === 0 && !n.backendSessionId && !t.getState().processingByConversationId[n.id]);
314
- n ? L(n.id) : R(void 0, e);
215
+ n ? R(n.id) : z(void 0, e);
315
216
  }
316
- } else M && I(M, e);
317
- F(e);
217
+ } else N && L(N, e);
218
+ I(e);
318
219
  }, [
319
- M,
220
+ N,
221
+ z,
320
222
  R,
321
223
  L,
322
- I,
323
- F
224
+ I
324
225
  ]);
325
- return /* @__PURE__ */ y("div", {
226
+ return /* @__PURE__ */ S("div", {
326
227
  className: "flex flex-col flex-1 overflow-hidden pt-3",
327
- children: [q.length === 0 ? /* @__PURE__ */ v(h, {
328
- mode: N,
329
- onSuggestionClick: ge
330
- }) : /* @__PURE__ */ v(p, {
331
- messages: q,
332
- streamingMessageId: pe
333
- }), /* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("div", {
228
+ children: [J.length === 0 ? /* @__PURE__ */ x(h, {
229
+ mode: P,
230
+ onSuggestionClick: se
231
+ }) : /* @__PURE__ */ x(p, {
232
+ messages: J,
233
+ streamingMessageId: ae
234
+ }), /* @__PURE__ */ S("div", { children: [/* @__PURE__ */ x("div", {
334
235
  className: "px-3 pb-1",
335
- children: /* @__PURE__ */ v(m, {
336
- mode: N,
337
- onModeChange: _e
236
+ children: /* @__PURE__ */ x(m, {
237
+ mode: P,
238
+ onModeChange: ce
338
239
  })
339
- }), /* @__PURE__ */ v(f, {
240
+ }), /* @__PURE__ */ x(f, {
340
241
  onSend: (e) => void Q(e),
341
- disabled: me,
342
- placeholder: x("vibecontrols.assistant.chatArea.placeholder", `Ask about ${N.replace(/-/g, " ")}...`)
242
+ disabled: oe,
243
+ placeholder: w("vibecontrols.assistant.chatArea.placeholder", `Ask about ${P.replace(/-/g, " ")}...`)
343
244
  })] })]
344
245
  });
345
246
  };
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantChatArea.js","names":[],"sources":["../../../src/components/assistant/AssistantChatArea.tsx"],"sourcesContent":["import { useCallback, useEffect, useRef, type FC } from 'react';\nimport { useGatewayClient } from '@burdenoff/fe-libs/shared/graphql';\nimport { useAuthToken } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { AssistantChatInput } from './AssistantChatInput';\nimport { AssistantMessageList } from './AssistantMessageList';\nimport { AssistantModeSelector } from './AssistantModeSelector';\nimport { AssistantWelcome } from './AssistantWelcome';\nimport { useAssistantStore } from '@/store/assistantStore';\nimport {\n createAssistantSandbox,\n createAssistantSession,\n extendAssistantSandboxTTL,\n findExistingSandbox,\n getAssistantArtifacts,\n getAssistantMessages,\n getAssistantSession,\n sendAssistantPromptAsync,\n waitForAssistantServiceReady,\n waitForSandboxReady,\n type AssistantRawMessage,\n type AssistantSandboxAuthContext,\n} from '@/services/assistantApi';\nimport { gatherPageContext } from '@/utils/pageContext';\nimport { useTr } from '../../shared/hooks/useTr';\nimport type {\n AssistantArtifact,\n AssistantConversationStatus,\n AssistantMode,\n Message,\n} from '@/types/assistant';\n\nfunction generateId(): string {\n return `${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;\n}\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 {\n workspaceId?: string;\n organizationId?: string;\n };\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 isRecoverableAssistantError(error: unknown): boolean {\n const message =\n error instanceof Error ? error.message.toLowerCase() : String(error).toLowerCase();\n\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\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 'session mode mismatch',\n ].some((fragment) => message.includes(fragment));\n}\n\nfunction sanitizeAssistantResponse(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\nconst VIBECONTROLS_HELP_TOPICS: Record<string, string> = {\n action:\n 'An Action is a reusable operation VibeControls can run against a target, vibe, session, or automation flow. Create one from VibeControls > Actions, choose the action type, configure the inputs and permissions, then save and run it from the relevant page.',\n component:\n 'A Component represents a software unit such as a service, frontend, library, API, database, or infrastructure asset. Add one from VibeControls > Components, fill in the metadata, lifecycle, owner, language/framework, and tags, then attach it to catalogs or vibes as needed.',\n vibe: 'A Vibe is a workspace project/repository context managed by VibeControls. Create one from VibeControls > Vibes, select the type and path, optionally attach an agent, then use its detail tabs for sessions, docs, catalogs, GitOps, and related resources.',\n session:\n 'A Session is a managed terminal/workflow runtime connected to an agent. Open VibeControls > Sessions, create or start a session, then use terminal tabs to interact with it, share it, restart it, or bookmark a specific session tab from the URL.',\n target:\n 'A Target is a machine or runtime endpoint that an agent can manage. Register or inspect targets from VibeControls > Targets & Agents, then use them for sessions, actions, tunnels, and vibe operations.',\n};\n\nfunction resolveVibeControlsHelpPrompt(prompt: string): string | null {\n const normalized = prompt.toLowerCase();\n if (!normalized.includes('vibecontrols') && !normalized.includes('vibe controls')) {\n return null;\n }\n\n const topic = Object.keys(VIBECONTROLS_HELP_TOPICS).find((key) =>\n new RegExp(`\\\\b${key}s?\\\\b`).test(normalized)\n );\n\n if (!topic) return null;\n return VIBECONTROLS_HELP_TOPICS[topic] ?? null;\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 buildAssistantProgress(\n messages: AssistantRawMessage[],\n sinceMs: number\n): {\n content: string;\n done: boolean;\n tokens?: { input: number; output: number };\n} {\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) {\n return { content: 'Thinking...', done: false };\n }\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 tokens: latest.info?.tokens,\n };\n}\n\nfunction getConversationStatusMessage(status: AssistantConversationStatus): string {\n switch (status) {\n case 'provisioning':\n return 'Starting assistant environment...';\n case 'connecting':\n return 'Connecting to assistant...';\n case 'streaming':\n return 'Thinking...';\n default:\n return '';\n }\n}\n\nfunction isWorkspaceListPrompt(prompt: string): boolean {\n const normalized = prompt.toLowerCase();\n return (\n normalized.includes('workspace') &&\n (normalized.includes('access') ||\n normalized.includes('authorized') ||\n normalized.includes('list'))\n );\n}\n\nfunction isApiCapabilitiesPrompt(prompt: string): boolean {\n const normalized = prompt.toLowerCase();\n return (\n normalized.includes('what api calls') ||\n normalized.includes('what can you do') ||\n normalized.includes('which api calls')\n );\n}\n\nfunction isProfileNamePrompt(prompt: string): boolean {\n const normalized = prompt.toLowerCase();\n return normalized.includes('what is my name') || normalized.includes('my profile name');\n}\n\nfunction extractTargetNamePrompt(prompt: string): string | null {\n const match = prompt.match(/create\\s+a\\s+target\\s+named\\s+(.+)/i);\n return match?.[1]?.trim() ?? null;\n}\n\nfunction getLocalProfileName(): { name?: string; email?: string } {\n try {\n const profileId = sessionStorage.getItem('bf-active-profile');\n if (!profileId) return {};\n const raw = localStorage.getItem(`bf-p-${profileId}-user`);\n if (!raw) return {};\n const user = JSON.parse(raw) as {\n username?: string;\n name?: string;\n firstName?: string;\n email?: string;\n };\n return {\n name: user.name || user.username || user.firstName,\n email: user.email,\n };\n } catch {\n return {};\n }\n}\n\nfunction isGeneralCapabilitiesPrompt(prompt: string): boolean {\n return prompt.toLowerCase().trim() === 'what can you do';\n}\n\nexport const AssistantChatArea: FC = () => {\n const tr = useTr();\n const apollo = useGatewayClient('workspace');\n const { getAccessToken, getWorkspaceToken, userId } = useAuthToken();\n\n const {\n conversations,\n activeConversationId,\n mode,\n processingByConversationId,\n setMode,\n setConversationMode,\n setActiveConversation,\n createConversation,\n addMessage,\n updateMessage,\n patchMessage,\n setConversationProcessing,\n clearConversationProcessing,\n setBackendSessionId,\n clearBackendSessionId,\n setSandbox,\n clearSandbox,\n } = useAssistantStore();\n\n const activeConversation = conversations.find(\n (conversation) => conversation.id === activeConversationId\n );\n const messages = activeConversation?.messages ?? [];\n const activeProcessing = activeConversationId\n ? processingByConversationId[activeConversationId]\n : undefined;\n const activeStreamingMessageId = activeProcessing?.messageId ?? null;\n const activeIsProcessing =\n activeProcessing?.status === 'provisioning' ||\n activeProcessing?.status === 'connecting' ||\n activeProcessing?.status === 'streaming';\n\n const updateConversationStage = useCallback(\n (\n conversationId: string,\n assistantMessageId: string,\n status: AssistantConversationStatus,\n content?: string\n ) => {\n setConversationProcessing(conversationId, status, assistantMessageId, null);\n if (content) {\n updateMessage(conversationId, assistantMessageId, content);\n } else {\n updateMessage(conversationId, assistantMessageId, getConversationStatusMessage(status));\n }\n },\n [setConversationProcessing, updateMessage]\n );\n\n const resolveApiCallsPromptLocally = useCallback(\n async (prompt: string): Promise<string | null> => {\n if (isWorkspaceListPrompt(prompt)) {\n const workspaceId = getWorkspaceId();\n const organizationId = getOrganizationId();\n\n if (!workspaceId) {\n return 'No authorized workspace is attached to this assistant session yet.';\n }\n\n const publicUrl = organizationId\n ? `https://api.${organizationId}.burdenoff.com/workspaces/graphql`\n : '';\n\n return `This assistant sandbox is authorized for 1 workspace:\\n\\n1. Current active workspace — ${workspaceId}${publicUrl ? `\\n Public URL: ${publicUrl}` : ''}`;\n }\n\n if (isProfileNamePrompt(prompt)) {\n const profile = getLocalProfileName();\n if (!profile.name && !profile.email) {\n return 'I could not determine your profile name from the local session.';\n }\n\n const nameLine = profile.name ? `Your profile name is ${profile.name}.` : '';\n const emailLine = profile.email ? `Your profile email is ${profile.email}.` : '';\n return [nameLine, emailLine].filter(Boolean).join('\\n');\n }\n\n const requestedTargetName = extractTargetNamePrompt(prompt);\n if (requestedTargetName) {\n return [\n `I can create the target \"${requestedTargetName}\", but I still need the target connection details before I can execute the mutation.`,\n '',\n 'Please provide at least:',\n '- target type (SSH, RDP, VNC, or DIRECT)',\n '- host or IP address',\n '- port if it is not the default for that protocol',\n '- any credentials or auth method the target requires',\n '',\n `For example: create a target named ${requestedTargetName} using SSH at 10.0.0.15:22 with username ubuntu.`,\n ].join('\\n');\n }\n\n if (isApiCapabilitiesPrompt(prompt)) {\n return [\n 'I can query or mutate both Burdenoff GraphQL gateways on your behalf:',\n '',\n '- Global gateway: organizations, workspaces, apps, billing, notifications, store, support, and dev portal operations',\n '- Workspace gateway: workspace-scoped modules like vibecontrols, files, tags, conversations, calendar, sandbox, and related resources',\n '',\n 'Ask me for a specific action like listing your workspaces, fetching a resource, or creating/updating something through the APIs.',\n ].join('\\n');\n }\n\n return null;\n },\n []\n );\n\n const resolveLocalPromptByMode = useCallback(\n async (currentMode: AssistantMode, prompt: string): Promise<string | null> => {\n if (currentMode === 'api-calls') {\n return resolveApiCallsPromptLocally(prompt);\n }\n\n if (currentMode === 'general' && isGeneralCapabilitiesPrompt(prompt)) {\n return [\n 'I can help explain VibeControls concepts, navigation, sessions, targets, tunnels, and platform workflows.',\n '',\n 'I can also guide you through the UI, describe features, and help you understand how different parts of the product fit together.',\n ].join('\\n');\n }\n\n if (currentMode === 'vibe-plugins' && isGeneralCapabilitiesPrompt(prompt)) {\n return [\n 'I can help design, generate, explain, and package Vibe Plugins.',\n '',\n 'I can create plugin scaffolds, explain manifests and lifecycle hooks, and provide downloadable plugin artifacts for this session.',\n ].join('\\n');\n }\n\n const helpResponse = resolveVibeControlsHelpPrompt(prompt);\n if (helpResponse) return helpResponse;\n\n return null;\n },\n [resolveApiCallsPromptLocally]\n );\n\n const ensureAssistantRuntime = useCallback(\n async (\n conversationId: string,\n assistantMessageId: string,\n currentMode: AssistantMode,\n workspaceId: string,\n authContext: AssistantSandboxAuthContext\n ): Promise<{ sandboxId: string; sessionId: string }> => {\n let currentSandboxId =\n useAssistantStore.getState().sandboxesByMode[currentMode]?.sandboxId ?? null;\n\n if (!currentSandboxId) {\n updateConversationStage(\n conversationId,\n assistantMessageId,\n 'provisioning',\n 'Looking for existing environment...'\n );\n const existingId = await findExistingSandbox(apollo, workspaceId, currentMode, authContext);\n\n if (existingId) {\n currentSandboxId = existingId;\n setSandbox(currentMode, currentSandboxId, 'provisioning');\n updateConversationStage(\n conversationId,\n assistantMessageId,\n 'provisioning',\n 'Reusing assistant environment...'\n );\n await waitForSandboxReady(\n apollo,\n currentSandboxId,\n workspaceId,\n authContext,\n 300_000,\n (message) =>\n updateConversationStage(conversationId, assistantMessageId, 'provisioning', message)\n );\n await waitForAssistantServiceReady(\n apollo,\n currentSandboxId,\n workspaceId,\n authContext,\n 90_000,\n (message) =>\n updateConversationStage(conversationId, assistantMessageId, 'connecting', message)\n );\n setSandbox(currentMode, currentSandboxId, 'running');\n } else {\n if (currentMode === 'api-calls' && !getAccessToken()) {\n throw new Error(\n 'API Calls mode requires an authenticated session. Please sign in again.'\n );\n }\n\n updateConversationStage(\n conversationId,\n assistantMessageId,\n 'provisioning',\n 'Starting assistant environment...'\n );\n setSandbox(currentMode, null, 'provisioning');\n currentSandboxId = await createAssistantSandbox(\n apollo,\n currentMode,\n workspaceId,\n authContext\n );\n\n setSandbox(currentMode, currentSandboxId, 'provisioning');\n await waitForSandboxReady(\n apollo,\n currentSandboxId,\n workspaceId,\n authContext,\n 300_000,\n (message) =>\n updateConversationStage(conversationId, assistantMessageId, 'provisioning', message)\n );\n await waitForAssistantServiceReady(\n apollo,\n currentSandboxId,\n workspaceId,\n authContext,\n 90_000,\n (message) =>\n updateConversationStage(conversationId, assistantMessageId, 'connecting', message)\n );\n setSandbox(currentMode, currentSandboxId, 'running');\n }\n }\n\n let sessionId =\n useAssistantStore\n .getState()\n .conversations.find((conversation) => conversation.id === conversationId)\n ?.backendSessionId ?? null;\n\n if (sessionId) {\n try {\n const session = await getAssistantSession(\n apollo,\n currentSandboxId,\n workspaceId,\n sessionId,\n authContext\n );\n if (session.mode !== currentMode) {\n throw new Error(\n `Session mode mismatch: expected ${currentMode}, received ${session.mode}`\n );\n }\n } catch {\n clearBackendSessionId(conversationId);\n sessionId = null;\n }\n }\n\n if (!sessionId) {\n updateConversationStage(\n conversationId,\n assistantMessageId,\n 'connecting',\n 'Preparing session...'\n );\n const result = await createAssistantSession(\n apollo,\n currentSandboxId,\n workspaceId,\n currentMode,\n authContext\n );\n sessionId = result.sessionId;\n setBackendSessionId(conversationId, sessionId);\n }\n\n return {\n sandboxId: currentSandboxId,\n sessionId,\n };\n },\n [\n apollo,\n clearBackendSessionId,\n getAccessToken,\n setBackendSessionId,\n setSandbox,\n updateConversationStage,\n ]\n );\n\n const handleSend = useCallback(\n async (content: string) => {\n // Only block re-entry while a turn is genuinely in-flight. Earlier code\n // checked for *any* entry in the map, which stuck around as `complete`\n // / `error` after the first turn — making every subsequent message\n // silently disappear (the input cleared but handleSend bailed before\n // adding the user message to the conversation).\n if (activeConversationId) {\n const inflightStatus = processingByConversationId[activeConversationId]?.status;\n if (\n inflightStatus === 'provisioning' ||\n inflightStatus === 'connecting' ||\n inflightStatus === 'streaming'\n ) {\n return;\n }\n }\n\n const selectedMode = useAssistantStore.getState().mode;\n let conversationId = activeConversationId;\n const currentConversation = conversationId\n ? useAssistantStore\n .getState()\n .conversations.find((conversation) => conversation.id === conversationId)\n : undefined;\n\n if (!conversationId) {\n conversationId = createConversation(undefined, selectedMode);\n } else if (\n currentConversation &&\n currentConversation.mode !== selectedMode &&\n (currentConversation.messages.length > 0 || currentConversation.backendSessionId)\n ) {\n conversationId = createConversation(undefined, selectedMode);\n } else if (currentConversation && currentConversation.mode !== selectedMode) {\n setConversationMode(conversationId, selectedMode);\n }\n\n if (!conversationId) return;\n\n const workspaceId = getWorkspaceId();\n const authContext: AssistantSandboxAuthContext = {\n accessToken: getAccessToken(),\n workspaceToken: getWorkspaceToken(),\n userId,\n organizationId: getOrganizationId(),\n };\n\n const userMessage: Message = {\n id: generateId(),\n role: 'user',\n content,\n timestamp: new Date().toISOString(),\n };\n addMessage(conversationId, userMessage);\n\n const assistantMessageId = generateId();\n addMessage(conversationId, {\n id: assistantMessageId,\n role: 'assistant',\n content: '',\n timestamp: new Date().toISOString(),\n });\n\n const applyAssistantResponse = (\n response: string,\n artifacts?: AssistantArtifact[],\n sessionId?: string,\n sandboxId?: string\n ) => {\n patchMessage(conversationId, assistantMessageId, {\n content: sanitizeAssistantResponse(response),\n metadata:\n artifacts?.length || sessionId || sandboxId\n ? {\n artifacts,\n mode: selectedMode,\n sessionId,\n sandboxId,\n }\n : undefined,\n });\n };\n\n const sendWithRealBackend = async (attempt: 1 | 2 = 1): Promise<void> => {\n try {\n const { sandboxId, sessionId } = await ensureAssistantRuntime(\n conversationId,\n assistantMessageId,\n selectedMode,\n workspaceId,\n authContext\n );\n\n updateConversationStage(conversationId, assistantMessageId, 'streaming', 'Thinking...');\n const promptStartedAt = Date.now();\n await sendAssistantPromptAsync(\n apollo,\n sandboxId,\n workspaceId,\n sessionId,\n content,\n selectedMode,\n gatherPageContext(),\n authContext\n );\n\n let result = buildAssistantProgress([], promptStartedAt);\n const timeoutAt = Date.now() + 180_000;\n let lastTtlExtensionAt = Date.now();\n\n while (Date.now() < timeoutAt) {\n const sessionMessages = await getAssistantMessages(\n apollo,\n sandboxId,\n workspaceId,\n sessionId,\n authContext,\n 50\n );\n\n result = buildAssistantProgress(sessionMessages, promptStartedAt);\n patchMessage(conversationId, assistantMessageId, {\n content: sanitizeAssistantResponse(result.content),\n });\n\n if (result.done) break;\n\n if (Date.now() - lastTtlExtensionAt > 30_000) {\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, 1500));\n }\n\n if (!result.done) {\n throw new Error('Assistant response timed out while streaming progress');\n }\n\n const artifacts =\n selectedMode === 'vibe-plugins'\n ? await getAssistantArtifacts(\n apollo,\n sandboxId,\n workspaceId,\n sessionId,\n authContext\n ).catch(() => [])\n : undefined;\n\n applyAssistantResponse(result.content, artifacts, sessionId, sandboxId);\n\n if (result.tokens) {\n patchMessage(conversationId, assistantMessageId, { tokens: result.tokens });\n }\n setConversationProcessing(conversationId, 'complete', assistantMessageId, null);\n } catch (error) {\n if (attempt === 1 && isRecoverableAssistantError(error)) {\n clearBackendSessionId(conversationId);\n clearSandbox(selectedMode);\n return sendWithRealBackend(2);\n }\n\n throw error;\n }\n };\n\n try {\n if (!workspaceId) {\n throw new Error('Assistant backend is unavailable without an active workspace context.');\n }\n\n {\n const localResponse = await resolveLocalPromptByMode(selectedMode, content);\n if (localResponse) {\n applyAssistantResponse(localResponse);\n setConversationProcessing(conversationId, 'complete', assistantMessageId, null);\n return;\n }\n }\n\n await sendWithRealBackend();\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Something went wrong';\n\n {\n const localResponse = await resolveLocalPromptByMode(selectedMode, content).catch(\n () => null\n );\n if (localResponse) {\n applyAssistantResponse(localResponse);\n setConversationProcessing(conversationId, 'complete', assistantMessageId, null);\n return;\n }\n }\n\n setConversationProcessing(conversationId, 'error', assistantMessageId, errorMessage);\n updateMessage(\n conversationId,\n assistantMessageId,\n `Sorry, an error occurred: ${errorMessage}. Please try again.`\n );\n }\n },\n [\n activeConversationId,\n addMessage,\n apollo,\n clearBackendSessionId,\n clearSandbox,\n conversations,\n createConversation,\n ensureAssistantRuntime,\n getAccessToken,\n getWorkspaceToken,\n patchMessage,\n processingByConversationId,\n setBackendSessionId,\n setConversationMode,\n setConversationProcessing,\n resolveLocalPromptByMode,\n updateConversationStage,\n updateMessage,\n userId,\n ]\n );\n\n const handleSuggestionClick = useCallback(\n (suggestion: string) => {\n void handleSend(suggestion);\n },\n [handleSend]\n );\n\n // Auto-send any prompt that was queued by `useOpenAssistantHelp` (from\n // the shared GetHelpButton). We keep the latest handleSend in a ref so\n // the subscription effect below doesn't need to tear down on every\n // render — the store subscription lives for the component lifetime and\n // always calls the freshest handler.\n const handleSendRef = useRef(handleSend);\n useEffect(() => {\n handleSendRef.current = handleSend;\n }, [handleSend]);\n\n useEffect(() => {\n // Flush any prompt that was queued before this component mounted.\n const initial = useAssistantStore.getState().consumePendingPrompt();\n if (initial) {\n void handleSendRef.current(initial);\n }\n\n // Watch for new prompts queued while we're already mounted.\n const unsubscribe = useAssistantStore.subscribe((state, prev) => {\n if (state.pendingPrompt && state.pendingPrompt !== prev.pendingPrompt) {\n const queued = useAssistantStore.getState().consumePendingPrompt();\n if (queued) {\n void handleSendRef.current(queued);\n }\n }\n });\n return unsubscribe;\n }, []);\n\n const handleModeChange = useCallback(\n (newMode: AssistantMode) => {\n const currentConversation = activeConversationId\n ? useAssistantStore\n .getState()\n .conversations.find((conversation) => conversation.id === activeConversationId)\n : undefined;\n\n if (\n currentConversation &&\n (currentConversation.messages.length > 0 || currentConversation.backendSessionId)\n ) {\n if (currentConversation.mode !== newMode) {\n const reusableDraft = useAssistantStore\n .getState()\n .conversations.find(\n (conversation) =>\n conversation.mode === newMode &&\n conversation.messages.length === 0 &&\n !conversation.backendSessionId &&\n !useAssistantStore.getState().processingByConversationId[conversation.id]\n );\n\n if (reusableDraft) {\n setActiveConversation(reusableDraft.id);\n } else {\n createConversation(undefined, newMode);\n }\n }\n } else if (activeConversationId) {\n setConversationMode(activeConversationId, newMode);\n }\n\n setMode(newMode);\n },\n [activeConversationId, createConversation, setActiveConversation, setConversationMode, setMode]\n );\n\n return (\n <div className=\"flex flex-col flex-1 overflow-hidden pt-3\">\n {messages.length === 0 ? (\n <AssistantWelcome mode={mode} onSuggestionClick={handleSuggestionClick} />\n ) : (\n <AssistantMessageList messages={messages} streamingMessageId={activeStreamingMessageId} />\n )}\n\n <div>\n <div className=\"px-3 pb-1\">\n <AssistantModeSelector mode={mode} onModeChange={handleModeChange} />\n </div>\n <AssistantChatInput\n onSend={(value) => void handleSend(value)}\n disabled={activeIsProcessing}\n placeholder={tr(\n 'vibecontrols.assistant.chatArea.placeholder',\n `Ask about ${mode.replace(/-/g, ' ')}...`\n )}\n />\n </div>\n </div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"AssistantChatArea.js","names":[],"sources":["../../../src/components/assistant/AssistantChatArea.tsx"],"sourcesContent":["import { useCallback, useEffect, useRef, type FC } from 'react';\nimport { useGatewayClient } from '@burdenoff/fe-libs/shared/graphql';\nimport { useAuthToken } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { AssistantChatInput } from './AssistantChatInput';\nimport { AssistantMessageList } from './AssistantMessageList';\nimport { AssistantModeSelector } from './AssistantModeSelector';\nimport { AssistantWelcome } from './AssistantWelcome';\nimport { useAssistantStore } from '@/store/assistantStore';\nimport {\n createAssistantSandbox,\n createAssistantSession,\n extendAssistantSandboxTTL,\n findExistingSandbox,\n getAssistantArtifacts,\n getAssistantMessages,\n getAssistantSession,\n sendAssistantPromptAsync,\n waitForAssistantServiceReady,\n waitForSandboxReady,\n type AssistantRawMessage,\n type AssistantSandboxAuthContext,\n} from '@/services/assistantApi';\nimport { gatherPageContext } from '@/utils/pageContext';\nimport { useTr } from '../../shared/hooks/useTr';\nimport type {\n AssistantArtifact,\n AssistantConversationStatus,\n AssistantMode,\n Message,\n} from '@/types/assistant';\n\nfunction generateId(): string {\n return `${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;\n}\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 {\n workspaceId?: string;\n organizationId?: string;\n };\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 isRecoverableAssistantError(error: unknown): boolean {\n const message =\n error instanceof Error ? error.message.toLowerCase() : String(error).toLowerCase();\n\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\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 'session mode mismatch',\n ].some((fragment) => message.includes(fragment));\n}\n\nfunction sanitizeAssistantResponse(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 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 buildAssistantProgress(\n messages: AssistantRawMessage[],\n sinceMs: number\n): {\n content: string;\n done: boolean;\n tokens?: { input: number; output: number };\n} {\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) {\n return { content: 'Thinking...', done: false };\n }\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 tokens: latest.info?.tokens,\n };\n}\n\nfunction getConversationStatusMessage(status: AssistantConversationStatus): string {\n switch (status) {\n case 'provisioning':\n return 'Starting assistant environment...';\n case 'connecting':\n return 'Connecting to assistant...';\n case 'streaming':\n return 'Thinking...';\n default:\n return '';\n }\n}\n\nexport const AssistantChatArea: FC = () => {\n const tr = useTr();\n const apollo = useGatewayClient('workspace');\n const { getAccessToken, getWorkspaceToken, userId } = useAuthToken();\n\n const {\n conversations,\n activeConversationId,\n mode,\n processingByConversationId,\n setMode,\n setConversationMode,\n setActiveConversation,\n createConversation,\n addMessage,\n updateMessage,\n patchMessage,\n setConversationProcessing,\n clearConversationProcessing,\n setBackendSessionId,\n clearBackendSessionId,\n setSandbox,\n clearSandbox,\n } = useAssistantStore();\n\n const activeConversation = conversations.find(\n (conversation) => conversation.id === activeConversationId\n );\n const messages = activeConversation?.messages ?? [];\n const activeProcessing = activeConversationId\n ? processingByConversationId[activeConversationId]\n : undefined;\n const activeStreamingMessageId = activeProcessing?.messageId ?? null;\n const activeIsProcessing =\n activeProcessing?.status === 'provisioning' ||\n activeProcessing?.status === 'connecting' ||\n activeProcessing?.status === 'streaming';\n\n const updateConversationStage = useCallback(\n (\n conversationId: string,\n assistantMessageId: string,\n status: AssistantConversationStatus,\n content?: string\n ) => {\n setConversationProcessing(conversationId, status, assistantMessageId, null);\n if (content) {\n updateMessage(conversationId, assistantMessageId, content);\n } else {\n updateMessage(conversationId, assistantMessageId, getConversationStatusMessage(status));\n }\n },\n [setConversationProcessing, updateMessage]\n );\n\n const ensureAssistantRuntime = useCallback(\n async (\n conversationId: string,\n assistantMessageId: string,\n currentMode: AssistantMode,\n workspaceId: string,\n authContext: AssistantSandboxAuthContext\n ): Promise<{ sandboxId: string; sessionId: string }> => {\n let currentSandboxId =\n useAssistantStore.getState().sandboxesByMode[currentMode]?.sandboxId ?? null;\n\n if (!currentSandboxId) {\n updateConversationStage(\n conversationId,\n assistantMessageId,\n 'provisioning',\n 'Looking for existing environment...'\n );\n const existingId = await findExistingSandbox(apollo, workspaceId, currentMode, authContext);\n\n if (existingId) {\n currentSandboxId = existingId;\n setSandbox(currentMode, currentSandboxId, 'provisioning');\n updateConversationStage(\n conversationId,\n assistantMessageId,\n 'provisioning',\n 'Reusing assistant environment...'\n );\n await waitForSandboxReady(\n apollo,\n currentSandboxId,\n workspaceId,\n authContext,\n 300_000,\n (message) =>\n updateConversationStage(conversationId, assistantMessageId, 'provisioning', message)\n );\n await waitForAssistantServiceReady(\n apollo,\n currentSandboxId,\n workspaceId,\n authContext,\n 90_000,\n (message) =>\n updateConversationStage(conversationId, assistantMessageId, 'connecting', message)\n );\n setSandbox(currentMode, currentSandboxId, 'running');\n } else {\n if (currentMode === 'api-calls' && !getAccessToken()) {\n throw new Error(\n 'API Calls mode requires an authenticated session. Please sign in again.'\n );\n }\n\n updateConversationStage(\n conversationId,\n assistantMessageId,\n 'provisioning',\n 'Starting assistant environment...'\n );\n setSandbox(currentMode, null, 'provisioning');\n currentSandboxId = await createAssistantSandbox(\n apollo,\n currentMode,\n workspaceId,\n authContext\n );\n\n setSandbox(currentMode, currentSandboxId, 'provisioning');\n await waitForSandboxReady(\n apollo,\n currentSandboxId,\n workspaceId,\n authContext,\n 300_000,\n (message) =>\n updateConversationStage(conversationId, assistantMessageId, 'provisioning', message)\n );\n await waitForAssistantServiceReady(\n apollo,\n currentSandboxId,\n workspaceId,\n authContext,\n 90_000,\n (message) =>\n updateConversationStage(conversationId, assistantMessageId, 'connecting', message)\n );\n setSandbox(currentMode, currentSandboxId, 'running');\n }\n }\n\n let sessionId =\n useAssistantStore\n .getState()\n .conversations.find((conversation) => conversation.id === conversationId)\n ?.backendSessionId ?? null;\n\n if (sessionId) {\n try {\n const session = await getAssistantSession(\n apollo,\n currentSandboxId,\n workspaceId,\n sessionId,\n authContext\n );\n if (session.mode !== currentMode) {\n throw new Error(\n `Session mode mismatch: expected ${currentMode}, received ${session.mode}`\n );\n }\n } catch {\n clearBackendSessionId(conversationId);\n sessionId = null;\n }\n }\n\n if (!sessionId) {\n updateConversationStage(\n conversationId,\n assistantMessageId,\n 'connecting',\n 'Preparing session...'\n );\n const result = await createAssistantSession(\n apollo,\n currentSandboxId,\n workspaceId,\n currentMode,\n authContext\n );\n sessionId = result.sessionId;\n setBackendSessionId(conversationId, sessionId);\n }\n\n return {\n sandboxId: currentSandboxId,\n sessionId,\n };\n },\n [\n apollo,\n clearBackendSessionId,\n getAccessToken,\n setBackendSessionId,\n setSandbox,\n updateConversationStage,\n ]\n );\n\n const handleSend = useCallback(\n async (content: string) => {\n // Only block re-entry while a turn is genuinely in-flight. Earlier code\n // checked for *any* entry in the map, which stuck around as `complete`\n // / `error` after the first turn — making every subsequent message\n // silently disappear (the input cleared but handleSend bailed before\n // adding the user message to the conversation).\n if (activeConversationId) {\n const inflightStatus = processingByConversationId[activeConversationId]?.status;\n if (\n inflightStatus === 'provisioning' ||\n inflightStatus === 'connecting' ||\n inflightStatus === 'streaming'\n ) {\n return;\n }\n }\n\n const selectedMode = useAssistantStore.getState().mode;\n let conversationId = activeConversationId;\n const currentConversation = conversationId\n ? useAssistantStore\n .getState()\n .conversations.find((conversation) => conversation.id === conversationId)\n : undefined;\n\n if (!conversationId) {\n conversationId = createConversation(undefined, selectedMode);\n } else if (\n currentConversation &&\n currentConversation.mode !== selectedMode &&\n (currentConversation.messages.length > 0 || currentConversation.backendSessionId)\n ) {\n conversationId = createConversation(undefined, selectedMode);\n } else if (currentConversation && currentConversation.mode !== selectedMode) {\n setConversationMode(conversationId, selectedMode);\n }\n\n if (!conversationId) return;\n\n const workspaceId = getWorkspaceId();\n const authContext: AssistantSandboxAuthContext = {\n accessToken: getAccessToken(),\n workspaceToken: getWorkspaceToken(),\n userId,\n organizationId: getOrganizationId(),\n };\n\n const userMessage: Message = {\n id: generateId(),\n role: 'user',\n content,\n timestamp: new Date().toISOString(),\n };\n addMessage(conversationId, userMessage);\n\n const assistantMessageId = generateId();\n addMessage(conversationId, {\n id: assistantMessageId,\n role: 'assistant',\n content: '',\n timestamp: new Date().toISOString(),\n });\n\n const applyAssistantResponse = (\n response: string,\n artifacts?: AssistantArtifact[],\n sessionId?: string,\n sandboxId?: string\n ) => {\n patchMessage(conversationId, assistantMessageId, {\n content: sanitizeAssistantResponse(response),\n metadata:\n artifacts?.length || sessionId || sandboxId\n ? {\n artifacts,\n mode: selectedMode,\n sessionId,\n sandboxId,\n }\n : undefined,\n });\n };\n\n const sendWithRealBackend = async (attempt: 1 | 2 = 1): Promise<void> => {\n try {\n const { sandboxId, sessionId } = await ensureAssistantRuntime(\n conversationId,\n assistantMessageId,\n selectedMode,\n workspaceId,\n authContext\n );\n\n updateConversationStage(conversationId, assistantMessageId, 'streaming', 'Thinking...');\n const promptStartedAt = Date.now();\n await sendAssistantPromptAsync(\n apollo,\n sandboxId,\n workspaceId,\n sessionId,\n content,\n selectedMode,\n gatherPageContext(),\n authContext\n );\n\n let result = buildAssistantProgress([], promptStartedAt);\n const timeoutAt = Date.now() + 180_000;\n let lastTtlExtensionAt = Date.now();\n\n while (Date.now() < timeoutAt) {\n const sessionMessages = await getAssistantMessages(\n apollo,\n sandboxId,\n workspaceId,\n sessionId,\n authContext,\n 50\n );\n\n result = buildAssistantProgress(sessionMessages, promptStartedAt);\n patchMessage(conversationId, assistantMessageId, {\n content: sanitizeAssistantResponse(result.content),\n });\n\n if (result.done) break;\n\n if (Date.now() - lastTtlExtensionAt > 30_000) {\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, 1500));\n }\n\n if (!result.done) {\n throw new Error('Assistant response timed out while streaming progress');\n }\n\n const artifacts =\n selectedMode === 'vibe-plugins'\n ? await getAssistantArtifacts(\n apollo,\n sandboxId,\n workspaceId,\n sessionId,\n authContext\n ).catch(() => [])\n : undefined;\n\n applyAssistantResponse(result.content, artifacts, sessionId, sandboxId);\n\n if (result.tokens) {\n patchMessage(conversationId, assistantMessageId, { tokens: result.tokens });\n }\n setConversationProcessing(conversationId, 'complete', assistantMessageId, null);\n } catch (error) {\n if (attempt === 1 && isRecoverableAssistantError(error)) {\n clearBackendSessionId(conversationId);\n clearSandbox(selectedMode);\n return sendWithRealBackend(2);\n }\n\n throw error;\n }\n };\n\n try {\n if (!workspaceId) {\n throw new Error('Assistant backend is unavailable without an active workspace context.');\n }\n await sendWithRealBackend();\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Something went wrong';\n setConversationProcessing(conversationId, 'error', assistantMessageId, errorMessage);\n updateMessage(\n conversationId,\n assistantMessageId,\n `Sorry, an error occurred: ${errorMessage}. Please try again.`\n );\n }\n },\n [\n activeConversationId,\n addMessage,\n apollo,\n clearBackendSessionId,\n clearSandbox,\n conversations,\n createConversation,\n ensureAssistantRuntime,\n getAccessToken,\n getWorkspaceToken,\n patchMessage,\n processingByConversationId,\n setBackendSessionId,\n setConversationMode,\n setConversationProcessing,\n updateConversationStage,\n updateMessage,\n userId,\n ]\n );\n\n const handleSuggestionClick = useCallback(\n (suggestion: string) => {\n void handleSend(suggestion);\n },\n [handleSend]\n );\n\n // Auto-send any prompt that was queued by `useOpenAssistantHelp` (from\n // the shared GetHelpButton). We keep the latest handleSend in a ref so\n // the subscription effect below doesn't need to tear down on every\n // render — the store subscription lives for the component lifetime and\n // always calls the freshest handler.\n const handleSendRef = useRef(handleSend);\n useEffect(() => {\n handleSendRef.current = handleSend;\n }, [handleSend]);\n\n useEffect(() => {\n // Flush any prompt that was queued before this component mounted.\n const initial = useAssistantStore.getState().consumePendingPrompt();\n if (initial) {\n void handleSendRef.current(initial);\n }\n\n // Watch for new prompts queued while we're already mounted.\n const unsubscribe = useAssistantStore.subscribe((state, prev) => {\n if (state.pendingPrompt && state.pendingPrompt !== prev.pendingPrompt) {\n const queued = useAssistantStore.getState().consumePendingPrompt();\n if (queued) {\n void handleSendRef.current(queued);\n }\n }\n });\n return unsubscribe;\n }, []);\n\n const handleModeChange = useCallback(\n (newMode: AssistantMode) => {\n const currentConversation = activeConversationId\n ? useAssistantStore\n .getState()\n .conversations.find((conversation) => conversation.id === activeConversationId)\n : undefined;\n\n if (\n currentConversation &&\n (currentConversation.messages.length > 0 || currentConversation.backendSessionId)\n ) {\n if (currentConversation.mode !== newMode) {\n const reusableDraft = useAssistantStore\n .getState()\n .conversations.find(\n (conversation) =>\n conversation.mode === newMode &&\n conversation.messages.length === 0 &&\n !conversation.backendSessionId &&\n !useAssistantStore.getState().processingByConversationId[conversation.id]\n );\n\n if (reusableDraft) {\n setActiveConversation(reusableDraft.id);\n } else {\n createConversation(undefined, newMode);\n }\n }\n } else if (activeConversationId) {\n setConversationMode(activeConversationId, newMode);\n }\n\n setMode(newMode);\n },\n [activeConversationId, createConversation, setActiveConversation, setConversationMode, setMode]\n );\n\n return (\n <div className=\"flex flex-col flex-1 overflow-hidden pt-3\">\n {messages.length === 0 ? (\n <AssistantWelcome mode={mode} onSuggestionClick={handleSuggestionClick} />\n ) : (\n <AssistantMessageList messages={messages} streamingMessageId={activeStreamingMessageId} />\n )}\n\n <div>\n <div className=\"px-3 pb-1\">\n <AssistantModeSelector mode={mode} onModeChange={handleModeChange} />\n </div>\n <AssistantChatInput\n onSend={(value) => void handleSend(value)}\n disabled={activeIsProcessing}\n placeholder={tr(\n 'vibecontrols.assistant.chatArea.placeholder',\n `Ask about ${mode.replace(/-/g, ' ')}...`\n )}\n />\n </div>\n </div>\n );\n};\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burdenoff/microfe-vibecontrols",
3
- "version": "2026.515.4",
3
+ "version": "2026.515.5",
4
4
  "description": "VibeControls microfrontend for Burdenoff products",
5
5
  "type": "module",
6
6
  "files": [