@burdenoff/fe-libs 2026.906.5 → 2026.907.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.
@@ -2,69 +2,69 @@ import { useI18n as e } from "../../providers/shell/I18nProvider.js";
2
2
  import { useAuthToken as t } from "../../providers/shell/AuthTokenProvider.js";
3
3
  import "../../../shared-providers-shell.js";
4
4
  import { isQuotaExhaustedError as n } from "../quota.js";
5
- import { createAssistantSandbox as r, createAssistantSession as i, extendAssistantSandboxTTL as a, findExistingSandbox as o, getAssistantArtifacts as s, getAssistantMessages as c, getAssistantSession as l, sendAssistantPromptAsync as u, waitForAssistantServiceReady as d, waitForSandboxRunning as f } from "../api.js";
6
- import { getAssistantMedia as p, sanitize as ee } from "../progress.js";
7
- import { isVoiceTurn as m, voiceMarker as h, voiceSessionIdOf as g } from "../voice/turnVisibility.js";
8
- import { buildContinuedFromVoiceNote as _, buildVoiceTranscriptMarkdown as v, voiceTranscriptFilename as te } from "../voice/voiceTranscript.js";
9
- import { pollDelayMs as ne } from "../voice/assistantPollSchedule.js";
10
- import { toCaptionText as y } from "../voice/captionText.js";
5
+ import { approvePendingWrite as r, createAssistantSandbox as i, createAssistantSession as a, extendAssistantSandboxTTL as o, findExistingSandbox as s, getAssistantArtifacts as c, getAssistantMessages as l, getAssistantSession as u, releaseSupersededAssistantSandboxes as d, sendAssistantPromptAsync as f, waitForAssistantServiceReady as p, waitForSandboxRunning as m } from "../api.js";
6
+ import { getAssistantMedia as h, sanitize as ee } from "../progress.js";
7
+ import { isVoiceTurn as g, voiceMarker as _, voiceSessionIdOf as v } from "../voice/turnVisibility.js";
8
+ import { buildContinuedFromVoiceNote as te, buildVoiceTranscriptMarkdown as y, voiceTranscriptFilename as ne } from "../voice/voiceTranscript.js";
9
+ import { pollDelayMs as re } from "../voice/assistantPollSchedule.js";
10
+ import { toCaptionText as ie } from "../voice/captionText.js";
11
11
  import { resolveAssistantLanguage as b } from "../voice/languages.js";
12
- import { resolveLanguagePair as re } from "../voice/languagePair.js";
13
- import { findPendingWrite as x } from "../pendingWrite.js";
14
- import { useAssistantProduct as ie } from "../product.js";
15
- import { useAssistantTr as ae } from "../i18n.js";
16
- import { buildPromptParts as oe, buildPromptWithAttachments as se, countInlineImageCandidates as ce, countInlinedImageParts as le, getSendableAttachments as ue, toMessageAttachment as de } from "../attachments.js";
17
- import { useAssistantStore as S } from "../store.js";
18
- import { isTurnInFlight as fe } from "../turnState.js";
19
- import { parseToolActivity as pe } from "./AssistantToolActivity.js";
20
- import { useVoiceSession as me } from "./useVoiceSession.js";
21
- import { getOrganizationId as he, getWorkspaceId as ge } from "../context.js";
22
- import { createReadinessTracker as _e } from "../sandboxReadiness.js";
23
- import { AssistantSpokenTurnsNotice as ve } from "./AssistantSpokenTurnsNotice.js";
24
- import { VoiceTranscriptDrawer as ye } from "./voice/VoiceTranscriptDrawer.js";
25
- import { downloadFile as be } from "../exportConversation.js";
26
- import { AssistantEmptyState as xe } from "./AssistantEmptyState.js";
27
- import { AssistantMessageList as Se } from "./AssistantMessageList.js";
28
- import { AssistantVoiceSession as Ce } from "./voice/AssistantVoiceSession.js";
29
- import { useAssistantApiAccess as we } from "../useAssistantApiAccess.js";
30
- import { useConversationTurns as Te } from "../useConversationTurns.js";
31
- import { isMultimodalBodyRejection as Ee, isRecoverableAssistantError as De } from "../transportErrors.js";
32
- import { dispatchAssistantQuotaExhausted as Oe, notifyAiCreditsUpdated as ke } from "../aiCredits.js";
33
- import { useAssistantAttachments as Ae } from "../useAssistantAttachments.js";
34
- import { AssistantComposer as je } from "./composer/AssistantComposer.js";
35
- import { isProdRuntime as Me } from "../env.js";
36
- import { AssistantApiCallsConsentDialog as Ne } from "./AssistantApiCallsConsentDialog.js";
37
- import { useCallback as C, useEffect as w, useMemo as T, useRef as E, useState as Pe } from "react";
38
- import { jsx as D, jsxs as Fe } from "react/jsx-runtime";
12
+ import { resolveLanguagePair as ae } from "../voice/languagePair.js";
13
+ import { findPendingWrite as oe } from "../pendingWrite.js";
14
+ import { useAssistantProduct as se } from "../product.js";
15
+ import { useAssistantTr as ce } from "../i18n.js";
16
+ import { buildPromptParts as le, buildPromptWithAttachments as ue, countInlineImageCandidates as de, countInlinedImageParts as fe, getSendableAttachments as pe, toMessageAttachment as me } from "../attachments.js";
17
+ import { useAssistantStore as x } from "../store.js";
18
+ import { isTurnInFlight as he } from "../turnState.js";
19
+ import { parseToolActivity as ge } from "./AssistantToolActivity.js";
20
+ import { useVoiceSession as _e } from "./useVoiceSession.js";
21
+ import { getOrganizationId as ve, getWorkspaceId as ye } from "../context.js";
22
+ import { createReadinessTracker as be } from "../sandboxReadiness.js";
23
+ import { AssistantSpokenTurnsNotice as xe } from "./AssistantSpokenTurnsNotice.js";
24
+ import { VoiceTranscriptDrawer as Se } from "./voice/VoiceTranscriptDrawer.js";
25
+ import { downloadFile as Ce } from "../exportConversation.js";
26
+ import { AssistantEmptyState as we } from "./AssistantEmptyState.js";
27
+ import { AssistantMessageList as Te } from "./AssistantMessageList.js";
28
+ import { AssistantVoiceSession as Ee } from "./voice/AssistantVoiceSession.js";
29
+ import { useAssistantApiAccess as De } from "../useAssistantApiAccess.js";
30
+ import { useConversationTurns as Oe } from "../useConversationTurns.js";
31
+ import { isMultimodalBodyRejection as ke, isRecoverableAssistantError as Ae } from "../transportErrors.js";
32
+ import { dispatchAssistantQuotaExhausted as je, notifyAiCreditsUpdated as Me } from "../aiCredits.js";
33
+ import { useAssistantAttachments as Ne } from "../useAssistantAttachments.js";
34
+ import { AssistantComposer as Pe } from "./composer/AssistantComposer.js";
35
+ import { isProdRuntime as Fe } from "../env.js";
36
+ import { AssistantApiCallsConsentDialog as Ie } from "./AssistantApiCallsConsentDialog.js";
37
+ import { useCallback as S, useEffect as C, useMemo as w, useRef as T, useState as Le } from "react";
38
+ import { jsx as E, jsxs as Re } from "react/jsx-runtime";
39
39
  //#region src/shared/assistant/ui/AssistantChatArea.tsx
40
- var Ie = {
40
+ var ze = {
41
41
  general: 18e4,
42
42
  assistant: 18e4,
43
43
  "api-calls": 18e4,
44
44
  "vibe-plugins": 6e5
45
- }, Le = 18e4, Re = 600, ze = 2e4;
46
- function Be() {
45
+ }, Be = 18e4, Ve = 600, He = 2e4;
46
+ function Ue() {
47
47
  return `${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
48
48
  }
49
- function Ve(e) {
49
+ function We(e) {
50
50
  return e.info?.time?.created ?? 0;
51
51
  }
52
- function O(e) {
52
+ function D(e) {
53
53
  return (e ?? []).filter((e) => e.type === "text" && typeof e.text == "string").map((e) => e.text?.trim() ?? "").filter(Boolean).join("\n");
54
54
  }
55
- function k(e) {
55
+ function O(e) {
56
56
  return (e ?? []).filter((e) => e.type === "tool" && e.tool).map((e) => {
57
57
  let t = e.state?.status ?? "running", n = e.tool ?? "tool";
58
58
  return t === "completed" ? `Completed: ${n}` : t === "failed" ? `Failed: ${n}` : `Running: ${n}`;
59
59
  });
60
60
  }
61
- function He(e, t) {
62
- let n = e.filter((e) => e.info?.role === "assistant" && Ve(e) > t).sort((e, t) => Ve(e) - Ve(t));
61
+ function Ge(e, t) {
62
+ let n = e.filter((e) => e.info?.role === "assistant" && We(e) > t).sort((e, t) => We(e) - We(t));
63
63
  if (n.length === 0) return {
64
64
  content: "Thinking...",
65
65
  done: !1
66
66
  };
67
- let r = n[n.length - 1], i = O(r.parts), a = p(r.parts), o = k(r.parts), s = x(r.parts), c = [
67
+ let r = n[n.length - 1], i = D(r.parts), a = h(r.parts), o = O(r.parts), s = oe(r.parts), c = [
68
68
  i,
69
69
  ...a,
70
70
  ...o
@@ -78,7 +78,7 @@ function He(e, t) {
78
78
  ...s ? { pendingWrite: s } : {}
79
79
  };
80
80
  }
81
- function Ue(e) {
81
+ function Ke(e) {
82
82
  switch (e) {
83
83
  case "provisioning": return "Starting assistant environment...";
84
84
  case "connecting": return "Connecting to assistant...";
@@ -86,239 +86,265 @@ function Ue(e) {
86
86
  default: return "";
87
87
  }
88
88
  }
89
- var A = ({ visible: p = !0, writeAccess: x = "unknown" }) => {
90
- let O = ae(), { product: k, modes: A, gatherPageContext: We, buildPrompt: Ge, reportTokenUsage: Ke } = ie(), { getAccessToken: j, getWorkspaceToken: qe, userId: Je } = t(), { locale: Ye } = e(), Xe = S((e) => e.assistantLanguage), Ze = S((e) => e.replyLanguage), Qe = T(() => re(Xe, Ze, Ye), [
91
- Xe,
92
- Ze,
93
- Ye
94
- ]), $e = Qe.reply.english, et = Qe.replyIsExplicit, tt = Qe.reply.code, { conversations: nt, activeConversationId: M, mode: N, processingByConversationId: rt, setMode: it, setConversationMode: at, setActiveConversation: ot, createConversation: P, addMessage: F, updateMessage: st, patchMessage: I, mergeMessageMetadata: ct, setConversationProcessing: L, setBackendSessionId: lt, clearBackendSessionId: R, setSandbox: z, clearSandbox: ut, acknowledgeApiCalls: dt } = S(), ft = nt.find((e) => e.id === M), B = Te(ft), V = B.all, H = M ? rt[M] : void 0, U = fe(H?.status), pt = U ? H?.messageId ?? null : null, mt = H?.status === "error" ? H.messageId : null, { canUseApiCalls: W, loading: ht } = we(he()), gt = T(() => A.filter((e) => !e.requiresAdmin || W), [A, W]), [_t, vt] = Pe(null), [yt, G] = Pe(!1), bt = E({}), K = E(_e()), xt = E(/* @__PURE__ */ new Set()), St = T(() => A.find((e) => e.id === N), [A, N]);
95
- w(() => {
96
- ht || (!St || St.requiresAdmin && !W) && N !== "assistant" && it("assistant");
89
+ var k = ({ visible: h = !0, writeAccess: oe = "unknown" }) => {
90
+ let D = ce(), { product: O, modes: k, gatherPageContext: qe, buildPrompt: Je, reportTokenUsage: Ye } = se(), { getAccessToken: A, getWorkspaceToken: Xe, userId: Ze } = t(), { locale: Qe } = e(), $e = x((e) => e.assistantLanguage), et = x((e) => e.replyLanguage), tt = w(() => ae($e, et, Qe), [
91
+ $e,
92
+ et,
93
+ Qe
94
+ ]), nt = tt.reply.english, rt = tt.replyIsExplicit, it = tt.reply.code, { conversations: at, activeConversationId: j, mode: M, processingByConversationId: ot, setMode: st, setConversationMode: N, setActiveConversation: ct, createConversation: P, addMessage: F, updateMessage: lt, patchMessage: I, mergeMessageMetadata: ut, setConversationProcessing: L, setBackendSessionId: dt, clearBackendSessionId: ft, setSandbox: R, clearSandbox: pt, acknowledgeApiCalls: mt } = x(), ht = at.find((e) => e.id === j), z = Oe(ht), B = z.all, V = j ? ot[j] : void 0, H = he(V?.status), gt = H ? V?.messageId ?? null : null, _t = V?.status === "error" ? V.messageId : null, { canUseApiCalls: U, loading: vt } = De(ve()), yt = w(() => k.filter((e) => !e.requiresAdmin || U), [k, U]), [bt, xt] = Le(null), [St, W] = Le(!1), Ct = T({}), G = T(be()), wt = T(/* @__PURE__ */ new Set()), K = w(() => k.find((e) => e.id === M), [k, M]);
95
+ C(() => {
96
+ vt || (!K || K.requiresAdmin && !U) && M !== "assistant" && st("assistant");
97
97
  }, [
98
- N,
99
- St,
100
- W,
101
- ht,
102
- it
98
+ M,
99
+ K,
100
+ U,
101
+ vt,
102
+ st
103
103
  ]);
104
- let q = C((e, t, n, r) => {
105
- L(e, n, t, null), r ? st(e, t, r) : st(e, t, Ue(n));
106
- }, [L, st]), Ct = C(async (e, t, n, a, s) => {
107
- let c = S.getState().sandboxesByMode[n]?.sandboxId ?? null, u = async (e) => {
108
- if (K.current.isFresh(e)) return !0;
104
+ let q = S((e, t, n, r) => {
105
+ L(e, n, t, null), r ? lt(e, t, r) : lt(e, t, Ke(n));
106
+ }, [L, lt]), Tt = S(async (e, t, n, r, o) => {
107
+ let c = x.getState().sandboxesByMode[n]?.sandboxId ?? null, l = async (e) => {
108
+ if (G.current.isFresh(e)) return !0;
109
109
  try {
110
- return await f(e, a, s, 3e5), await d(e, a, s, 9e4), K.current.markVerified(e), !0;
110
+ return await m(e, r, o, 3e5), await p(e, r, o, 9e4), G.current.markVerified(e), !0;
111
111
  } catch {
112
- return K.current.invalidate(e), !1;
112
+ return G.current.invalidate(e), !1;
113
113
  }
114
114
  };
115
- if (c && (z(n, c, "provisioning"), q(e, t, "provisioning", "Reusing assistant environment..."), await u(c) || (z(n, null, "provisioning"), c = null)), !c) {
115
+ if (c && (R(n, c, "provisioning"), q(e, t, "provisioning", "Reusing assistant environment..."), await l(c) || (R(n, null, "provisioning"), c = null)), !c) {
116
116
  q(e, t, "provisioning", "Looking for existing environment...");
117
- let r = await o(a, k, n, Me(), s);
118
- r && (z(n, r, "provisioning"), q(e, t, "provisioning", "Reusing assistant environment..."), await u(r) ? c = r : z(n, null, "provisioning"));
117
+ let i = await s(r, O, n, Fe(), o);
118
+ i && (R(n, i, "provisioning"), q(e, t, "provisioning", "Reusing assistant environment..."), await l(i) ? c = i : R(n, null, "provisioning"));
119
119
  }
120
120
  if (!c) {
121
- if (n === "api-calls" && !j()) throw Error("API Calls mode requires an authenticated session. Please sign in again.");
122
- q(e, t, "provisioning", "Starting assistant environment..."), z(n, null, "provisioning"), c = await r(k, n, a, Me(), Re, s), z(n, c, "provisioning"), await f(c, a, s, 3e5), await d(c, a, s, 9e4);
121
+ if (n === "api-calls" && !A()) throw Error("API Calls mode requires an authenticated session. Please sign in again.");
122
+ q(e, t, "provisioning", "Starting assistant environment..."), R(n, null, "provisioning"), await d(r, O, n, Fe(), o), c = await i(O, n, r, Fe(), Ve, o), R(n, c, "provisioning"), await m(c, r, o, 3e5), await p(c, r, o, 9e4);
123
123
  }
124
- z(n, c, "running");
125
- let p = S.getState().conversations.find((t) => t.id === e)?.backendSessionId ?? null;
126
- if (p) try {
127
- let e = await l(c, a, p, s);
124
+ R(n, c, "running");
125
+ let f = x.getState().conversations.find((t) => t.id === e)?.backendSessionId ?? null;
126
+ if (f) try {
127
+ let e = await u(c, r, f, o);
128
128
  if (e.mode !== n) throw Error(`Session mode mismatch: expected ${n}, received ${e.mode}`);
129
129
  } catch {
130
- R(e), p = null;
130
+ ft(e), f = null;
131
131
  }
132
- return p || (q(e, t, "connecting", "Preparing session..."), p = (await i(c, a, n, s)).sessionId, lt(e, p)), {
132
+ return f || (q(e, t, "connecting", "Preparing session..."), f = (await a(c, r, n, o)).sessionId, dt(e, f)), {
133
133
  sandboxId: c,
134
- sessionId: p
134
+ sessionId: f
135
135
  };
136
136
  }, [
137
+ ft,
138
+ A,
139
+ O,
140
+ dt,
137
141
  R,
138
- j,
139
- k,
140
- lt,
141
- z,
142
142
  q
143
- ]), J = C(async (e, t = [], r = {}) => {
144
- let i = r.voiceSessionId !== void 0, o = S.getState(), l = o.activeConversationId ?? M;
145
- if (l && (fe(o.processingByConversationId[l]?.status) || xt.current.has(l))) return;
146
- let d = o.mode, f = M, p = f ? S.getState().conversations.find((e) => e.id === f) : void 0;
147
- if (f ? p && p.mode !== d && (p.messages.length > 0 || p.backendSessionId) ? f = P(void 0, d) : p && p.mode !== d && at(f, d) : f = P(void 0, d), !f) return;
148
- bt.current[f] = t;
149
- let m = ge(), g = {
150
- accessToken: j(),
151
- workspaceToken: qe(),
152
- userId: Je,
153
- organizationId: he()
154
- }, _ = {
155
- id: Be(),
143
+ ]), [Et, Dt] = Le(null), Ot = S(async (e) => {
144
+ let t = x.getState(), n = t.sandboxesByMode[t.mode]?.sandboxId, i = ye(), a = t.activeConversationId;
145
+ if (!(!n || !i || !a)) {
146
+ Dt(e);
147
+ try {
148
+ await r(n, i, e, {
149
+ accessToken: A(),
150
+ workspaceToken: Xe(),
151
+ userId: Ze,
152
+ organizationId: ve()
153
+ });
154
+ } catch (e) {
155
+ Dt(null), F(a, {
156
+ id: Ue(),
157
+ role: "system",
158
+ content: e instanceof Error ? e.message : "The change could not be approved.",
159
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
160
+ });
161
+ return;
162
+ }
163
+ Dt(null), Y.current(D("pendingWrite.approvedPrompt", "I approved that change — go ahead."));
164
+ }
165
+ }, [
166
+ Ze,
167
+ F,
168
+ D
169
+ ]), J = S(async (e, t = [], r = {}) => {
170
+ let i = r.voiceSessionId !== void 0, a = x.getState(), s = a.activeConversationId ?? j;
171
+ if (s && (he(a.processingByConversationId[s]?.status) || wt.current.has(s))) return;
172
+ let u = a.mode, d = j, p = d ? x.getState().conversations.find((e) => e.id === d) : void 0;
173
+ if (d ? p && p.mode !== u && (p.messages.length > 0 || p.backendSessionId) ? d = P(void 0, u) : p && p.mode !== u && N(d, u) : d = P(void 0, u), !d) return;
174
+ Ct.current[d] = t;
175
+ let m = ye(), h = {
176
+ accessToken: A(),
177
+ workspaceToken: Xe(),
178
+ userId: Ze,
179
+ organizationId: ve()
180
+ }, g = {
181
+ id: Ue(),
156
182
  role: "user",
157
183
  content: e,
158
184
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
159
185
  metadata: {
160
- ...t.length ? { attachments: t.map(de) } : {},
161
- ...h(r.voiceSessionId)
186
+ ...t.length ? { attachments: t.map(me) } : {},
187
+ ..._(r.voiceSessionId)
162
188
  }
163
189
  };
164
- F(f, _);
165
- let v = Be();
166
- F(f, {
190
+ F(d, g);
191
+ let v = Ue();
192
+ F(d, {
167
193
  id: v,
168
194
  role: "assistant",
169
195
  content: "",
170
196
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
171
197
  metadata: {
172
- lang: tt,
173
- ...h(r.voiceSessionId)
198
+ lang: it,
199
+ ..._(r.voiceSessionId)
174
200
  }
175
- }), L(f, "provisioning", v, null);
176
- let te = (e, t, n, i, a = tt) => {
177
- I(f, v, { content: ee(e) }), ct(f, v, {
201
+ }), L(d, "provisioning", v, null);
202
+ let te = (e, t, n, i, a = it) => {
203
+ I(d, v, { content: ee(e) }), ut(d, v, {
178
204
  lang: a,
179
205
  ...t?.length ? { artifacts: t } : {},
180
- ...t?.length || n || i ? { mode: d } : {},
206
+ ...t?.length || n || i ? { mode: u } : {},
181
207
  ...n ? { sessionId: n } : {},
182
208
  ...i ? { sandboxId: i } : {},
183
- ...h(r.voiceSessionId)
209
+ ..._(r.voiceSessionId)
184
210
  });
185
211
  }, y = async (n = 1) => {
186
212
  let r = !1;
187
213
  try {
188
- let { sandboxId: n, sessionId: o } = await Ct(f, v, d, m, g), l = (await c(n, m, o, g, { limit: 50 }).catch(() => [])).reduce((e, t) => Math.max(e, Ve(t)), 0);
189
- q(f, v, "streaming", "Thinking...");
190
- let p = se(e, t), h = Ge?.(d, p, $e, et, i) ?? p, _ = oe(h, t), y = le(_), b = y > 0, re = We?.();
191
- r = ce(t) > y;
214
+ let { sandboxId: n, sessionId: a } = await Tt(d, v, u, m, h), s = (await l(n, m, a, h, { limit: 50 }).catch(() => [])).reduce((e, t) => Math.max(e, We(t)), 0);
215
+ q(d, v, "streaming", "Thinking...");
216
+ let p = ue(e, t), g = Je?.(u, p, nt, rt, i) ?? p, _ = le(g, t), y = fe(_), ne = y > 0, ie = qe?.();
217
+ r = de(t) > y;
192
218
  try {
193
- await u(n, m, o, h, d, re, g, _?.length ? { parts: _ } : void 0);
219
+ await f(n, m, a, g, u, ie, h, _?.length ? { parts: _ } : void 0);
194
220
  } catch (e) {
195
- if (!_ || !Ee(e)) throw e;
196
- await u(n, m, o, h, d, re, g, void 0), r ||= b;
221
+ if (!_ || !ke(e)) throw e;
222
+ await f(n, m, a, g, u, ie, h, void 0), r ||= ne;
197
223
  }
198
- let x = He([], l), ie = Date.now() + (Ie[d] ?? Le), ae = Date.now(), ue = Date.now();
199
- for (; Date.now() < ie && (x = He(await c(n, m, o, g, {
224
+ let b = Ge([], s), ae = Date.now() + (ze[u] ?? Be), oe = Date.now(), se = Date.now();
225
+ for (; Date.now() < ae && (b = Ge(await l(n, m, a, h, {
200
226
  limit: 50,
201
- sinceMs: l
202
- }), l), I(f, v, { content: ee(x.content) }), x.pendingWrite && ct(f, v, { pendingWrite: x.pendingWrite }), !x.done);) Date.now() - ae > 3e4 && (await a(n, m, 600, g).catch(() => void 0), ae = Date.now()), await new Promise((e) => setTimeout(e, ne(Date.now() - ue)));
203
- if (!x.done && d !== "vibe-plugins") throw Error("Assistant response timed out while streaming progress");
204
- let de = d === "vibe-plugins" ? await s(n, m, o, g).then((e) => e).catch(() => []) : void 0;
205
- if (x.done || (x = {
206
- ...x,
207
- content: `${x.content}\n\n_Still building in the background — any artifacts below will finish shortly. Re-open this conversation to pick up the completed plugin._`
208
- }), r && (x = {
209
- ...x,
210
- content: `${x.content}\n\n${O("attachments.imagesNotSent", "_Your photo was too large to include with this message, so the answer above is from the text and the file link only. Try a smaller or more tightly cropped photo._")}`
211
- }), te(x.content, de, o, n), x.tokens) {
212
- I(f, v, { tokens: x.tokens });
227
+ sinceMs: s
228
+ }), s), I(d, v, { content: ee(b.content) }), b.pendingWrite && ut(d, v, { pendingWrite: b.pendingWrite }), !b.done);) Date.now() - oe > 3e4 && (await o(n, m, 600, h).catch(() => void 0), oe = Date.now()), await new Promise((e) => setTimeout(e, re(Date.now() - se)));
229
+ if (!b.done && u !== "vibe-plugins") throw Error("Assistant response timed out while streaming progress");
230
+ let ce = u === "vibe-plugins" ? await c(n, m, a, h).then((e) => e).catch(() => []) : void 0;
231
+ if (b.done || (b = {
232
+ ...b,
233
+ content: `${b.content}\n\n_Still building in the background — any artifacts below will finish shortly. Re-open this conversation to pick up the completed plugin._`
234
+ }), r && (b = {
235
+ ...b,
236
+ content: `${b.content}\n\n${D("attachments.imagesNotSent", "_Your photo was too large to include with this message, so the answer above is from the text and the file link only. Try a smaller or more tightly cropped photo._")}`
237
+ }), te(b.content, ce, a, n), b.tokens) {
238
+ I(d, v, { tokens: b.tokens });
213
239
  try {
214
- await Ke?.({
240
+ await Ye?.({
215
241
  workspaceId: m,
216
- sessionId: o,
217
- messageId: x.messageId,
218
- model: x.model,
219
- tokens: x.tokens
220
- }), ke(k);
242
+ sessionId: a,
243
+ messageId: b.messageId,
244
+ model: b.model,
245
+ tokens: b.tokens
246
+ }), Me(O);
221
247
  } catch {}
222
248
  }
223
- L(f, "complete", v, null);
249
+ L(d, "complete", v, null);
224
250
  } catch (e) {
225
- if (n === 1 && De(e)) return R(f), ut(d), y(2);
251
+ if (n === 1 && Ae(e)) return ft(d), pt(u), y(2);
226
252
  throw e;
227
253
  }
228
- }, b = f;
229
- xt.current.add(b);
254
+ }, ne = d;
255
+ wt.current.add(ne);
230
256
  try {
231
257
  if (!m) throw Error("Assistant backend is unavailable without an active workspace context.");
232
258
  await y();
233
259
  } catch (e) {
234
- if (K.current.invalidate(S.getState().sandboxesByMode[d]?.sandboxId ?? null), n(e)) {
235
- Oe(k, "sandbox"), te("You've reached your sandbox limit on the current plan. Upgrade to start the AI assistant.", void 0, void 0, void 0, "en"), L(f, "error", v, null);
260
+ if (G.current.invalidate(x.getState().sandboxesByMode[u]?.sandboxId ?? null), n(e)) {
261
+ je(O, "sandbox"), te("You've reached your sandbox limit on the current plan. Upgrade to start the AI assistant.", void 0, void 0, void 0, "en"), L(d, "error", v, null);
236
262
  return;
237
263
  }
238
264
  let t = e instanceof Error ? e.message : "Something went wrong";
239
- L(f, "error", v, t), I(f, v, { content: `Sorry, an error occurred: ${t}. Please try again.` }), ct(f, v, {
265
+ L(d, "error", v, t), I(d, v, { content: `Sorry, an error occurred: ${t}. Please try again.` }), ut(d, v, {
240
266
  lang: "en",
241
- ...h(r.voiceSessionId)
267
+ ..._(r.voiceSessionId)
242
268
  });
243
269
  } finally {
244
- xt.current.delete(b);
270
+ wt.current.delete(ne);
245
271
  }
246
272
  }, [
247
- M,
273
+ j,
248
274
  F,
249
- Ge,
250
- R,
251
- ut,
252
- nt,
275
+ Je,
276
+ ft,
277
+ pt,
278
+ at,
253
279
  P,
254
- Ct,
255
- We,
256
- j,
280
+ Tt,
257
281
  qe,
282
+ A,
283
+ Xe,
258
284
  I,
259
- k,
260
- Ke,
261
- et,
262
- tt,
263
- $e,
264
- lt,
265
- at,
266
- L,
267
285
  O,
286
+ Ye,
287
+ rt,
288
+ it,
289
+ nt,
290
+ dt,
291
+ N,
292
+ L,
293
+ D,
268
294
  q,
269
- Je
270
- ]), wt = C((e) => {
295
+ Ze
296
+ ]), kt = S((e) => {
271
297
  J(e);
272
- }, [J]), Tt = C(() => {
273
- let e = [...B.chat].reverse().find((e) => e.role === "user"), t = M ? bt.current[M] ?? [] : [];
298
+ }, [J]), At = S(() => {
299
+ let e = [...z.chat].reverse().find((e) => e.role === "user"), t = j ? Ct.current[j] ?? [] : [];
274
300
  e && J(e.content, t);
275
301
  }, [
276
- V,
302
+ B,
277
303
  J,
278
- M
279
- ]), Y = E(J);
280
- w(() => {
304
+ j
305
+ ]), Y = T(J);
306
+ C(() => {
281
307
  Y.current = J;
282
308
  }, [J]);
283
- let Et = T(() => {
284
- if (U) return null;
285
- for (let e = V.length - 1; e >= 0; --e) {
286
- let t = V[e];
287
- if (t?.role !== "assistant" || !m(t)) continue;
288
- let n = pe(t.content).text.trim();
309
+ let jt = w(() => {
310
+ if (H) return null;
311
+ for (let e = B.length - 1; e >= 0; --e) {
312
+ let t = B[e];
313
+ if (t?.role !== "assistant" || !g(t)) continue;
314
+ let n = ge(t.content).text.trim();
289
315
  return n ? {
290
316
  id: t.id,
291
317
  text: n
292
318
  } : null;
293
319
  }
294
320
  return null;
295
- }, [V, U]), Dt = T(() => Et ? y(Et.text) : null, [Et]), Ot = B.chat, X = T(() => B.voice.filter((e) => e.role === "user" || e.role === "assistant").map((e) => ({
321
+ }, [B, H]), Mt = w(() => jt ? ie(jt.text) : null, [jt]), Nt = z.chat, X = w(() => z.voice.filter((e) => e.role === "user" || e.role === "assistant").map((e) => ({
296
322
  id: e.id,
297
323
  role: e.role,
298
- text: pe(e.content).text.trim(),
299
- sessionId: g(e),
324
+ text: ge(e.content).text.trim(),
325
+ sessionId: v(e),
300
326
  timestamp: e.timestamp
301
- })).filter((e) => e.text.length > 0), [B.voice]), kt = C(() => {
327
+ })).filter((e) => e.text.length > 0), [z.voice]), Pt = S(() => {
302
328
  if (X.length === 0) return;
303
329
  let e = /* @__PURE__ */ new Date();
304
- be(v(X, {
305
- title: O("voiceSession.transcript", "Voice conversation"),
306
- savedAt: O("voiceSession.savedAt", "Saved"),
307
- session: O("voiceSession.sessionLabel", "Session"),
308
- earlier: O("voiceSession.earlierLabel", "Earlier"),
309
- you: O("voiceSession.speakerYou", "You"),
310
- assistant: O("voiceSession.speakerAssistant", "Assistant")
311
- }, e), te(k, e), "text/markdown");
330
+ Ce(y(X, {
331
+ title: D("voiceSession.transcript", "Voice conversation"),
332
+ savedAt: D("voiceSession.savedAt", "Saved"),
333
+ session: D("voiceSession.sessionLabel", "Session"),
334
+ earlier: D("voiceSession.earlierLabel", "Earlier"),
335
+ you: D("voiceSession.speakerYou", "You"),
336
+ assistant: D("voiceSession.speakerAssistant", "Assistant")
337
+ }, e), ne(O, e), "text/markdown");
312
338
  }, [
313
- k,
339
+ O,
314
340
  X,
315
- O
316
- ]), Z = Ae(), Q = E(Z);
341
+ D
342
+ ]), Z = Ne(), Q = T(Z);
317
343
  Q.current = Z;
318
- let $ = me({
319
- onSubmit: C((e, t) => {
344
+ let $ = _e({
345
+ onSubmit: S((e, t) => {
320
346
  let n = () => {
321
- let n = Q.current, r = ue(n.attachments);
347
+ let n = Q.current, r = pe(n.attachments);
322
348
  Y.current(e, r, { voiceSessionId: t }), n.clear();
323
349
  };
324
350
  if (!Q.current.isBusy) {
@@ -326,125 +352,127 @@ var A = ({ visible: p = !0, writeAccess: x = "unknown" }) => {
326
352
  return;
327
353
  }
328
354
  let r = Date.now(), i = window.setInterval(() => {
329
- Q.current.isBusy && Date.now() - r < ze || (window.clearInterval(i), n());
355
+ Q.current.isBusy && Date.now() - r < He || (window.clearInterval(i), n());
330
356
  }, 200);
331
357
  }, []),
332
- latestReply: Et,
333
- language: b(Xe, Ye).tag
334
- }), At = T(() => (ft?.messages ?? []).reduce((e, t) => Math.max(e, t.metadata?.continuedVoiceTurns ?? 0), 0), [ft?.messages]), jt = X.length > At, Mt = C(() => {
335
- let e = S.getState().activeConversationId;
358
+ latestReply: jt,
359
+ language: b($e, Qe).tag
360
+ }), Ft = w(() => (ht?.messages ?? []).reduce((e, t) => Math.max(e, t.metadata?.continuedVoiceTurns ?? 0), 0), [ht?.messages]), It = X.length > Ft, Lt = S(() => {
361
+ let e = x.getState().activeConversationId;
336
362
  !e || X.length === 0 || (F(e, {
337
- id: Be(),
363
+ id: Ue(),
338
364
  role: "system",
339
- content: _(X.slice(At), {
340
- intro: O("voiceSession.continuedIntro", "Continued from a voice conversation. You asked about:"),
341
- nothing: O("voiceSession.continuedNothing", "Continued from a voice conversation."),
342
- more: (e) => O("voiceSession.continuedMore", "…and {{count}} more", { count: e })
365
+ content: te(X.slice(Ft), {
366
+ intro: D("voiceSession.continuedIntro", "Continued from a voice conversation. You asked about:"),
367
+ nothing: D("voiceSession.continuedNothing", "Continued from a voice conversation."),
368
+ more: (e) => D("voiceSession.continuedMore", "…and {{count}} more", { count: e })
343
369
  }),
344
370
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
345
371
  metadata: { continuedVoiceTurns: X.length }
346
- }), G(!1), $.end());
372
+ }), W(!1), $.end());
347
373
  }, [
348
374
  X,
349
- At,
375
+ Ft,
350
376
  F,
351
- O,
377
+ D,
352
378
  $
353
- ]), Nt = E(0);
354
- w(() => {
355
- $.active && (Nt.current = X.length);
379
+ ]), Rt = T(0);
380
+ C(() => {
381
+ $.active && (Rt.current = X.length);
356
382
  }, [$.active]);
357
- let Pt = C(() => {
358
- let e = X.length > Nt.current;
359
- $.end(), e && G(!0);
383
+ let zt = S(() => {
384
+ let e = X.length > Rt.current;
385
+ $.end(), e && W(!0);
360
386
  }, [X, $]);
361
- w(() => {
362
- !p && $.active && $.end();
363
- }, [p, $]), w(() => {
387
+ C(() => {
388
+ !h && $.active && $.end();
389
+ }, [h, $]), C(() => {
364
390
  $.active || Q.current.clear();
365
- }, [$.active]), w(() => {
366
- let e = S.getState().consumePendingPrompt();
367
- return e && Y.current(e), S.subscribe((e, t) => {
391
+ }, [$.active]), C(() => {
392
+ let e = x.getState().consumePendingPrompt();
393
+ return e && Y.current(e), x.subscribe((e, t) => {
368
394
  if (e.pendingPrompt && e.pendingPrompt !== t.pendingPrompt) {
369
- let e = S.getState().consumePendingPrompt();
395
+ let e = x.getState().consumePendingPrompt();
370
396
  e && Y.current(e);
371
397
  }
372
398
  });
373
399
  }, []);
374
- let Ft = C((e) => {
375
- let t = M ? S.getState().conversations.find((e) => e.id === M) : void 0;
400
+ let Bt = S((e) => {
401
+ let t = j ? x.getState().conversations.find((e) => e.id === j) : void 0;
376
402
  if (t && (t.messages.length > 0 || t.backendSessionId)) {
377
403
  if (t.mode !== e) {
378
- let t = S.getState().conversations.find((t) => t.mode === e && t.messages.length === 0 && !t.backendSessionId && !S.getState().processingByConversationId[t.id]);
379
- t ? ot(t.id) : P(void 0, e);
404
+ let t = x.getState().conversations.find((t) => t.mode === e && t.messages.length === 0 && !t.backendSessionId && !x.getState().processingByConversationId[t.id]);
405
+ t ? ct(t.id) : P(void 0, e);
380
406
  }
381
- } else M && at(M, e);
382
- it(e);
407
+ } else j && N(j, e);
408
+ st(e);
383
409
  }, [
384
- M,
410
+ j,
385
411
  P,
386
- ot,
387
- at,
388
- it
389
- ]), It = C((e) => {
390
- if (A.find((t) => t.id === e)?.writeCapable && !S.getState().apiCallsAcknowledged) {
391
- vt(e);
412
+ ct,
413
+ N,
414
+ st
415
+ ]), Vt = S((e) => {
416
+ if (k.find((t) => t.id === e)?.writeCapable && !x.getState().apiCallsAcknowledged) {
417
+ xt(e);
392
418
  return;
393
419
  }
394
- Ft(e);
395
- }, [Ft, A]), Lt = C(() => {
396
- let e = _t;
397
- vt(null), dt(), e && Ft(e);
420
+ Bt(e);
421
+ }, [Bt, k]), Ht = S(() => {
422
+ let e = bt;
423
+ xt(null), mt(), e && Bt(e);
398
424
  }, [
399
- _t,
400
- dt,
401
- Ft
402
- ]), Rt = C(() => {
403
- vt(null);
425
+ bt,
426
+ mt,
427
+ Bt
428
+ ]), Ut = S(() => {
429
+ xt(null);
404
430
  }, []);
405
- return /* @__PURE__ */ Fe("div", {
431
+ return /* @__PURE__ */ Re("div", {
406
432
  className: "relative flex flex-1 flex-col overflow-hidden",
407
433
  children: [
408
- /* @__PURE__ */ Fe("div", {
434
+ /* @__PURE__ */ Re("div", {
409
435
  className: "contents",
410
436
  inert: $.active || void 0,
411
437
  children: [
412
- X.length > 0 && !$.active ? /* @__PURE__ */ D(ve, {
438
+ X.length > 0 && !$.active ? /* @__PURE__ */ E(xe, {
413
439
  count: X.length,
414
- onOpenTranscript: () => G(!0)
440
+ onOpenTranscript: () => W(!0)
415
441
  }) : null,
416
- Ot.length === 0 ? /* @__PURE__ */ D(xe, {
417
- mode: N,
418
- onSuggestionClick: wt
419
- }) : /* @__PURE__ */ D("div", {
442
+ Nt.length === 0 ? /* @__PURE__ */ E(we, {
443
+ mode: M,
444
+ onSuggestionClick: kt
445
+ }) : /* @__PURE__ */ E("div", {
420
446
  className: "flex min-h-0 flex-1 flex-col",
421
- children: /* @__PURE__ */ D(Se, {
422
- messages: Ot,
423
- streamingMessageId: pt,
424
- failedMessageId: mt,
425
- onRetry: Tt
447
+ children: /* @__PURE__ */ E(Te, {
448
+ onApprovePendingWrite: Ot,
449
+ approvingWriteRef: Et,
450
+ messages: Nt,
451
+ streamingMessageId: gt,
452
+ failedMessageId: _t,
453
+ onRetry: At
426
454
  })
427
455
  }),
428
- /* @__PURE__ */ D(je, {
429
- onStartVoiceSession: $.available && N !== "api-calls" ? $.start : void 0,
456
+ /* @__PURE__ */ E(Pe, {
457
+ onStartVoiceSession: $.available && M !== "api-calls" ? $.start : void 0,
430
458
  onSend: (e, t) => void J(e, t),
431
- disabled: U,
432
- placeholder: N === "api-calls" ? O("chatArea.placeholderActions", "What would you like me to do?") : O("chatArea.placeholderGeneral", "Ask me anything…"),
433
- mode: N,
434
- writeAccessDenied: x === "denied" && !!St?.writeCapable,
435
- availableModes: gt,
436
- onModeChange: It
459
+ disabled: H,
460
+ placeholder: M === "api-calls" ? D("chatArea.placeholderActions", "What would you like me to do?") : D("chatArea.placeholderGeneral", "Ask me anything…"),
461
+ mode: M,
462
+ writeAccessDenied: oe === "denied" && !!K?.writeCapable,
463
+ availableModes: yt,
464
+ onModeChange: Vt
437
465
  })
438
466
  ]
439
467
  }),
440
- yt && !$.active ? /* @__PURE__ */ D(ye, {
468
+ St && !$.active ? /* @__PURE__ */ E(Se, {
441
469
  turns: X,
442
- onClose: () => G(!1),
443
- onSave: kt,
444
- onContinueInChat: jt ? Mt : void 0,
470
+ onClose: () => W(!1),
471
+ onSave: Pt,
472
+ onContinueInChat: It ? Lt : void 0,
445
473
  closeOnEscape: !0
446
474
  }) : null,
447
- $.active && /* @__PURE__ */ D(Ce, {
475
+ $.active && /* @__PURE__ */ E(Ee, {
448
476
  session: $.session,
449
477
  notice: $.notice,
450
478
  capturing: $.capturing,
@@ -458,20 +486,20 @@ var A = ({ visible: p = !0, writeAccess: x = "unknown" }) => {
458
486
  onRetryAttachment: Z.retry,
459
487
  canAttachMore: Z.canAddMore,
460
488
  preparingAttachments: Z.preparingCount,
461
- onSaveTranscript: kt,
462
- onContinueInChat: Mt,
489
+ onSaveTranscript: Pt,
490
+ onContinueInChat: Lt,
463
491
  onInterrupt: $.interrupt,
464
- spoken: Dt,
492
+ spoken: Mt,
465
493
  onToggleMute: $.toggleMute,
466
- onEnd: Pt
494
+ onEnd: zt
467
495
  }),
468
- /* @__PURE__ */ D(Ne, {
469
- open: _t !== null,
470
- onConfirm: Lt,
471
- onCancel: Rt
496
+ /* @__PURE__ */ E(Ie, {
497
+ open: bt !== null,
498
+ onConfirm: Ht,
499
+ onCancel: Ut
472
500
  })
473
501
  ]
474
502
  });
475
503
  };
476
504
  //#endregion
477
- export { A as AssistantChatArea };
505
+ export { k as AssistantChatArea };