@helpai/elements 0.50.2 → 0.50.4
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/elements-web-component.esm.js +18 -18
- package/elements-web-component.esm.js.map +3 -3
- package/elements.cjs.js +18 -18
- package/elements.cjs.js.map +3 -3
- package/elements.esm.js +18 -18
- package/elements.esm.js.map +3 -3
- package/elements.js +18 -18
- package/elements.js.map +3 -3
- package/index.d.ts +1 -1
- package/index.mjs +42 -19
- package/package.json +1 -1
- package/schema.d.ts +26 -26
- package/web-component.mjs +42 -19
package/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { A as Asset, B as BlocksConfig, C as ConnectionConfig, a as ConnectionConfigPartial, H as HandshakeResponse, L as Link, S as ServerConfig, b as SiteConfig, W as WidgetConfig, c as WidgetConfigPartial, d as WidgetSettings, e as WidgetSettingsPartial } from './deployment-
|
|
1
|
+
export { A as Asset, B as BlocksConfig, C as ConnectionConfig, a as ConnectionConfigPartial, H as HandshakeResponse, L as Link, S as ServerConfig, b as SiteConfig, W as WidgetConfig, c as WidgetConfigPartial, d as WidgetSettings, e as WidgetSettingsPartial } from './deployment-oSJ2nv2G.js';
|
|
2
2
|
import 'zod';
|
|
3
3
|
|
|
4
4
|
/**
|
package/index.mjs
CHANGED
|
@@ -29,7 +29,7 @@ var BRAND = {
|
|
|
29
29
|
};
|
|
30
30
|
|
|
31
31
|
// src/core/version.ts
|
|
32
|
-
var ELEMENTS_VERSION = true ? "0.50.
|
|
32
|
+
var ELEMENTS_VERSION = true ? "0.50.4" : "0.0.0-dev";
|
|
33
33
|
var ELEMENTS_VERSION_PARAM = "_ev";
|
|
34
34
|
|
|
35
35
|
// src/i18n/strings.ts
|
|
@@ -2016,7 +2016,8 @@ function buildSendMessageRequest(params) {
|
|
|
2016
2016
|
conversationId: params.conversationId,
|
|
2017
2017
|
trigger: params.trigger ?? "submit-message"
|
|
2018
2018
|
};
|
|
2019
|
-
|
|
2019
|
+
const anchorId = wire.at(-1)?.id;
|
|
2020
|
+
if (anchorId) body.messageId = anchorId;
|
|
2020
2021
|
if (params.visitorId) body.visitorId = params.visitorId;
|
|
2021
2022
|
if (params.userPrefs) body.userPrefs = params.userPrefs;
|
|
2022
2023
|
const tools = params.tools?.map(normalizeToolRef).filter((t) => t !== null);
|
|
@@ -2875,12 +2876,44 @@ var StreamReducer = class {
|
|
|
2875
2876
|
__publicField(this, "messagesSig", messagesSig);
|
|
2876
2877
|
/** Currently-streaming assistant message; null when no stream is active. */
|
|
2877
2878
|
__publicField(this, "active", null);
|
|
2879
|
+
/**
|
|
2880
|
+
* Text/reasoning parts still "open" in the CURRENT step, keyed `${kind}:${id}`.
|
|
2881
|
+
* Cleared per stream (`attach`) and per step boundary (`finish-step`) — exactly
|
|
2882
|
+
* like web-www's per-step `activeTextParts`. Lookups go through this map, NOT a
|
|
2883
|
+
* scan of the whole message, so a text id reused in a LATER step or in a resume
|
|
2884
|
+
* stream (e.g. the reply that continues after an approval pause) starts a NEW
|
|
2885
|
+
* part instead of merging into an earlier same-id part. Without it the
|
|
2886
|
+
* continuation text merges into the pre-tool text and renders ABOVE the tool
|
|
2887
|
+
* card (correct only after a reload, when the backend replays ordered parts).
|
|
2888
|
+
*/
|
|
2889
|
+
__publicField(this, "openTextParts", /* @__PURE__ */ new Map());
|
|
2890
|
+
/** Monotonic counter for client-unique part ids (the React key). The backend
|
|
2891
|
+
* reuses chunk ids across steps/streams, so the chunk id alone is NOT a safe
|
|
2892
|
+
* key — two parts could share `txt-0` and collide. Part ids are client-only
|
|
2893
|
+
* (text/reasoning ids never ride the wire), so a counter is sufficient. */
|
|
2894
|
+
__publicField(this, "partSeq", 0);
|
|
2878
2895
|
}
|
|
2879
2896
|
attach(msg) {
|
|
2880
2897
|
this.active = msg;
|
|
2898
|
+
this.openTextParts.clear();
|
|
2881
2899
|
}
|
|
2882
2900
|
detach() {
|
|
2883
2901
|
this.active = null;
|
|
2902
|
+
this.openTextParts.clear();
|
|
2903
|
+
}
|
|
2904
|
+
/**
|
|
2905
|
+
* Find-or-create the open text/reasoning part for `id` within the current step.
|
|
2906
|
+
* Scoped to {@link openTextParts} (reset on step/stream boundaries) so parts
|
|
2907
|
+
* never merge across a tool/resume boundary. Mirrors www's `ensureTextPart`.
|
|
2908
|
+
*/
|
|
2909
|
+
ensureTextPart(m, kind, id) {
|
|
2910
|
+
const key = `${kind}:${id}`;
|
|
2911
|
+
const existing = this.openTextParts.get(key);
|
|
2912
|
+
if (existing) return existing;
|
|
2913
|
+
const part = { kind, id: `${id}#${this.partSeq++}`, textSig: signal2(""), doneSig: signal2(false) };
|
|
2914
|
+
this.openTextParts.set(key, part);
|
|
2915
|
+
appendPart(m, part);
|
|
2916
|
+
return part;
|
|
2884
2917
|
}
|
|
2885
2918
|
apply(chunk) {
|
|
2886
2919
|
const m = this.active;
|
|
@@ -2890,6 +2923,7 @@ var StreamReducer = class {
|
|
|
2890
2923
|
if (chunk.messageId) m.serverMessageId = chunk.messageId;
|
|
2891
2924
|
return;
|
|
2892
2925
|
case "finish-step":
|
|
2926
|
+
this.openTextParts.clear();
|
|
2893
2927
|
return;
|
|
2894
2928
|
case "start-step":
|
|
2895
2929
|
appendPart(m, { kind: "step-start", id: `ss${m.partsSig.value.length}` });
|
|
@@ -2907,26 +2941,26 @@ var StreamReducer = class {
|
|
|
2907
2941
|
this.bumpDone(m);
|
|
2908
2942
|
return;
|
|
2909
2943
|
case "text-start":
|
|
2910
|
-
ensureTextPart(m, "text", chunk.id);
|
|
2944
|
+
this.ensureTextPart(m, "text", chunk.id);
|
|
2911
2945
|
return;
|
|
2912
2946
|
case "text-delta": {
|
|
2913
|
-
const p36 = ensureTextPart(m, "text", chunk.id);
|
|
2947
|
+
const p36 = this.ensureTextPart(m, "text", chunk.id);
|
|
2914
2948
|
p36.textSig.value += chunk.delta;
|
|
2915
2949
|
return;
|
|
2916
2950
|
}
|
|
2917
2951
|
case "text-end":
|
|
2918
|
-
ensureTextPart(m, "text", chunk.id).doneSig.value = true;
|
|
2952
|
+
this.ensureTextPart(m, "text", chunk.id).doneSig.value = true;
|
|
2919
2953
|
return;
|
|
2920
2954
|
case "reasoning-start":
|
|
2921
|
-
ensureTextPart(m, "reasoning", chunk.id).doneSig.value = false;
|
|
2955
|
+
this.ensureTextPart(m, "reasoning", chunk.id).doneSig.value = false;
|
|
2922
2956
|
return;
|
|
2923
2957
|
case "reasoning-delta": {
|
|
2924
|
-
const p36 = ensureTextPart(m, "reasoning", chunk.id);
|
|
2958
|
+
const p36 = this.ensureTextPart(m, "reasoning", chunk.id);
|
|
2925
2959
|
p36.textSig.value += chunk.delta;
|
|
2926
2960
|
return;
|
|
2927
2961
|
}
|
|
2928
2962
|
case "reasoning-end":
|
|
2929
|
-
ensureTextPart(m, "reasoning", chunk.id).doneSig.value = true;
|
|
2963
|
+
this.ensureTextPart(m, "reasoning", chunk.id).doneSig.value = true;
|
|
2930
2964
|
return;
|
|
2931
2965
|
case "tool-input-start":
|
|
2932
2966
|
case "tool-input-delta":
|
|
@@ -2971,13 +3005,6 @@ var StreamReducer = class {
|
|
|
2971
3005
|
this.messagesSig.value = [...this.messagesSig.value];
|
|
2972
3006
|
}
|
|
2973
3007
|
};
|
|
2974
|
-
function ensureTextPart(m, kind, id) {
|
|
2975
|
-
const existing = m.partsSig.value.find((p36) => p36.kind === kind && p36.id === id);
|
|
2976
|
-
if (existing) return existing;
|
|
2977
|
-
const part = { kind, id, textSig: signal2(""), doneSig: signal2(false) };
|
|
2978
|
-
appendPart(m, part);
|
|
2979
|
-
return part;
|
|
2980
|
-
}
|
|
2981
3008
|
function ensureToolPart(m, toolCallId, toolName2) {
|
|
2982
3009
|
const existing = m.partsSig.value.find((p36) => p36.kind === "tool" && p36.toolCallId === toolCallId);
|
|
2983
3010
|
if (existing) return existing;
|
|
@@ -7950,10 +7977,6 @@ function App({ options, hostElement, bus }) {
|
|
|
7950
7977
|
const body = buildSendMessageRequest({
|
|
7951
7978
|
messages: thread.map(fromReactive),
|
|
7952
7979
|
conversationId: activeConversationId,
|
|
7953
|
-
// The assistant message being generated / resumed — prefer the id the
|
|
7954
|
-
// backend assigned (adopted from the `start` chunk) so a HITL re-POST
|
|
7955
|
-
// resumes the message the backend persisted, not the client-minted id.
|
|
7956
|
-
messageId: assistantMsg.serverMessageId ?? assistantMsg.id,
|
|
7957
7980
|
// textModel + imageModel are backend-only — selected per deployment.
|
|
7958
7981
|
tools: options.features.tools,
|
|
7959
7982
|
// Identity + preferences ride on every message — server may need
|
package/package.json
CHANGED
package/schema.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { A as Asset, B as BlocksConfig, C as ConnectionConfig, a as ConnectionConfigPartial, E as Endpoints, H as HandshakeResponse, L as Link, P as PAGE_AREA_SUGGESTIONS, f as PageContext, S as ServerConfig, b as SiteConfig, U as UserContext, W as WidgetConfig, c as WidgetConfigPartial, d as WidgetSettings, e as WidgetSettingsPartial, g as assetSchema, h as blocksConfigSchema, i as connectionConfigPartialSchema, j as connectionConfigSchema, k as cssColorSchema, l as cssLengthSchema, m as endpointsSchema, n as handshakeResponseSchema, o as linkSchema, p as localeSchema, q as pageContextSchema, s as serverConfigSchema, r as siteConfigSchema, u as userContextSchema, t as uuid7Schema, w as widgetConfigPartialSchema, v as widgetConfigSchema, x as widgetSettingsPartialSchema, y as widgetSettingsSchema } from './deployment-
|
|
1
|
+
export { A as Asset, B as BlocksConfig, C as ConnectionConfig, a as ConnectionConfigPartial, E as Endpoints, H as HandshakeResponse, L as Link, P as PAGE_AREA_SUGGESTIONS, f as PageContext, S as ServerConfig, b as SiteConfig, U as UserContext, W as WidgetConfig, c as WidgetConfigPartial, d as WidgetSettings, e as WidgetSettingsPartial, g as assetSchema, h as blocksConfigSchema, i as connectionConfigPartialSchema, j as connectionConfigSchema, k as cssColorSchema, l as cssLengthSchema, m as endpointsSchema, n as handshakeResponseSchema, o as linkSchema, p as localeSchema, q as pageContextSchema, s as serverConfigSchema, r as siteConfigSchema, u as userContextSchema, t as uuid7Schema, w as widgetConfigPartialSchema, v as widgetConfigSchema, x as widgetSettingsPartialSchema, y as widgetSettingsSchema } from './deployment-oSJ2nv2G.js';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -56,9 +56,9 @@ declare const presentationSchema: z.ZodObject<{
|
|
|
56
56
|
inset: z.ZodOptional<z.ZodString>;
|
|
57
57
|
initialSize: z.ZodDefault<z.ZodEnum<{
|
|
58
58
|
fullscreen: "fullscreen";
|
|
59
|
+
normal: "normal";
|
|
59
60
|
expanded: "expanded";
|
|
60
61
|
auto: "auto";
|
|
61
|
-
normal: "normal";
|
|
62
62
|
}>>;
|
|
63
63
|
autoSizeBreakpoint: z.ZodDefault<z.ZodNumber>;
|
|
64
64
|
}, z.core.$loose>>;
|
|
@@ -240,9 +240,9 @@ type LauncherOptions = z.infer<typeof launcherOptionsSchema>;
|
|
|
240
240
|
|
|
241
241
|
declare const initialSizeSchema: z.ZodEnum<{
|
|
242
242
|
fullscreen: "fullscreen";
|
|
243
|
+
normal: "normal";
|
|
243
244
|
expanded: "expanded";
|
|
244
245
|
auto: "auto";
|
|
245
|
-
normal: "normal";
|
|
246
246
|
}>;
|
|
247
247
|
declare const resizeOptionsSchema: z.ZodObject<{
|
|
248
248
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
@@ -269,9 +269,9 @@ declare const sizeOptionsSchema: z.ZodObject<{
|
|
|
269
269
|
inset: z.ZodOptional<z.ZodString>;
|
|
270
270
|
initialSize: z.ZodDefault<z.ZodEnum<{
|
|
271
271
|
fullscreen: "fullscreen";
|
|
272
|
+
normal: "normal";
|
|
272
273
|
expanded: "expanded";
|
|
273
274
|
auto: "auto";
|
|
274
|
-
normal: "normal";
|
|
275
275
|
}>>;
|
|
276
276
|
autoSizeBreakpoint: z.ZodDefault<z.ZodNumber>;
|
|
277
277
|
}, z.core.$loose>;
|
|
@@ -323,40 +323,40 @@ type FeatureFlags = z.infer<typeof featureFlagsSchema>;
|
|
|
323
323
|
*/
|
|
324
324
|
|
|
325
325
|
declare const actionNameSchema: z.ZodEnum<{
|
|
326
|
-
close: "close";
|
|
327
326
|
expand: "expand";
|
|
328
327
|
fullscreen: "fullscreen";
|
|
329
|
-
|
|
330
|
-
theme: "theme";
|
|
328
|
+
close: "close";
|
|
331
329
|
language: "language";
|
|
330
|
+
theme: "theme";
|
|
332
331
|
textSize: "textSize";
|
|
333
332
|
history: "history";
|
|
333
|
+
clear: "clear";
|
|
334
334
|
sound: "sound";
|
|
335
335
|
}>;
|
|
336
336
|
type ActionName = z.infer<typeof actionNameSchema>;
|
|
337
337
|
declare const headerActionsSchema: z.ZodArray<z.ZodEnum<{
|
|
338
|
-
close: "close";
|
|
339
338
|
expand: "expand";
|
|
340
339
|
fullscreen: "fullscreen";
|
|
341
|
-
|
|
342
|
-
theme: "theme";
|
|
340
|
+
close: "close";
|
|
343
341
|
language: "language";
|
|
342
|
+
theme: "theme";
|
|
344
343
|
textSize: "textSize";
|
|
345
344
|
history: "history";
|
|
345
|
+
clear: "clear";
|
|
346
346
|
sound: "sound";
|
|
347
347
|
}>>;
|
|
348
348
|
type HeaderActions = z.infer<typeof headerActionsSchema>;
|
|
349
349
|
/** Section wrapper — `actions` list wrapped under `header` in the dashboard form. */
|
|
350
350
|
declare const headerSchema: z.ZodObject<{
|
|
351
351
|
actions: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
352
|
-
close: "close";
|
|
353
352
|
expand: "expand";
|
|
354
353
|
fullscreen: "fullscreen";
|
|
355
|
-
|
|
356
|
-
theme: "theme";
|
|
354
|
+
close: "close";
|
|
357
355
|
language: "language";
|
|
356
|
+
theme: "theme";
|
|
358
357
|
textSize: "textSize";
|
|
359
358
|
history: "history";
|
|
359
|
+
clear: "clear";
|
|
360
360
|
sound: "sound";
|
|
361
361
|
}>>>;
|
|
362
362
|
}, z.core.$loose>;
|
|
@@ -372,33 +372,33 @@ type HeaderOptions = z.infer<typeof headerSchema>;
|
|
|
372
372
|
*/
|
|
373
373
|
|
|
374
374
|
declare const feedbackEventSchema: z.ZodEnum<{
|
|
375
|
-
voiceStart: "voiceStart";
|
|
376
|
-
voiceStop: "voiceStop";
|
|
377
375
|
error: "error";
|
|
378
376
|
messageReceived: "messageReceived";
|
|
379
377
|
messageSent: "messageSent";
|
|
378
|
+
voiceStart: "voiceStart";
|
|
379
|
+
voiceStop: "voiceStop";
|
|
380
380
|
}>;
|
|
381
381
|
type FeedbackEvent = z.infer<typeof feedbackEventSchema>;
|
|
382
382
|
declare const soundOptionsSchema: z.ZodObject<{
|
|
383
383
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
384
384
|
volume: z.ZodDefault<z.ZodNumber>;
|
|
385
385
|
events: z.ZodOptional<z.ZodRecord<z.ZodEnum<{
|
|
386
|
-
voiceStart: "voiceStart";
|
|
387
|
-
voiceStop: "voiceStop";
|
|
388
386
|
error: "error";
|
|
389
387
|
messageReceived: "messageReceived";
|
|
390
388
|
messageSent: "messageSent";
|
|
389
|
+
voiceStart: "voiceStart";
|
|
390
|
+
voiceStop: "voiceStop";
|
|
391
391
|
}> & z.core.$partial, z.ZodUnion<readonly [z.ZodBoolean, z.ZodString]>>>;
|
|
392
392
|
}, z.core.$loose>;
|
|
393
393
|
type SoundOptions = z.infer<typeof soundOptionsSchema>;
|
|
394
394
|
declare const hapticsOptionsSchema: z.ZodObject<{
|
|
395
395
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
396
396
|
events: z.ZodOptional<z.ZodRecord<z.ZodEnum<{
|
|
397
|
-
voiceStart: "voiceStart";
|
|
398
|
-
voiceStop: "voiceStop";
|
|
399
397
|
error: "error";
|
|
400
398
|
messageReceived: "messageReceived";
|
|
401
399
|
messageSent: "messageSent";
|
|
400
|
+
voiceStart: "voiceStart";
|
|
401
|
+
voiceStop: "voiceStop";
|
|
402
402
|
}> & z.core.$partial, z.ZodUnion<readonly [z.ZodBoolean, z.ZodNumber, z.ZodArray<z.ZodNumber>]>>>;
|
|
403
403
|
}, z.core.$loose>;
|
|
404
404
|
type HapticsOptions = z.infer<typeof hapticsOptionsSchema>;
|
|
@@ -407,21 +407,21 @@ declare const feedbackSchema: z.ZodObject<{
|
|
|
407
407
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
408
408
|
volume: z.ZodDefault<z.ZodNumber>;
|
|
409
409
|
events: z.ZodOptional<z.ZodRecord<z.ZodEnum<{
|
|
410
|
-
voiceStart: "voiceStart";
|
|
411
|
-
voiceStop: "voiceStop";
|
|
412
410
|
error: "error";
|
|
413
411
|
messageReceived: "messageReceived";
|
|
414
412
|
messageSent: "messageSent";
|
|
413
|
+
voiceStart: "voiceStart";
|
|
414
|
+
voiceStop: "voiceStop";
|
|
415
415
|
}> & z.core.$partial, z.ZodUnion<readonly [z.ZodBoolean, z.ZodString]>>>;
|
|
416
416
|
}, z.core.$loose>>;
|
|
417
417
|
haptics: z.ZodOptional<z.ZodObject<{
|
|
418
418
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
419
419
|
events: z.ZodOptional<z.ZodRecord<z.ZodEnum<{
|
|
420
|
-
voiceStart: "voiceStart";
|
|
421
|
-
voiceStop: "voiceStop";
|
|
422
420
|
error: "error";
|
|
423
421
|
messageReceived: "messageReceived";
|
|
424
422
|
messageSent: "messageSent";
|
|
423
|
+
voiceStart: "voiceStart";
|
|
424
|
+
voiceStop: "voiceStop";
|
|
425
425
|
}> & z.core.$partial, z.ZodUnion<readonly [z.ZodBoolean, z.ZodNumber, z.ZodArray<z.ZodNumber>]>>>;
|
|
426
426
|
}, z.core.$loose>>;
|
|
427
427
|
}, z.core.$loose>;
|
|
@@ -856,18 +856,18 @@ type I18nOptions = z.infer<typeof i18nSchema>;
|
|
|
856
856
|
*/
|
|
857
857
|
|
|
858
858
|
declare const moduleLayoutSchema: z.ZodEnum<{
|
|
859
|
-
home: "home";
|
|
860
859
|
chat: "chat";
|
|
861
860
|
help: "help";
|
|
861
|
+
home: "home";
|
|
862
862
|
news: "news";
|
|
863
863
|
}>;
|
|
864
864
|
type ModuleLayout = z.infer<typeof moduleLayoutSchema>;
|
|
865
865
|
declare const moduleSchema: z.ZodObject<{
|
|
866
866
|
label: z.ZodString;
|
|
867
867
|
layout: z.ZodEnum<{
|
|
868
|
-
home: "home";
|
|
869
868
|
chat: "chat";
|
|
870
869
|
help: "help";
|
|
870
|
+
home: "home";
|
|
871
871
|
news: "news";
|
|
872
872
|
}>;
|
|
873
873
|
contentTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -893,9 +893,9 @@ type ModuleOptions = z.infer<typeof moduleSchema>;
|
|
|
893
893
|
declare const modulesSchema: z.ZodArray<z.ZodObject<{
|
|
894
894
|
label: z.ZodString;
|
|
895
895
|
layout: z.ZodEnum<{
|
|
896
|
-
home: "home";
|
|
897
896
|
chat: "chat";
|
|
898
897
|
help: "help";
|
|
898
|
+
home: "home";
|
|
899
899
|
news: "news";
|
|
900
900
|
}>;
|
|
901
901
|
contentTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
package/web-component.mjs
CHANGED
|
@@ -1794,7 +1794,7 @@ function createAuth(opts) {
|
|
|
1794
1794
|
}
|
|
1795
1795
|
|
|
1796
1796
|
// src/core/version.ts
|
|
1797
|
-
var ELEMENTS_VERSION = true ? "0.50.
|
|
1797
|
+
var ELEMENTS_VERSION = true ? "0.50.4" : "0.0.0-dev";
|
|
1798
1798
|
var ELEMENTS_VERSION_PARAM = "_ev";
|
|
1799
1799
|
|
|
1800
1800
|
// src/stream/types.ts
|
|
@@ -1975,7 +1975,8 @@ function buildSendMessageRequest(params) {
|
|
|
1975
1975
|
conversationId: params.conversationId,
|
|
1976
1976
|
trigger: params.trigger ?? "submit-message"
|
|
1977
1977
|
};
|
|
1978
|
-
|
|
1978
|
+
const anchorId = wire.at(-1)?.id;
|
|
1979
|
+
if (anchorId) body.messageId = anchorId;
|
|
1979
1980
|
if (params.visitorId) body.visitorId = params.visitorId;
|
|
1980
1981
|
if (params.userPrefs) body.userPrefs = params.userPrefs;
|
|
1981
1982
|
const tools = params.tools?.map(normalizeToolRef).filter((t) => t !== null);
|
|
@@ -2834,12 +2835,44 @@ var StreamReducer = class {
|
|
|
2834
2835
|
__publicField(this, "messagesSig", messagesSig);
|
|
2835
2836
|
/** Currently-streaming assistant message; null when no stream is active. */
|
|
2836
2837
|
__publicField(this, "active", null);
|
|
2838
|
+
/**
|
|
2839
|
+
* Text/reasoning parts still "open" in the CURRENT step, keyed `${kind}:${id}`.
|
|
2840
|
+
* Cleared per stream (`attach`) and per step boundary (`finish-step`) — exactly
|
|
2841
|
+
* like web-www's per-step `activeTextParts`. Lookups go through this map, NOT a
|
|
2842
|
+
* scan of the whole message, so a text id reused in a LATER step or in a resume
|
|
2843
|
+
* stream (e.g. the reply that continues after an approval pause) starts a NEW
|
|
2844
|
+
* part instead of merging into an earlier same-id part. Without it the
|
|
2845
|
+
* continuation text merges into the pre-tool text and renders ABOVE the tool
|
|
2846
|
+
* card (correct only after a reload, when the backend replays ordered parts).
|
|
2847
|
+
*/
|
|
2848
|
+
__publicField(this, "openTextParts", /* @__PURE__ */ new Map());
|
|
2849
|
+
/** Monotonic counter for client-unique part ids (the React key). The backend
|
|
2850
|
+
* reuses chunk ids across steps/streams, so the chunk id alone is NOT a safe
|
|
2851
|
+
* key — two parts could share `txt-0` and collide. Part ids are client-only
|
|
2852
|
+
* (text/reasoning ids never ride the wire), so a counter is sufficient. */
|
|
2853
|
+
__publicField(this, "partSeq", 0);
|
|
2837
2854
|
}
|
|
2838
2855
|
attach(msg) {
|
|
2839
2856
|
this.active = msg;
|
|
2857
|
+
this.openTextParts.clear();
|
|
2840
2858
|
}
|
|
2841
2859
|
detach() {
|
|
2842
2860
|
this.active = null;
|
|
2861
|
+
this.openTextParts.clear();
|
|
2862
|
+
}
|
|
2863
|
+
/**
|
|
2864
|
+
* Find-or-create the open text/reasoning part for `id` within the current step.
|
|
2865
|
+
* Scoped to {@link openTextParts} (reset on step/stream boundaries) so parts
|
|
2866
|
+
* never merge across a tool/resume boundary. Mirrors www's `ensureTextPart`.
|
|
2867
|
+
*/
|
|
2868
|
+
ensureTextPart(m, kind, id) {
|
|
2869
|
+
const key = `${kind}:${id}`;
|
|
2870
|
+
const existing = this.openTextParts.get(key);
|
|
2871
|
+
if (existing) return existing;
|
|
2872
|
+
const part = { kind, id: `${id}#${this.partSeq++}`, textSig: signal2(""), doneSig: signal2(false) };
|
|
2873
|
+
this.openTextParts.set(key, part);
|
|
2874
|
+
appendPart(m, part);
|
|
2875
|
+
return part;
|
|
2843
2876
|
}
|
|
2844
2877
|
apply(chunk) {
|
|
2845
2878
|
const m = this.active;
|
|
@@ -2849,6 +2882,7 @@ var StreamReducer = class {
|
|
|
2849
2882
|
if (chunk.messageId) m.serverMessageId = chunk.messageId;
|
|
2850
2883
|
return;
|
|
2851
2884
|
case "finish-step":
|
|
2885
|
+
this.openTextParts.clear();
|
|
2852
2886
|
return;
|
|
2853
2887
|
case "start-step":
|
|
2854
2888
|
appendPart(m, { kind: "step-start", id: `ss${m.partsSig.value.length}` });
|
|
@@ -2866,26 +2900,26 @@ var StreamReducer = class {
|
|
|
2866
2900
|
this.bumpDone(m);
|
|
2867
2901
|
return;
|
|
2868
2902
|
case "text-start":
|
|
2869
|
-
ensureTextPart(m, "text", chunk.id);
|
|
2903
|
+
this.ensureTextPart(m, "text", chunk.id);
|
|
2870
2904
|
return;
|
|
2871
2905
|
case "text-delta": {
|
|
2872
|
-
const p36 = ensureTextPart(m, "text", chunk.id);
|
|
2906
|
+
const p36 = this.ensureTextPart(m, "text", chunk.id);
|
|
2873
2907
|
p36.textSig.value += chunk.delta;
|
|
2874
2908
|
return;
|
|
2875
2909
|
}
|
|
2876
2910
|
case "text-end":
|
|
2877
|
-
ensureTextPart(m, "text", chunk.id).doneSig.value = true;
|
|
2911
|
+
this.ensureTextPart(m, "text", chunk.id).doneSig.value = true;
|
|
2878
2912
|
return;
|
|
2879
2913
|
case "reasoning-start":
|
|
2880
|
-
ensureTextPart(m, "reasoning", chunk.id).doneSig.value = false;
|
|
2914
|
+
this.ensureTextPart(m, "reasoning", chunk.id).doneSig.value = false;
|
|
2881
2915
|
return;
|
|
2882
2916
|
case "reasoning-delta": {
|
|
2883
|
-
const p36 = ensureTextPart(m, "reasoning", chunk.id);
|
|
2917
|
+
const p36 = this.ensureTextPart(m, "reasoning", chunk.id);
|
|
2884
2918
|
p36.textSig.value += chunk.delta;
|
|
2885
2919
|
return;
|
|
2886
2920
|
}
|
|
2887
2921
|
case "reasoning-end":
|
|
2888
|
-
ensureTextPart(m, "reasoning", chunk.id).doneSig.value = true;
|
|
2922
|
+
this.ensureTextPart(m, "reasoning", chunk.id).doneSig.value = true;
|
|
2889
2923
|
return;
|
|
2890
2924
|
case "tool-input-start":
|
|
2891
2925
|
case "tool-input-delta":
|
|
@@ -2930,13 +2964,6 @@ var StreamReducer = class {
|
|
|
2930
2964
|
this.messagesSig.value = [...this.messagesSig.value];
|
|
2931
2965
|
}
|
|
2932
2966
|
};
|
|
2933
|
-
function ensureTextPart(m, kind, id) {
|
|
2934
|
-
const existing = m.partsSig.value.find((p36) => p36.kind === kind && p36.id === id);
|
|
2935
|
-
if (existing) return existing;
|
|
2936
|
-
const part = { kind, id, textSig: signal2(""), doneSig: signal2(false) };
|
|
2937
|
-
appendPart(m, part);
|
|
2938
|
-
return part;
|
|
2939
|
-
}
|
|
2940
2967
|
function ensureToolPart(m, toolCallId, toolName2) {
|
|
2941
2968
|
const existing = m.partsSig.value.find((p36) => p36.kind === "tool" && p36.toolCallId === toolCallId);
|
|
2942
2969
|
if (existing) return existing;
|
|
@@ -7909,10 +7936,6 @@ function App({ options, hostElement, bus }) {
|
|
|
7909
7936
|
const body = buildSendMessageRequest({
|
|
7910
7937
|
messages: thread.map(fromReactive),
|
|
7911
7938
|
conversationId: activeConversationId,
|
|
7912
|
-
// The assistant message being generated / resumed — prefer the id the
|
|
7913
|
-
// backend assigned (adopted from the `start` chunk) so a HITL re-POST
|
|
7914
|
-
// resumes the message the backend persisted, not the client-minted id.
|
|
7915
|
-
messageId: assistantMsg.serverMessageId ?? assistantMsg.id,
|
|
7916
7939
|
// textModel + imageModel are backend-only — selected per deployment.
|
|
7917
7940
|
tools: options.features.tools,
|
|
7918
7941
|
// Identity + preferences ride on every message — server may need
|