@runtypelabs/persona 3.16.0 → 3.18.0

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.
Files changed (71) hide show
  1. package/README.md +142 -0
  2. package/dist/animations/glyph-cycle.cjs +279 -0
  3. package/dist/animations/glyph-cycle.d.cts +5 -0
  4. package/dist/animations/glyph-cycle.d.ts +5 -0
  5. package/dist/animations/glyph-cycle.js +252 -0
  6. package/dist/animations/types-cwY5HaFD.d.cts +307 -0
  7. package/dist/animations/types-cwY5HaFD.d.ts +307 -0
  8. package/dist/animations/wipe.cjs +107 -0
  9. package/dist/animations/wipe.d.cts +5 -0
  10. package/dist/animations/wipe.d.ts +5 -0
  11. package/dist/animations/wipe.js +80 -0
  12. package/dist/index.cjs +49 -48
  13. package/dist/index.cjs.map +1 -1
  14. package/dist/index.d.cts +504 -1
  15. package/dist/index.d.ts +504 -1
  16. package/dist/index.global.js +143 -88
  17. package/dist/index.global.js.map +1 -1
  18. package/dist/index.js +49 -48
  19. package/dist/index.js.map +1 -1
  20. package/dist/testing.cjs +85 -0
  21. package/dist/testing.d.cts +39 -0
  22. package/dist/testing.d.ts +39 -0
  23. package/dist/testing.js +56 -0
  24. package/dist/theme-editor.cjs +2095 -207
  25. package/dist/theme-editor.d.cts +432 -2
  26. package/dist/theme-editor.d.ts +432 -2
  27. package/dist/theme-editor.js +2093 -207
  28. package/dist/theme-reference.cjs +1 -1
  29. package/dist/theme-reference.d.cts +14 -0
  30. package/dist/theme-reference.d.ts +14 -0
  31. package/dist/widget.css +565 -0
  32. package/package.json +20 -3
  33. package/src/animations/glyph-cycle.ts +332 -0
  34. package/src/animations/wipe.ts +66 -0
  35. package/src/client.test.ts +275 -0
  36. package/src/client.ts +99 -0
  37. package/src/components/ask-user-question-bubble.test.ts +583 -0
  38. package/src/components/ask-user-question-bubble.ts +924 -0
  39. package/src/components/composer-builder.ts +61 -10
  40. package/src/components/message-bubble.test.ts +181 -2
  41. package/src/components/message-bubble.ts +209 -14
  42. package/src/components/messages.ts +33 -1
  43. package/src/components/panel.ts +45 -5
  44. package/src/defaults.ts +37 -0
  45. package/src/index-global.ts +31 -0
  46. package/src/index.ts +34 -1
  47. package/src/plugins/types.ts +57 -0
  48. package/src/session.test.ts +276 -1
  49. package/src/session.ts +247 -3
  50. package/src/styles/widget.css +565 -0
  51. package/src/testing/index.ts +11 -0
  52. package/src/testing/mock-stream.test.ts +80 -0
  53. package/src/testing/mock-stream.ts +94 -0
  54. package/src/testing.ts +2 -0
  55. package/src/theme-editor/index.ts +4 -0
  56. package/src/theme-editor/preview-utils.test.ts +60 -0
  57. package/src/theme-editor/preview-utils.ts +129 -0
  58. package/src/theme-editor/sections.test.ts +19 -0
  59. package/src/theme-editor/sections.ts +84 -1
  60. package/src/types/theme.ts +15 -0
  61. package/src/types.ts +360 -0
  62. package/src/ui.ask-user-question-plugin.test.ts +649 -0
  63. package/src/ui.stop-button.test.ts +165 -0
  64. package/src/ui.ts +706 -11
  65. package/src/utils/message-fingerprint.ts +2 -0
  66. package/src/utils/morph.ts +7 -0
  67. package/src/utils/storage.ts +10 -2
  68. package/src/utils/stream-animation.test.ts +417 -0
  69. package/src/utils/stream-animation.ts +449 -0
  70. package/src/utils/theme.test.ts +36 -0
  71. package/src/utils/tokens.ts +23 -0
@@ -80,6 +80,7 @@ __export(theme_editor_exports, {
80
80
  buildPreviewConfigWithMessages: () => buildPreviewConfigWithMessages,
81
81
  buildShellCss: () => buildShellCss,
82
82
  buildSrcdoc: () => buildSrcdoc,
83
+ buildTranscriptStreamFrames: () => buildTranscriptStreamFrames,
83
84
  convertFromPx: () => convertFromPx,
84
85
  convertToPx: () => convertToPx,
85
86
  createPreviewMessages: () => createPreviewMessages,
@@ -99,6 +100,7 @@ __export(theme_editor_exports, {
99
100
  normalizeColorValue: () => normalizeColorValue,
100
101
  paletteColorPath: () => paletteColorPath,
101
102
  parseCssValue: () => parseCssValue,
103
+ presetStreamsText: () => presetStreamsText,
102
104
  resolveRoleAssignment: () => resolveRoleAssignment,
103
105
  resolveThemeColorPath: () => resolveThemeColorPath,
104
106
  scopeSection: () => scopeSection,
@@ -247,6 +249,19 @@ var DEFAULT_WIDGET_CONFIG = {
247
249
  previewMaxLines: 3,
248
250
  expandable: true,
249
251
  loadingAnimation: "none"
252
+ },
253
+ streamAnimation: {
254
+ type: "none",
255
+ placeholder: "none",
256
+ speed: 120,
257
+ duration: 1800
258
+ },
259
+ askUserQuestion: {
260
+ enabled: true,
261
+ slideInMs: 180,
262
+ freeTextLabel: "Other\u2026",
263
+ freeTextPlaceholder: "Type your answer\u2026",
264
+ submitLabel: "Send"
250
265
  }
251
266
  },
252
267
  suggestionChips: [
@@ -349,11 +364,15 @@ function mergeWithDefaults(config) {
349
364
  ...config.voiceRecognition
350
365
  },
351
366
  features: (() => {
352
- var _a2, _b2, _c2, _d2;
367
+ var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2;
353
368
  const da = (_a2 = DEFAULT_WIDGET_CONFIG.features) == null ? void 0 : _a2.artifacts;
354
369
  const ca = (_b2 = config.features) == null ? void 0 : _b2.artifacts;
355
370
  const dsb = (_c2 = DEFAULT_WIDGET_CONFIG.features) == null ? void 0 : _c2.scrollToBottom;
356
371
  const csb = (_d2 = config.features) == null ? void 0 : _d2.scrollToBottom;
372
+ const dsa = (_e2 = DEFAULT_WIDGET_CONFIG.features) == null ? void 0 : _e2.streamAnimation;
373
+ const csa = (_f2 = config.features) == null ? void 0 : _f2.streamAnimation;
374
+ const dau = (_g2 = DEFAULT_WIDGET_CONFIG.features) == null ? void 0 : _g2.askUserQuestion;
375
+ const cau = (_h2 = config.features) == null ? void 0 : _h2.askUserQuestion;
357
376
  const mergedArtifacts = da === void 0 && ca === void 0 ? void 0 : {
358
377
  ...da,
359
378
  ...ca,
@@ -366,11 +385,25 @@ function mergeWithDefaults(config) {
366
385
  ...dsb,
367
386
  ...csb
368
387
  };
388
+ const mergedStreamAnimation = dsa === void 0 && csa === void 0 ? void 0 : {
389
+ ...dsa,
390
+ ...csa
391
+ };
392
+ const mergedAskUserQuestion = dau === void 0 && cau === void 0 ? void 0 : {
393
+ ...dau,
394
+ ...cau,
395
+ styles: {
396
+ ...dau == null ? void 0 : dau.styles,
397
+ ...cau == null ? void 0 : cau.styles
398
+ }
399
+ };
369
400
  return {
370
401
  ...DEFAULT_WIDGET_CONFIG.features,
371
402
  ...config.features,
372
403
  ...mergedScrollToBottom !== void 0 ? { scrollToBottom: mergedScrollToBottom } : {},
373
- ...mergedArtifacts !== void 0 ? { artifacts: mergedArtifacts } : {}
404
+ ...mergedArtifacts !== void 0 ? { artifacts: mergedArtifacts } : {},
405
+ ...mergedStreamAnimation !== void 0 ? { streamAnimation: mergedStreamAnimation } : {},
406
+ ...mergedAskUserQuestion !== void 0 ? { askUserQuestion: mergedAskUserQuestion } : {}
374
407
  };
375
408
  })(),
376
409
  suggestionChips: (_e = config.suggestionChips) != null ? _e : DEFAULT_WIDGET_CONFIG.suggestionChips,
@@ -721,6 +754,14 @@ var DEFAULT_COMPONENTS = {
721
754
  },
722
755
  border: "semantic.colors.border"
723
756
  },
757
+ introCard: {
758
+ // Defaults preserve the legacy `persona-shadow-sm` look exactly so existing
759
+ // pages render unchanged when no token is set.
760
+ background: "semantic.colors.surface",
761
+ borderRadius: "palette.radius.2xl",
762
+ padding: "semantic.spacing.lg",
763
+ shadow: "0 5px 15px rgba(15, 23, 42, 0.08)"
764
+ },
724
765
  toolBubble: {
725
766
  shadow: "palette.shadows.sm"
726
767
  },
@@ -997,7 +1038,7 @@ function createTheme(userConfig, options = {}) {
997
1038
  return theme;
998
1039
  }
999
1040
  function themeToCssVariables(theme) {
1000
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y, _Z, __, _$, _aa, _ba, _ca, _da, _ea, _fa, _ga, _ha, _ia, _ja, _ka, _la, _ma, _na, _oa, _pa, _qa, _ra, _sa, _ta, _ua, _va, _wa, _xa, _ya, _za, _Aa, _Ba, _Ca, _Da, _Ea, _Fa, _Ga, _Ha, _Ia, _Ja, _Ka, _La, _Ma, _Na, _Oa, _Pa, _Qa, _Ra, _Sa, _Ta, _Ua, _Va, _Wa, _Xa, _Ya, _Za, __a, _$a, _ab, _bb;
1041
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y, _Z, __, _$, _aa, _ba, _ca, _da, _ea, _fa, _ga, _ha, _ia, _ja, _ka, _la, _ma, _na, _oa, _pa, _qa, _ra, _sa, _ta, _ua, _va, _wa, _xa, _ya, _za, _Aa, _Ba, _Ca, _Da, _Ea, _Fa, _Ga, _Ha, _Ia, _Ja, _Ka, _La, _Ma, _Na, _Oa, _Pa, _Qa, _Ra, _Sa, _Ta, _Ua, _Va, _Wa, _Xa, _Ya, _Za, __a, _$a, _ab, _bb, _cb, _db, _eb, _fb, _gb, _hb;
1001
1042
  const resolved = resolveTokens(theme);
1002
1043
  const cssVars = {};
1003
1044
  for (const [path, token] of Object.entries(resolved)) {
@@ -1061,31 +1102,36 @@ function themeToCssVariables(theme) {
1061
1102
  const headerTokens = (_ea = theme.components) == null ? void 0 : _ea.header;
1062
1103
  if (headerTokens == null ? void 0 : headerTokens.shadow) cssVars["--persona-header-shadow"] = headerTokens.shadow;
1063
1104
  if (headerTokens == null ? void 0 : headerTokens.borderBottom) cssVars["--persona-header-border-bottom"] = headerTokens.borderBottom;
1064
- cssVars["--persona-input-background"] = (_fa = cssVars["--persona-components-input-background"]) != null ? _fa : cssVars["--persona-surface"];
1065
- cssVars["--persona-input-placeholder"] = (_ga = cssVars["--persona-components-input-placeholder"]) != null ? _ga : cssVars["--persona-text-muted"];
1066
- cssVars["--persona-message-user-bg"] = (_ha = cssVars["--persona-components-message-user-background"]) != null ? _ha : cssVars["--persona-accent"];
1067
- cssVars["--persona-message-user-text"] = (_ia = cssVars["--persona-components-message-user-text"]) != null ? _ia : cssVars["--persona-text-inverse"];
1068
- cssVars["--persona-message-user-shadow"] = (_ja = cssVars["--persona-components-message-user-shadow"]) != null ? _ja : "0 5px 15px rgba(15, 23, 42, 0.08)";
1069
- cssVars["--persona-message-assistant-bg"] = (_ka = cssVars["--persona-components-message-assistant-background"]) != null ? _ka : cssVars["--persona-surface"];
1070
- cssVars["--persona-message-assistant-text"] = (_la = cssVars["--persona-components-message-assistant-text"]) != null ? _la : cssVars["--persona-text"];
1071
- cssVars["--persona-message-assistant-border"] = (_ma = cssVars["--persona-components-message-assistant-border"]) != null ? _ma : cssVars["--persona-border"];
1072
- cssVars["--persona-message-assistant-shadow"] = (_na = cssVars["--persona-components-message-assistant-shadow"]) != null ? _na : "0 1px 2px 0 rgb(0 0 0 / 0.05)";
1073
- cssVars["--persona-scroll-to-bottom-bg"] = (_pa = (_oa = cssVars["--persona-components-scrollToBottom-background"]) != null ? _oa : cssVars["--persona-button-primary-bg"]) != null ? _pa : cssVars["--persona-accent"];
1074
- cssVars["--persona-scroll-to-bottom-fg"] = (_ra = (_qa = cssVars["--persona-components-scrollToBottom-foreground"]) != null ? _qa : cssVars["--persona-button-primary-fg"]) != null ? _ra : cssVars["--persona-text-inverse"];
1075
- cssVars["--persona-scroll-to-bottom-border"] = (_sa = cssVars["--persona-components-scrollToBottom-border"]) != null ? _sa : cssVars["--persona-primary"];
1076
- cssVars["--persona-scroll-to-bottom-size"] = (_ta = cssVars["--persona-components-scrollToBottom-size"]) != null ? _ta : "40px";
1077
- cssVars["--persona-scroll-to-bottom-radius"] = (_wa = (_va = (_ua = cssVars["--persona-components-scrollToBottom-borderRadius"]) != null ? _ua : cssVars["--persona-button-radius"]) != null ? _va : cssVars["--persona-radius-full"]) != null ? _wa : "9999px";
1078
- cssVars["--persona-scroll-to-bottom-shadow"] = (_ya = (_xa = cssVars["--persona-components-scrollToBottom-shadow"]) != null ? _xa : cssVars["--persona-palette-shadows-sm"]) != null ? _ya : "0 1px 2px 0 rgb(0 0 0 / 0.05)";
1079
- cssVars["--persona-scroll-to-bottom-padding"] = (_za = cssVars["--persona-components-scrollToBottom-padding"]) != null ? _za : "0.5rem 0.875rem";
1080
- cssVars["--persona-scroll-to-bottom-gap"] = (_Aa = cssVars["--persona-components-scrollToBottom-gap"]) != null ? _Aa : "0.5rem";
1081
- cssVars["--persona-scroll-to-bottom-font-size"] = (_Ca = (_Ba = cssVars["--persona-components-scrollToBottom-fontSize"]) != null ? _Ba : cssVars["--persona-palette-typography-fontSize-sm"]) != null ? _Ca : "0.875rem";
1082
- cssVars["--persona-scroll-to-bottom-icon-size"] = (_Da = cssVars["--persona-components-scrollToBottom-iconSize"]) != null ? _Da : "14px";
1083
- cssVars["--persona-tool-bubble-shadow"] = (_Ea = cssVars["--persona-components-toolBubble-shadow"]) != null ? _Ea : "0 5px 15px rgba(15, 23, 42, 0.08)";
1084
- cssVars["--persona-reasoning-bubble-shadow"] = (_Fa = cssVars["--persona-components-reasoningBubble-shadow"]) != null ? _Fa : "0 5px 15px rgba(15, 23, 42, 0.08)";
1085
- cssVars["--persona-composer-shadow"] = (_Ga = cssVars["--persona-components-composer-shadow"]) != null ? _Ga : "none";
1086
- cssVars["--persona-md-inline-code-bg"] = (_Ha = cssVars["--persona-components-markdown-inlineCode-background"]) != null ? _Ha : cssVars["--persona-container"];
1087
- cssVars["--persona-md-inline-code-color"] = (_Ia = cssVars["--persona-components-markdown-inlineCode-foreground"]) != null ? _Ia : cssVars["--persona-text"];
1088
- cssVars["--persona-md-link-color"] = (_Ka = (_Ja = cssVars["--persona-components-markdown-link-foreground"]) != null ? _Ja : cssVars["--persona-accent"]) != null ? _Ka : "#0f0f0f";
1105
+ const introCardTokens = (_fa = theme.components) == null ? void 0 : _fa.introCard;
1106
+ cssVars["--persona-intro-card-bg"] = (_ga = cssVars["--persona-components-introCard-background"]) != null ? _ga : cssVars["--persona-surface"];
1107
+ cssVars["--persona-intro-card-radius"] = (_ha = cssVars["--persona-components-introCard-borderRadius"]) != null ? _ha : "1rem";
1108
+ cssVars["--persona-intro-card-padding"] = (_ia = cssVars["--persona-components-introCard-padding"]) != null ? _ia : "1.5rem";
1109
+ cssVars["--persona-intro-card-shadow"] = (_ka = (_ja = introCardTokens == null ? void 0 : introCardTokens.shadow) != null ? _ja : cssVars["--persona-components-introCard-shadow"]) != null ? _ka : "0 5px 15px rgba(15, 23, 42, 0.08)";
1110
+ cssVars["--persona-input-background"] = (_la = cssVars["--persona-components-input-background"]) != null ? _la : cssVars["--persona-surface"];
1111
+ cssVars["--persona-input-placeholder"] = (_ma = cssVars["--persona-components-input-placeholder"]) != null ? _ma : cssVars["--persona-text-muted"];
1112
+ cssVars["--persona-message-user-bg"] = (_na = cssVars["--persona-components-message-user-background"]) != null ? _na : cssVars["--persona-accent"];
1113
+ cssVars["--persona-message-user-text"] = (_oa = cssVars["--persona-components-message-user-text"]) != null ? _oa : cssVars["--persona-text-inverse"];
1114
+ cssVars["--persona-message-user-shadow"] = (_pa = cssVars["--persona-components-message-user-shadow"]) != null ? _pa : "0 5px 15px rgba(15, 23, 42, 0.08)";
1115
+ cssVars["--persona-message-assistant-bg"] = (_qa = cssVars["--persona-components-message-assistant-background"]) != null ? _qa : cssVars["--persona-surface"];
1116
+ cssVars["--persona-message-assistant-text"] = (_ra = cssVars["--persona-components-message-assistant-text"]) != null ? _ra : cssVars["--persona-text"];
1117
+ cssVars["--persona-message-assistant-border"] = (_sa = cssVars["--persona-components-message-assistant-border"]) != null ? _sa : cssVars["--persona-border"];
1118
+ cssVars["--persona-message-assistant-shadow"] = (_ta = cssVars["--persona-components-message-assistant-shadow"]) != null ? _ta : "0 1px 2px 0 rgb(0 0 0 / 0.05)";
1119
+ cssVars["--persona-scroll-to-bottom-bg"] = (_va = (_ua = cssVars["--persona-components-scrollToBottom-background"]) != null ? _ua : cssVars["--persona-button-primary-bg"]) != null ? _va : cssVars["--persona-accent"];
1120
+ cssVars["--persona-scroll-to-bottom-fg"] = (_xa = (_wa = cssVars["--persona-components-scrollToBottom-foreground"]) != null ? _wa : cssVars["--persona-button-primary-fg"]) != null ? _xa : cssVars["--persona-text-inverse"];
1121
+ cssVars["--persona-scroll-to-bottom-border"] = (_ya = cssVars["--persona-components-scrollToBottom-border"]) != null ? _ya : cssVars["--persona-primary"];
1122
+ cssVars["--persona-scroll-to-bottom-size"] = (_za = cssVars["--persona-components-scrollToBottom-size"]) != null ? _za : "40px";
1123
+ cssVars["--persona-scroll-to-bottom-radius"] = (_Ca = (_Ba = (_Aa = cssVars["--persona-components-scrollToBottom-borderRadius"]) != null ? _Aa : cssVars["--persona-button-radius"]) != null ? _Ba : cssVars["--persona-radius-full"]) != null ? _Ca : "9999px";
1124
+ cssVars["--persona-scroll-to-bottom-shadow"] = (_Ea = (_Da = cssVars["--persona-components-scrollToBottom-shadow"]) != null ? _Da : cssVars["--persona-palette-shadows-sm"]) != null ? _Ea : "0 1px 2px 0 rgb(0 0 0 / 0.05)";
1125
+ cssVars["--persona-scroll-to-bottom-padding"] = (_Fa = cssVars["--persona-components-scrollToBottom-padding"]) != null ? _Fa : "0.5rem 0.875rem";
1126
+ cssVars["--persona-scroll-to-bottom-gap"] = (_Ga = cssVars["--persona-components-scrollToBottom-gap"]) != null ? _Ga : "0.5rem";
1127
+ cssVars["--persona-scroll-to-bottom-font-size"] = (_Ia = (_Ha = cssVars["--persona-components-scrollToBottom-fontSize"]) != null ? _Ha : cssVars["--persona-palette-typography-fontSize-sm"]) != null ? _Ia : "0.875rem";
1128
+ cssVars["--persona-scroll-to-bottom-icon-size"] = (_Ja = cssVars["--persona-components-scrollToBottom-iconSize"]) != null ? _Ja : "14px";
1129
+ cssVars["--persona-tool-bubble-shadow"] = (_Ka = cssVars["--persona-components-toolBubble-shadow"]) != null ? _Ka : "0 5px 15px rgba(15, 23, 42, 0.08)";
1130
+ cssVars["--persona-reasoning-bubble-shadow"] = (_La = cssVars["--persona-components-reasoningBubble-shadow"]) != null ? _La : "0 5px 15px rgba(15, 23, 42, 0.08)";
1131
+ cssVars["--persona-composer-shadow"] = (_Ma = cssVars["--persona-components-composer-shadow"]) != null ? _Ma : "none";
1132
+ cssVars["--persona-md-inline-code-bg"] = (_Na = cssVars["--persona-components-markdown-inlineCode-background"]) != null ? _Na : cssVars["--persona-container"];
1133
+ cssVars["--persona-md-inline-code-color"] = (_Oa = cssVars["--persona-components-markdown-inlineCode-foreground"]) != null ? _Oa : cssVars["--persona-text"];
1134
+ cssVars["--persona-md-link-color"] = (_Qa = (_Pa = cssVars["--persona-components-markdown-link-foreground"]) != null ? _Pa : cssVars["--persona-accent"]) != null ? _Qa : "#0f0f0f";
1089
1135
  const mdH1Size = cssVars["--persona-components-markdown-heading-h1-fontSize"];
1090
1136
  if (mdH1Size) cssVars["--persona-md-h1-size"] = mdH1Size;
1091
1137
  const mdH1Weight = cssVars["--persona-components-markdown-heading-h1-fontWeight"];
@@ -1098,19 +1144,19 @@ function themeToCssVariables(theme) {
1098
1144
  if (mdProseFont && mdProseFont !== "inherit") {
1099
1145
  cssVars["--persona-md-prose-font-family"] = mdProseFont;
1100
1146
  }
1101
- cssVars["--persona-md-code-block-bg"] = (_La = cssVars["--persona-components-markdown-codeBlock-background"]) != null ? _La : cssVars["--persona-container"];
1102
- cssVars["--persona-md-code-block-border-color"] = (_Ma = cssVars["--persona-components-markdown-codeBlock-borderColor"]) != null ? _Ma : cssVars["--persona-border"];
1103
- cssVars["--persona-md-code-block-text-color"] = (_Na = cssVars["--persona-components-markdown-codeBlock-textColor"]) != null ? _Na : "inherit";
1104
- cssVars["--persona-md-table-header-bg"] = (_Oa = cssVars["--persona-components-markdown-table-headerBackground"]) != null ? _Oa : cssVars["--persona-container"];
1105
- cssVars["--persona-md-table-border-color"] = (_Pa = cssVars["--persona-components-markdown-table-borderColor"]) != null ? _Pa : cssVars["--persona-border"];
1106
- cssVars["--persona-md-hr-color"] = (_Qa = cssVars["--persona-components-markdown-hr-color"]) != null ? _Qa : cssVars["--persona-divider"];
1107
- cssVars["--persona-md-blockquote-border-color"] = (_Ra = cssVars["--persona-components-markdown-blockquote-borderColor"]) != null ? _Ra : cssVars["--persona-palette-colors-gray-900"];
1108
- cssVars["--persona-md-blockquote-bg"] = (_Sa = cssVars["--persona-components-markdown-blockquote-background"]) != null ? _Sa : "transparent";
1109
- cssVars["--persona-md-blockquote-text-color"] = (_Ta = cssVars["--persona-components-markdown-blockquote-textColor"]) != null ? _Ta : cssVars["--persona-palette-colors-gray-500"];
1110
- cssVars["--cw-container"] = (_Ua = cssVars["--persona-components-collapsibleWidget-container"]) != null ? _Ua : cssVars["--persona-surface"];
1111
- cssVars["--cw-surface"] = (_Va = cssVars["--persona-components-collapsibleWidget-surface"]) != null ? _Va : cssVars["--persona-surface"];
1112
- cssVars["--cw-border"] = (_Wa = cssVars["--persona-components-collapsibleWidget-border"]) != null ? _Wa : cssVars["--persona-border"];
1113
- cssVars["--persona-message-border"] = (_Xa = cssVars["--persona-components-message-border"]) != null ? _Xa : cssVars["--persona-border"];
1147
+ cssVars["--persona-md-code-block-bg"] = (_Ra = cssVars["--persona-components-markdown-codeBlock-background"]) != null ? _Ra : cssVars["--persona-container"];
1148
+ cssVars["--persona-md-code-block-border-color"] = (_Sa = cssVars["--persona-components-markdown-codeBlock-borderColor"]) != null ? _Sa : cssVars["--persona-border"];
1149
+ cssVars["--persona-md-code-block-text-color"] = (_Ta = cssVars["--persona-components-markdown-codeBlock-textColor"]) != null ? _Ta : "inherit";
1150
+ cssVars["--persona-md-table-header-bg"] = (_Ua = cssVars["--persona-components-markdown-table-headerBackground"]) != null ? _Ua : cssVars["--persona-container"];
1151
+ cssVars["--persona-md-table-border-color"] = (_Va = cssVars["--persona-components-markdown-table-borderColor"]) != null ? _Va : cssVars["--persona-border"];
1152
+ cssVars["--persona-md-hr-color"] = (_Wa = cssVars["--persona-components-markdown-hr-color"]) != null ? _Wa : cssVars["--persona-divider"];
1153
+ cssVars["--persona-md-blockquote-border-color"] = (_Xa = cssVars["--persona-components-markdown-blockquote-borderColor"]) != null ? _Xa : cssVars["--persona-palette-colors-gray-900"];
1154
+ cssVars["--persona-md-blockquote-bg"] = (_Ya = cssVars["--persona-components-markdown-blockquote-background"]) != null ? _Ya : "transparent";
1155
+ cssVars["--persona-md-blockquote-text-color"] = (_Za = cssVars["--persona-components-markdown-blockquote-textColor"]) != null ? _Za : cssVars["--persona-palette-colors-gray-500"];
1156
+ cssVars["--cw-container"] = (__a = cssVars["--persona-components-collapsibleWidget-container"]) != null ? __a : cssVars["--persona-surface"];
1157
+ cssVars["--cw-surface"] = (_$a = cssVars["--persona-components-collapsibleWidget-surface"]) != null ? _$a : cssVars["--persona-surface"];
1158
+ cssVars["--cw-border"] = (_ab = cssVars["--persona-components-collapsibleWidget-border"]) != null ? _ab : cssVars["--persona-border"];
1159
+ cssVars["--persona-message-border"] = (_bb = cssVars["--persona-components-message-border"]) != null ? _bb : cssVars["--persona-border"];
1114
1160
  const components = theme.components;
1115
1161
  const iconBtn = components == null ? void 0 : components.iconButton;
1116
1162
  if (iconBtn) {
@@ -1157,23 +1203,23 @@ function themeToCssVariables(theme) {
1157
1203
  if (t.copyPadding) cssVars["--persona-artifact-toolbar-copy-padding"] = t.copyPadding;
1158
1204
  if (t.copyMenuBackground) {
1159
1205
  cssVars["--persona-artifact-toolbar-copy-menu-bg"] = t.copyMenuBackground;
1160
- cssVars["--persona-dropdown-bg"] = (_Ya = cssVars["--persona-dropdown-bg"]) != null ? _Ya : t.copyMenuBackground;
1206
+ cssVars["--persona-dropdown-bg"] = (_cb = cssVars["--persona-dropdown-bg"]) != null ? _cb : t.copyMenuBackground;
1161
1207
  }
1162
1208
  if (t.copyMenuBorder) {
1163
1209
  cssVars["--persona-artifact-toolbar-copy-menu-border"] = t.copyMenuBorder;
1164
- cssVars["--persona-dropdown-border"] = (_Za = cssVars["--persona-dropdown-border"]) != null ? _Za : t.copyMenuBorder;
1210
+ cssVars["--persona-dropdown-border"] = (_db = cssVars["--persona-dropdown-border"]) != null ? _db : t.copyMenuBorder;
1165
1211
  }
1166
1212
  if (t.copyMenuShadow) {
1167
1213
  cssVars["--persona-artifact-toolbar-copy-menu-shadow"] = t.copyMenuShadow;
1168
- cssVars["--persona-dropdown-shadow"] = (__a = cssVars["--persona-dropdown-shadow"]) != null ? __a : t.copyMenuShadow;
1214
+ cssVars["--persona-dropdown-shadow"] = (_eb = cssVars["--persona-dropdown-shadow"]) != null ? _eb : t.copyMenuShadow;
1169
1215
  }
1170
1216
  if (t.copyMenuBorderRadius) {
1171
1217
  cssVars["--persona-artifact-toolbar-copy-menu-radius"] = t.copyMenuBorderRadius;
1172
- cssVars["--persona-dropdown-radius"] = (_$a = cssVars["--persona-dropdown-radius"]) != null ? _$a : t.copyMenuBorderRadius;
1218
+ cssVars["--persona-dropdown-radius"] = (_fb = cssVars["--persona-dropdown-radius"]) != null ? _fb : t.copyMenuBorderRadius;
1173
1219
  }
1174
1220
  if (t.copyMenuItemHoverBackground) {
1175
1221
  cssVars["--persona-artifact-toolbar-copy-menu-item-hover-bg"] = t.copyMenuItemHoverBackground;
1176
- cssVars["--persona-dropdown-item-hover-bg"] = (_ab = cssVars["--persona-dropdown-item-hover-bg"]) != null ? _ab : t.copyMenuItemHoverBackground;
1222
+ cssVars["--persona-dropdown-item-hover-bg"] = (_gb = cssVars["--persona-dropdown-item-hover-bg"]) != null ? _gb : t.copyMenuItemHoverBackground;
1177
1223
  }
1178
1224
  if (t.iconBackground) cssVars["--persona-artifact-toolbar-icon-bg"] = t.iconBackground;
1179
1225
  if (t.toolbarBorder) cssVars["--persona-artifact-toolbar-border"] = t.toolbarBorder;
@@ -1193,7 +1239,7 @@ function themeToCssVariables(theme) {
1193
1239
  if (artifact == null ? void 0 : artifact.pane) {
1194
1240
  const t = artifact.pane;
1195
1241
  if (t.toolbarBackground) {
1196
- const toolbarBg = (_bb = resolveTokenValue(theme, t.toolbarBackground)) != null ? _bb : t.toolbarBackground;
1242
+ const toolbarBg = (_hb = resolveTokenValue(theme, t.toolbarBackground)) != null ? _hb : t.toolbarBackground;
1197
1243
  cssVars["--persona-artifact-toolbar-bg"] = toolbarBg;
1198
1244
  }
1199
1245
  }
@@ -2673,6 +2719,91 @@ var featuresSectionDef = {
2673
2719
  { id: "feat-scroll-bottom-label", label: "Scroll To Bottom Label", description: "Leave empty for icon-only mode", type: "text", path: "features.scrollToBottom.label", defaultValue: "" }
2674
2720
  ]
2675
2721
  };
2722
+ var streamAnimationSectionDef = {
2723
+ id: "stream-animation",
2724
+ title: "Stream Animation",
2725
+ description: "Control how assistant text appears while streaming.",
2726
+ collapsed: true,
2727
+ fields: [
2728
+ {
2729
+ id: "stream-anim-type",
2730
+ label: "Animation",
2731
+ description: "Reveal effect applied to each assistant reply as it streams.",
2732
+ type: "select",
2733
+ path: "features.streamAnimation.type",
2734
+ defaultValue: "none",
2735
+ options: [
2736
+ { value: "none", label: "None" },
2737
+ { value: "typewriter", label: "Typewriter" },
2738
+ { value: "word-fade", label: "Word fade" },
2739
+ { value: "letter-rise", label: "Letter rise" },
2740
+ { value: "glyph-cycle", label: "Glyph cycle" },
2741
+ { value: "wipe", label: "Wipe" },
2742
+ { value: "pop-bubble", label: "Pop bubble" }
2743
+ ]
2744
+ },
2745
+ {
2746
+ id: "stream-anim-placeholder",
2747
+ label: "Pre-first-token Placeholder",
2748
+ description: "What to show before the first token arrives.",
2749
+ type: "select",
2750
+ path: "features.streamAnimation.placeholder",
2751
+ defaultValue: "none",
2752
+ options: [
2753
+ { value: "none", label: "Typing indicator (default)" },
2754
+ { value: "skeleton", label: "Skeleton shimmer" }
2755
+ ]
2756
+ },
2757
+ {
2758
+ id: "stream-anim-buffer",
2759
+ label: "Content Buffering",
2760
+ description: "Trim in-progress units so only complete words/lines reveal.",
2761
+ type: "select",
2762
+ path: "features.streamAnimation.buffer",
2763
+ defaultValue: "none",
2764
+ options: [
2765
+ { value: "none", label: "None \u2014 stream every character" },
2766
+ { value: "word", label: "Word \u2014 hold until whitespace" },
2767
+ { value: "line", label: "Line \u2014 hold until newline" }
2768
+ ]
2769
+ },
2770
+ {
2771
+ id: "stream-anim-speed",
2772
+ label: "Per-unit Duration (ms)",
2773
+ description: "Animation length for each character or word.",
2774
+ type: "select",
2775
+ path: "features.streamAnimation.speed",
2776
+ defaultValue: 120,
2777
+ options: [
2778
+ { value: "40", label: "40ms \u2014 snappy" },
2779
+ { value: "80", label: "80ms" },
2780
+ { value: "120", label: "120ms (default)" },
2781
+ { value: "200", label: "200ms" },
2782
+ { value: "320", label: "320ms" },
2783
+ { value: "480", label: "480ms \u2014 slow" }
2784
+ ],
2785
+ formatValue: (v) => String(v != null ? v : 120),
2786
+ parseValue: (v) => Number(v)
2787
+ },
2788
+ {
2789
+ id: "stream-anim-duration",
2790
+ label: "Container Duration (ms)",
2791
+ description: "Length of container-level effects (pop-bubble, custom plugins).",
2792
+ type: "select",
2793
+ path: "features.streamAnimation.duration",
2794
+ defaultValue: 1800,
2795
+ options: [
2796
+ { value: "600", label: "600ms" },
2797
+ { value: "1200", label: "1200ms" },
2798
+ { value: "1800", label: "1800ms (default)" },
2799
+ { value: "2400", label: "2400ms" },
2800
+ { value: "3600", label: "3600ms \u2014 slow" }
2801
+ ],
2802
+ formatValue: (v) => String(v != null ? v : 1800),
2803
+ parseValue: (v) => Number(v)
2804
+ }
2805
+ ]
2806
+ };
2676
2807
  var attachmentsSectionDef = {
2677
2808
  id: "attachments-config",
2678
2809
  title: "Attachments",
@@ -2756,7 +2887,7 @@ var CONFIGURE_SUB_GROUPS = [
2756
2887
  { label: "Content", sections: [copySectionDef, suggestionsSectionDef] },
2757
2888
  { label: "Layout", sections: [generalLayoutSectionDef, headerLayoutSectionDef, messagesLayoutSectionDef, messageActionsSectionDef] },
2758
2889
  { label: "Widget", sections: [launcherBasicsSectionDef, launcherAdvancedSectionDef, sendButtonSectionDef, closeButtonSectionDef, clearChatSectionDef, statusIndicatorSectionDef] },
2759
- { label: "Features", sections: [featuresSectionDef, attachmentsSectionDef, artifactsSectionDef, artifactCustomizationSectionDef] },
2890
+ { label: "Features", sections: [featuresSectionDef, streamAnimationSectionDef, attachmentsSectionDef, artifactsSectionDef, artifactCustomizationSectionDef] },
2760
2891
  { label: "Developer", collapsedByDefault: true, sections: [apiIntegrationSectionDef, debugSectionDef, markdownSectionDef] }
2761
2892
  ];
2762
2893
  var CONFIGURE_SECTIONS = CONFIGURE_SUB_GROUPS.flatMap((g) => g.sections);
@@ -4245,6 +4376,40 @@ var AgentWidgetClient = class {
4245
4376
  })
4246
4377
  });
4247
4378
  }
4379
+ /**
4380
+ * Resume a paused flow execution by supplying outputs for LOCAL
4381
+ * (client-executed) tools. Used by the built-in `ask_user_question`
4382
+ * answer-pill sheet, but generic enough for any LOCAL tool.
4383
+ *
4384
+ * Posts to the upstream `/resume` endpoint (the dispatch URL with
4385
+ * `/dispatch` replaced by `/resume` — works for both direct-to-Runtype
4386
+ * and the persona proxy) and returns the raw Response so the caller can
4387
+ * pipe its SSE body through `connectStream()`.
4388
+ *
4389
+ * @param executionId - The paused execution id carried on `step_await`.
4390
+ * @param toolOutputs - Map keyed by tool name → the tool's result value.
4391
+ */
4392
+ async resumeFlow(executionId, toolOutputs, options) {
4393
+ var _a, _b;
4394
+ const trimmed = ((_a = this.config.apiUrl) == null ? void 0 : _a.replace(/\/+$/, "")) || DEFAULT_CLIENT_API_BASE;
4395
+ const url = `${trimmed}/resume`;
4396
+ let headers = {
4397
+ "Content-Type": "application/json",
4398
+ ...this.headers
4399
+ };
4400
+ if (this.getHeaders) {
4401
+ Object.assign(headers, await this.getHeaders());
4402
+ }
4403
+ return fetch(url, {
4404
+ method: "POST",
4405
+ headers,
4406
+ body: JSON.stringify({
4407
+ executionId,
4408
+ toolOutputs,
4409
+ streamResponse: (_b = options == null ? void 0 : options.streamResponse) != null ? _b : true
4410
+ })
4411
+ });
4412
+ }
4248
4413
  async buildAgentPayload(messages) {
4249
4414
  if (!this.config.agent) {
4250
4415
  throw new Error("Agent configuration required for agent mode");
@@ -4806,7 +4971,7 @@ var AgentWidgetClient = class {
4806
4971
  const agentIterationMessages = /* @__PURE__ */ new Map();
4807
4972
  const iterationDisplay = (_a = this.config.iterationDisplay) != null ? _a : "separate";
4808
4973
  drainReadyQueue = () => {
4809
- var _a2, _b2, _c2, _d2, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y, _Z, __, _$, _aa, _ba, _ca, _da, _ea, _fa, _ga, _ha, _ia, _ja, _ka, _la, _ma, _na, _oa, _pa, _qa, _ra, _sa, _ta, _ua, _va, _wa, _xa, _ya, _za, _Aa, _Ba, _Ca, _Da, _Ea, _Fa, _Ga, _Ha, _Ia, _Ja, _Ka, _La, _Ma, _Na, _Oa, _Pa, _Qa, _Ra, _Sa, _Ta, _Ua, _Va, _Wa, _Xa, _Ya, _Za, __a, _$a, _ab, _bb, _cb, _db, _eb, _fb, _gb, _hb, _ib, _jb, _kb, _lb, _mb, _nb, _ob, _pb, _qb, _rb, _sb, _tb, _ub;
4974
+ var _a2, _b2, _c2, _d2, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y, _Z, __, _$, _aa, _ba, _ca, _da, _ea, _fa, _ga, _ha, _ia, _ja, _ka, _la, _ma, _na, _oa, _pa, _qa, _ra, _sa, _ta, _ua, _va, _wa, _xa, _ya, _za, _Aa, _Ba, _Ca, _Da, _Ea, _Fa, _Ga, _Ha, _Ia, _Ja, _Ka, _La, _Ma, _Na, _Oa, _Pa, _Qa, _Ra, _Sa, _Ta, _Ua, _Va, _Wa, _Xa, _Ya, _Za, __a, _$a, _ab, _bb, _cb, _db, _eb, _fb, _gb, _hb, _ib, _jb, _kb, _lb, _mb, _nb, _ob, _pb, _qb, _rb, _sb, _tb, _ub, _vb, _wb, _xb, _yb, _zb, _Ab, _Bb, _Cb, _Db;
4810
4975
  for (let i = 0; i < seqReadyQueue.length; i++) {
4811
4976
  const payloadType = seqReadyQueue[i].payloadType;
4812
4977
  const payload = seqReadyQueue[i].payload;
@@ -4978,8 +5143,26 @@ var AgentWidgetClient = class {
4978
5143
  if (callKey) {
4979
5144
  toolContext.byCall.delete(callKey);
4980
5145
  }
5146
+ } else if (payloadType === "step_await" && payload.awaitReason === "local_tool_required" && payload.toolName) {
5147
+ const toolId = (_X = payload.toolId) != null ? _X : `local-${nextSequence()}`;
5148
+ const toolMessage = ensureToolMessage(toolId);
5149
+ const tool = (_Y = toolMessage.toolCall) != null ? _Y : { id: toolId, status: "pending" };
5150
+ tool.name = payload.toolName;
5151
+ tool.args = payload.parameters;
5152
+ tool.status = "complete";
5153
+ tool.chunks = (_Z = tool.chunks) != null ? _Z : [];
5154
+ tool.startedAt = (_$ = tool.startedAt) != null ? _$ : resolveTimestamp((__ = payload.startedAt) != null ? __ : payload.timestamp);
5155
+ tool.completedAt = (_aa = tool.completedAt) != null ? _aa : tool.startedAt;
5156
+ toolMessage.toolCall = tool;
5157
+ toolMessage.streaming = false;
5158
+ toolMessage.agentMetadata = {
5159
+ ...toolMessage.agentMetadata,
5160
+ executionId: (_ca = payload.executionId) != null ? _ca : (_ba = toolMessage.agentMetadata) == null ? void 0 : _ba.executionId,
5161
+ awaitingLocalTool: true
5162
+ };
5163
+ emitMessage(toolMessage);
4981
5164
  } else if (payloadType === "text_start") {
4982
- if ((_X = payload.toolContext) == null ? void 0 : _X.toolId) {
5165
+ if ((_da = payload.toolContext) == null ? void 0 : _da.toolId) {
4983
5166
  continue;
4984
5167
  }
4985
5168
  const incomingPartId = payload.partId;
@@ -4997,7 +5180,7 @@ var AgentWidgetClient = class {
4997
5180
  partIdState.current = incomingPartId;
4998
5181
  }
4999
5182
  } else if (payloadType === "text_end") {
5000
- if ((_Y = payload.toolContext) == null ? void 0 : _Y.toolId) {
5183
+ if ((_ea = payload.toolContext) == null ? void 0 : _ea.toolId) {
5001
5184
  continue;
5002
5185
  }
5003
5186
  const prev = assistantMessage;
@@ -5017,7 +5200,7 @@ var AgentWidgetClient = class {
5017
5200
  const nestedToolCtx = payload.toolContext;
5018
5201
  if (nestedToolCtx == null ? void 0 : nestedToolCtx.toolId) {
5019
5202
  const nestedStepId = String(
5020
- (__ = (_Z = payload.id) != null ? _Z : nestedToolCtx.stepId) != null ? __ : `step-${nextSequence()}`
5203
+ (_ga = (_fa = payload.id) != null ? _fa : nestedToolCtx.stepId) != null ? _ga : `step-${nextSequence()}`
5021
5204
  );
5022
5205
  const incomingPartId2 = payload.partId !== void 0 && payload.partId !== null ? String(payload.partId) : "";
5023
5206
  const stepScopeKey = `${nestedToolCtx.toolId}::${nestedStepId}`;
@@ -5044,7 +5227,7 @@ var AgentWidgetClient = class {
5044
5227
  incomingPartId2,
5045
5228
  nestedToolCtx.executionId
5046
5229
  );
5047
- const nestedChunk = (_ca = (_ba = (_aa = (_$ = payload.text) != null ? _$ : payload.delta) != null ? _aa : payload.content) != null ? _ba : payload.chunk) != null ? _ca : "";
5230
+ const nestedChunk = (_ka = (_ja = (_ia = (_ha = payload.text) != null ? _ha : payload.delta) != null ? _ia : payload.content) != null ? _ja : payload.chunk) != null ? _ka : "";
5048
5231
  if (nestedChunk) {
5049
5232
  nestedMsg.content += String(nestedChunk);
5050
5233
  nestedMsg.streaming = true;
@@ -5070,18 +5253,18 @@ var AgentWidgetClient = class {
5070
5253
  if (incomingPartId !== void 0) {
5071
5254
  partIdState.current = incomingPartId;
5072
5255
  }
5073
- const assistant = incomingPartId !== void 0 ? (_da = assistantMessagesByPartId.get(incomingPartId)) != null ? _da : ensureAssistantMessage() : ensureAssistantMessage();
5256
+ const assistant = incomingPartId !== void 0 ? (_la = assistantMessagesByPartId.get(incomingPartId)) != null ? _la : ensureAssistantMessage() : ensureAssistantMessage();
5074
5257
  if (incomingPartId !== void 0) {
5075
5258
  if (!assistant.partId) {
5076
5259
  assistant.partId = incomingPartId;
5077
5260
  }
5078
5261
  assistantMessagesByPartId.set(incomingPartId, assistant);
5079
5262
  }
5080
- const chunk = (_ha = (_ga = (_fa = (_ea = payload.text) != null ? _ea : payload.delta) != null ? _fa : payload.content) != null ? _ga : payload.chunk) != null ? _ha : "";
5263
+ const chunk = (_pa = (_oa = (_na = (_ma = payload.text) != null ? _ma : payload.delta) != null ? _na : payload.content) != null ? _oa : payload.chunk) != null ? _pa : "";
5081
5264
  if (chunk) {
5082
5265
  const chunkSeq = typeof payload.seq === "number" ? payload.seq : void 0;
5083
5266
  const chunkBufferKey = incomingPartId != null ? incomingPartId : assistant.id;
5084
- const accumulatedRaw = chunkSeq !== void 0 ? insertOrderedChunk(chunkBufferKey, chunkSeq, String(chunk)) : ((_ia = rawContentBuffers.get(assistant.id)) != null ? _ia : "") + chunk;
5267
+ const accumulatedRaw = chunkSeq !== void 0 ? insertOrderedChunk(chunkBufferKey, chunkSeq, String(chunk)) : ((_qa = rawContentBuffers.get(assistant.id)) != null ? _qa : "") + chunk;
5085
5268
  assistant.rawContent = accumulatedRaw;
5086
5269
  if (!streamParsers.has(assistant.id)) {
5087
5270
  streamParsers.set(assistant.id, this.createStreamParser());
@@ -5127,7 +5310,7 @@ var AgentWidgetClient = class {
5127
5310
  emitMessage(assistant);
5128
5311
  });
5129
5312
  } else {
5130
- const text = typeof parsedResult === "string" ? parsedResult : (_ja = parsedResult == null ? void 0 : parsedResult.text) != null ? _ja : null;
5313
+ const text = typeof parsedResult === "string" ? parsedResult : (_ra = parsedResult == null ? void 0 : parsedResult.text) != null ? _ra : null;
5131
5314
  if (text !== null && text.trim() !== "") {
5132
5315
  assistant.content = text;
5133
5316
  emitMessage(assistant);
@@ -5141,7 +5324,7 @@ var AgentWidgetClient = class {
5141
5324
  }
5142
5325
  }
5143
5326
  if (payload.isComplete) {
5144
- const finalContent = (_la = (_ka = payload.result) == null ? void 0 : _ka.response) != null ? _la : assistant.content;
5327
+ const finalContent = (_ta = (_sa = payload.result) == null ? void 0 : _sa.response) != null ? _ta : assistant.content;
5145
5328
  if (finalContent) {
5146
5329
  const rawBuffer = rawContentBuffers.get(assistant.id);
5147
5330
  const contentToProcess = rawBuffer != null ? rawBuffer : ensureStringContent(finalContent);
@@ -5173,7 +5356,7 @@ var AgentWidgetClient = class {
5173
5356
  }
5174
5357
  });
5175
5358
  } else {
5176
- extractedText = typeof parsedResult === "string" ? parsedResult : (_ma = parsedResult == null ? void 0 : parsedResult.text) != null ? _ma : null;
5359
+ extractedText = typeof parsedResult === "string" ? parsedResult : (_ua = parsedResult == null ? void 0 : parsedResult.text) != null ? _ua : null;
5177
5360
  }
5178
5361
  }
5179
5362
  }
@@ -5185,7 +5368,7 @@ var AgentWidgetClient = class {
5185
5368
  }
5186
5369
  const parserToClose = streamParsers.get(assistant.id);
5187
5370
  if (parserToClose) {
5188
- const closeResult = (_na = parserToClose.close) == null ? void 0 : _na.call(parserToClose);
5371
+ const closeResult = (_va = parserToClose.close) == null ? void 0 : _va.call(parserToClose);
5189
5372
  if (closeResult instanceof Promise) {
5190
5373
  closeResult.catch(() => {
5191
5374
  });
@@ -5207,7 +5390,7 @@ var AgentWidgetClient = class {
5207
5390
  const nestedCompleteCtx = payload.toolContext;
5208
5391
  if (nestedCompleteCtx == null ? void 0 : nestedCompleteCtx.toolId) {
5209
5392
  const nestedStepId = String(
5210
- (_pa = (_oa = payload.id) != null ? _oa : nestedCompleteCtx.stepId) != null ? _pa : ""
5393
+ (_xa = (_wa = payload.id) != null ? _wa : nestedCompleteCtx.stepId) != null ? _xa : ""
5211
5394
  );
5212
5395
  if (nestedStepId) {
5213
5396
  const prefix = getNestedStepPrefix(
@@ -5226,9 +5409,11 @@ var AgentWidgetClient = class {
5226
5409
  }
5227
5410
  continue;
5228
5411
  }
5412
+ const stepStopReason = payload.stopReason;
5229
5413
  if (didSplitByPartId) {
5230
5414
  if (assistantMessage !== null) {
5231
5415
  const msg = assistantMessage;
5416
+ if (stepStopReason) msg.stopReason = stepStopReason;
5232
5417
  streamParsers.delete(msg.id);
5233
5418
  rawContentBuffers.delete(msg.id);
5234
5419
  if (msg.streaming !== false) {
@@ -5236,9 +5421,10 @@ var AgentWidgetClient = class {
5236
5421
  emitMessage(msg);
5237
5422
  }
5238
5423
  }
5239
- const splitFinalContent = (_qa = payload.result) == null ? void 0 : _qa.response;
5424
+ const splitFinalContent = (_ya = payload.result) == null ? void 0 : _ya.response;
5240
5425
  const sealedForReconcile = lastSealedTextSegment;
5241
5426
  if (sealedForReconcile) {
5427
+ if (stepStopReason) sealedForReconcile.stopReason = stepStopReason;
5242
5428
  if (splitFinalContent !== void 0 && splitFinalContent !== null) {
5243
5429
  reconcileSealedAssistantWithFinalResponse(sealedForReconcile, splitFinalContent);
5244
5430
  } else {
@@ -5249,8 +5435,9 @@ var AgentWidgetClient = class {
5249
5435
  lastSealedTextSegment = null;
5250
5436
  continue;
5251
5437
  }
5252
- const finalContent = (_ra = payload.result) == null ? void 0 : _ra.response;
5438
+ const finalContent = (_za = payload.result) == null ? void 0 : _za.response;
5253
5439
  const assistant = ensureAssistantMessage();
5440
+ if (stepStopReason) assistant.stopReason = stepStopReason;
5254
5441
  if (finalContent !== void 0 && finalContent !== null) {
5255
5442
  const parser = streamParsers.get(assistant.id);
5256
5443
  let hasExtractedText = false;
@@ -5301,7 +5488,7 @@ var AgentWidgetClient = class {
5301
5488
  }
5302
5489
  });
5303
5490
  } else {
5304
- const text = typeof parsedResult === "string" ? parsedResult : (_sa = parsedResult == null ? void 0 : parsedResult.text) != null ? _sa : null;
5491
+ const text = typeof parsedResult === "string" ? parsedResult : (_Aa = parsedResult == null ? void 0 : parsedResult.text) != null ? _Aa : null;
5305
5492
  if (text !== null && text.trim() !== "") {
5306
5493
  assistant.content = text;
5307
5494
  hasExtractedText = true;
@@ -5325,7 +5512,7 @@ var AgentWidgetClient = class {
5325
5512
  assistant.content = ensureStringContent(finalContent);
5326
5513
  }
5327
5514
  if (parser) {
5328
- const closeResult = (_ta = parser.close) == null ? void 0 : _ta.call(parser);
5515
+ const closeResult = (_Ba = parser.close) == null ? void 0 : _Ba.call(parser);
5329
5516
  if (closeResult instanceof Promise) {
5330
5517
  closeResult.catch(() => {
5331
5518
  });
@@ -5343,7 +5530,7 @@ var AgentWidgetClient = class {
5343
5530
  emitMessage(assistant);
5344
5531
  }
5345
5532
  } else if (payloadType === "flow_complete") {
5346
- const finalContent = (_ua = payload.result) == null ? void 0 : _ua.response;
5533
+ const finalContent = (_Ca = payload.result) == null ? void 0 : _Ca.response;
5347
5534
  if (didSplitByPartId) {
5348
5535
  if (assistantMessage !== null) {
5349
5536
  const msg = assistantMessage;
@@ -5410,11 +5597,11 @@ var AgentWidgetClient = class {
5410
5597
  } else if (payloadType === "agent_start") {
5411
5598
  agentExecution = {
5412
5599
  executionId: payload.executionId,
5413
- agentId: (_va = payload.agentId) != null ? _va : "virtual",
5414
- agentName: (_wa = payload.agentName) != null ? _wa : "",
5600
+ agentId: (_Da = payload.agentId) != null ? _Da : "virtual",
5601
+ agentName: (_Ea = payload.agentName) != null ? _Ea : "",
5415
5602
  status: "running",
5416
5603
  currentIteration: 0,
5417
- maxTurns: (_xa = payload.maxTurns) != null ? _xa : 1,
5604
+ maxTurns: (_Fa = payload.maxTurns) != null ? _Fa : 1,
5418
5605
  startedAt: resolveTimestamp(payload.startedAt)
5419
5606
  };
5420
5607
  } else if (payloadType === "agent_iteration_start") {
@@ -5434,7 +5621,7 @@ var AgentWidgetClient = class {
5434
5621
  } else if (payloadType === "agent_turn_delta") {
5435
5622
  if (payload.contentType === "text") {
5436
5623
  const assistant = ensureAssistantMessage();
5437
- assistant.content += (_ya = payload.delta) != null ? _ya : "";
5624
+ assistant.content += (_Ga = payload.delta) != null ? _Ga : "";
5438
5625
  assistant.agentMetadata = {
5439
5626
  executionId: payload.executionId,
5440
5627
  iteration: payload.iteration,
@@ -5443,14 +5630,14 @@ var AgentWidgetClient = class {
5443
5630
  };
5444
5631
  emitMessage(assistant);
5445
5632
  } else if (payload.contentType === "thinking") {
5446
- const reasoningId = (_za = payload.turnId) != null ? _za : `agent-think-${payload.iteration}`;
5633
+ const reasoningId = (_Ha = payload.turnId) != null ? _Ha : `agent-think-${payload.iteration}`;
5447
5634
  const reasoningMessage = ensureReasoningMessage(reasoningId);
5448
- reasoningMessage.reasoning = (_Aa = reasoningMessage.reasoning) != null ? _Aa : {
5635
+ reasoningMessage.reasoning = (_Ia = reasoningMessage.reasoning) != null ? _Ia : {
5449
5636
  id: reasoningId,
5450
5637
  status: "streaming",
5451
5638
  chunks: []
5452
5639
  };
5453
- reasoningMessage.reasoning.chunks.push((_Ba = payload.delta) != null ? _Ba : "");
5640
+ reasoningMessage.reasoning.chunks.push((_Ja = payload.delta) != null ? _Ja : "");
5454
5641
  reasoningMessage.agentMetadata = {
5455
5642
  executionId: payload.executionId,
5456
5643
  iteration: payload.iteration,
@@ -5458,12 +5645,12 @@ var AgentWidgetClient = class {
5458
5645
  };
5459
5646
  emitMessage(reasoningMessage);
5460
5647
  } else if (payload.contentType === "tool_input") {
5461
- const toolId = (_Ca = payload.toolCallId) != null ? _Ca : toolContext.lastId;
5648
+ const toolId = (_Ka = payload.toolCallId) != null ? _Ka : toolContext.lastId;
5462
5649
  if (toolId) {
5463
5650
  const toolMessage = toolMessages.get(toolId);
5464
5651
  if (toolMessage == null ? void 0 : toolMessage.toolCall) {
5465
- toolMessage.toolCall.chunks = (_Da = toolMessage.toolCall.chunks) != null ? _Da : [];
5466
- toolMessage.toolCall.chunks.push((_Ea = payload.delta) != null ? _Ea : "");
5652
+ toolMessage.toolCall.chunks = (_La = toolMessage.toolCall.chunks) != null ? _La : [];
5653
+ toolMessage.toolCall.chunks.push((_Ma = payload.delta) != null ? _Ma : "");
5467
5654
  emitMessage(toolMessage);
5468
5655
  }
5469
5656
  }
@@ -5475,20 +5662,29 @@ var AgentWidgetClient = class {
5475
5662
  if (reasoningMessage == null ? void 0 : reasoningMessage.reasoning) {
5476
5663
  reasoningMessage.reasoning.status = "complete";
5477
5664
  reasoningMessage.reasoning.completedAt = resolveTimestamp(payload.completedAt);
5478
- const start = (_Fa = reasoningMessage.reasoning.startedAt) != null ? _Fa : Date.now();
5665
+ const start = (_Na = reasoningMessage.reasoning.startedAt) != null ? _Na : Date.now();
5479
5666
  reasoningMessage.reasoning.durationMs = Math.max(
5480
5667
  0,
5481
- ((_Ga = reasoningMessage.reasoning.completedAt) != null ? _Ga : Date.now()) - start
5668
+ ((_Oa = reasoningMessage.reasoning.completedAt) != null ? _Oa : Date.now()) - start
5482
5669
  );
5483
5670
  reasoningMessage.streaming = false;
5484
5671
  emitMessage(reasoningMessage);
5485
5672
  }
5486
5673
  }
5674
+ const turnStopReason = payload.stopReason;
5675
+ if (turnStopReason && assistantMessage !== null) {
5676
+ const turnId = payload.turnId;
5677
+ const matchesTurn = !turnId || ((_Pa = assistantMessage.agentMetadata) == null ? void 0 : _Pa.turnId) === turnId;
5678
+ if (matchesTurn) {
5679
+ assistantMessage.stopReason = turnStopReason;
5680
+ emitMessage(assistantMessage);
5681
+ }
5682
+ }
5487
5683
  } else if (payloadType === "agent_tool_start") {
5488
- const toolId = (_Ha = payload.toolCallId) != null ? _Ha : `agent-tool-${nextSequence()}`;
5684
+ const toolId = (_Qa = payload.toolCallId) != null ? _Qa : `agent-tool-${nextSequence()}`;
5489
5685
  trackToolId(getToolCallKey(payload), toolId);
5490
5686
  const toolMessage = ensureToolMessage(toolId);
5491
- const tool = (_Ia = toolMessage.toolCall) != null ? _Ia : {
5687
+ const tool = (_Ra = toolMessage.toolCall) != null ? _Ra : {
5492
5688
  id: toolId,
5493
5689
  status: "pending",
5494
5690
  name: void 0,
@@ -5500,12 +5696,12 @@ var AgentWidgetClient = class {
5500
5696
  completedAt: void 0,
5501
5697
  durationMs: void 0
5502
5698
  };
5503
- tool.name = (_Ka = (_Ja = payload.toolName) != null ? _Ja : payload.name) != null ? _Ka : tool.name;
5699
+ tool.name = (_Ta = (_Sa = payload.toolName) != null ? _Sa : payload.name) != null ? _Ta : tool.name;
5504
5700
  tool.status = "running";
5505
5701
  if (payload.parameters !== void 0) {
5506
5702
  tool.args = payload.parameters;
5507
5703
  }
5508
- tool.startedAt = resolveTimestamp((_La = payload.startedAt) != null ? _La : payload.timestamp);
5704
+ tool.startedAt = resolveTimestamp((_Ua = payload.startedAt) != null ? _Ua : payload.timestamp);
5509
5705
  toolMessage.toolCall = tool;
5510
5706
  toolMessage.streaming = true;
5511
5707
  toolMessage.agentMetadata = {
@@ -5514,21 +5710,21 @@ var AgentWidgetClient = class {
5514
5710
  };
5515
5711
  emitMessage(toolMessage);
5516
5712
  } else if (payloadType === "agent_tool_delta") {
5517
- const toolId = (_Ma = payload.toolCallId) != null ? _Ma : toolContext.lastId;
5713
+ const toolId = (_Va = payload.toolCallId) != null ? _Va : toolContext.lastId;
5518
5714
  if (toolId) {
5519
- const toolMessage = (_Na = toolMessages.get(toolId)) != null ? _Na : ensureToolMessage(toolId);
5715
+ const toolMessage = (_Wa = toolMessages.get(toolId)) != null ? _Wa : ensureToolMessage(toolId);
5520
5716
  if (toolMessage.toolCall) {
5521
- toolMessage.toolCall.chunks = (_Oa = toolMessage.toolCall.chunks) != null ? _Oa : [];
5522
- toolMessage.toolCall.chunks.push((_Pa = payload.delta) != null ? _Pa : "");
5717
+ toolMessage.toolCall.chunks = (_Xa = toolMessage.toolCall.chunks) != null ? _Xa : [];
5718
+ toolMessage.toolCall.chunks.push((_Ya = payload.delta) != null ? _Ya : "");
5523
5719
  toolMessage.toolCall.status = "running";
5524
5720
  toolMessage.streaming = true;
5525
5721
  emitMessage(toolMessage);
5526
5722
  }
5527
5723
  }
5528
5724
  } else if (payloadType === "agent_tool_complete") {
5529
- const toolId = (_Qa = payload.toolCallId) != null ? _Qa : toolContext.lastId;
5725
+ const toolId = (_Za = payload.toolCallId) != null ? _Za : toolContext.lastId;
5530
5726
  if (toolId) {
5531
- const toolMessage = (_Ra = toolMessages.get(toolId)) != null ? _Ra : ensureToolMessage(toolId);
5727
+ const toolMessage = (__a = toolMessages.get(toolId)) != null ? __a : ensureToolMessage(toolId);
5532
5728
  if (toolMessage.toolCall) {
5533
5729
  toolMessage.toolCall.status = "complete";
5534
5730
  if (payload.result !== void 0) {
@@ -5537,7 +5733,7 @@ var AgentWidgetClient = class {
5537
5733
  if (typeof payload.executionTime === "number") {
5538
5734
  toolMessage.toolCall.durationMs = payload.executionTime;
5539
5735
  }
5540
- toolMessage.toolCall.completedAt = resolveTimestamp((_Sa = payload.completedAt) != null ? _Sa : payload.timestamp);
5736
+ toolMessage.toolCall.completedAt = resolveTimestamp((_$a = payload.completedAt) != null ? _$a : payload.timestamp);
5541
5737
  toolMessage.streaming = false;
5542
5738
  emitMessage(toolMessage);
5543
5739
  const callKey = getToolCallKey(payload);
@@ -5552,7 +5748,7 @@ var AgentWidgetClient = class {
5552
5748
  const reflectionMessage = {
5553
5749
  id: reflectionId,
5554
5750
  role: "assistant",
5555
- content: (_Ta = payload.reflection) != null ? _Ta : "",
5751
+ content: (_ab = payload.reflection) != null ? _ab : "",
5556
5752
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
5557
5753
  streaming: false,
5558
5754
  variant: "reasoning",
@@ -5560,7 +5756,7 @@ var AgentWidgetClient = class {
5560
5756
  reasoning: {
5561
5757
  id: reflectionId,
5562
5758
  status: "complete",
5563
- chunks: [(_Ua = payload.reflection) != null ? _Ua : ""]
5759
+ chunks: [(_bb = payload.reflection) != null ? _bb : ""]
5564
5760
  },
5565
5761
  agentMetadata: {
5566
5762
  executionId: payload.executionId,
@@ -5581,7 +5777,7 @@ var AgentWidgetClient = class {
5581
5777
  }
5582
5778
  onEvent({ type: "status", status: "idle" });
5583
5779
  } else if (payloadType === "agent_error") {
5584
- const errorMessage = typeof payload.error === "string" ? payload.error : (_Wa = (_Va = payload.error) == null ? void 0 : _Va.message) != null ? _Wa : "Agent execution error";
5780
+ const errorMessage = typeof payload.error === "string" ? payload.error : (_db = (_cb = payload.error) == null ? void 0 : _cb.message) != null ? _db : "Agent execution error";
5585
5781
  if (payload.recoverable) {
5586
5782
  if (typeof console !== "undefined") {
5587
5783
  console.warn("[AgentWidget] Recoverable agent error:", errorMessage);
@@ -5594,7 +5790,7 @@ var AgentWidgetClient = class {
5594
5790
  }
5595
5791
  } else if (payloadType === "agent_ping") {
5596
5792
  } else if (payloadType === "agent_approval_start") {
5597
- const approvalId = (_Xa = payload.approvalId) != null ? _Xa : `approval-${nextSequence()}`;
5793
+ const approvalId = (_eb = payload.approvalId) != null ? _eb : `approval-${nextSequence()}`;
5598
5794
  const approvalMessage = {
5599
5795
  id: `approval-${approvalId}`,
5600
5796
  role: "assistant",
@@ -5606,17 +5802,17 @@ var AgentWidgetClient = class {
5606
5802
  approval: {
5607
5803
  id: approvalId,
5608
5804
  status: "pending",
5609
- agentId: (_Ya = agentExecution == null ? void 0 : agentExecution.agentId) != null ? _Ya : "virtual",
5610
- executionId: (__a = (_Za = payload.executionId) != null ? _Za : agentExecution == null ? void 0 : agentExecution.executionId) != null ? __a : "",
5611
- toolName: (_$a = payload.toolName) != null ? _$a : "",
5805
+ agentId: (_fb = agentExecution == null ? void 0 : agentExecution.agentId) != null ? _fb : "virtual",
5806
+ executionId: (_hb = (_gb = payload.executionId) != null ? _gb : agentExecution == null ? void 0 : agentExecution.executionId) != null ? _hb : "",
5807
+ toolName: (_ib = payload.toolName) != null ? _ib : "",
5612
5808
  toolType: payload.toolType,
5613
- description: (_bb = payload.description) != null ? _bb : `Execute ${(_ab = payload.toolName) != null ? _ab : "tool"}`,
5809
+ description: (_kb = payload.description) != null ? _kb : `Execute ${(_jb = payload.toolName) != null ? _jb : "tool"}`,
5614
5810
  parameters: payload.parameters
5615
5811
  }
5616
5812
  };
5617
5813
  emitMessage(approvalMessage);
5618
5814
  } else if (payloadType === "step_await" && payload.awaitReason === "approval_required") {
5619
- const approvalId = (_cb = payload.approvalId) != null ? _cb : `approval-${nextSequence()}`;
5815
+ const approvalId = (_lb = payload.approvalId) != null ? _lb : `approval-${nextSequence()}`;
5620
5816
  const approvalMessage = {
5621
5817
  id: `approval-${approvalId}`,
5622
5818
  role: "assistant",
@@ -5628,11 +5824,11 @@ var AgentWidgetClient = class {
5628
5824
  approval: {
5629
5825
  id: approvalId,
5630
5826
  status: "pending",
5631
- agentId: (_db = agentExecution == null ? void 0 : agentExecution.agentId) != null ? _db : "virtual",
5632
- executionId: (_fb = (_eb = payload.executionId) != null ? _eb : agentExecution == null ? void 0 : agentExecution.executionId) != null ? _fb : "",
5633
- toolName: (_gb = payload.toolName) != null ? _gb : "",
5827
+ agentId: (_mb = agentExecution == null ? void 0 : agentExecution.agentId) != null ? _mb : "virtual",
5828
+ executionId: (_ob = (_nb = payload.executionId) != null ? _nb : agentExecution == null ? void 0 : agentExecution.executionId) != null ? _ob : "",
5829
+ toolName: (_pb = payload.toolName) != null ? _pb : "",
5634
5830
  toolType: payload.toolType,
5635
- description: (_ib = payload.description) != null ? _ib : `Execute ${(_hb = payload.toolName) != null ? _hb : "tool"}`,
5831
+ description: (_rb = payload.description) != null ? _rb : `Execute ${(_qb = payload.toolName) != null ? _qb : "tool"}`,
5636
5832
  parameters: payload.parameters
5637
5833
  }
5638
5834
  };
@@ -5651,11 +5847,11 @@ var AgentWidgetClient = class {
5651
5847
  sequence: nextSequence(),
5652
5848
  approval: {
5653
5849
  id: approvalId,
5654
- status: (_jb = payload.decision) != null ? _jb : "approved",
5655
- agentId: (_kb = agentExecution == null ? void 0 : agentExecution.agentId) != null ? _kb : "virtual",
5656
- executionId: (_mb = (_lb = payload.executionId) != null ? _lb : agentExecution == null ? void 0 : agentExecution.executionId) != null ? _mb : "",
5657
- toolName: (_nb = payload.toolName) != null ? _nb : "",
5658
- description: (_ob = payload.description) != null ? _ob : "",
5850
+ status: (_sb = payload.decision) != null ? _sb : "approved",
5851
+ agentId: (_tb = agentExecution == null ? void 0 : agentExecution.agentId) != null ? _tb : "virtual",
5852
+ executionId: (_vb = (_ub = payload.executionId) != null ? _ub : agentExecution == null ? void 0 : agentExecution.executionId) != null ? _vb : "",
5853
+ toolName: (_wb = payload.toolName) != null ? _wb : "",
5854
+ description: (_xb = payload.description) != null ? _xb : "",
5659
5855
  resolvedAt: Date.now()
5660
5856
  }
5661
5857
  };
@@ -5693,7 +5889,7 @@ var AgentWidgetClient = class {
5693
5889
  }
5694
5890
  } else if (payloadType === "artifact_delta") {
5695
5891
  const deltaId = String(payload.id);
5696
- const deltaText = typeof payload.delta === "string" ? payload.delta : String((_pb = payload.delta) != null ? _pb : "");
5892
+ const deltaText = typeof payload.delta === "string" ? payload.delta : String((_yb = payload.delta) != null ? _yb : "");
5697
5893
  onEvent({
5698
5894
  type: "artifact_delta",
5699
5895
  id: deltaId,
@@ -5716,7 +5912,7 @@ var AgentWidgetClient = class {
5716
5912
  if (refMsg) {
5717
5913
  refMsg.streaming = false;
5718
5914
  try {
5719
- const parsed = JSON.parse((_qb = refMsg.rawContent) != null ? _qb : "{}");
5915
+ const parsed = JSON.parse((_zb = refMsg.rawContent) != null ? _zb : "{}");
5720
5916
  if (parsed.props) {
5721
5917
  parsed.props.status = "complete";
5722
5918
  const acc = artifactContent.get(artCompleteId);
@@ -5737,7 +5933,7 @@ var AgentWidgetClient = class {
5737
5933
  if (!m || typeof m !== "object") {
5738
5934
  continue;
5739
5935
  }
5740
- const id = String((_rb = m.id) != null ? _rb : `msg-${nextSequence()}`);
5936
+ const id = String((_Ab = m.id) != null ? _Ab : `msg-${nextSequence()}`);
5741
5937
  const roleRaw = m.role;
5742
5938
  const role = roleRaw === "user" ? "user" : roleRaw === "system" ? "system" : "assistant";
5743
5939
  const msg = {
@@ -5756,7 +5952,7 @@ var AgentWidgetClient = class {
5756
5952
  if (msg.rawContent) {
5757
5953
  try {
5758
5954
  const parsed = JSON.parse(msg.rawContent);
5759
- const refArtId = (_sb = parsed == null ? void 0 : parsed.props) == null ? void 0 : _sb.artifactId;
5955
+ const refArtId = (_Bb = parsed == null ? void 0 : parsed.props) == null ? void 0 : _Bb.artifactId;
5760
5956
  if (typeof refArtId === "string") {
5761
5957
  artifactIdsWithCards.add(refArtId);
5762
5958
  }
@@ -5772,7 +5968,7 @@ var AgentWidgetClient = class {
5772
5968
  if (payload.error instanceof Error) {
5773
5969
  resolvedError = payload.error;
5774
5970
  } else if (payloadType === "dispatch_error") {
5775
- const msg = (_tb = payload.message) != null ? _tb : payload.error;
5971
+ const msg = (_Cb = payload.message) != null ? _Cb : payload.error;
5776
5972
  if (msg != null && msg !== "") {
5777
5973
  resolvedError = new Error(String(msg));
5778
5974
  }
@@ -5781,7 +5977,7 @@ var AgentWidgetClient = class {
5781
5977
  if (typeof e === "string" && e !== "") {
5782
5978
  resolvedError = new Error(e);
5783
5979
  } else if (e != null && typeof e === "object" && "message" in e) {
5784
- resolvedError = new Error(String((_ub = e.message) != null ? _ub : e));
5980
+ resolvedError = new Error(String((_Db = e.message) != null ? _Db : e));
5785
5981
  }
5786
5982
  } else if (payloadType === "error" && payload.error != null && payload.error !== "") {
5787
5983
  resolvedError = new Error(String(payload.error));
@@ -6885,7 +7081,7 @@ var AgentWidgetSession = class _AgentWidgetSession {
6885
7081
  this.applyArtifactStreamEvent(event);
6886
7082
  }
6887
7083
  };
6888
- var _a;
7084
+ var _a, _b;
6889
7085
  this.messages = [...(_a = config.initialMessages) != null ? _a : []].map((message) => {
6890
7086
  var _a2;
6891
7087
  return {
@@ -6895,9 +7091,18 @@ var AgentWidgetSession = class _AgentWidgetSession {
6895
7091
  });
6896
7092
  this.messages = this.sortMessages(this.messages);
6897
7093
  this.client = new AgentWidgetClient(config);
7094
+ for (const rec of (_b = config.initialArtifacts) != null ? _b : []) {
7095
+ this.artifacts.set(rec.id, { ...rec, status: "complete" });
7096
+ }
7097
+ if (config.initialSelectedArtifactId != null) {
7098
+ this.selectedArtifactId = config.initialSelectedArtifactId;
7099
+ }
6898
7100
  if (this.messages.length) {
6899
7101
  this.callbacks.onMessagesChanged([...this.messages]);
6900
7102
  }
7103
+ if (this.artifacts.size > 0) {
7104
+ this.emitArtifactsState();
7105
+ }
6901
7106
  this.callbacks.onStatusChanged(this.status);
6902
7107
  }
6903
7108
  /**
@@ -7622,10 +7827,147 @@ var AgentWidgetSession = class _AgentWidgetSession {
7622
7827
  );
7623
7828
  }
7624
7829
  }
7830
+ /**
7831
+ * Resolve a paused `ask_user_question` LOCAL tool call.
7832
+ *
7833
+ * When the server emits `step_await` for `ask_user_question`, the widget
7834
+ * renders the answer-pill sheet and calls this method once the user
7835
+ * picks. Steps:
7836
+ * 1. POST the answer to `/resume` via `client.resumeFlow`.
7837
+ * 2. Pipe the resulting SSE stream through `connectStream()` so the
7838
+ * paused agent execution continues.
7839
+ * 3. Append a user-visible bubble with the answer text so the
7840
+ * transcript reads naturally.
7841
+ */
7842
+ /**
7843
+ * Persist in-progress answers and the current page index for a multi-question
7844
+ * `ask_user_question` payload, so a refresh resumes on the same page with
7845
+ * prior answers intact. Called by ui.ts on every Back/Next/pick interaction.
7846
+ */
7847
+ persistAskUserQuestionProgress(toolMessage, progress) {
7848
+ const current = this.messages.find((m) => m.id === toolMessage.id);
7849
+ if (!current) return;
7850
+ this.upsertMessage({
7851
+ ...current,
7852
+ agentMetadata: {
7853
+ ...current.agentMetadata,
7854
+ askUserQuestionAnswers: progress.answers,
7855
+ askUserQuestionIndex: progress.currentIndex
7856
+ }
7857
+ });
7858
+ }
7859
+ /**
7860
+ * Flip an `ask_user_question` tool message from awaiting → answered so
7861
+ * render passes stop re-mounting its answer-pill sheet. Idempotent.
7862
+ * When `answers` is provided, persists the full structured answer Record
7863
+ * atomically with the answered flag — guarding against later events that
7864
+ * could re-emit the tool message and clobber the per-pick persisted
7865
+ * answers via top-level merge.
7866
+ */
7867
+ markAskUserQuestionResolved(toolMessage, answers) {
7868
+ const current = this.messages.find((m) => m.id === toolMessage.id);
7869
+ if (!current) return;
7870
+ this.upsertMessage({
7871
+ ...current,
7872
+ agentMetadata: {
7873
+ ...current.agentMetadata,
7874
+ awaitingLocalTool: false,
7875
+ askUserQuestionAnswered: true,
7876
+ ...answers ? { askUserQuestionAnswers: answers } : {}
7877
+ }
7878
+ });
7879
+ }
7880
+ async resolveAskUserQuestion(toolMessage, answer) {
7881
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
7882
+ const live = this.messages.find((m) => m.id === toolMessage.id);
7883
+ if (((_a = live == null ? void 0 : live.agentMetadata) == null ? void 0 : _a.askUserQuestionAnswered) === true) return;
7884
+ const executionId = (_b = toolMessage.agentMetadata) == null ? void 0 : _b.executionId;
7885
+ const toolName = (_c = toolMessage.toolCall) == null ? void 0 : _c.name;
7886
+ if (!executionId || !toolName) {
7887
+ (_e = (_d = this.callbacks).onError) == null ? void 0 : _e.call(
7888
+ _d,
7889
+ new Error(
7890
+ "resolveAskUserQuestion: message is missing executionId or toolCall.name"
7891
+ )
7892
+ );
7893
+ return;
7894
+ }
7895
+ let structuredAnswers = typeof answer === "string" ? void 0 : answer;
7896
+ if (structuredAnswers === void 0 && typeof answer === "string") {
7897
+ const args2 = (_f = toolMessage.toolCall) == null ? void 0 : _f.args;
7898
+ const questions2 = Array.isArray(args2 == null ? void 0 : args2.questions) ? args2.questions : [];
7899
+ if (questions2.length === 1) {
7900
+ const qText = typeof ((_g = questions2[0]) == null ? void 0 : _g.question) === "string" ? questions2[0].question : "";
7901
+ if (qText) structuredAnswers = { [qText]: answer };
7902
+ }
7903
+ }
7904
+ this.markAskUserQuestionResolved(toolMessage, structuredAnswers);
7905
+ const toolCallId = toolMessage.toolCall.id;
7906
+ const args = (_h = toolMessage.toolCall) == null ? void 0 : _h.args;
7907
+ const questions = Array.isArray(args == null ? void 0 : args.questions) ? args.questions : [];
7908
+ if (questions.length === 0) {
7909
+ const fallback = typeof answer === "string" ? answer : Object.entries(answer).map(
7910
+ ([q, v]) => `${q}: ${Array.isArray(v) ? v.join(", ") : v}`
7911
+ ).join(" | ");
7912
+ this.appendMessage({
7913
+ id: `ask-user-answer-${toolCallId}`,
7914
+ role: "user",
7915
+ content: fallback,
7916
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
7917
+ streaming: false,
7918
+ sequence: this.nextSequence()
7919
+ });
7920
+ } else {
7921
+ const stored = structuredAnswers != null ? structuredAnswers : {};
7922
+ questions.forEach((p, i) => {
7923
+ const qText = typeof (p == null ? void 0 : p.question) === "string" ? p.question : "";
7924
+ if (!qText) return;
7925
+ const ans = stored[qText];
7926
+ const answerStr = Array.isArray(ans) ? ans.join(", ") : typeof ans === "string" ? ans : "";
7927
+ this.appendMessage({
7928
+ id: `ask-user-q-${toolCallId}-${i}`,
7929
+ role: "assistant",
7930
+ content: qText,
7931
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
7932
+ streaming: false,
7933
+ sequence: this.nextSequence()
7934
+ });
7935
+ this.appendMessage({
7936
+ id: `ask-user-a-${toolCallId}-${i}`,
7937
+ role: "user",
7938
+ content: answerStr || "*Skipped*",
7939
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
7940
+ streaming: false,
7941
+ sequence: this.nextSequence()
7942
+ });
7943
+ });
7944
+ }
7945
+ try {
7946
+ const response = await this.client.resumeFlow(executionId, {
7947
+ [toolName]: answer
7948
+ });
7949
+ if (!response.ok) {
7950
+ const errorData = await response.json().catch(() => null);
7951
+ throw new Error(
7952
+ (_i = errorData == null ? void 0 : errorData.error) != null ? _i : `Resume failed: ${response.status}`
7953
+ );
7954
+ }
7955
+ if (response.body) {
7956
+ await this.connectStream(response.body);
7957
+ }
7958
+ } catch (error) {
7959
+ (_k = (_j = this.callbacks).onError) == null ? void 0 : _k.call(
7960
+ _j,
7961
+ error instanceof Error ? error : new Error(String(error))
7962
+ );
7963
+ }
7964
+ }
7625
7965
  cancel() {
7626
7966
  var _a;
7627
7967
  (_a = this.abortController) == null ? void 0 : _a.abort();
7628
7968
  this.abortController = null;
7969
+ this.stopSpeaking();
7970
+ this.stopVoicePlayback();
7629
7971
  this.setStreaming(false);
7630
7972
  this.setStatus("idle");
7631
7973
  }
@@ -7767,6 +8109,14 @@ var AgentWidgetSession = class _AgentWidgetSession {
7767
8109
  this.setStatus("idle");
7768
8110
  this.callbacks.onMessagesChanged([...this.messages]);
7769
8111
  }
8112
+ hydrateArtifacts(artifacts, selectedId = null) {
8113
+ this.artifacts.clear();
8114
+ for (const rec of artifacts) {
8115
+ this.artifacts.set(rec.id, { ...rec, status: "complete" });
8116
+ }
8117
+ this.selectedArtifactId = selectedId;
8118
+ this.emitArtifactsState();
8119
+ }
7770
8120
  setStatus(status) {
7771
8121
  if (this.status === status) return;
7772
8122
  this.status = status;
@@ -7873,9 +8223,24 @@ var AgentWidgetSession = class _AgentWidgetSession {
7873
8223
  this.appendMessage(withSequence);
7874
8224
  return;
7875
8225
  }
7876
- this.messages = this.messages.map(
7877
- (existing, idx) => idx === index ? { ...existing, ...withSequence } : existing
7878
- );
8226
+ this.messages = this.messages.map((existing, idx) => {
8227
+ var _a;
8228
+ if (idx !== index) return existing;
8229
+ const merged = { ...existing, ...withSequence };
8230
+ if (((_a = existing.agentMetadata) == null ? void 0 : _a.askUserQuestionAnswered) === true && withSequence.agentMetadata) {
8231
+ merged.agentMetadata = {
8232
+ ...withSequence.agentMetadata,
8233
+ askUserQuestionAnswered: true,
8234
+ ...existing.agentMetadata.askUserQuestionAnswers ? {
8235
+ askUserQuestionAnswers: existing.agentMetadata.askUserQuestionAnswers
8236
+ } : {},
8237
+ // Keep awaiting flag false once resolved — never let a stale
8238
+ // re-emit flip us back to awaiting.
8239
+ awaitingLocalTool: false
8240
+ };
8241
+ }
8242
+ return merged;
8243
+ });
7879
8244
  this.messages = this.sortMessages(this.messages);
7880
8245
  this.callbacks.onMessagesChanged([...this.messages]);
7881
8246
  }
@@ -8258,6 +8623,9 @@ var morphMessages = (container, newContent, options = {}) => {
8258
8623
  if (oldNode.classList.contains("persona-animate-typing")) {
8259
8624
  return false;
8260
8625
  }
8626
+ if (oldNode.hasAttribute("data-preserve-runtime")) {
8627
+ return false;
8628
+ }
8261
8629
  if (oldNode.hasAttribute("data-preserve-animation")) {
8262
8630
  if (newNode instanceof HTMLElement && !newNode.hasAttribute("data-preserve-animation")) {
8263
8631
  return;
@@ -8279,7 +8647,7 @@ var morphMessages = (container, newContent, options = {}) => {
8279
8647
 
8280
8648
  // src/utils/message-fingerprint.ts
8281
8649
  function computeMessageFingerprint(message, configVersion) {
8282
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C;
8650
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D;
8283
8651
  return [
8284
8652
  message.id,
8285
8653
  message.role,
@@ -8297,6 +8665,7 @@ function computeMessageFingerprint(message, configVersion) {
8297
8665
  typeof ((_w = message.toolCall) == null ? void 0 : _w.args) === "string" ? message.toolCall.args.length : ((_x = message.toolCall) == null ? void 0 : _x.args) ? JSON.stringify(message.toolCall.args).length : 0,
8298
8666
  (_A = (_z = (_y = message.reasoning) == null ? void 0 : _y.chunks) == null ? void 0 : _z.length) != null ? _A : 0,
8299
8667
  (_C = (_B = message.contentParts) == null ? void 0 : _B.length) != null ? _C : 0,
8668
+ (_D = message.stopReason) != null ? _D : "",
8300
8669
  configVersion
8301
8670
  ].join("\0");
8302
8671
  }
@@ -8397,6 +8766,241 @@ var statusCopy = {
8397
8766
  var DEFAULT_OVERLAY_Z_INDEX = 1e5;
8398
8767
  var PORTALED_OVERLAY_Z_INDEX = DEFAULT_OVERLAY_Z_INDEX + 1;
8399
8768
 
8769
+ // src/utils/stream-animation.ts
8770
+ var DEFAULT_STREAM_ANIMATION = {
8771
+ type: "none",
8772
+ placeholder: "none",
8773
+ speed: 120,
8774
+ duration: 1800,
8775
+ buffer: "none"
8776
+ };
8777
+ var DEFAULT_SKIP_TAGS = ["pre", "code", "a", "script", "style"];
8778
+ var resolveStreamAnimation = (feature) => {
8779
+ var _a, _b, _c, _d, _e;
8780
+ return {
8781
+ type: (_a = feature == null ? void 0 : feature.type) != null ? _a : DEFAULT_STREAM_ANIMATION.type,
8782
+ placeholder: (_b = feature == null ? void 0 : feature.placeholder) != null ? _b : DEFAULT_STREAM_ANIMATION.placeholder,
8783
+ speed: (_c = feature == null ? void 0 : feature.speed) != null ? _c : DEFAULT_STREAM_ANIMATION.speed,
8784
+ duration: (_d = feature == null ? void 0 : feature.duration) != null ? _d : DEFAULT_STREAM_ANIMATION.duration,
8785
+ buffer: (_e = feature == null ? void 0 : feature.buffer) != null ? _e : DEFAULT_STREAM_ANIMATION.buffer
8786
+ };
8787
+ };
8788
+ var BUILTIN_PLUGINS = [
8789
+ {
8790
+ name: "typewriter",
8791
+ containerClass: "persona-stream-typewriter",
8792
+ wrap: "char",
8793
+ useCaret: true
8794
+ },
8795
+ {
8796
+ name: "pop-bubble",
8797
+ bubbleClass: "persona-stream-pop",
8798
+ wrap: "none"
8799
+ },
8800
+ {
8801
+ name: "letter-rise",
8802
+ containerClass: "persona-stream-letter-rise",
8803
+ wrap: "char"
8804
+ },
8805
+ {
8806
+ name: "word-fade",
8807
+ containerClass: "persona-stream-word-fade",
8808
+ wrap: "word"
8809
+ }
8810
+ ];
8811
+ var globalRegistry = /* @__PURE__ */ new Map();
8812
+ for (const plugin of BUILTIN_PLUGINS) globalRegistry.set(plugin.name, plugin);
8813
+ var resolveStreamAnimationPlugin = (type, overrides) => {
8814
+ var _a, _b;
8815
+ if (type === "none") return null;
8816
+ if (overrides && Object.prototype.hasOwnProperty.call(overrides, type)) {
8817
+ return (_a = overrides[type]) != null ? _a : null;
8818
+ }
8819
+ return (_b = globalRegistry.get(type)) != null ? _b : null;
8820
+ };
8821
+ var applyStreamBuffer = (content, buffer, plugin, message, streaming) => {
8822
+ if (!streaming) return content;
8823
+ if (plugin == null ? void 0 : plugin.bufferContent) return plugin.bufferContent(content, message);
8824
+ if (!content) return content;
8825
+ if (buffer === "word") {
8826
+ const lastSpace = content.search(/\s(?=\S*$)/);
8827
+ if (lastSpace < 0) return "";
8828
+ return content.slice(0, lastSpace);
8829
+ }
8830
+ if (buffer === "line") {
8831
+ const lastNewline = content.lastIndexOf("\n");
8832
+ if (lastNewline < 0) return "";
8833
+ return content.slice(0, lastNewline);
8834
+ }
8835
+ return content;
8836
+ };
8837
+ var makeCharSpan = (doc, ch, messageId, index) => {
8838
+ const span = doc.createElement("span");
8839
+ span.className = "persona-stream-char";
8840
+ span.id = `stream-c-${messageId}-${index}`;
8841
+ span.style.setProperty("--char-index", String(index));
8842
+ span.textContent = ch;
8843
+ return span;
8844
+ };
8845
+ var makeWordSpan = (doc, word, messageId, index) => {
8846
+ const span = doc.createElement("span");
8847
+ span.className = "persona-stream-word";
8848
+ span.id = `stream-w-${messageId}-${index}`;
8849
+ span.style.setProperty("--word-index", String(index));
8850
+ span.textContent = word;
8851
+ return span;
8852
+ };
8853
+ var WHITESPACE_RE = /\s/;
8854
+ var shouldSkipSubtree = (node, skipTags) => {
8855
+ let current = node.parentNode;
8856
+ while (current) {
8857
+ if (current.nodeType === 1) {
8858
+ const el = current;
8859
+ if (skipTags.has(el.tagName.toLowerCase())) return true;
8860
+ }
8861
+ current = current.parentNode;
8862
+ }
8863
+ return false;
8864
+ };
8865
+ var wrapTextNodeChars = (textNode, messageId, counterRef) => {
8866
+ var _a;
8867
+ const doc = textNode.ownerDocument;
8868
+ const parent = textNode.parentNode;
8869
+ if (!doc || !parent) return;
8870
+ const text = (_a = textNode.nodeValue) != null ? _a : "";
8871
+ if (!text) return;
8872
+ const fragment = doc.createDocumentFragment();
8873
+ let i = 0;
8874
+ while (i < text.length) {
8875
+ if (WHITESPACE_RE.test(text[i])) {
8876
+ let j = i;
8877
+ while (j < text.length && WHITESPACE_RE.test(text[j])) j += 1;
8878
+ fragment.appendChild(doc.createTextNode(text.slice(i, j)));
8879
+ i = j;
8880
+ } else {
8881
+ const group = doc.createElement("span");
8882
+ group.className = "persona-stream-word-group";
8883
+ let j = i;
8884
+ while (j < text.length && !WHITESPACE_RE.test(text[j])) {
8885
+ group.appendChild(makeCharSpan(doc, text[j], messageId, counterRef.value));
8886
+ counterRef.value += 1;
8887
+ j += 1;
8888
+ }
8889
+ fragment.appendChild(group);
8890
+ i = j;
8891
+ }
8892
+ }
8893
+ parent.replaceChild(fragment, textNode);
8894
+ };
8895
+ var wrapTextNodeWords = (textNode, messageId, counterRef) => {
8896
+ var _a;
8897
+ const doc = textNode.ownerDocument;
8898
+ const parent = textNode.parentNode;
8899
+ if (!doc || !parent) return;
8900
+ const text = (_a = textNode.nodeValue) != null ? _a : "";
8901
+ if (!text) return;
8902
+ const fragment = doc.createDocumentFragment();
8903
+ const tokens = text.split(/(\s+)/);
8904
+ for (const token of tokens) {
8905
+ if (!token) continue;
8906
+ if (/^\s+$/.test(token)) {
8907
+ fragment.appendChild(doc.createTextNode(token));
8908
+ } else {
8909
+ fragment.appendChild(makeWordSpan(doc, token, messageId, counterRef.value));
8910
+ counterRef.value += 1;
8911
+ }
8912
+ }
8913
+ parent.replaceChild(fragment, textNode);
8914
+ };
8915
+ var wrapStreamAnimation = (html, mode, messageId, options) => {
8916
+ var _a;
8917
+ if (!html) return html;
8918
+ if (typeof document === "undefined") return html;
8919
+ const scratch = document.createElement("div");
8920
+ scratch.innerHTML = html;
8921
+ const skipTags = new Set(((_a = options == null ? void 0 : options.skipTags) != null ? _a : DEFAULT_SKIP_TAGS).map((t) => t.toLowerCase()));
8922
+ const walker = document.createTreeWalker(scratch, NodeFilter.SHOW_TEXT, null);
8923
+ const textNodes = [];
8924
+ let node = walker.nextNode();
8925
+ while (node) {
8926
+ if (!shouldSkipSubtree(node, skipTags)) {
8927
+ textNodes.push(node);
8928
+ }
8929
+ node = walker.nextNode();
8930
+ }
8931
+ const counterRef = { value: 0 };
8932
+ const wrap = mode === "char" ? wrapTextNodeChars : wrapTextNodeWords;
8933
+ for (const textNode of textNodes) {
8934
+ wrap(textNode, messageId, counterRef);
8935
+ }
8936
+ return scratch.innerHTML;
8937
+ };
8938
+ var createStreamCaret = (doc = document) => {
8939
+ const caret = doc.createElement("span");
8940
+ caret.className = "persona-stream-caret";
8941
+ caret.setAttribute("aria-hidden", "true");
8942
+ caret.setAttribute("data-preserve-animation", "stream-caret");
8943
+ return caret;
8944
+ };
8945
+ var createSkeletonPlaceholder = (doc = document) => {
8946
+ const wrapper = doc.createElement("div");
8947
+ wrapper.className = "persona-stream-skeleton";
8948
+ wrapper.setAttribute("data-preserve-animation", "stream-skeleton");
8949
+ wrapper.setAttribute("aria-hidden", "true");
8950
+ const line = doc.createElement("div");
8951
+ line.className = "persona-stream-skeleton-line";
8952
+ wrapper.appendChild(line);
8953
+ return wrapper;
8954
+ };
8955
+ var injectedStyleRoots = /* @__PURE__ */ new WeakMap();
8956
+ var injectPluginStyles = (plugin, root) => {
8957
+ var _a;
8958
+ if (!plugin.styles) return;
8959
+ let names = injectedStyleRoots.get(root);
8960
+ if (!names) {
8961
+ names = /* @__PURE__ */ new Set();
8962
+ injectedStyleRoots.set(root, names);
8963
+ }
8964
+ if (names.has(plugin.name)) {
8965
+ const escaped = plugin.name.replace(/["\\]/g, "\\$&");
8966
+ const existing = root.querySelector(
8967
+ `style[data-persona-animation="${escaped}"]`
8968
+ );
8969
+ if (existing) return;
8970
+ names.delete(plugin.name);
8971
+ }
8972
+ names.add(plugin.name);
8973
+ const doc = root instanceof ShadowRoot ? root.ownerDocument : (_a = root.ownerDocument) != null ? _a : document;
8974
+ const style = doc.createElement("style");
8975
+ style.setAttribute("data-persona-animation", plugin.name);
8976
+ style.textContent = plugin.styles;
8977
+ root.appendChild(style);
8978
+ };
8979
+ var attachedCleanups = /* @__PURE__ */ new WeakMap();
8980
+ var attachPlugin = (plugin, root) => {
8981
+ if (!plugin.onAttach) return;
8982
+ let cleanups = attachedCleanups.get(root);
8983
+ if (!cleanups) {
8984
+ cleanups = /* @__PURE__ */ new Map();
8985
+ attachedCleanups.set(root, cleanups);
8986
+ }
8987
+ if (cleanups.has(plugin.name)) return;
8988
+ const cleanup = plugin.onAttach(root);
8989
+ cleanups.set(plugin.name, cleanup);
8990
+ };
8991
+ var detachAllPlugins = (root) => {
8992
+ const cleanups = attachedCleanups.get(root);
8993
+ if (!cleanups) return;
8994
+ for (const cleanup of cleanups.values()) {
8995
+ if (typeof cleanup === "function") cleanup();
8996
+ }
8997
+ cleanups.clear();
8998
+ };
8999
+ var ensurePluginActive = (plugin, root) => {
9000
+ injectPluginStyles(plugin, root);
9001
+ attachPlugin(plugin, root);
9002
+ };
9003
+
8400
9004
  // src/utils/overlay-host-stacking.ts
8401
9005
  function syncOverlayHostStacking(host, zIndex = DEFAULT_OVERLAY_Z_INDEX) {
8402
9006
  const originalPosition = host.style.position;
@@ -9482,7 +10086,7 @@ var buildHeaderWithLayout = (config, layoutConfig, context) => {
9482
10086
 
9483
10087
  // src/components/composer-builder.ts
9484
10088
  var buildComposer = (context) => {
9485
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A;
10089
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E;
9486
10090
  const { config } = context;
9487
10091
  const footer = createElement(
9488
10092
  "div",
@@ -9538,9 +10142,13 @@ var buildComposer = (context) => {
9538
10142
  const useIcon = (_d = sendButtonConfig.useIcon) != null ? _d : false;
9539
10143
  const iconText = (_e = sendButtonConfig.iconText) != null ? _e : "\u2191";
9540
10144
  const iconName = sendButtonConfig.iconName;
9541
- const tooltipText = (_f = sendButtonConfig.tooltipText) != null ? _f : "Send message";
9542
- const showTooltip = (_g = sendButtonConfig.showTooltip) != null ? _g : false;
9543
- const buttonSize = (_h = sendButtonConfig.size) != null ? _h : "40px";
10145
+ const stopIconName = (_f = sendButtonConfig.stopIconName) != null ? _f : "square";
10146
+ const tooltipText = (_g = sendButtonConfig.tooltipText) != null ? _g : "Send message";
10147
+ const stopTooltipText = (_h = sendButtonConfig.stopTooltipText) != null ? _h : "Stop generating";
10148
+ const sendLabel = (_j = (_i = config == null ? void 0 : config.copy) == null ? void 0 : _i.sendButtonLabel) != null ? _j : "Send";
10149
+ const stopLabel = (_l = (_k = config == null ? void 0 : config.copy) == null ? void 0 : _k.stopButtonLabel) != null ? _l : "Stop";
10150
+ const showTooltip = (_m = sendButtonConfig.showTooltip) != null ? _m : false;
10151
+ const buttonSize = (_n = sendButtonConfig.size) != null ? _n : "40px";
9544
10152
  const backgroundColor = sendButtonConfig.backgroundColor;
9545
10153
  const textColor = sendButtonConfig.textColor;
9546
10154
  const sendButtonWrapper = createElement("div", "persona-send-button-wrapper");
@@ -9550,6 +10158,8 @@ var buildComposer = (context) => {
9550
10158
  );
9551
10159
  sendButton.type = "submit";
9552
10160
  sendButton.setAttribute("data-persona-composer-submit", "");
10161
+ let sendIcon = null;
10162
+ let stopIcon = null;
9553
10163
  if (useIcon) {
9554
10164
  sendButton.style.width = buttonSize;
9555
10165
  sendButton.style.height = buttonSize;
@@ -9563,25 +10173,26 @@ var buildComposer = (context) => {
9563
10173
  } else {
9564
10174
  sendButton.style.color = "var(--persona-button-primary-fg, #ffffff)";
9565
10175
  }
10176
+ const iconSize = parseFloat(buttonSize) || 24;
10177
+ const iconColor = (textColor == null ? void 0 : textColor.trim()) || "currentColor";
9566
10178
  if (iconName) {
9567
- const iconSize = parseFloat(buttonSize) || 24;
9568
- const iconColor = (textColor == null ? void 0 : textColor.trim()) || "currentColor";
9569
- const iconSvg = renderLucideIcon(iconName, iconSize, iconColor, 2);
9570
- if (iconSvg) {
9571
- sendButton.appendChild(iconSvg);
10179
+ sendIcon = renderLucideIcon(iconName, iconSize, iconColor, 2);
10180
+ if (sendIcon) {
10181
+ sendButton.appendChild(sendIcon);
9572
10182
  } else {
9573
10183
  sendButton.textContent = iconText;
9574
10184
  }
9575
10185
  } else {
9576
10186
  sendButton.textContent = iconText;
9577
10187
  }
10188
+ stopIcon = renderLucideIcon(stopIconName, iconSize, iconColor, 2);
9578
10189
  if (backgroundColor) {
9579
10190
  sendButton.style.backgroundColor = backgroundColor;
9580
10191
  } else {
9581
10192
  sendButton.classList.add("persona-bg-persona-primary");
9582
10193
  }
9583
10194
  } else {
9584
- sendButton.textContent = (_j = (_i = config == null ? void 0 : config.copy) == null ? void 0 : _i.sendButtonLabel) != null ? _j : "Send";
10195
+ sendButton.textContent = sendLabel;
9585
10196
  if (textColor) {
9586
10197
  sendButton.style.color = textColor;
9587
10198
  } else {
@@ -9609,18 +10220,43 @@ var buildComposer = (context) => {
9609
10220
  sendButton.style.paddingTop = "";
9610
10221
  sendButton.style.paddingBottom = "";
9611
10222
  }
10223
+ let sendTooltip = null;
9612
10224
  if (showTooltip && tooltipText) {
9613
- const tooltip = createElement("div", "persona-send-button-tooltip");
9614
- tooltip.textContent = tooltipText;
9615
- sendButtonWrapper.appendChild(tooltip);
10225
+ sendTooltip = createElement("div", "persona-send-button-tooltip");
10226
+ sendTooltip.textContent = tooltipText;
10227
+ sendButtonWrapper.appendChild(sendTooltip);
9616
10228
  }
10229
+ sendButton.setAttribute("aria-label", tooltipText);
9617
10230
  sendButtonWrapper.appendChild(sendButton);
9618
- const voiceRecognitionConfig = (_k = config == null ? void 0 : config.voiceRecognition) != null ? _k : {};
10231
+ let currentMode = "send";
10232
+ const setSendButtonMode = (mode) => {
10233
+ if (mode === currentMode) return;
10234
+ currentMode = mode;
10235
+ const label = mode === "stop" ? stopTooltipText : tooltipText;
10236
+ sendButton.setAttribute("aria-label", label);
10237
+ if (sendTooltip) {
10238
+ sendTooltip.textContent = label;
10239
+ }
10240
+ if (useIcon) {
10241
+ if (sendIcon && stopIcon) {
10242
+ const next = mode === "stop" ? stopIcon : sendIcon;
10243
+ const prev = mode === "stop" ? sendIcon : stopIcon;
10244
+ if (prev.parentNode === sendButton) {
10245
+ sendButton.replaceChild(next, prev);
10246
+ } else {
10247
+ sendButton.appendChild(next);
10248
+ }
10249
+ }
10250
+ } else {
10251
+ sendButton.textContent = mode === "stop" ? stopLabel : sendLabel;
10252
+ }
10253
+ };
10254
+ const voiceRecognitionConfig = (_o = config == null ? void 0 : config.voiceRecognition) != null ? _o : {};
9619
10255
  const voiceRecognitionEnabled = voiceRecognitionConfig.enabled === true;
9620
10256
  let micButton = null;
9621
10257
  let micButtonWrapper = null;
9622
10258
  const hasSpeechRecognition = typeof window !== "undefined" && (typeof window.webkitSpeechRecognition !== "undefined" || typeof window.SpeechRecognition !== "undefined");
9623
- const hasRuntypeProvider = ((_l = voiceRecognitionConfig.provider) == null ? void 0 : _l.type) === "runtype";
10259
+ const hasRuntypeProvider = ((_p = voiceRecognitionConfig.provider) == null ? void 0 : _p.type) === "runtype";
9624
10260
  const hasVoiceInput = hasSpeechRecognition || hasRuntypeProvider;
9625
10261
  if (voiceRecognitionEnabled && hasVoiceInput) {
9626
10262
  micButtonWrapper = createElement("div", "persona-send-button-wrapper");
@@ -9631,11 +10267,11 @@ var buildComposer = (context) => {
9631
10267
  micButton.type = "button";
9632
10268
  micButton.setAttribute("data-persona-composer-mic", "");
9633
10269
  micButton.setAttribute("aria-label", "Start voice recognition");
9634
- const micIconName = (_m = voiceRecognitionConfig.iconName) != null ? _m : "mic";
9635
- const micIconSize = (_n = voiceRecognitionConfig.iconSize) != null ? _n : buttonSize;
10270
+ const micIconName = (_q = voiceRecognitionConfig.iconName) != null ? _q : "mic";
10271
+ const micIconSize = (_r = voiceRecognitionConfig.iconSize) != null ? _r : buttonSize;
9636
10272
  const micIconSizeNum = parseFloat(micIconSize) || 24;
9637
- const micBackgroundColor = (_o = voiceRecognitionConfig.backgroundColor) != null ? _o : backgroundColor;
9638
- const micIconColor = (_p = voiceRecognitionConfig.iconColor) != null ? _p : textColor;
10273
+ const micBackgroundColor = (_s = voiceRecognitionConfig.backgroundColor) != null ? _s : backgroundColor;
10274
+ const micIconColor = (_t = voiceRecognitionConfig.iconColor) != null ? _t : textColor;
9639
10275
  micButton.style.width = micIconSize;
9640
10276
  micButton.style.height = micIconSize;
9641
10277
  micButton.style.minWidth = micIconSize;
@@ -9678,15 +10314,15 @@ var buildComposer = (context) => {
9678
10314
  micButton.style.paddingBottom = voiceRecognitionConfig.paddingY;
9679
10315
  }
9680
10316
  micButtonWrapper.appendChild(micButton);
9681
- const micTooltipText = (_q = voiceRecognitionConfig.tooltipText) != null ? _q : "Start voice recognition";
9682
- const showMicTooltip = (_r = voiceRecognitionConfig.showTooltip) != null ? _r : false;
10317
+ const micTooltipText = (_u = voiceRecognitionConfig.tooltipText) != null ? _u : "Start voice recognition";
10318
+ const showMicTooltip = (_v = voiceRecognitionConfig.showTooltip) != null ? _v : false;
9683
10319
  if (showMicTooltip && micTooltipText) {
9684
10320
  const tooltip = createElement("div", "persona-send-button-tooltip");
9685
10321
  tooltip.textContent = micTooltipText;
9686
10322
  micButtonWrapper.appendChild(tooltip);
9687
10323
  }
9688
10324
  }
9689
- const attachmentsConfig = (_s = config == null ? void 0 : config.attachments) != null ? _s : {};
10325
+ const attachmentsConfig = (_w = config == null ? void 0 : config.attachments) != null ? _w : {};
9690
10326
  const attachmentsEnabled = attachmentsConfig.enabled === true;
9691
10327
  let attachmentButton = null;
9692
10328
  let attachmentButtonWrapper = null;
@@ -9700,8 +10336,8 @@ var buildComposer = (context) => {
9700
10336
  attachmentPreviewsContainer.style.display = "none";
9701
10337
  attachmentInput = createElement("input");
9702
10338
  attachmentInput.type = "file";
9703
- attachmentInput.accept = ((_t = attachmentsConfig.allowedTypes) != null ? _t : ALL_SUPPORTED_MIME_TYPES).join(",");
9704
- attachmentInput.multiple = ((_u = attachmentsConfig.maxFiles) != null ? _u : 4) > 1;
10339
+ attachmentInput.accept = ((_x = attachmentsConfig.allowedTypes) != null ? _x : ALL_SUPPORTED_MIME_TYPES).join(",");
10340
+ attachmentInput.multiple = ((_y = attachmentsConfig.maxFiles) != null ? _y : 4) > 1;
9705
10341
  attachmentInput.style.display = "none";
9706
10342
  attachmentInput.setAttribute("aria-label", "Attach files");
9707
10343
  attachmentButtonWrapper = createElement("div", "persona-send-button-wrapper");
@@ -9710,8 +10346,8 @@ var buildComposer = (context) => {
9710
10346
  "persona-rounded-button persona-flex persona-items-center persona-justify-center disabled:persona-opacity-50 persona-cursor-pointer persona-attachment-button"
9711
10347
  );
9712
10348
  attachmentButton.type = "button";
9713
- attachmentButton.setAttribute("aria-label", (_v = attachmentsConfig.buttonTooltipText) != null ? _v : "Attach file");
9714
- const attachIconName = (_w = attachmentsConfig.buttonIconName) != null ? _w : "paperclip";
10349
+ attachmentButton.setAttribute("aria-label", (_z = attachmentsConfig.buttonTooltipText) != null ? _z : "Attach file");
10350
+ const attachIconName = (_A = attachmentsConfig.buttonIconName) != null ? _A : "paperclip";
9715
10351
  const attachIconSize = buttonSize;
9716
10352
  const buttonSizeNum = parseFloat(attachIconSize) || 40;
9717
10353
  const attachIconSizeNum = Math.round(buttonSizeNum * 0.6);
@@ -9748,7 +10384,7 @@ var buildComposer = (context) => {
9748
10384
  attachmentInput == null ? void 0 : attachmentInput.click();
9749
10385
  });
9750
10386
  attachmentButtonWrapper.appendChild(attachmentButton);
9751
- const attachTooltipText = (_x = attachmentsConfig.buttonTooltipText) != null ? _x : "Attach file";
10387
+ const attachTooltipText = (_B = attachmentsConfig.buttonTooltipText) != null ? _B : "Attach file";
9752
10388
  const tooltip = createElement("div", "persona-send-button-tooltip");
9753
10389
  tooltip.textContent = attachTooltipText;
9754
10390
  attachmentButtonWrapper.appendChild(tooltip);
@@ -9778,16 +10414,16 @@ var buildComposer = (context) => {
9778
10414
  rightActions.append(sendButtonWrapper);
9779
10415
  actionsRow.append(leftActions, rightActions);
9780
10416
  composerForm.append(actionsRow);
9781
- const statusConfig = (_y = config == null ? void 0 : config.statusIndicator) != null ? _y : {};
10417
+ const statusConfig = (_C = config == null ? void 0 : config.statusIndicator) != null ? _C : {};
9782
10418
  const alignClass = statusConfig.align === "left" ? "persona-text-left" : statusConfig.align === "center" ? "persona-text-center" : "persona-text-right";
9783
10419
  const statusText = createElement(
9784
10420
  "div",
9785
10421
  `persona-mt-2 ${alignClass} persona-text-xs persona-text-persona-muted`
9786
10422
  );
9787
10423
  statusText.setAttribute("data-persona-composer-status", "");
9788
- const isVisible = (_z = statusConfig.visible) != null ? _z : true;
10424
+ const isVisible = (_D = statusConfig.visible) != null ? _D : true;
9789
10425
  statusText.style.display = isVisible ? "" : "none";
9790
- const idleLabel = (_A = statusConfig.idleText) != null ? _A : "Online";
10426
+ const idleLabel = (_E = statusConfig.idleText) != null ? _E : "Online";
9791
10427
  if (statusConfig.idleLink) {
9792
10428
  const link = createElement("a");
9793
10429
  link.href = statusConfig.idleLink;
@@ -9819,7 +10455,8 @@ var buildComposer = (context) => {
9819
10455
  // Actions row layout elements
9820
10456
  actionsRow,
9821
10457
  leftActions,
9822
- rightActions
10458
+ rightActions,
10459
+ setSendButtonMode
9823
10460
  };
9824
10461
  };
9825
10462
 
@@ -9889,8 +10526,11 @@ var buildPanel = (config, showClose = true) => {
9889
10526
  );
9890
10527
  body.id = "persona-scroll-container";
9891
10528
  body.setAttribute("data-persona-theme-zone", "messages");
9892
- const introCardClasses = isDockedMountMode(config) ? "persona-rounded-2xl persona-bg-persona-surface persona-p-6" : "persona-rounded-2xl persona-bg-persona-surface persona-p-6 persona-shadow-sm";
9893
- const introCard = createElement("div", introCardClasses);
10529
+ const introCard = createElement(
10530
+ "div",
10531
+ "persona-rounded-2xl persona-bg-persona-surface persona-p-6"
10532
+ );
10533
+ introCard.style.boxShadow = isDockedMountMode(config) ? "none" : "var(--persona-intro-card-shadow, 0 5px 15px rgba(15, 23, 42, 0.08))";
9894
10534
  const introTitle = createElement(
9895
10535
  "h2",
9896
10536
  "persona-text-lg persona-font-semibold persona-text-persona-primary"
@@ -9930,16 +10570,28 @@ var buildPanel = (config, showClose = true) => {
9930
10570
  attachHeaderToContainer(container, headerElements, config);
9931
10571
  }
9932
10572
  container.append(body);
10573
+ const composerOverlay = createElement(
10574
+ "div",
10575
+ "persona-composer-overlay persona-pointer-events-none"
10576
+ );
10577
+ composerOverlay.setAttribute("data-persona-composer-overlay", "");
10578
+ composerOverlay.style.position = "absolute";
10579
+ composerOverlay.style.left = "0";
10580
+ composerOverlay.style.right = "0";
10581
+ composerOverlay.style.bottom = "0";
10582
+ composerOverlay.style.zIndex = "20";
9933
10583
  if (showFooter) {
9934
10584
  container.append(composerElements.footer);
9935
10585
  } else {
9936
10586
  composerElements.footer.style.display = "none";
9937
10587
  container.append(composerElements.footer);
9938
10588
  }
10589
+ container.append(composerOverlay);
9939
10590
  return {
9940
10591
  container,
9941
10592
  body,
9942
10593
  messagesWrapper,
10594
+ composerOverlay,
9943
10595
  suggestions: composerElements.suggestions,
9944
10596
  textarea: composerElements.textarea,
9945
10597
  sendButton: composerElements.sendButton,
@@ -9967,11 +10619,48 @@ var buildPanel = (config, showClose = true) => {
9967
10619
  // Actions row layout elements
9968
10620
  actionsRow: composerElements.actionsRow,
9969
10621
  leftActions: composerElements.leftActions,
9970
- rightActions: composerElements.rightActions
10622
+ rightActions: composerElements.rightActions,
10623
+ setSendButtonMode: composerElements.setSendButtonMode
9971
10624
  };
9972
10625
  };
9973
10626
 
9974
10627
  // src/components/message-bubble.ts
10628
+ var getDefaultStopReasonNoticeCopy = (stopReason) => {
10629
+ switch (stopReason) {
10630
+ case "max_tool_calls":
10631
+ return "Stopped after calling a tool. Send a follow-up to continue.";
10632
+ case "length":
10633
+ return "Response cut off as max tokens reached. Ask for more to continue.";
10634
+ case "content_filter":
10635
+ return "The provider filtered this response.";
10636
+ case "error":
10637
+ return "Something went wrong generating this response.";
10638
+ case "end_turn":
10639
+ case "unknown":
10640
+ default:
10641
+ return null;
10642
+ }
10643
+ };
10644
+ var resolveStopReasonNoticeText = (stopReason, overrides) => {
10645
+ if (!stopReason) return null;
10646
+ const fallback = getDefaultStopReasonNoticeCopy(stopReason);
10647
+ if (fallback === null) return null;
10648
+ const override = overrides == null ? void 0 : overrides[stopReason];
10649
+ const text = override !== void 0 ? override : fallback;
10650
+ if (!text) return null;
10651
+ return text;
10652
+ };
10653
+ var createStopReasonNotice = (stopReason, text) => {
10654
+ const notice = createElement(
10655
+ "div",
10656
+ "persona-message-stop-reason persona-text-xs persona-mt-2 persona-italic"
10657
+ );
10658
+ notice.setAttribute("data-stop-reason", stopReason);
10659
+ notice.setAttribute("role", "note");
10660
+ notice.style.opacity = "0.75";
10661
+ notice.textContent = text;
10662
+ return notice;
10663
+ };
9975
10664
  var isSafeImageSrc = (src) => {
9976
10665
  const lower = src.toLowerCase();
9977
10666
  if (lower.startsWith("data:image/svg+xml")) return false;
@@ -10274,7 +10963,7 @@ var createMessageActions = (message, actionsConfig, _callbacks) => {
10274
10963
  return container;
10275
10964
  };
10276
10965
  var createStandardBubble = (message, transform, layoutConfig, actionsConfig, actionCallbacks, options) => {
10277
- var _a, _b, _c, _d, _e, _f, _g;
10966
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
10278
10967
  const config = layoutConfig != null ? layoutConfig : {};
10279
10968
  const layout = (_a = config.layout) != null ? _a : "bubble";
10280
10969
  const avatarConfig = config.avatar;
@@ -10299,22 +10988,73 @@ var createStandardBubble = (message, transform, layoutConfig, actionsConfig, act
10299
10988
  const messageContentText = (_g = (_f = message.content) == null ? void 0 : _f.trim()) != null ? _g : "";
10300
10989
  const isImageOnlyFallbackMessage = imageParts.length > 0 && messageContentText === IMAGE_ONLY_MESSAGE_FALLBACK_TEXT;
10301
10990
  const shouldHideTextUntilPreviewFails = isImageOnlyFallbackMessage;
10991
+ const streamAnimation = resolveStreamAnimation(
10992
+ (_i = (_h = options == null ? void 0 : options.widgetConfig) == null ? void 0 : _h.features) == null ? void 0 : _i.streamAnimation
10993
+ );
10994
+ const streamPluginOverrides = (_l = (_k = (_j = options == null ? void 0 : options.widgetConfig) == null ? void 0 : _j.features) == null ? void 0 : _k.streamAnimation) == null ? void 0 : _l.plugins;
10995
+ const streamPlugin = message.role === "assistant" && streamAnimation.type !== "none" ? resolveStreamAnimationPlugin(streamAnimation.type, streamPluginOverrides) : null;
10996
+ const pluginStillAnimating = message.role === "assistant" && ((_m = streamPlugin == null ? void 0 : streamPlugin.isAnimating) == null ? void 0 : _m.call(streamPlugin, message)) === true;
10997
+ const streamAnimationActive = message.role === "assistant" && streamPlugin !== null && (Boolean(message.streaming) || pluginStillAnimating);
10998
+ if (streamAnimationActive && (streamPlugin == null ? void 0 : streamPlugin.bubbleClass)) {
10999
+ bubble.classList.add(streamPlugin.bubbleClass);
11000
+ }
10302
11001
  const contentDiv = document.createElement("div");
10303
11002
  contentDiv.classList.add("persona-message-content");
11003
+ if (streamAnimationActive && streamPlugin) {
11004
+ if (streamPlugin.containerClass) {
11005
+ contentDiv.classList.add(streamPlugin.containerClass);
11006
+ }
11007
+ contentDiv.style.setProperty("--persona-stream-step", `${streamAnimation.speed}ms`);
11008
+ contentDiv.style.setProperty("--persona-stream-duration", `${streamAnimation.duration}ms`);
11009
+ }
11010
+ const bufferedContent = streamAnimationActive ? applyStreamBuffer(
11011
+ (_n = message.content) != null ? _n : "",
11012
+ streamAnimation.buffer,
11013
+ streamPlugin,
11014
+ message,
11015
+ Boolean(message.streaming)
11016
+ ) : (_o = message.content) != null ? _o : "";
10304
11017
  const transformedContent = transform({
10305
- text: message.content,
11018
+ text: bufferedContent,
10306
11019
  message,
10307
11020
  streaming: Boolean(message.streaming),
10308
11021
  raw: message.rawContent
10309
11022
  });
11023
+ let animatedContent = transformedContent;
11024
+ if (streamAnimationActive && (streamPlugin == null ? void 0 : streamPlugin.wrap) === "char") {
11025
+ animatedContent = wrapStreamAnimation(transformedContent, "char", message.id, {
11026
+ skipTags: streamPlugin.skipTags
11027
+ });
11028
+ } else if (streamAnimationActive && (streamPlugin == null ? void 0 : streamPlugin.wrap) === "word") {
11029
+ animatedContent = wrapStreamAnimation(transformedContent, "word", message.id, {
11030
+ skipTags: streamPlugin.skipTags
11031
+ });
11032
+ }
10310
11033
  let textContentDiv = null;
10311
11034
  if (shouldHideTextUntilPreviewFails) {
10312
11035
  textContentDiv = document.createElement("div");
10313
- textContentDiv.innerHTML = transformedContent;
11036
+ textContentDiv.innerHTML = animatedContent;
10314
11037
  textContentDiv.style.display = "none";
10315
11038
  contentDiv.appendChild(textContentDiv);
10316
11039
  } else {
10317
- contentDiv.innerHTML = transformedContent;
11040
+ contentDiv.innerHTML = animatedContent;
11041
+ }
11042
+ if (streamAnimationActive && (streamPlugin == null ? void 0 : streamPlugin.useCaret) && !shouldHideTextUntilPreviewFails && messageContentText) {
11043
+ const caret = createStreamCaret();
11044
+ const spans = contentDiv.querySelectorAll(
11045
+ ".persona-stream-char, .persona-stream-word"
11046
+ );
11047
+ const lastSpan = spans[spans.length - 1];
11048
+ if (lastSpan == null ? void 0 : lastSpan.parentNode) {
11049
+ lastSpan.parentNode.insertBefore(caret, lastSpan.nextSibling);
11050
+ } else {
11051
+ const lastChild = contentDiv.lastElementChild;
11052
+ if (lastChild) {
11053
+ lastChild.appendChild(caret);
11054
+ } else {
11055
+ contentDiv.appendChild(caret);
11056
+ }
11057
+ }
10318
11058
  }
10319
11059
  if (showTimestamp && timestampPosition === "inline" && message.createdAt) {
10320
11060
  const timestamp = createTimestamp(message, timestampConfig);
@@ -10343,17 +11083,36 @@ var createStandardBubble = (message, transform, layoutConfig, actionsConfig, act
10343
11083
  timestamp.classList.add("persona-mt-1");
10344
11084
  bubble.appendChild(timestamp);
10345
11085
  }
11086
+ const stopReasonNoticeText = message.role === "assistant" ? resolveStopReasonNoticeText(
11087
+ message.stopReason,
11088
+ (_q = (_p = options == null ? void 0 : options.widgetConfig) == null ? void 0 : _p.copy) == null ? void 0 : _q.stopReasonNotice
11089
+ ) : null;
10346
11090
  if (message.streaming && message.role === "assistant") {
10347
- if (!message.content || !message.content.trim()) {
10348
- const indicator = renderLoadingIndicatorWithFallback(
10349
- "inline",
10350
- options == null ? void 0 : options.loadingIndicatorRenderer,
10351
- options == null ? void 0 : options.widgetConfig
10352
- );
10353
- if (indicator) {
10354
- bubble.appendChild(indicator);
11091
+ const hasVisibleContent = Boolean(bufferedContent && bufferedContent.trim());
11092
+ const skeletonEnabled = streamAnimation.placeholder === "skeleton";
11093
+ const trailSkeleton = skeletonEnabled && streamAnimation.buffer === "line" && hasVisibleContent;
11094
+ if (!hasVisibleContent) {
11095
+ if (skeletonEnabled) {
11096
+ bubble.appendChild(createSkeletonPlaceholder());
11097
+ } else {
11098
+ const indicator = renderLoadingIndicatorWithFallback(
11099
+ "inline",
11100
+ options == null ? void 0 : options.loadingIndicatorRenderer,
11101
+ options == null ? void 0 : options.widgetConfig
11102
+ );
11103
+ if (indicator) {
11104
+ bubble.appendChild(indicator);
11105
+ }
10355
11106
  }
11107
+ } else if (trailSkeleton) {
11108
+ bubble.appendChild(createSkeletonPlaceholder());
11109
+ }
11110
+ }
11111
+ if (stopReasonNoticeText && message.stopReason && !message.streaming) {
11112
+ if (!messageContentText) {
11113
+ contentDiv.style.display = "none";
10356
11114
  }
11115
+ bubble.appendChild(createStopReasonNotice(message.stopReason, stopReasonNoticeText));
10357
11116
  }
10358
11117
  const shouldShowActions = message.role === "assistant" && !message.streaming && message.content && message.content.trim() && (actionsConfig == null ? void 0 : actionsConfig.enabled) !== false;
10359
11118
  if (shouldShowActions && actionsConfig) {
@@ -11098,6 +11857,582 @@ var createToolBubble = (message, config) => {
11098
11857
  return bubble;
11099
11858
  };
11100
11859
 
11860
+ // src/components/ask-user-question-bubble.ts
11861
+ var import_partial_json2 = require("partial-json");
11862
+ var ASK_USER_QUESTION_TOOL_NAME = "ask_user_question";
11863
+ var ASK_USER_QUESTION_MAX = 8;
11864
+ var SHEET_SENTINEL = "data-persona-ask-sheet-for";
11865
+ var DEFAULT_FREE_TEXT_LABEL_ROWS = "Other";
11866
+ var DEFAULT_FREE_TEXT_LABEL_PILLS = "Other\u2026";
11867
+ var DEFAULT_FREE_TEXT_PLACEHOLDER = "Type your own answer here";
11868
+ var DEFAULT_SUBMIT_LABEL = "Send";
11869
+ var DEFAULT_NEXT_LABEL = "Next";
11870
+ var DEFAULT_BACK_LABEL = "Back";
11871
+ var DEFAULT_SUBMIT_ALL_LABEL = "Submit all";
11872
+ var DEFAULT_SKIP_LABEL = "Skip";
11873
+ var DEFAULT_SKELETON_PILLS = 3;
11874
+ var ATTR_CURRENT_INDEX = "data-ask-current-index";
11875
+ var ATTR_QUESTION_COUNT = "data-ask-question-count";
11876
+ var ATTR_ANSWERS = "data-ask-answers";
11877
+ var ATTR_GROUPED = "data-ask-grouped";
11878
+ var ATTR_LAYOUT = "data-ask-layout";
11879
+ var resolveLayout = (feature) => feature.layout === "pills" ? "pills" : "rows";
11880
+ var getLayout = (sheet) => sheet.getAttribute(ATTR_LAYOUT) === "pills" ? "pills" : "rows";
11881
+ var truncateWarned = false;
11882
+ var escapeAttrValue = (value) => value.replace(/["\\]/g, "\\$&");
11883
+ var isAskUserQuestionMessage = (message) => {
11884
+ return message.variant === "tool" && !!message.toolCall && message.toolCall.name === ASK_USER_QUESTION_TOOL_NAME;
11885
+ };
11886
+ var resolveFeature = (config) => {
11887
+ var _a, _b;
11888
+ return (_b = (_a = config == null ? void 0 : config.features) == null ? void 0 : _a.askUserQuestion) != null ? _b : {};
11889
+ };
11890
+ var parseAskUserQuestionPayload = (message) => {
11891
+ const toolCall = message.toolCall;
11892
+ if (!toolCall) return { payload: null, complete: false };
11893
+ const complete = toolCall.status === "complete";
11894
+ if (toolCall.args && typeof toolCall.args === "object") {
11895
+ return { payload: toolCall.args, complete };
11896
+ }
11897
+ const chunks = toolCall.chunks;
11898
+ if (!chunks || chunks.length === 0) return { payload: null, complete };
11899
+ try {
11900
+ const text = chunks.join("");
11901
+ const parsed = (0, import_partial_json2.parse)(text, import_partial_json2.STR | import_partial_json2.OBJ | import_partial_json2.ARR);
11902
+ if (parsed && typeof parsed === "object") {
11903
+ return { payload: parsed, complete };
11904
+ }
11905
+ } catch {
11906
+ }
11907
+ return { payload: null, complete };
11908
+ };
11909
+ var promptsFromPayload = (payload) => {
11910
+ const all = Array.isArray(payload == null ? void 0 : payload.questions) ? payload.questions : [];
11911
+ if (all.length > ASK_USER_QUESTION_MAX && !truncateWarned) {
11912
+ truncateWarned = true;
11913
+ if (typeof console !== "undefined") {
11914
+ console.warn(
11915
+ `[AgentWidget] ask_user_question received ${all.length} questions; truncating to ${ASK_USER_QUESTION_MAX}.`
11916
+ );
11917
+ }
11918
+ }
11919
+ return all.slice(0, ASK_USER_QUESTION_MAX);
11920
+ };
11921
+ var firstPrompt = (payload) => {
11922
+ var _a;
11923
+ return (_a = promptsFromPayload(payload)[0]) != null ? _a : null;
11924
+ };
11925
+ var promptAt = (payload, index) => {
11926
+ var _a;
11927
+ return (_a = promptsFromPayload(payload)[index]) != null ? _a : null;
11928
+ };
11929
+ var applyStyleVars = (root, feature) => {
11930
+ const s = feature.styles;
11931
+ if (!s) return;
11932
+ if (s.sheetBackground) root.style.setProperty("--persona-ask-sheet-bg", s.sheetBackground);
11933
+ if (s.sheetBorder) root.style.setProperty("--persona-ask-sheet-border", s.sheetBorder);
11934
+ if (s.sheetShadow) root.style.setProperty("--persona-ask-sheet-shadow", s.sheetShadow);
11935
+ if (s.pillBackground) root.style.setProperty("--persona-ask-pill-bg", s.pillBackground);
11936
+ if (s.pillBackgroundSelected)
11937
+ root.style.setProperty("--persona-ask-pill-bg-selected", s.pillBackgroundSelected);
11938
+ if (s.pillTextColor) root.style.setProperty("--persona-ask-pill-fg", s.pillTextColor);
11939
+ if (s.pillTextColorSelected)
11940
+ root.style.setProperty("--persona-ask-pill-fg-selected", s.pillTextColorSelected);
11941
+ if (s.pillBorderRadius) root.style.setProperty("--persona-ask-pill-radius", s.pillBorderRadius);
11942
+ if (s.customInputBackground)
11943
+ root.style.setProperty("--persona-ask-input-bg", s.customInputBackground);
11944
+ };
11945
+ var buildAffordance = (layout, multiSelect, index) => {
11946
+ if (layout !== "rows") return null;
11947
+ const wrap = createElement("span", "persona-ask-row-affordance");
11948
+ wrap.setAttribute("aria-hidden", "true");
11949
+ if (multiSelect) {
11950
+ const check = createElement("span", "persona-ask-row-check");
11951
+ wrap.appendChild(check);
11952
+ } else {
11953
+ const badge = createElement("span", "persona-ask-row-badge");
11954
+ badge.textContent = String(index + 1);
11955
+ wrap.appendChild(badge);
11956
+ }
11957
+ return wrap;
11958
+ };
11959
+ var buildPill = (option, index, layout, multiSelect) => {
11960
+ const cls = layout === "rows" ? "persona-ask-pill persona-ask-row persona-pointer-events-auto" : "persona-ask-pill persona-pointer-events-auto";
11961
+ const btn = createElement("button", cls);
11962
+ btn.type = "button";
11963
+ btn.setAttribute("role", multiSelect ? "checkbox" : "button");
11964
+ btn.setAttribute("aria-pressed", "false");
11965
+ btn.setAttribute("data-ask-user-action", "pick");
11966
+ btn.setAttribute("data-option-index", String(index));
11967
+ btn.setAttribute("data-option-label", option.label);
11968
+ if (layout === "rows") {
11969
+ const content = createElement("span", "persona-ask-row-content");
11970
+ const label = createElement("span", "persona-ask-row-label");
11971
+ label.textContent = option.label;
11972
+ content.appendChild(label);
11973
+ if (option.description) {
11974
+ const desc = createElement("span", "persona-ask-row-description");
11975
+ desc.textContent = option.description;
11976
+ content.appendChild(desc);
11977
+ }
11978
+ btn.appendChild(content);
11979
+ const aff = buildAffordance(layout, multiSelect, index);
11980
+ if (aff) btn.appendChild(aff);
11981
+ } else {
11982
+ btn.textContent = option.label;
11983
+ if (option.description) btn.title = option.description;
11984
+ }
11985
+ return btn;
11986
+ };
11987
+ var buildSkeletonPill = (layout) => {
11988
+ const cls = layout === "rows" ? "persona-ask-pill persona-ask-row persona-ask-pill-skeleton persona-pointer-events-none" : "persona-ask-pill persona-ask-pill-skeleton persona-pointer-events-none";
11989
+ const el = createElement("span", cls);
11990
+ el.setAttribute("aria-hidden", "true");
11991
+ return el;
11992
+ };
11993
+ var buildPillList = (prompt, feature, complete, layout) => {
11994
+ var _a, _b, _c;
11995
+ const baseClass = layout === "rows" ? "persona-ask-pills persona-ask-pills--rows persona-flex persona-flex-col persona-gap-2" : "persona-ask-pills persona-flex persona-flex-wrap persona-gap-2";
11996
+ const list = createElement("div", baseClass);
11997
+ list.setAttribute("role", "group");
11998
+ list.setAttribute("data-ask-pill-list", "true");
11999
+ const multiSelect = !!(prompt == null ? void 0 : prompt.multiSelect);
12000
+ const realOptions = Array.isArray(prompt == null ? void 0 : prompt.options) ? prompt.options : [];
12001
+ const cleanOptions = realOptions.filter((o) => o && typeof o.label === "string" && o.label.length > 0);
12002
+ if (cleanOptions.length === 0 && !complete) {
12003
+ for (let i = 0; i < DEFAULT_SKELETON_PILLS; i++) {
12004
+ list.appendChild(buildSkeletonPill(layout));
12005
+ }
12006
+ return list;
12007
+ }
12008
+ cleanOptions.forEach((option, index) => {
12009
+ list.appendChild(buildPill(option, index, layout, multiSelect));
12010
+ });
12011
+ const allowFreeText = (prompt == null ? void 0 : prompt.allowFreeText) !== false;
12012
+ if (allowFreeText) {
12013
+ const defaultLabel = layout === "rows" ? DEFAULT_FREE_TEXT_LABEL_ROWS : DEFAULT_FREE_TEXT_LABEL_PILLS;
12014
+ if (layout === "rows") {
12015
+ const otherRow = createElement(
12016
+ "div",
12017
+ "persona-ask-pill persona-ask-row persona-ask-row--other persona-ask-pill-custom persona-pointer-events-auto"
12018
+ );
12019
+ otherRow.setAttribute("data-ask-user-action", "focus-free-text");
12020
+ otherRow.setAttribute("data-option-index", String(cleanOptions.length));
12021
+ otherRow.setAttribute("data-ask-other-row", "true");
12022
+ const content = createElement("span", "persona-ask-row-content");
12023
+ const input = document.createElement("input");
12024
+ input.type = "text";
12025
+ input.className = "persona-ask-row-input persona-flex-1 persona-pointer-events-auto";
12026
+ input.placeholder = (_a = feature.freeTextPlaceholder) != null ? _a : DEFAULT_FREE_TEXT_PLACEHOLDER;
12027
+ input.setAttribute("data-ask-free-text-input", "true");
12028
+ input.setAttribute(
12029
+ "aria-label",
12030
+ (_b = feature.freeTextLabel) != null ? _b : defaultLabel
12031
+ );
12032
+ content.appendChild(input);
12033
+ otherRow.appendChild(content);
12034
+ const aff = buildAffordance(layout, multiSelect, cleanOptions.length);
12035
+ if (aff) otherRow.appendChild(aff);
12036
+ list.appendChild(otherRow);
12037
+ } else {
12038
+ const freeBtn = createElement(
12039
+ "button",
12040
+ "persona-ask-pill persona-ask-pill-custom persona-pointer-events-auto"
12041
+ );
12042
+ freeBtn.type = "button";
12043
+ freeBtn.setAttribute("data-ask-user-action", "open-free-text");
12044
+ freeBtn.textContent = (_c = feature.freeTextLabel) != null ? _c : defaultLabel;
12045
+ list.appendChild(freeBtn);
12046
+ }
12047
+ }
12048
+ return list;
12049
+ };
12050
+ var buildFreeTextRow = (feature, layout) => {
12051
+ var _a, _b;
12052
+ const cls = layout === "rows" ? "persona-ask-free-text persona-ask-free-text--rows persona-flex persona-gap-2 persona-mt-2" : "persona-ask-free-text persona-hidden persona-flex persona-gap-2 persona-mt-2";
12053
+ const row = createElement("div", cls);
12054
+ row.setAttribute("data-ask-free-text-row", "true");
12055
+ const input = document.createElement("input");
12056
+ input.type = "text";
12057
+ input.className = "persona-ask-free-text-input persona-flex-1 persona-pointer-events-auto";
12058
+ input.placeholder = (_a = feature.freeTextPlaceholder) != null ? _a : DEFAULT_FREE_TEXT_PLACEHOLDER;
12059
+ input.setAttribute("data-ask-free-text-input", "true");
12060
+ row.appendChild(input);
12061
+ if (layout !== "rows") {
12062
+ const submit = createElement(
12063
+ "button",
12064
+ "persona-ask-free-text-submit persona-pointer-events-auto"
12065
+ );
12066
+ submit.type = "button";
12067
+ submit.textContent = (_b = feature.submitLabel) != null ? _b : DEFAULT_SUBMIT_LABEL;
12068
+ submit.setAttribute("data-ask-user-action", "submit-free-text");
12069
+ row.appendChild(submit);
12070
+ }
12071
+ return row;
12072
+ };
12073
+ var buildMultiSelectActions = (feature) => {
12074
+ var _a;
12075
+ const row = createElement(
12076
+ "div",
12077
+ "persona-ask-multi-actions persona-flex persona-justify-end persona-mt-2"
12078
+ );
12079
+ row.setAttribute("data-ask-multi-actions", "true");
12080
+ const submit = createElement(
12081
+ "button",
12082
+ "persona-ask-multi-submit persona-pointer-events-auto"
12083
+ );
12084
+ submit.type = "button";
12085
+ submit.textContent = (_a = feature.submitLabel) != null ? _a : DEFAULT_SUBMIT_LABEL;
12086
+ submit.setAttribute("data-ask-user-action", "submit-multi");
12087
+ submit.disabled = true;
12088
+ row.appendChild(submit);
12089
+ return row;
12090
+ };
12091
+ var buildNavRow = (index, count, feature) => {
12092
+ var _a, _b, _c, _d;
12093
+ const row = createElement(
12094
+ "div",
12095
+ "persona-ask-nav persona-flex persona-justify-between persona-items-center persona-gap-2 persona-mt-2"
12096
+ );
12097
+ row.setAttribute("data-ask-nav-row", "true");
12098
+ const back = createElement(
12099
+ "button",
12100
+ "persona-ask-nav-back persona-pointer-events-auto"
12101
+ );
12102
+ back.type = "button";
12103
+ back.textContent = (_a = feature.backLabel) != null ? _a : DEFAULT_BACK_LABEL;
12104
+ back.setAttribute("data-ask-user-action", "back");
12105
+ back.disabled = index === 0;
12106
+ row.appendChild(back);
12107
+ const rightGroup = createElement(
12108
+ "div",
12109
+ "persona-ask-nav-right persona-flex persona-items-center persona-gap-2"
12110
+ );
12111
+ const skip = createElement(
12112
+ "button",
12113
+ "persona-ask-nav-skip persona-pointer-events-auto"
12114
+ );
12115
+ skip.type = "button";
12116
+ skip.textContent = (_b = feature.skipLabel) != null ? _b : DEFAULT_SKIP_LABEL;
12117
+ skip.setAttribute("data-ask-user-action", "skip");
12118
+ rightGroup.appendChild(skip);
12119
+ const next = createElement(
12120
+ "button",
12121
+ "persona-ask-nav-next persona-pointer-events-auto"
12122
+ );
12123
+ next.type = "button";
12124
+ const isFinal = index === count - 1;
12125
+ next.textContent = isFinal ? (_c = feature.submitAllLabel) != null ? _c : DEFAULT_SUBMIT_ALL_LABEL : (_d = feature.nextLabel) != null ? _d : DEFAULT_NEXT_LABEL;
12126
+ next.setAttribute("data-ask-user-action", isFinal ? "submit-all" : "next");
12127
+ next.disabled = true;
12128
+ rightGroup.appendChild(next);
12129
+ row.appendChild(rightGroup);
12130
+ return row;
12131
+ };
12132
+ var readAnswersFromSheet = (sheet) => {
12133
+ const raw = sheet.getAttribute(ATTR_ANSWERS);
12134
+ if (!raw) return {};
12135
+ try {
12136
+ const parsed = JSON.parse(raw);
12137
+ return parsed && typeof parsed === "object" ? parsed : {};
12138
+ } catch {
12139
+ return {};
12140
+ }
12141
+ };
12142
+ var writeAnswersToSheet = (sheet, answers) => {
12143
+ sheet.setAttribute(ATTR_ANSWERS, JSON.stringify(answers));
12144
+ };
12145
+ var getCurrentIndex = (sheet) => {
12146
+ var _a;
12147
+ const raw = Number((_a = sheet.getAttribute(ATTR_CURRENT_INDEX)) != null ? _a : "0");
12148
+ return Number.isFinite(raw) ? Math.max(0, Math.floor(raw)) : 0;
12149
+ };
12150
+ var setCurrentIndex = (sheet, index) => {
12151
+ sheet.setAttribute(ATTR_CURRENT_INDEX, String(Math.max(0, Math.floor(index))));
12152
+ };
12153
+ var getQuestionCount = (sheet) => {
12154
+ var _a;
12155
+ const raw = Number((_a = sheet.getAttribute(ATTR_QUESTION_COUNT)) != null ? _a : "1");
12156
+ return Number.isFinite(raw) ? Math.max(1, Math.floor(raw)) : 1;
12157
+ };
12158
+ var isGroupedSheet = (sheet) => {
12159
+ return sheet.getAttribute(ATTR_GROUPED) === "true";
12160
+ };
12161
+ var restoreAnswersFromMessage = (message, prompts) => {
12162
+ var _a;
12163
+ const stored = (_a = message.agentMetadata) == null ? void 0 : _a.askUserQuestionAnswers;
12164
+ if (!stored || typeof stored !== "object") return {};
12165
+ const result = {};
12166
+ prompts.forEach((p, i) => {
12167
+ const q = typeof (p == null ? void 0 : p.question) === "string" ? p.question : "";
12168
+ if (q && Object.prototype.hasOwnProperty.call(stored, q)) {
12169
+ const v = stored[q];
12170
+ if (typeof v === "string" || Array.isArray(v)) {
12171
+ result[i] = v;
12172
+ }
12173
+ }
12174
+ });
12175
+ return result;
12176
+ };
12177
+ var restoreIndexFromMessage = (message, count) => {
12178
+ var _a;
12179
+ const stored = (_a = message.agentMetadata) == null ? void 0 : _a.askUserQuestionIndex;
12180
+ if (typeof stored !== "number" || !Number.isFinite(stored)) return 0;
12181
+ return Math.max(0, Math.min(count - 1, Math.floor(stored)));
12182
+ };
12183
+ var buildStructuredAnswers = (sheet, message) => {
12184
+ const { payload } = parseAskUserQuestionPayload(message);
12185
+ const prompts = promptsFromPayload(payload);
12186
+ const indexed = readAnswersFromSheet(sheet);
12187
+ const result = {};
12188
+ const seen = /* @__PURE__ */ new Set();
12189
+ prompts.forEach((p, i) => {
12190
+ const q = typeof (p == null ? void 0 : p.question) === "string" ? p.question : "";
12191
+ if (!q) return;
12192
+ if (seen.has(q) && typeof console !== "undefined") {
12193
+ console.warn(`[AgentWidget] ask_user_question has duplicate question text "${q}"; later answer wins.`);
12194
+ }
12195
+ seen.add(q);
12196
+ if (Object.prototype.hasOwnProperty.call(indexed, i)) {
12197
+ result[q] = indexed[i];
12198
+ }
12199
+ });
12200
+ return result;
12201
+ };
12202
+ var applySelectionState = (sheet) => {
12203
+ const answers = readAnswersFromSheet(sheet);
12204
+ const currentIndex = getCurrentIndex(sheet);
12205
+ const stored = answers[currentIndex];
12206
+ const selected = /* @__PURE__ */ new Set();
12207
+ if (typeof stored === "string") selected.add(stored);
12208
+ else if (Array.isArray(stored)) stored.forEach((s) => selected.add(s));
12209
+ const pills = sheet.querySelectorAll('[data-ask-user-action="pick"][data-option-label]');
12210
+ pills.forEach((pill) => {
12211
+ var _a;
12212
+ const label = (_a = pill.getAttribute("data-option-label")) != null ? _a : "";
12213
+ const on = selected.has(label);
12214
+ pill.setAttribute("aria-pressed", on ? "true" : "false");
12215
+ pill.classList.toggle("persona-ask-pill-selected", on);
12216
+ });
12217
+ const realPillLabels = new Set(
12218
+ Array.from(pills).map((p) => {
12219
+ var _a;
12220
+ return (_a = p.getAttribute("data-option-label")) != null ? _a : "";
12221
+ })
12222
+ );
12223
+ const freeInput = sheet.querySelector('[data-ask-free-text-input="true"]');
12224
+ if (freeInput) {
12225
+ if (typeof stored === "string" && stored.length > 0 && !realPillLabels.has(stored)) {
12226
+ freeInput.value = stored;
12227
+ const freeRow = freeInput.closest('[data-ask-free-text-row="true"]');
12228
+ freeRow == null ? void 0 : freeRow.classList.remove("persona-hidden");
12229
+ } else {
12230
+ freeInput.value = "";
12231
+ }
12232
+ }
12233
+ };
12234
+ var syncNavState = (sheet) => {
12235
+ if (!isGroupedSheet(sheet)) return;
12236
+ const answers = readAnswersFromSheet(sheet);
12237
+ const currentIndex = getCurrentIndex(sheet);
12238
+ const v = answers[currentIndex];
12239
+ const hasAnswer = typeof v === "string" && v.length > 0 || Array.isArray(v) && v.length > 0;
12240
+ const next = sheet.querySelector(
12241
+ '[data-ask-user-action="next"], [data-ask-user-action="submit-all"]'
12242
+ );
12243
+ if (next) next.disabled = !hasAnswer;
12244
+ const multi = sheet.querySelector('[data-ask-user-action="submit-multi"]');
12245
+ if (multi) {
12246
+ const labels = Array.from(
12247
+ sheet.querySelectorAll('[aria-pressed="true"][data-option-label]')
12248
+ );
12249
+ multi.disabled = labels.length === 0;
12250
+ }
12251
+ };
12252
+ var renderCurrentPage = (sheet, message, config) => {
12253
+ const feature = resolveFeature(config);
12254
+ const layout = getLayout(sheet);
12255
+ const { payload, complete } = parseAskUserQuestionPayload(message);
12256
+ const grouped = isGroupedSheet(sheet);
12257
+ const index = getCurrentIndex(sheet);
12258
+ const count = getQuestionCount(sheet);
12259
+ const prompt = grouped ? promptAt(payload, index) : firstPrompt(payload);
12260
+ const multiSelect = !!(prompt == null ? void 0 : prompt.multiSelect);
12261
+ const stepInline = sheet.querySelector('[data-ask-step-inline="true"]');
12262
+ if (stepInline) {
12263
+ stepInline.textContent = grouped ? `${index + 1}/${count}` : "";
12264
+ }
12265
+ const oldStepper = sheet.querySelector('[data-ask-stepper="true"]');
12266
+ if (oldStepper) oldStepper.remove();
12267
+ const qText = sheet.querySelector('[data-ask-question="true"]');
12268
+ if (qText) {
12269
+ const text = typeof (prompt == null ? void 0 : prompt.question) === "string" ? prompt.question : "";
12270
+ qText.textContent = text;
12271
+ qText.classList.toggle("persona-ask-question-skeleton", !text && !complete);
12272
+ }
12273
+ const pillList = sheet.querySelector('[data-ask-pill-list="true"]');
12274
+ if (pillList) {
12275
+ const fresh = buildPillList(prompt, feature, complete, layout);
12276
+ pillList.replaceWith(fresh);
12277
+ }
12278
+ if (layout !== "rows") {
12279
+ const oldFree = sheet.querySelector('[data-ask-free-text-row="true"]');
12280
+ if (oldFree) oldFree.replaceWith(buildFreeTextRow(feature, layout));
12281
+ }
12282
+ const oldMulti = sheet.querySelector('[data-ask-multi-actions="true"]');
12283
+ if (!grouped && multiSelect && !oldMulti) {
12284
+ sheet.appendChild(buildMultiSelectActions(feature));
12285
+ } else if ((!multiSelect || grouped) && oldMulti) {
12286
+ oldMulti.remove();
12287
+ }
12288
+ sheet.setAttribute("data-multi-select", multiSelect ? "true" : "false");
12289
+ const oldNav = sheet.querySelector('[data-ask-nav-row="true"]');
12290
+ if (grouped) {
12291
+ const fresh = buildNavRow(index, count, feature);
12292
+ if (oldNav) oldNav.replaceWith(fresh);
12293
+ else sheet.appendChild(fresh);
12294
+ } else if (oldNav) {
12295
+ oldNav.remove();
12296
+ }
12297
+ applySelectionState(sheet);
12298
+ syncNavState(sheet);
12299
+ };
12300
+ var buildSheet = (message, config, payload) => {
12301
+ const feature = resolveFeature(config);
12302
+ const layout = resolveLayout(feature);
12303
+ const toolCallId = message.toolCall.id;
12304
+ const prompts = promptsFromPayload(payload);
12305
+ const count = Math.max(1, prompts.length);
12306
+ const grouped = count > 1;
12307
+ const initialAnswers = restoreAnswersFromMessage(message, prompts);
12308
+ const initialIndex = grouped ? restoreIndexFromMessage(message, count) : 0;
12309
+ const sheet = createElement(
12310
+ "div",
12311
+ [
12312
+ "persona-ask-sheet",
12313
+ `persona-ask-sheet--${layout}`,
12314
+ "persona-pointer-events-auto",
12315
+ "persona-ask-sheet-enter"
12316
+ ].join(" ")
12317
+ );
12318
+ sheet.setAttribute(SHEET_SENTINEL, toolCallId);
12319
+ sheet.setAttribute("data-tool-call-id", toolCallId);
12320
+ sheet.setAttribute("data-message-id", message.id);
12321
+ sheet.setAttribute(ATTR_QUESTION_COUNT, String(count));
12322
+ sheet.setAttribute(ATTR_CURRENT_INDEX, String(initialIndex));
12323
+ sheet.setAttribute(ATTR_GROUPED, grouped ? "true" : "false");
12324
+ sheet.setAttribute(ATTR_LAYOUT, layout);
12325
+ writeAnswersToSheet(sheet, initialAnswers);
12326
+ sheet.setAttribute("role", "group");
12327
+ sheet.setAttribute("aria-label", "Suggested answers");
12328
+ if (feature.slideInMs !== void 0) {
12329
+ sheet.style.setProperty("--persona-ask-sheet-duration", `${feature.slideInMs}ms`);
12330
+ }
12331
+ applyStyleVars(sheet, feature);
12332
+ const header = createElement(
12333
+ "div",
12334
+ "persona-ask-sheet-header persona-flex persona-items-center persona-gap-3"
12335
+ );
12336
+ const qText = createElement("div", "persona-ask-sheet-question persona-flex-1");
12337
+ qText.setAttribute("data-ask-question", "true");
12338
+ qText.textContent = "";
12339
+ header.appendChild(qText);
12340
+ const stepInline = createElement(
12341
+ "span",
12342
+ "persona-ask-sheet-step-inline"
12343
+ );
12344
+ stepInline.setAttribute("data-ask-step-inline", "true");
12345
+ stepInline.textContent = "";
12346
+ header.appendChild(stepInline);
12347
+ sheet.appendChild(header);
12348
+ const skeletonClass = layout === "rows" ? "persona-ask-pills persona-ask-pills--rows persona-flex persona-flex-col persona-gap-2" : "persona-ask-pills persona-flex persona-flex-wrap persona-gap-2";
12349
+ const list = createElement("div", skeletonClass);
12350
+ list.setAttribute("data-ask-pill-list", "true");
12351
+ list.setAttribute("role", "group");
12352
+ sheet.appendChild(list);
12353
+ if (layout !== "rows") {
12354
+ sheet.appendChild(buildFreeTextRow(feature, layout));
12355
+ }
12356
+ renderCurrentPage(sheet, message, config);
12357
+ requestAnimationFrame(() => {
12358
+ requestAnimationFrame(() => sheet.classList.remove("persona-ask-sheet-enter"));
12359
+ });
12360
+ return sheet;
12361
+ };
12362
+ var syncSheetFromMessage = (sheet, message, config) => {
12363
+ const { payload } = parseAskUserQuestionPayload(message);
12364
+ const newCount = Math.max(1, promptsFromPayload(payload).length);
12365
+ if (newCount > getQuestionCount(sheet)) {
12366
+ sheet.setAttribute(ATTR_QUESTION_COUNT, String(newCount));
12367
+ if (newCount > 1 && !isGroupedSheet(sheet)) {
12368
+ sheet.setAttribute(ATTR_GROUPED, "true");
12369
+ }
12370
+ }
12371
+ renderCurrentPage(sheet, message, config);
12372
+ };
12373
+ var ensureAskUserQuestionSheet = (message, config, overlay) => {
12374
+ if (!overlay) return;
12375
+ if (!isAskUserQuestionMessage(message)) return;
12376
+ const feature = resolveFeature(config);
12377
+ if (feature.enabled === false) return;
12378
+ const toolCallId = message.toolCall.id;
12379
+ const siblings = overlay.querySelectorAll(`[${SHEET_SENTINEL}]`);
12380
+ siblings.forEach((el) => {
12381
+ if (el.getAttribute(SHEET_SENTINEL) !== toolCallId) {
12382
+ el.remove();
12383
+ }
12384
+ });
12385
+ const existing = overlay.querySelector(
12386
+ `[${SHEET_SENTINEL}="${escapeAttrValue(toolCallId)}"]`
12387
+ );
12388
+ if (existing) {
12389
+ syncSheetFromMessage(existing, message, config);
12390
+ return;
12391
+ }
12392
+ const { payload } = parseAskUserQuestionPayload(message);
12393
+ const sheet = buildSheet(message, config, payload);
12394
+ overlay.appendChild(sheet);
12395
+ };
12396
+ var removeAskUserQuestionSheet = (overlay, toolCallId) => {
12397
+ if (!overlay) return;
12398
+ const selector = toolCallId ? `[${SHEET_SENTINEL}="${escapeAttrValue(toolCallId)}"]` : `[${SHEET_SENTINEL}]`;
12399
+ const sheets = overlay.querySelectorAll(selector);
12400
+ sheets.forEach((sheet) => {
12401
+ sheet.classList.add("persona-ask-sheet-leave");
12402
+ const duration = Number.parseInt(
12403
+ getComputedStyle(sheet).getPropertyValue("--persona-ask-sheet-duration") || "180",
12404
+ 10
12405
+ );
12406
+ const remove = () => sheet.remove();
12407
+ setTimeout(remove, Number.isFinite(duration) ? duration : 180);
12408
+ });
12409
+ };
12410
+ var getSelectedLabels = (sheet) => {
12411
+ return Array.from(
12412
+ sheet.querySelectorAll('[aria-pressed="true"][data-option-label]')
12413
+ ).map((el) => el.getAttribute("data-option-label")).filter((label) => typeof label === "string" && label.length > 0);
12414
+ };
12415
+ var setCurrentAnswer = (sheet, answer) => {
12416
+ const answers = readAnswersFromSheet(sheet);
12417
+ const idx = getCurrentIndex(sheet);
12418
+ if (typeof answer === "string" && answer.length === 0) {
12419
+ delete answers[idx];
12420
+ } else if (Array.isArray(answer) && answer.length === 0) {
12421
+ delete answers[idx];
12422
+ } else {
12423
+ answers[idx] = answer;
12424
+ }
12425
+ writeAnswersToSheet(sheet, answers);
12426
+ applySelectionState(sheet);
12427
+ syncNavState(sheet);
12428
+ };
12429
+ var navigateToPage = (sheet, message, config, index) => {
12430
+ const count = getQuestionCount(sheet);
12431
+ const clamped = Math.max(0, Math.min(count - 1, index));
12432
+ setCurrentIndex(sheet, clamped);
12433
+ renderCurrentPage(sheet, message, config);
12434
+ };
12435
+
11101
12436
  // src/components/approval-bubble.ts
11102
12437
  var createApprovalBubble = (message, config) => {
11103
12438
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
@@ -13506,6 +14841,10 @@ var sanitizeMessages = (messages) => messages.map((message) => ({
13506
14841
  ...message,
13507
14842
  streaming: false
13508
14843
  }));
14844
+ var sanitizeArtifacts = (artifacts) => artifacts.map((artifact) => ({
14845
+ ...artifact,
14846
+ status: "complete"
14847
+ }));
13509
14848
  var createLocalStorageAdapter = (key = "persona-state") => {
13510
14849
  const getStorage = () => {
13511
14850
  if (typeof window === "undefined" || !window.localStorage) {
@@ -13525,7 +14864,8 @@ var createLocalStorageAdapter = (key = "persona-state") => {
13525
14864
  try {
13526
14865
  const payload = {
13527
14866
  ...state,
13528
- messages: state.messages ? sanitizeMessages(state.messages) : void 0
14867
+ messages: state.messages ? sanitizeMessages(state.messages) : void 0,
14868
+ artifacts: state.artifacts ? sanitizeArtifacts(state.artifacts) : void 0
13529
14869
  };
13530
14870
  storage.setItem(key, JSON.stringify(payload));
13531
14871
  } catch (error) {
@@ -13549,7 +14889,7 @@ var createLocalStorageAdapter = (key = "persona-state") => {
13549
14889
  };
13550
14890
 
13551
14891
  // src/utils/component-parser.ts
13552
- var import_partial_json2 = require("partial-json");
14892
+ var import_partial_json3 = require("partial-json");
13553
14893
 
13554
14894
  // src/utils/component-middleware.ts
13555
14895
  function renderComponentDirective(directive, options) {
@@ -14025,7 +15365,7 @@ function buildDropOverlay(dropCfg) {
14025
15365
  return overlay;
14026
15366
  }
14027
15367
  var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
14028
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N;
15368
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q;
14029
15369
  if (mount == null) {
14030
15370
  throw new Error(
14031
15371
  'createAgentExperience: mount must be a non-null HTMLElement (e.g. pass document.getElementById("my-root") after the node exists).'
@@ -14084,6 +15424,13 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
14084
15424
  if ((_b = processedState.messages) == null ? void 0 : _b.length) {
14085
15425
  config = { ...config, initialMessages: processedState.messages };
14086
15426
  }
15427
+ if ((_c = processedState.artifacts) == null ? void 0 : _c.length) {
15428
+ config = {
15429
+ ...config,
15430
+ initialArtifacts: processedState.artifacts,
15431
+ initialSelectedArtifactId: (_d = processedState.selectedArtifactId) != null ? _d : null
15432
+ };
15433
+ }
14087
15434
  }
14088
15435
  } catch (error) {
14089
15436
  if (typeof console !== "undefined") {
@@ -14093,7 +15440,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
14093
15440
  } else if (config.onStateLoaded) {
14094
15441
  try {
14095
15442
  const processedState = applyStateLoadedHook({ messages: [], metadata: {} });
14096
- if ((_c = processedState.messages) == null ? void 0 : _c.length) {
15443
+ if ((_e = processedState.messages) == null ? void 0 : _e.length) {
14097
15444
  config = { ...config, initialMessages: processedState.messages };
14098
15445
  }
14099
15446
  } catch (error) {
@@ -14120,12 +15467,12 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
14120
15467
  documentRef: typeof document !== "undefined" ? document : null
14121
15468
  });
14122
15469
  actionManager.syncFromMetadata();
14123
- let launcherEnabled = (_e = (_d = config.launcher) == null ? void 0 : _d.enabled) != null ? _e : true;
14124
- let autoExpand = (_g = (_f = config.launcher) == null ? void 0 : _f.autoExpand) != null ? _g : false;
14125
- const autoFocusInput = (_h = config.autoFocusInput) != null ? _h : false;
15470
+ let launcherEnabled = (_g = (_f = config.launcher) == null ? void 0 : _f.enabled) != null ? _g : true;
15471
+ let autoExpand = (_i = (_h = config.launcher) == null ? void 0 : _h.autoExpand) != null ? _i : false;
15472
+ const autoFocusInput = (_j = config.autoFocusInput) != null ? _j : false;
14126
15473
  let prevAutoExpand = autoExpand;
14127
15474
  let prevLauncherEnabled = launcherEnabled;
14128
- let prevHeaderLayout = (_j = (_i = config.layout) == null ? void 0 : _i.header) == null ? void 0 : _j.layout;
15475
+ let prevHeaderLayout = (_l = (_k = config.layout) == null ? void 0 : _k.header) == null ? void 0 : _l.layout;
14129
15476
  let wasMobileFullscreen = false;
14130
15477
  let open = launcherEnabled ? autoExpand : true;
14131
15478
  let pendingResubmit = false;
@@ -14145,14 +15492,14 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
14145
15492
  }, 1e4);
14146
15493
  };
14147
15494
  let postprocess = buildPostprocessor(config, actionManager, handleResubmitRequested);
14148
- let showReasoning = (_l = (_k = config.features) == null ? void 0 : _k.showReasoning) != null ? _l : true;
14149
- let showToolCalls = (_n = (_m = config.features) == null ? void 0 : _m.showToolCalls) != null ? _n : true;
14150
- let showEventStreamToggle = (_p = (_o = config.features) == null ? void 0 : _o.showEventStreamToggle) != null ? _p : false;
14151
- let scrollToBottomFeature = (_r = (_q = config.features) == null ? void 0 : _q.scrollToBottom) != null ? _r : {};
14152
- const persistKeyPrefix = (_t = typeof config.persistState === "object" ? (_s = config.persistState) == null ? void 0 : _s.keyPrefix : void 0) != null ? _t : "persona-";
15495
+ let showReasoning = (_n = (_m = config.features) == null ? void 0 : _m.showReasoning) != null ? _n : true;
15496
+ let showToolCalls = (_p = (_o = config.features) == null ? void 0 : _o.showToolCalls) != null ? _p : true;
15497
+ let showEventStreamToggle = (_r = (_q = config.features) == null ? void 0 : _q.showEventStreamToggle) != null ? _r : false;
15498
+ let scrollToBottomFeature = (_t = (_s = config.features) == null ? void 0 : _s.scrollToBottom) != null ? _t : {};
15499
+ const persistKeyPrefix = (_v = typeof config.persistState === "object" ? (_u = config.persistState) == null ? void 0 : _u.keyPrefix : void 0) != null ? _v : "persona-";
14153
15500
  const eventStreamDbName = `${persistKeyPrefix}event-stream`;
14154
15501
  let eventStreamStore = showEventStreamToggle ? new EventStreamStore(eventStreamDbName) : null;
14155
- const eventStreamMaxEvents = (_w = (_v = (_u = config.features) == null ? void 0 : _u.eventStream) == null ? void 0 : _v.maxEvents) != null ? _w : 2e3;
15502
+ const eventStreamMaxEvents = (_y = (_x = (_w = config.features) == null ? void 0 : _w.eventStream) == null ? void 0 : _x.maxEvents) != null ? _y : 2e3;
14156
15503
  let eventStreamBuffer = showEventStreamToggle ? new EventStreamBuffer(eventStreamMaxEvents, eventStreamStore) : null;
14157
15504
  let eventStreamView = null;
14158
15505
  let eventStreamVisible = false;
@@ -14189,7 +15536,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
14189
15536
  (_b2 = (_a2 = config.messageActions) == null ? void 0 : _a2.onFeedback) == null ? void 0 : _b2.call(_a2, feedback);
14190
15537
  }
14191
15538
  };
14192
- const statusConfig = (_x = config.statusIndicator) != null ? _x : {};
15539
+ const statusConfig = (_z = config.statusIndicator) != null ? _z : {};
14193
15540
  const _getStatusText = (status) => {
14194
15541
  var _a2, _b2, _c2, _d2;
14195
15542
  if (status === "idle") return (_a2 = statusConfig.idleText) != null ? _a2 : statusCopy.idle;
@@ -14237,6 +15584,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
14237
15584
  leftActions,
14238
15585
  rightActions
14239
15586
  } = panelElements;
15587
+ let setSendButtonMode = panelElements.setSendButtonMode;
14240
15588
  let micButton = panelElements.micButton;
14241
15589
  let micButtonWrapper = panelElements.micButtonWrapper;
14242
15590
  let attachmentButton = panelElements.attachmentButton;
@@ -14369,7 +15717,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
14369
15717
  };
14370
15718
  let eventStreamToggleBtn = null;
14371
15719
  if (showEventStreamToggle) {
14372
- const esClassNames = (_z = (_y = config.features) == null ? void 0 : _y.eventStream) == null ? void 0 : _z.classNames;
15720
+ const esClassNames = (_B = (_A = config.features) == null ? void 0 : _A.eventStream) == null ? void 0 : _B.classNames;
14373
15721
  const toggleBtnClasses = "persona-inline-flex persona-items-center persona-justify-center persona-rounded-full hover:persona-opacity-80 persona-cursor-pointer persona-border-none persona-bg-transparent persona-p-1" + ((esClassNames == null ? void 0 : esClassNames.toggleButton) ? " " + esClassNames.toggleButton : "");
14374
15722
  eventStreamToggleBtn = createElement("button", toggleBtnClasses);
14375
15723
  eventStreamToggleBtn.style.width = "28px";
@@ -14465,7 +15813,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
14465
15813
  config.agent = { ...config.agent, model: modelId };
14466
15814
  }
14467
15815
  },
14468
- onVoiceToggle: ((_A = config.voiceRecognition) == null ? void 0 : _A.enabled) === true ? () => {
15816
+ onVoiceToggle: ((_C = config.voiceRecognition) == null ? void 0 : _C.enabled) === true ? () => {
14469
15817
  composerVoiceBridge == null ? void 0 : composerVoiceBridge();
14470
15818
  } : void 0
14471
15819
  });
@@ -14504,7 +15852,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
14504
15852
  };
14505
15853
  ensureComposerAttachmentSurface(footer);
14506
15854
  bindComposerRefsFromFooter(footer);
14507
- const contentMaxWidth = (_B = config.layout) == null ? void 0 : _B.contentMaxWidth;
15855
+ const contentMaxWidth = (_D = config.layout) == null ? void 0 : _D.contentMaxWidth;
14508
15856
  if (contentMaxWidth && composerForm) {
14509
15857
  composerForm.style.maxWidth = contentMaxWidth;
14510
15858
  composerForm.style.marginLeft = "auto";
@@ -14520,7 +15868,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
14520
15868
  attachmentPreviewsContainer.style.marginLeft = "auto";
14521
15869
  attachmentPreviewsContainer.style.marginRight = "auto";
14522
15870
  }
14523
- if (((_C = config.attachments) == null ? void 0 : _C.enabled) && attachmentInput && attachmentPreviewsContainer) {
15871
+ if (((_E = config.attachments) == null ? void 0 : _E.enabled) && attachmentInput && attachmentPreviewsContainer) {
14524
15872
  attachmentManager = AttachmentManager.fromConfig(config.attachments);
14525
15873
  attachmentManager.setPreviewsContainer(attachmentPreviewsContainer);
14526
15874
  attachmentInput.addEventListener("change", (e) => {
@@ -14832,6 +16180,300 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
14832
16180
  event.preventDefault();
14833
16181
  target.click();
14834
16182
  });
16183
+ const askUserOverlay = panelElements.composerOverlay;
16184
+ const submitAskUserAnswer = (sheet, text, meta) => {
16185
+ var _a2, _b2, _c2, _d2;
16186
+ const trimmed = text.trim();
16187
+ if (!trimmed || !sessionRef.current) return;
16188
+ const toolCallId = (_a2 = sheet.getAttribute("data-tool-call-id")) != null ? _a2 : "";
16189
+ const isFreeText = meta.source === "free-text";
16190
+ mount.dispatchEvent(
16191
+ new CustomEvent("persona:askUserQuestion:answered", {
16192
+ detail: {
16193
+ toolUseId: toolCallId,
16194
+ answer: trimmed,
16195
+ answers: meta.structured,
16196
+ values: (_b2 = meta.values) != null ? _b2 : meta.source === "multi" ? trimmed.split(", ") : [trimmed],
16197
+ isFreeText,
16198
+ source: meta.source
16199
+ },
16200
+ bubbles: true,
16201
+ composed: true
16202
+ })
16203
+ );
16204
+ removeAskUserQuestionSheet(askUserOverlay, toolCallId);
16205
+ const sourceMessage = sessionRef.current.getMessages().find((m) => {
16206
+ var _a3;
16207
+ return ((_a3 = m.toolCall) == null ? void 0 : _a3.id) === toolCallId;
16208
+ });
16209
+ if ((_c2 = sourceMessage == null ? void 0 : sourceMessage.agentMetadata) == null ? void 0 : _c2.awaitingLocalTool) {
16210
+ sessionRef.current.resolveAskUserQuestion(sourceMessage, (_d2 = meta.structured) != null ? _d2 : trimmed);
16211
+ } else {
16212
+ sessionRef.current.sendMessage(trimmed);
16213
+ }
16214
+ };
16215
+ const persistGroupedProgress = (sheet) => {
16216
+ var _a2;
16217
+ const session2 = sessionRef.current;
16218
+ if (!session2) return;
16219
+ const toolCallId = (_a2 = sheet.getAttribute("data-tool-call-id")) != null ? _a2 : "";
16220
+ const sourceMessage = session2.getMessages().find((m) => {
16221
+ var _a3;
16222
+ return ((_a3 = m.toolCall) == null ? void 0 : _a3.id) === toolCallId;
16223
+ });
16224
+ if (!sourceMessage) return;
16225
+ session2.persistAskUserQuestionProgress(sourceMessage, {
16226
+ answers: buildStructuredAnswers(sheet, sourceMessage),
16227
+ currentIndex: getCurrentIndex(sheet)
16228
+ });
16229
+ };
16230
+ const stringifyStructured = (answers) => {
16231
+ return Object.entries(answers).map(([q, v]) => `${q}: ${Array.isArray(v) ? v.join(", ") : v}`).join(" | ");
16232
+ };
16233
+ const maybeAutoAdvance = (sheet) => {
16234
+ var _a2, _b2, _c2;
16235
+ if (((_b2 = (_a2 = config.features) == null ? void 0 : _a2.askUserQuestion) == null ? void 0 : _b2.groupedAutoAdvance) === false) return;
16236
+ const idx = getCurrentIndex(sheet);
16237
+ const count = getQuestionCount(sheet);
16238
+ if (idx >= count - 1) return;
16239
+ const sourceMessage = (_c2 = sessionRef.current) == null ? void 0 : _c2.getMessages().find((m) => {
16240
+ var _a3;
16241
+ return ((_a3 = m.toolCall) == null ? void 0 : _a3.id) === sheet.getAttribute("data-tool-call-id");
16242
+ });
16243
+ if (!sourceMessage) return;
16244
+ navigateToPage(sheet, sourceMessage, config, idx + 1);
16245
+ persistGroupedProgress(sheet);
16246
+ };
16247
+ askUserOverlay.addEventListener("click", (event) => {
16248
+ var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2, _i2, _j2, _k2, _l2, _m2, _n2;
16249
+ const target = event.target;
16250
+ const trigger = target.closest("[data-ask-user-action]");
16251
+ if (!trigger) return;
16252
+ const sheet = trigger.closest("[data-persona-ask-sheet-for]");
16253
+ if (!sheet) return;
16254
+ const action = trigger.getAttribute("data-ask-user-action");
16255
+ event.preventDefault();
16256
+ event.stopPropagation();
16257
+ if (action === "dismiss") {
16258
+ const toolCallId = (_a2 = sheet.getAttribute("data-tool-call-id")) != null ? _a2 : "";
16259
+ mount.dispatchEvent(
16260
+ new CustomEvent("persona:askUserQuestion:dismissed", {
16261
+ detail: { toolUseId: toolCallId },
16262
+ bubbles: true,
16263
+ composed: true
16264
+ })
16265
+ );
16266
+ removeAskUserQuestionSheet(askUserOverlay, toolCallId);
16267
+ const sourceMessage = (_b2 = sessionRef.current) == null ? void 0 : _b2.getMessages().find((m) => {
16268
+ var _a3;
16269
+ return ((_a3 = m.toolCall) == null ? void 0 : _a3.id) === toolCallId;
16270
+ });
16271
+ if ((_c2 = sourceMessage == null ? void 0 : sourceMessage.agentMetadata) == null ? void 0 : _c2.awaitingLocalTool) {
16272
+ (_d2 = sessionRef.current) == null ? void 0 : _d2.markAskUserQuestionResolved(sourceMessage);
16273
+ (_e2 = sessionRef.current) == null ? void 0 : _e2.resolveAskUserQuestion(sourceMessage, "(dismissed)");
16274
+ }
16275
+ return;
16276
+ }
16277
+ if (action === "pick") {
16278
+ const label = trigger.getAttribute("data-option-label");
16279
+ if (!label) return;
16280
+ const multiSelect = sheet.getAttribute("data-multi-select") === "true";
16281
+ const grouped = isGroupedSheet(sheet);
16282
+ if (grouped && multiSelect) {
16283
+ const stored = readAnswersFromSheet(sheet)[getCurrentIndex(sheet)];
16284
+ const set = new Set(Array.isArray(stored) ? stored : []);
16285
+ if (set.has(label)) set.delete(label);
16286
+ else set.add(label);
16287
+ setCurrentAnswer(sheet, Array.from(set));
16288
+ persistGroupedProgress(sheet);
16289
+ return;
16290
+ }
16291
+ if (grouped) {
16292
+ setCurrentAnswer(sheet, label);
16293
+ persistGroupedProgress(sheet);
16294
+ maybeAutoAdvance(sheet);
16295
+ return;
16296
+ }
16297
+ if (multiSelect) {
16298
+ const pressed = trigger.getAttribute("aria-pressed") === "true";
16299
+ trigger.setAttribute("aria-pressed", pressed ? "false" : "true");
16300
+ trigger.classList.toggle("persona-ask-pill-selected", !pressed);
16301
+ const submitBtn = sheet.querySelector(
16302
+ '[data-ask-user-action="submit-multi"]'
16303
+ );
16304
+ if (submitBtn) {
16305
+ submitBtn.disabled = getSelectedLabels(sheet).length === 0;
16306
+ }
16307
+ return;
16308
+ }
16309
+ submitAskUserAnswer(sheet, label, { source: "pick", values: [label] });
16310
+ return;
16311
+ }
16312
+ if (action === "submit-multi") {
16313
+ const labels = getSelectedLabels(sheet);
16314
+ if (labels.length === 0) return;
16315
+ submitAskUserAnswer(sheet, labels.join(", "), {
16316
+ source: "multi",
16317
+ values: labels
16318
+ });
16319
+ return;
16320
+ }
16321
+ if (action === "open-free-text") {
16322
+ const row = sheet.querySelector('[data-ask-free-text-row="true"]');
16323
+ if (row) {
16324
+ row.classList.remove("persona-hidden");
16325
+ const input = row.querySelector('[data-ask-free-text-input="true"]');
16326
+ input == null ? void 0 : input.focus();
16327
+ }
16328
+ return;
16329
+ }
16330
+ if (action === "focus-free-text") {
16331
+ const input = sheet.querySelector('[data-ask-free-text-input="true"]');
16332
+ input == null ? void 0 : input.focus();
16333
+ return;
16334
+ }
16335
+ if (action === "submit-free-text") {
16336
+ const input = sheet.querySelector('[data-ask-free-text-input="true"]');
16337
+ const text = (_f2 = input == null ? void 0 : input.value) != null ? _f2 : "";
16338
+ if (!text.trim()) return;
16339
+ if (isGroupedSheet(sheet)) {
16340
+ setCurrentAnswer(sheet, text.trim());
16341
+ persistGroupedProgress(sheet);
16342
+ maybeAutoAdvance(sheet);
16343
+ return;
16344
+ }
16345
+ submitAskUserAnswer(sheet, text, { source: "free-text" });
16346
+ return;
16347
+ }
16348
+ if (action === "next" || action === "back") {
16349
+ if (!sessionRef.current) return;
16350
+ const toolCallId = (_g2 = sheet.getAttribute("data-tool-call-id")) != null ? _g2 : "";
16351
+ const sourceMessage = sessionRef.current.getMessages().find((m) => {
16352
+ var _a3;
16353
+ return ((_a3 = m.toolCall) == null ? void 0 : _a3.id) === toolCallId;
16354
+ });
16355
+ if (!sourceMessage) return;
16356
+ const freeInput = sheet.querySelector('[data-ask-free-text-input="true"]');
16357
+ const pending = (_i2 = (_h2 = freeInput == null ? void 0 : freeInput.value) == null ? void 0 : _h2.trim()) != null ? _i2 : "";
16358
+ if (pending) {
16359
+ const stored = readAnswersFromSheet(sheet)[getCurrentIndex(sheet)];
16360
+ if (typeof stored !== "string" || stored !== pending) {
16361
+ setCurrentAnswer(sheet, pending);
16362
+ }
16363
+ }
16364
+ const direction = action === "next" ? 1 : -1;
16365
+ const nextIdx = getCurrentIndex(sheet) + direction;
16366
+ navigateToPage(sheet, sourceMessage, config, nextIdx);
16367
+ persistGroupedProgress(sheet);
16368
+ return;
16369
+ }
16370
+ if (action === "submit-all") {
16371
+ if (!sessionRef.current) return;
16372
+ const toolCallId = (_j2 = sheet.getAttribute("data-tool-call-id")) != null ? _j2 : "";
16373
+ const sourceMessage = sessionRef.current.getMessages().find((m) => {
16374
+ var _a3;
16375
+ return ((_a3 = m.toolCall) == null ? void 0 : _a3.id) === toolCallId;
16376
+ });
16377
+ if (!sourceMessage) return;
16378
+ const freeInput = sheet.querySelector('[data-ask-free-text-input="true"]');
16379
+ const pending = (_l2 = (_k2 = freeInput == null ? void 0 : freeInput.value) == null ? void 0 : _k2.trim()) != null ? _l2 : "";
16380
+ if (pending) setCurrentAnswer(sheet, pending);
16381
+ const structured = buildStructuredAnswers(sheet, sourceMessage);
16382
+ sessionRef.current.persistAskUserQuestionProgress(sourceMessage, {
16383
+ answers: structured,
16384
+ currentIndex: getCurrentIndex(sheet)
16385
+ });
16386
+ const summary = stringifyStructured(structured);
16387
+ submitAskUserAnswer(sheet, summary || "(submitted)", {
16388
+ source: "submit-all",
16389
+ structured
16390
+ });
16391
+ return;
16392
+ }
16393
+ if (action === "skip") {
16394
+ if (!sessionRef.current) return;
16395
+ const toolCallId = (_m2 = sheet.getAttribute("data-tool-call-id")) != null ? _m2 : "";
16396
+ const sourceMessage = sessionRef.current.getMessages().find((m) => {
16397
+ var _a3;
16398
+ return ((_a3 = m.toolCall) == null ? void 0 : _a3.id) === toolCallId;
16399
+ });
16400
+ if (!sourceMessage) return;
16401
+ const grouped = isGroupedSheet(sheet);
16402
+ const idx = getCurrentIndex(sheet);
16403
+ const count = getQuestionCount(sheet);
16404
+ const isFinal = idx >= count - 1;
16405
+ if (!grouped) {
16406
+ mount.dispatchEvent(
16407
+ new CustomEvent("persona:askUserQuestion:dismissed", {
16408
+ detail: { toolUseId: toolCallId },
16409
+ bubbles: true,
16410
+ composed: true
16411
+ })
16412
+ );
16413
+ removeAskUserQuestionSheet(askUserOverlay, toolCallId);
16414
+ if ((_n2 = sourceMessage.agentMetadata) == null ? void 0 : _n2.awaitingLocalTool) {
16415
+ sessionRef.current.markAskUserQuestionResolved(sourceMessage);
16416
+ sessionRef.current.resolveAskUserQuestion(sourceMessage, "(dismissed)");
16417
+ }
16418
+ return;
16419
+ }
16420
+ setCurrentAnswer(sheet, "");
16421
+ const freeInput = sheet.querySelector('[data-ask-free-text-input="true"]');
16422
+ if (freeInput) freeInput.value = "";
16423
+ if (isFinal) {
16424
+ const structured = buildStructuredAnswers(sheet, sourceMessage);
16425
+ const summary = stringifyStructured(structured);
16426
+ submitAskUserAnswer(sheet, summary || "(skipped)", {
16427
+ source: "submit-all",
16428
+ structured
16429
+ });
16430
+ return;
16431
+ }
16432
+ navigateToPage(sheet, sourceMessage, config, idx + 1);
16433
+ persistGroupedProgress(sheet);
16434
+ return;
16435
+ }
16436
+ });
16437
+ askUserOverlay.addEventListener("keydown", (event) => {
16438
+ var _a2;
16439
+ if (event.key !== "Enter") return;
16440
+ const target = event.target;
16441
+ const input = target;
16442
+ if (!((_a2 = input.matches) == null ? void 0 : _a2.call(input, '[data-ask-free-text-input="true"]'))) return;
16443
+ const sheet = input.closest("[data-persona-ask-sheet-for]");
16444
+ if (!sheet) return;
16445
+ event.preventDefault();
16446
+ const text = input.value;
16447
+ if (!text.trim()) return;
16448
+ if (isGroupedSheet(sheet)) {
16449
+ setCurrentAnswer(sheet, text.trim());
16450
+ persistGroupedProgress(sheet);
16451
+ maybeAutoAdvance(sheet);
16452
+ return;
16453
+ }
16454
+ submitAskUserAnswer(sheet, text, { source: "free-text" });
16455
+ });
16456
+ const handleAskUserDigitKey = (event) => {
16457
+ if (!/^[1-9]$/.test(event.key)) return;
16458
+ if (event.metaKey || event.ctrlKey || event.altKey) return;
16459
+ const target = event.target;
16460
+ if ((target == null ? void 0 : target.tagName) === "INPUT" || (target == null ? void 0 : target.tagName) === "TEXTAREA" || (target == null ? void 0 : target.isContentEditable)) {
16461
+ return;
16462
+ }
16463
+ const sheet = askUserOverlay.querySelector("[data-persona-ask-sheet-for]");
16464
+ if (!sheet) return;
16465
+ if (sheet.getAttribute("data-ask-layout") !== "rows") return;
16466
+ if (sheet.getAttribute("data-multi-select") === "true") return;
16467
+ const n = Number(event.key);
16468
+ const pills = sheet.querySelectorAll(
16469
+ '[data-ask-pill-list="true"] [data-ask-user-action="pick"], [data-ask-pill-list="true"] [data-ask-user-action="focus-free-text"]'
16470
+ );
16471
+ const target_pill = pills[n - 1];
16472
+ if (!target_pill) return;
16473
+ event.preventDefault();
16474
+ target_pill.click();
16475
+ };
16476
+ document.addEventListener("keydown", handleAskUserDigitKey);
14835
16477
  let artifactSplitRoot = null;
14836
16478
  let artifactResizeHandle = null;
14837
16479
  let artifactResizeUnbind = null;
@@ -15069,12 +16711,24 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
15069
16711
  const panelBorder = resolvePanelChrome(panelPartial == null ? void 0 : panelPartial.border, defaultPanelBorder);
15070
16712
  const panelShadow = resolvePanelChrome(panelPartial == null ? void 0 : panelPartial.shadow, defaultPanelShadow);
15071
16713
  const panelBorderRadius = resolvePanelChrome(panelPartial == null ? void 0 : panelPartial.borderRadius, defaultPanelBorderRadius);
16714
+ const prevBodyScrollTop = body.scrollTop;
15072
16715
  mount.style.cssText = "";
15073
16716
  wrapper.style.cssText = "";
15074
16717
  panel.style.cssText = "";
15075
16718
  container.style.cssText = "";
15076
16719
  body.style.cssText = "";
15077
16720
  footer.style.cssText = "";
16721
+ const restoreBodyScrollTop = () => {
16722
+ var _a3;
16723
+ if (prevBodyScrollTop <= 0) return;
16724
+ const ownerWindow3 = (_a3 = body.ownerDocument.defaultView) != null ? _a3 : window;
16725
+ ownerWindow3.requestAnimationFrame(() => {
16726
+ if (body.scrollTop === prevBodyScrollTop) return;
16727
+ const maxScrollTop = body.scrollHeight - body.clientHeight;
16728
+ if (maxScrollTop <= 0) return;
16729
+ body.scrollTop = Math.min(prevBodyScrollTop, maxScrollTop);
16730
+ });
16731
+ };
15078
16732
  if (shouldGoFullscreen) {
15079
16733
  wrapper.classList.remove(
15080
16734
  "persona-bottom-6",
@@ -15130,6 +16784,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
15130
16784
  body.style.overflowY = "auto";
15131
16785
  footer.style.flexShrink = "0";
15132
16786
  wasMobileFullscreen = true;
16787
+ restoreBodyScrollTop();
15133
16788
  return;
15134
16789
  }
15135
16790
  const launcherWidth = (_r2 = (_q2 = config == null ? void 0 : config.launcher) == null ? void 0 : _q2.width) != null ? _r2 : config == null ? void 0 : config.launcherWidth;
@@ -15272,12 +16927,16 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
15272
16927
  const zIndexStyles = !sidebarMode ? `z-index: ${(_w2 = (_v2 = config.launcher) == null ? void 0 : _v2.zIndex) != null ? _w2 : DEFAULT_OVERLAY_Z_INDEX} !important;` : "";
15273
16928
  wrapper.style.cssText += maxHeightStyles + paddingStyles + zIndexStyles;
15274
16929
  }
16930
+ restoreBodyScrollTop();
15275
16931
  };
15276
16932
  applyFullHeightStyles();
15277
16933
  applyThemeVariables(mount, config);
15278
16934
  applyArtifactLayoutCssVars(mount, config);
15279
16935
  applyArtifactPaneAppearance(mount, config);
15280
16936
  const destroyCallbacks = [];
16937
+ destroyCallbacks.push(() => {
16938
+ document.removeEventListener("keydown", handleAskUserDigitKey);
16939
+ });
15281
16940
  let teardownHostStacking = null;
15282
16941
  let releaseScrollLock = null;
15283
16942
  destroyCallbacks.push(() => {
@@ -15335,11 +16994,23 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
15335
16994
  cleanupThemeObserver = null;
15336
16995
  }
15337
16996
  });
16997
+ const streamAnimationConfig = (_F = config.features) == null ? void 0 : _F.streamAnimation;
16998
+ if ((streamAnimationConfig == null ? void 0 : streamAnimationConfig.type) && streamAnimationConfig.type !== "none") {
16999
+ const plugin = resolveStreamAnimationPlugin(
17000
+ streamAnimationConfig.type,
17001
+ streamAnimationConfig.plugins
17002
+ );
17003
+ if (plugin) {
17004
+ ensurePluginActive(plugin, mount);
17005
+ destroyCallbacks.push(() => detachAllPlugins(mount));
17006
+ }
17007
+ }
15338
17008
  const suggestionsManager = createSuggestions(suggestions);
15339
17009
  let closeHandler = null;
15340
17010
  let session;
15341
17011
  let isStreaming = false;
15342
17012
  const messageCache = createMessageCache();
17013
+ const lastAskBubbleFingerprint = /* @__PURE__ */ new Map();
15343
17014
  let configVersion = 0;
15344
17015
  const autoFollow = createFollowStateController();
15345
17016
  let lastScrollTop = 0;
@@ -15356,7 +17027,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
15356
17027
  lastUserMessageWasVoice: false,
15357
17028
  lastUserMessageId: null
15358
17029
  };
15359
- const voiceAutoResumeMode = (_E = (_D = config.voiceRecognition) == null ? void 0 : _D.autoResume) != null ? _E : false;
17030
+ const voiceAutoResumeMode = (_H = (_G = config.voiceRecognition) == null ? void 0 : _G.autoResume) != null ? _H : false;
15360
17031
  const emitVoiceState = (source) => {
15361
17032
  eventBus.emit("voice:state", {
15362
17033
  active: voiceState.active,
@@ -15405,7 +17076,9 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
15405
17076
  const messages = messagesOverride ? stripStreamingFromMessages(messagesOverride) : session ? getMessagesForPersistence() : [];
15406
17077
  const payload = {
15407
17078
  messages,
15408
- metadata: persistentMetadata
17079
+ metadata: persistentMetadata,
17080
+ artifacts: lastArtifactsState.artifacts,
17081
+ selectedArtifactId: lastArtifactsState.selectedId
15409
17082
  };
15410
17083
  try {
15411
17084
  const result = storageAdapter.save(payload);
@@ -15582,13 +17255,22 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
15582
17255
  return true;
15583
17256
  };
15584
17257
  const activeMessageIds = /* @__PURE__ */ new Set();
17258
+ const liveAskToolIds = /* @__PURE__ */ new Set();
17259
+ const hasAskPlugin = plugins.some((p) => p.renderAskUserQuestion);
17260
+ const askPluginHydrate = [];
15585
17261
  messages.forEach((message) => {
15586
- var _a3, _b3;
17262
+ var _a3, _b3, _c3, _d3, _e3, _f3, _g2, _h2, _i2, _j2, _k2, _l2, _m2, _n2;
15587
17263
  activeMessageIds.add(message.id);
15588
- const fingerprint = computeMessageFingerprint(message, configVersion);
15589
- const cachedWrapper = getCachedWrapper(messageCache, message.id, fingerprint);
17264
+ const askWithPlugin = hasAskPlugin && isAskUserQuestionMessage(message);
17265
+ const askMeta = isAskUserQuestionMessage(message) ? `:${((_a3 = message.agentMetadata) == null ? void 0 : _a3.askUserQuestionAnswered) ? "a" : "u"}:${((_b3 = message.agentMetadata) == null ? void 0 : _b3.askUserQuestionAnswers) ? Object.keys(message.agentMetadata.askUserQuestionAnswers).length : 0}` : "";
17266
+ const fingerprint = computeMessageFingerprint(message, configVersion) + askMeta;
17267
+ const cachedWrapper = askWithPlugin ? null : getCachedWrapper(messageCache, message.id, fingerprint);
15590
17268
  if (cachedWrapper) {
15591
17269
  tempContainer.appendChild(cachedWrapper.cloneNode(true));
17270
+ if (isAskUserQuestionMessage(message) && ((_c3 = message.toolCall) == null ? void 0 : _c3.id) && ((_d3 = message.agentMetadata) == null ? void 0 : _d3.awaitingLocalTool) === true && !((_e3 = message.agentMetadata) == null ? void 0 : _e3.askUserQuestionAnswered)) {
17271
+ liveAskToolIds.add(message.toolCall.id);
17272
+ ensureAskUserQuestionSheet(message, config, panelElements.composerOverlay);
17273
+ }
15592
17274
  return;
15593
17275
  }
15594
17276
  let bubble = null;
@@ -15607,8 +17289,75 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
15607
17289
  }
15608
17290
  return false;
15609
17291
  });
15610
- const messageLayoutConfig = (_a3 = config.layout) == null ? void 0 : _a3.messages;
15611
- if (matchingPlugin) {
17292
+ const messageLayoutConfig = (_f3 = config.layout) == null ? void 0 : _f3.messages;
17293
+ if (isAskUserQuestionMessage(message) && ((_g2 = message.agentMetadata) == null ? void 0 : _g2.askUserQuestionAnswered) === true) {
17294
+ lastAskBubbleFingerprint.delete(message.id);
17295
+ const existing = container2.querySelector(`#wrapper-${message.id}`);
17296
+ existing == null ? void 0 : existing.removeAttribute("data-preserve-runtime");
17297
+ return;
17298
+ }
17299
+ if (isAskUserQuestionMessage(message) && ((_i2 = (_h2 = config.features) == null ? void 0 : _h2.askUserQuestion) == null ? void 0 : _i2.enabled) !== false) {
17300
+ const askPlugin = plugins.find((p) => typeof p.renderAskUserQuestion === "function");
17301
+ if (askPlugin && sessionRef.current) {
17302
+ const lastFp = lastAskBubbleFingerprint.get(message.id);
17303
+ const needsRebuild = lastFp !== fingerprint;
17304
+ let pluginBubble = null;
17305
+ if (needsRebuild) {
17306
+ const { payload, complete } = parseAskUserQuestionPayload(message);
17307
+ const messageId = message.id;
17308
+ const liveMessage = () => {
17309
+ var _a4;
17310
+ return (_a4 = sessionRef.current) == null ? void 0 : _a4.getMessages().find((m) => m.id === messageId);
17311
+ };
17312
+ pluginBubble = askPlugin.renderAskUserQuestion({
17313
+ message,
17314
+ payload,
17315
+ complete,
17316
+ resolve: (answer) => {
17317
+ var _a4;
17318
+ const live = liveMessage();
17319
+ if (live) (_a4 = sessionRef.current) == null ? void 0 : _a4.resolveAskUserQuestion(live, answer);
17320
+ },
17321
+ dismiss: () => {
17322
+ var _a4, _b4, _c4;
17323
+ const live = liveMessage();
17324
+ if ((_a4 = live == null ? void 0 : live.agentMetadata) == null ? void 0 : _a4.awaitingLocalTool) {
17325
+ (_b4 = sessionRef.current) == null ? void 0 : _b4.markAskUserQuestionResolved(live);
17326
+ (_c4 = sessionRef.current) == null ? void 0 : _c4.resolveAskUserQuestion(live, "(dismissed)");
17327
+ }
17328
+ },
17329
+ config
17330
+ });
17331
+ }
17332
+ const previouslyMounted = lastFp != null;
17333
+ if (needsRebuild && pluginBubble === null && !previouslyMounted) {
17334
+ if (((_j2 = message.agentMetadata) == null ? void 0 : _j2.awaitingLocalTool) === true && !((_k2 = message.agentMetadata) == null ? void 0 : _k2.askUserQuestionAnswered)) {
17335
+ liveAskToolIds.add(message.toolCall.id);
17336
+ ensureAskUserQuestionSheet(message, config, panelElements.composerOverlay);
17337
+ }
17338
+ return;
17339
+ }
17340
+ const stub = document.createElement("div");
17341
+ stub.className = "persona-flex";
17342
+ stub.id = `wrapper-${message.id}`;
17343
+ stub.setAttribute("data-wrapper-id", message.id);
17344
+ stub.setAttribute("data-ask-plugin-stub", "true");
17345
+ stub.setAttribute("data-preserve-runtime", "true");
17346
+ tempContainer.appendChild(stub);
17347
+ askPluginHydrate.push({
17348
+ messageId: message.id,
17349
+ fingerprint,
17350
+ bubble: pluginBubble
17351
+ });
17352
+ return;
17353
+ } else {
17354
+ if (((_l2 = message.agentMetadata) == null ? void 0 : _l2.awaitingLocalTool) === true && !((_m2 = message.agentMetadata) == null ? void 0 : _m2.askUserQuestionAnswered)) {
17355
+ liveAskToolIds.add(message.toolCall.id);
17356
+ ensureAskUserQuestionSheet(message, config, panelElements.composerOverlay);
17357
+ }
17358
+ return;
17359
+ }
17360
+ } else if (matchingPlugin) {
15612
17361
  if (message.variant === "reasoning" && message.reasoning && matchingPlugin.renderReasoning) {
15613
17362
  if (!showReasoning) return;
15614
17363
  bubble = matchingPlugin.renderReasoning({
@@ -15727,7 +17476,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
15727
17476
  if (config.approval === false) return;
15728
17477
  bubble = createApprovalBubble(message, config);
15729
17478
  } else {
15730
- const messageLayoutConfig2 = (_b3 = config.layout) == null ? void 0 : _b3.messages;
17479
+ const messageLayoutConfig2 = (_n2 = config.layout) == null ? void 0 : _n2.messages;
15731
17480
  if ((messageLayoutConfig2 == null ? void 0 : messageLayoutConfig2.renderUserMessage) && message.role === "user") {
15732
17481
  bubble = messageLayoutConfig2.renderUserMessage({
15733
17482
  message,
@@ -15772,6 +17521,17 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
15772
17521
  setCachedWrapper(messageCache, message.id, fingerprint, wrapper2);
15773
17522
  tempContainer.appendChild(wrapper2);
15774
17523
  });
17524
+ if (panelElements.composerOverlay) {
17525
+ const sheets = panelElements.composerOverlay.querySelectorAll(
17526
+ "[data-persona-ask-sheet-for]"
17527
+ );
17528
+ sheets.forEach((sheet) => {
17529
+ const id = sheet.getAttribute("data-persona-ask-sheet-for");
17530
+ if (id && !liveAskToolIds.has(id)) {
17531
+ removeAskUserQuestionSheet(panelElements.composerOverlay, id);
17532
+ }
17533
+ });
17534
+ }
15775
17535
  if ((_b2 = (_a2 = config.features) == null ? void 0 : _a2.toolCallDisplay) == null ? void 0 : _b2.grouped) {
15776
17536
  const toolGroups = [];
15777
17537
  let currentGroup = [];
@@ -15936,6 +17696,23 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
15936
17696
  }
15937
17697
  }
15938
17698
  morphMessages(container2, tempContainer);
17699
+ if (askPluginHydrate.length > 0) {
17700
+ for (const { messageId, fingerprint, bubble } of askPluginHydrate) {
17701
+ const wrapper2 = container2.querySelector(`#wrapper-${messageId}`);
17702
+ if (!wrapper2) continue;
17703
+ if (bubble === null) {
17704
+ continue;
17705
+ }
17706
+ wrapper2.replaceChildren(bubble);
17707
+ wrapper2.setAttribute("data-bubble-fp", fingerprint);
17708
+ lastAskBubbleFingerprint.set(messageId, fingerprint);
17709
+ }
17710
+ }
17711
+ if (lastAskBubbleFingerprint.size > 0) {
17712
+ for (const id of lastAskBubbleFingerprint.keys()) {
17713
+ if (!activeMessageIds.has(id)) lastAskBubbleFingerprint.delete(id);
17714
+ }
17715
+ }
15939
17716
  };
15940
17717
  const renderMessagesWithPlugins = renderMessagesWithPluginsImpl;
15941
17718
  const updateOpenState = () => {
@@ -16044,7 +17821,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
16044
17821
  });
16045
17822
  };
16046
17823
  const setComposerDisabled = (disabled) => {
16047
- sendButton.disabled = disabled;
17824
+ setSendButtonMode(disabled ? "stop" : "send");
16048
17825
  if (micButton) {
16049
17826
  micButton.disabled = disabled;
16050
17827
  }
@@ -16084,7 +17861,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
16084
17861
  }
16085
17862
  }
16086
17863
  const useIcon = (_i2 = (_h2 = config.sendButton) == null ? void 0 : _h2.useIcon) != null ? _i2 : false;
16087
- if (!useIcon) {
17864
+ if (!useIcon && !(session == null ? void 0 : session.isStreaming())) {
16088
17865
  sendButton.textContent = (_k2 = (_j2 = config.copy) == null ? void 0 : _j2.sendButtonLabel) != null ? _k2 : "Send";
16089
17866
  }
16090
17867
  textarea.style.fontFamily = 'var(--persona-input-font-family, var(--persona-font-family, -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Arial, sans-serif))';
@@ -16200,10 +17977,11 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
16200
17977
  onArtifactsState(state) {
16201
17978
  lastArtifactsState = state;
16202
17979
  syncArtifactPane();
17980
+ persistState();
16203
17981
  }
16204
17982
  });
16205
17983
  sessionRef.current = session;
16206
- if (((_G = (_F = config.voiceRecognition) == null ? void 0 : _F.provider) == null ? void 0 : _G.type) === "runtype") {
17984
+ if (((_J = (_I = config.voiceRecognition) == null ? void 0 : _I.provider) == null ? void 0 : _J.type) === "runtype") {
16207
17985
  try {
16208
17986
  session.setupVoice();
16209
17987
  } catch (err) {
@@ -16233,7 +18011,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
16233
18011
  }
16234
18012
  if (pendingStoredState) {
16235
18013
  pendingStoredState.then((state) => {
16236
- var _a2;
18014
+ var _a2, _b2, _c2;
16237
18015
  if (!state) return;
16238
18016
  if (state.metadata) {
16239
18017
  persistentMetadata = ensureRecord(state.metadata);
@@ -16242,6 +18020,12 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
16242
18020
  if ((_a2 = state.messages) == null ? void 0 : _a2.length) {
16243
18021
  session.hydrateMessages(state.messages);
16244
18022
  }
18023
+ if ((_b2 = state.artifacts) == null ? void 0 : _b2.length) {
18024
+ session.hydrateArtifacts(
18025
+ state.artifacts,
18026
+ (_c2 = state.selectedArtifactId) != null ? _c2 : null
18027
+ );
18028
+ }
16245
18029
  }).catch((error) => {
16246
18030
  if (typeof console !== "undefined") {
16247
18031
  console.error("[AgentWidget] Failed to hydrate stored state:", error);
@@ -16251,6 +18035,10 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
16251
18035
  const handleSubmit = (event) => {
16252
18036
  var _a2;
16253
18037
  event.preventDefault();
18038
+ if (session.isStreaming()) {
18039
+ session.cancel();
18040
+ return;
18041
+ }
16254
18042
  const value = textarea.value.trim();
16255
18043
  const hasAttachments = (_a2 = attachmentManager == null ? void 0 : attachmentManager.hasAttachments()) != null ? _a2 : false;
16256
18044
  if (!value && !hasAttachments) return;
@@ -16805,7 +18593,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
16805
18593
  }
16806
18594
  };
16807
18595
  recalcPanelHeight();
16808
- const ownerWindow = (_H = mount.ownerDocument.defaultView) != null ? _H : window;
18596
+ const ownerWindow = (_K = mount.ownerDocument.defaultView) != null ? _K : window;
16809
18597
  ownerWindow.addEventListener("resize", recalcPanelHeight);
16810
18598
  destroyCallbacks.push(() => ownerWindow.removeEventListener("resize", recalcPanelHeight));
16811
18599
  if (typeof ResizeObserver !== "undefined") {
@@ -16816,15 +18604,19 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
16816
18604
  destroyCallbacks.push(() => footerResizeObserver.disconnect());
16817
18605
  }
16818
18606
  lastScrollTop = body.scrollTop;
18607
+ let lastScrollHeight = body.scrollHeight;
16819
18608
  const handleScroll = () => {
16820
18609
  const scrollTop = body.scrollTop;
18610
+ const currentScrollHeight = body.scrollHeight;
18611
+ const scrollHeightShrank = currentScrollHeight < lastScrollHeight;
18612
+ lastScrollHeight = currentScrollHeight;
16821
18613
  const { action, nextLastScrollTop } = resolveFollowStateFromScroll({
16822
18614
  following: autoFollow.isFollowing(),
16823
18615
  currentScrollTop: scrollTop,
16824
18616
  lastScrollTop,
16825
18617
  nearBottom: isElementNearBottom(body, BOTTOM_THRESHOLD),
16826
18618
  userScrollThreshold: USER_SCROLL_THRESHOLD,
16827
- isAutoScrolling: isAutoScrolling || hasPendingAutoScroll,
18619
+ isAutoScrolling: isAutoScrolling || hasPendingAutoScroll || scrollHeightShrank,
16828
18620
  pauseOnUpwardScroll: true,
16829
18621
  pauseWhenAwayFromBottom: false,
16830
18622
  resumeRequiresDownwardScroll: true
@@ -16889,6 +18681,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
16889
18681
  session.clearMessages();
16890
18682
  messageCache.clear();
16891
18683
  resumeAutoScroll();
18684
+ removeAskUserQuestionSheet(panelElements.composerOverlay);
16892
18685
  try {
16893
18686
  localStorage.removeItem(DEFAULT_CHAT_HISTORY_STORAGE_KEY);
16894
18687
  if (config.debug) {
@@ -17024,7 +18817,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17024
18817
  }
17025
18818
  const controller = {
17026
18819
  update(nextConfig) {
17027
- var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2, _i2, _j2, _k2, _l2, _m2, _n2, _o2, _p2, _q2, _r2, _s2, _t2, _u2, _v2, _w2, _x2, _y2, _z2, _A2, _B2, _C2, _D2, _E2, _F2, _G2, _H2, _I2, _J2, _K2, _L2, _M2, _N2, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y, _Z, __, _$, _aa, _ba, _ca, _da, _ea, _fa, _ga, _ha, _ia, _ja, _ka, _la, _ma, _na, _oa, _pa, _qa, _ra, _sa, _ta, _ua, _va, _wa, _xa, _ya, _za, _Aa, _Ba, _Ca, _Da, _Ea, _Fa, _Ga, _Ha, _Ia, _Ja, _Ka, _La, _Ma, _Na, _Oa, _Pa, _Qa, _Ra, _Sa, _Ta, _Ua, _Va, _Wa, _Xa, _Ya, _Za, __a, _$a, _ab;
18820
+ var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2, _i2, _j2, _k2, _l2, _m2, _n2, _o2, _p2, _q2, _r2, _s2, _t2, _u2, _v2, _w2, _x2, _y2, _z2, _A2, _B2, _C2, _D2, _E2, _F2, _G2, _H2, _I2, _J2, _K2, _L2, _M2, _N2, _O2, _P2, _Q2, _R, _S, _T, _U, _V, _W, _X, _Y, _Z, __, _$, _aa, _ba, _ca, _da, _ea, _fa, _ga, _ha, _ia, _ja, _ka, _la, _ma, _na, _oa, _pa, _qa, _ra, _sa, _ta, _ua, _va, _wa, _xa, _ya, _za, _Aa, _Ba, _Ca, _Da, _Ea, _Fa, _Ga, _Ha, _Ia, _Ja, _Ka, _La, _Ma, _Na, _Oa, _Pa, _Qa, _Ra, _Sa, _Ta, _Ua, _Va, _Wa, _Xa, _Ya, _Za, __a, _$a, _ab;
17028
18821
  const previousToolCallConfig = config.toolCall;
17029
18822
  const previousMessageActions = config.messageActions;
17030
18823
  const previousLayoutMessages = (_a2 = config.layout) == null ? void 0 : _a2.messages;
@@ -17235,10 +19028,10 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17235
19028
  }
17236
19029
  const launcher = (_L2 = config.launcher) != null ? _L2 : {};
17237
19030
  const headerIconHidden = (_M2 = launcher.headerIconHidden) != null ? _M2 : false;
17238
- const layoutShowIcon = (_O = (_N2 = config.layout) == null ? void 0 : _N2.header) == null ? void 0 : _O.showIcon;
19031
+ const layoutShowIcon = (_O2 = (_N2 = config.layout) == null ? void 0 : _N2.header) == null ? void 0 : _O2.showIcon;
17239
19032
  const shouldHideIcon = headerIconHidden || layoutShowIcon === false;
17240
19033
  const headerIconName = launcher.headerIconName;
17241
- const headerIconSize = (_P = launcher.headerIconSize) != null ? _P : "48px";
19034
+ const headerIconSize = (_P2 = launcher.headerIconSize) != null ? _P2 : "48px";
17242
19035
  if (iconHolder) {
17243
19036
  const headerEl = container.querySelector(".persona-border-b-persona-divider");
17244
19037
  const headerCopy = headerEl == null ? void 0 : headerEl.querySelector(".persona-flex-col");
@@ -17265,7 +19058,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17265
19058
  if (iconSvg) {
17266
19059
  iconHolder.replaceChildren(iconSvg);
17267
19060
  } else {
17268
- iconHolder.textContent = (_Q = launcher.agentIconText) != null ? _Q : "\u{1F4AC}";
19061
+ iconHolder.textContent = (_Q2 = launcher.agentIconText) != null ? _Q2 : "\u{1F4AC}";
17269
19062
  }
17270
19063
  } else if (launcher.iconUrl) {
17271
19064
  const img2 = iconHolder.querySelector("img");
@@ -18189,6 +19982,14 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
18189
19982
  if (!artifactsSidebarEnabled(config)) return;
18190
19983
  session.clearArtifacts();
18191
19984
  },
19985
+ getArtifacts() {
19986
+ var _a2;
19987
+ return (_a2 = session == null ? void 0 : session.getArtifacts()) != null ? _a2 : [];
19988
+ },
19989
+ getSelectedArtifactId() {
19990
+ var _a2;
19991
+ return (_a2 = session == null ? void 0 : session.getSelectedArtifactId()) != null ? _a2 : null;
19992
+ },
18192
19993
  focusInput() {
18193
19994
  if (launcherEnabled && !open) return false;
18194
19995
  if (!textarea) return false;
@@ -18306,7 +20107,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
18306
20107
  }
18307
20108
  }
18308
20109
  };
18309
- const shouldExposeDebugApi = ((_I = runtimeOptions == null ? void 0 : runtimeOptions.debugTools) != null ? _I : false) || Boolean(config.debug);
20110
+ const shouldExposeDebugApi = ((_L = runtimeOptions == null ? void 0 : runtimeOptions.debugTools) != null ? _L : false) || Boolean(config.debug);
18310
20111
  if (shouldExposeDebugApi && typeof window !== "undefined") {
18311
20112
  const previousDebug = window.AgentWidgetBrowser;
18312
20113
  const debugApi = {
@@ -18409,9 +20210,9 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
18409
20210
  const voiceKey = `${persistConfig.keyPrefix}widget-voice`;
18410
20211
  const voiceModeKey = `${persistConfig.keyPrefix}widget-voice-mode`;
18411
20212
  if (storage) {
18412
- const wasOpen = ((_J = persistConfig.persist) == null ? void 0 : _J.openState) && storage.getItem(openKey) === "true";
18413
- const wasVoiceActive = ((_K = persistConfig.persist) == null ? void 0 : _K.voiceState) && storage.getItem(voiceKey) === "true";
18414
- const wasInVoiceMode = ((_L = persistConfig.persist) == null ? void 0 : _L.voiceState) && storage.getItem(voiceModeKey) === "true";
20213
+ const wasOpen = ((_M = persistConfig.persist) == null ? void 0 : _M.openState) && storage.getItem(openKey) === "true";
20214
+ const wasVoiceActive = ((_N = persistConfig.persist) == null ? void 0 : _N.voiceState) && storage.getItem(voiceKey) === "true";
20215
+ const wasInVoiceMode = ((_O = persistConfig.persist) == null ? void 0 : _O.voiceState) && storage.getItem(voiceModeKey) === "true";
18415
20216
  if (wasOpen) {
18416
20217
  setTimeout(() => {
18417
20218
  controller.open();
@@ -18428,7 +20229,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
18428
20229
  }, 100);
18429
20230
  }, 0);
18430
20231
  }
18431
- if ((_M = persistConfig.persist) == null ? void 0 : _M.openState) {
20232
+ if ((_P = persistConfig.persist) == null ? void 0 : _P.openState) {
18432
20233
  eventBus.on("widget:opened", () => {
18433
20234
  storage.setItem(openKey, "true");
18434
20235
  });
@@ -18436,7 +20237,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
18436
20237
  storage.setItem(openKey, "false");
18437
20238
  });
18438
20239
  }
18439
- if ((_N = persistConfig.persist) == null ? void 0 : _N.voiceState) {
20240
+ if ((_Q = persistConfig.persist) == null ? void 0 : _Q.voiceState) {
18440
20241
  eventBus.on("voice:state", (event) => {
18441
20242
  storage.setItem(voiceKey, event.active ? "true" : "false");
18442
20243
  });
@@ -19010,6 +20811,9 @@ function buildSrcdoc(mountId, shellMode, docked, widgetCssPath) {
19010
20811
  var PREVIEW_TRANSCRIPT_PRESET_LABELS = {
19011
20812
  "user-message": "User message",
19012
20813
  "assistant-message": "Assistant message",
20814
+ "assistant-code-block": "Assistant \u2014 code block",
20815
+ "assistant-markdown-table": "Assistant \u2014 markdown table",
20816
+ "assistant-image": "Assistant \u2014 image",
19013
20817
  "reasoning-streaming": "Reasoning (streaming)",
19014
20818
  "reasoning-complete": "Reasoning (complete)",
19015
20819
  "tool-running": "Tool call (running)",
@@ -19036,6 +20840,56 @@ function createPreviewTranscriptEntry(preset, index = 0) {
19036
20840
  content: "Absolutely. I can keep going and explain what happens next.",
19037
20841
  createdAt
19038
20842
  };
20843
+ case "assistant-code-block":
20844
+ return {
20845
+ id: `preview-seq-assistant-code-${suffix}`,
20846
+ role: "assistant",
20847
+ content: [
20848
+ "Here's how you'd wire up a streaming animation:",
20849
+ "",
20850
+ "```ts",
20851
+ "import { createAgentExperience } from '@runtypelabs/persona';",
20852
+ "",
20853
+ "createAgentExperience(el, {",
20854
+ " features: {",
20855
+ ' streamAnimation: { type: "letter-rise", speed: 120 },',
20856
+ " },",
20857
+ "});",
20858
+ "```",
20859
+ "",
20860
+ "Swap the `type` value to try the other presets."
20861
+ ].join("\n"),
20862
+ createdAt
20863
+ };
20864
+ case "assistant-markdown-table":
20865
+ return {
20866
+ id: `preview-seq-assistant-table-${suffix}`,
20867
+ role: "assistant",
20868
+ content: [
20869
+ "Here are the built-in streaming animations at a glance:",
20870
+ "",
20871
+ "| Preset | Wrap unit | Best for |",
20872
+ "| ------------ | --------- | --------------------------- |",
20873
+ "| Typewriter | Character | Classic terminal feel |",
20874
+ "| Letter rise | Character | Soft, staggered entrance |",
20875
+ "| Word fade | Word | Longer-form assistant replies |",
20876
+ "| Pop bubble | Bubble | Short, punchy affirmations |"
20877
+ ].join("\n"),
20878
+ createdAt
20879
+ };
20880
+ case "assistant-image":
20881
+ return {
20882
+ id: `preview-seq-assistant-image-${suffix}`,
20883
+ role: "assistant",
20884
+ content: [
20885
+ "Here's the reference diagram you asked for \u2014 let me know if you'd like a different view:",
20886
+ "",
20887
+ "![Stream animation reference](https://placehold.co/320x200/png?text=Stream+Animation)",
20888
+ "",
20889
+ "The gradient shows how per-unit delays stagger across the reply."
20890
+ ].join("\n"),
20891
+ createdAt
20892
+ };
19039
20893
  case "reasoning-streaming":
19040
20894
  return {
19041
20895
  id: `preview-seq-reasoning-stream-${suffix}`,
@@ -19103,6 +20957,38 @@ function createPreviewTranscriptEntry(preset, index = 0) {
19103
20957
  function appendPreviewTranscriptEntry(messages, preset) {
19104
20958
  return [...messages, createPreviewTranscriptEntry(preset, messages.length)];
19105
20959
  }
20960
+ function presetStreamsText(preset) {
20961
+ return preset === "assistant-message" || preset === "assistant-code-block" || preset === "assistant-markdown-table" || preset === "assistant-image";
20962
+ }
20963
+ function buildTranscriptStreamFrames(preset, suffix, options) {
20964
+ var _a, _b;
20965
+ const completed = createPreviewTranscriptEntry(preset, suffix);
20966
+ if (!presetStreamsText(preset) || typeof completed.content !== "string") {
20967
+ return [{ message: completed, delayMs: 0, done: true }];
20968
+ }
20969
+ const chunkSize = Math.max(1, (_a = options == null ? void 0 : options.chunkSize) != null ? _a : 24);
20970
+ const delayMs = Math.max(0, (_b = options == null ? void 0 : options.delayMs) != null ? _b : 42);
20971
+ const fullText = completed.content;
20972
+ const frames = [];
20973
+ frames.push({
20974
+ message: { ...completed, content: "", streaming: true },
20975
+ delayMs: 0,
20976
+ done: false
20977
+ });
20978
+ for (let i = chunkSize; i < fullText.length; i += chunkSize) {
20979
+ frames.push({
20980
+ message: { ...completed, content: fullText.slice(0, i), streaming: true },
20981
+ delayMs,
20982
+ done: false
20983
+ });
20984
+ }
20985
+ frames.push({
20986
+ message: { ...completed, content: fullText, streaming: false },
20987
+ delayMs,
20988
+ done: true
20989
+ });
20990
+ return frames;
20991
+ }
19106
20992
  var createAdvancedTranscriptPreviewMessages = () => [
19107
20993
  {
19108
20994
  id: "preview-adv-1",
@@ -19553,6 +21439,7 @@ function createThemePreview(container, initialOptions) {
19553
21439
  buildPreviewConfigWithMessages,
19554
21440
  buildShellCss,
19555
21441
  buildSrcdoc,
21442
+ buildTranscriptStreamFrames,
19556
21443
  convertFromPx,
19557
21444
  convertToPx,
19558
21445
  createPreviewMessages,
@@ -19572,6 +21459,7 @@ function createThemePreview(container, initialOptions) {
19572
21459
  normalizeColorValue,
19573
21460
  paletteColorPath,
19574
21461
  parseCssValue,
21462
+ presetStreamsText,
19575
21463
  resolveRoleAssignment,
19576
21464
  resolveThemeColorPath,
19577
21465
  scopeSection,