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