@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
@@ -138,6 +138,19 @@ var DEFAULT_WIDGET_CONFIG = {
138
138
  previewMaxLines: 3,
139
139
  expandable: true,
140
140
  loadingAnimation: "none"
141
+ },
142
+ streamAnimation: {
143
+ type: "none",
144
+ placeholder: "none",
145
+ speed: 120,
146
+ duration: 1800
147
+ },
148
+ askUserQuestion: {
149
+ enabled: true,
150
+ slideInMs: 180,
151
+ freeTextLabel: "Other\u2026",
152
+ freeTextPlaceholder: "Type your answer\u2026",
153
+ submitLabel: "Send"
141
154
  }
142
155
  },
143
156
  suggestionChips: [
@@ -240,11 +253,15 @@ function mergeWithDefaults(config) {
240
253
  ...config.voiceRecognition
241
254
  },
242
255
  features: (() => {
243
- var _a2, _b2, _c2, _d2;
256
+ var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2;
244
257
  const da = (_a2 = DEFAULT_WIDGET_CONFIG.features) == null ? void 0 : _a2.artifacts;
245
258
  const ca = (_b2 = config.features) == null ? void 0 : _b2.artifacts;
246
259
  const dsb = (_c2 = DEFAULT_WIDGET_CONFIG.features) == null ? void 0 : _c2.scrollToBottom;
247
260
  const csb = (_d2 = config.features) == null ? void 0 : _d2.scrollToBottom;
261
+ const dsa = (_e2 = DEFAULT_WIDGET_CONFIG.features) == null ? void 0 : _e2.streamAnimation;
262
+ const csa = (_f2 = config.features) == null ? void 0 : _f2.streamAnimation;
263
+ const dau = (_g2 = DEFAULT_WIDGET_CONFIG.features) == null ? void 0 : _g2.askUserQuestion;
264
+ const cau = (_h2 = config.features) == null ? void 0 : _h2.askUserQuestion;
248
265
  const mergedArtifacts = da === void 0 && ca === void 0 ? void 0 : {
249
266
  ...da,
250
267
  ...ca,
@@ -257,11 +274,25 @@ function mergeWithDefaults(config) {
257
274
  ...dsb,
258
275
  ...csb
259
276
  };
277
+ const mergedStreamAnimation = dsa === void 0 && csa === void 0 ? void 0 : {
278
+ ...dsa,
279
+ ...csa
280
+ };
281
+ const mergedAskUserQuestion = dau === void 0 && cau === void 0 ? void 0 : {
282
+ ...dau,
283
+ ...cau,
284
+ styles: {
285
+ ...dau == null ? void 0 : dau.styles,
286
+ ...cau == null ? void 0 : cau.styles
287
+ }
288
+ };
260
289
  return {
261
290
  ...DEFAULT_WIDGET_CONFIG.features,
262
291
  ...config.features,
263
292
  ...mergedScrollToBottom !== void 0 ? { scrollToBottom: mergedScrollToBottom } : {},
264
- ...mergedArtifacts !== void 0 ? { artifacts: mergedArtifacts } : {}
293
+ ...mergedArtifacts !== void 0 ? { artifacts: mergedArtifacts } : {},
294
+ ...mergedStreamAnimation !== void 0 ? { streamAnimation: mergedStreamAnimation } : {},
295
+ ...mergedAskUserQuestion !== void 0 ? { askUserQuestion: mergedAskUserQuestion } : {}
265
296
  };
266
297
  })(),
267
298
  suggestionChips: (_e = config.suggestionChips) != null ? _e : DEFAULT_WIDGET_CONFIG.suggestionChips,
@@ -612,6 +643,14 @@ var DEFAULT_COMPONENTS = {
612
643
  },
613
644
  border: "semantic.colors.border"
614
645
  },
646
+ introCard: {
647
+ // Defaults preserve the legacy `persona-shadow-sm` look exactly so existing
648
+ // pages render unchanged when no token is set.
649
+ background: "semantic.colors.surface",
650
+ borderRadius: "palette.radius.2xl",
651
+ padding: "semantic.spacing.lg",
652
+ shadow: "0 5px 15px rgba(15, 23, 42, 0.08)"
653
+ },
615
654
  toolBubble: {
616
655
  shadow: "palette.shadows.sm"
617
656
  },
@@ -888,7 +927,7 @@ function createTheme(userConfig, options = {}) {
888
927
  return theme;
889
928
  }
890
929
  function themeToCssVariables(theme) {
891
- 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;
930
+ 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;
892
931
  const resolved = resolveTokens(theme);
893
932
  const cssVars = {};
894
933
  for (const [path, token] of Object.entries(resolved)) {
@@ -952,31 +991,36 @@ function themeToCssVariables(theme) {
952
991
  const headerTokens = (_ea = theme.components) == null ? void 0 : _ea.header;
953
992
  if (headerTokens == null ? void 0 : headerTokens.shadow) cssVars["--persona-header-shadow"] = headerTokens.shadow;
954
993
  if (headerTokens == null ? void 0 : headerTokens.borderBottom) cssVars["--persona-header-border-bottom"] = headerTokens.borderBottom;
955
- cssVars["--persona-input-background"] = (_fa = cssVars["--persona-components-input-background"]) != null ? _fa : cssVars["--persona-surface"];
956
- cssVars["--persona-input-placeholder"] = (_ga = cssVars["--persona-components-input-placeholder"]) != null ? _ga : cssVars["--persona-text-muted"];
957
- cssVars["--persona-message-user-bg"] = (_ha = cssVars["--persona-components-message-user-background"]) != null ? _ha : cssVars["--persona-accent"];
958
- cssVars["--persona-message-user-text"] = (_ia = cssVars["--persona-components-message-user-text"]) != null ? _ia : cssVars["--persona-text-inverse"];
959
- cssVars["--persona-message-user-shadow"] = (_ja = cssVars["--persona-components-message-user-shadow"]) != null ? _ja : "0 5px 15px rgba(15, 23, 42, 0.08)";
960
- cssVars["--persona-message-assistant-bg"] = (_ka = cssVars["--persona-components-message-assistant-background"]) != null ? _ka : cssVars["--persona-surface"];
961
- cssVars["--persona-message-assistant-text"] = (_la = cssVars["--persona-components-message-assistant-text"]) != null ? _la : cssVars["--persona-text"];
962
- cssVars["--persona-message-assistant-border"] = (_ma = cssVars["--persona-components-message-assistant-border"]) != null ? _ma : cssVars["--persona-border"];
963
- cssVars["--persona-message-assistant-shadow"] = (_na = cssVars["--persona-components-message-assistant-shadow"]) != null ? _na : "0 1px 2px 0 rgb(0 0 0 / 0.05)";
964
- 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"];
965
- 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"];
966
- cssVars["--persona-scroll-to-bottom-border"] = (_sa = cssVars["--persona-components-scrollToBottom-border"]) != null ? _sa : cssVars["--persona-primary"];
967
- cssVars["--persona-scroll-to-bottom-size"] = (_ta = cssVars["--persona-components-scrollToBottom-size"]) != null ? _ta : "40px";
968
- 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";
969
- 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)";
970
- cssVars["--persona-scroll-to-bottom-padding"] = (_za = cssVars["--persona-components-scrollToBottom-padding"]) != null ? _za : "0.5rem 0.875rem";
971
- cssVars["--persona-scroll-to-bottom-gap"] = (_Aa = cssVars["--persona-components-scrollToBottom-gap"]) != null ? _Aa : "0.5rem";
972
- 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";
973
- cssVars["--persona-scroll-to-bottom-icon-size"] = (_Da = cssVars["--persona-components-scrollToBottom-iconSize"]) != null ? _Da : "14px";
974
- cssVars["--persona-tool-bubble-shadow"] = (_Ea = cssVars["--persona-components-toolBubble-shadow"]) != null ? _Ea : "0 5px 15px rgba(15, 23, 42, 0.08)";
975
- cssVars["--persona-reasoning-bubble-shadow"] = (_Fa = cssVars["--persona-components-reasoningBubble-shadow"]) != null ? _Fa : "0 5px 15px rgba(15, 23, 42, 0.08)";
976
- cssVars["--persona-composer-shadow"] = (_Ga = cssVars["--persona-components-composer-shadow"]) != null ? _Ga : "none";
977
- cssVars["--persona-md-inline-code-bg"] = (_Ha = cssVars["--persona-components-markdown-inlineCode-background"]) != null ? _Ha : cssVars["--persona-container"];
978
- cssVars["--persona-md-inline-code-color"] = (_Ia = cssVars["--persona-components-markdown-inlineCode-foreground"]) != null ? _Ia : cssVars["--persona-text"];
979
- cssVars["--persona-md-link-color"] = (_Ka = (_Ja = cssVars["--persona-components-markdown-link-foreground"]) != null ? _Ja : cssVars["--persona-accent"]) != null ? _Ka : "#0f0f0f";
994
+ const introCardTokens = (_fa = theme.components) == null ? void 0 : _fa.introCard;
995
+ cssVars["--persona-intro-card-bg"] = (_ga = cssVars["--persona-components-introCard-background"]) != null ? _ga : cssVars["--persona-surface"];
996
+ cssVars["--persona-intro-card-radius"] = (_ha = cssVars["--persona-components-introCard-borderRadius"]) != null ? _ha : "1rem";
997
+ cssVars["--persona-intro-card-padding"] = (_ia = cssVars["--persona-components-introCard-padding"]) != null ? _ia : "1.5rem";
998
+ 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)";
999
+ cssVars["--persona-input-background"] = (_la = cssVars["--persona-components-input-background"]) != null ? _la : cssVars["--persona-surface"];
1000
+ cssVars["--persona-input-placeholder"] = (_ma = cssVars["--persona-components-input-placeholder"]) != null ? _ma : cssVars["--persona-text-muted"];
1001
+ cssVars["--persona-message-user-bg"] = (_na = cssVars["--persona-components-message-user-background"]) != null ? _na : cssVars["--persona-accent"];
1002
+ cssVars["--persona-message-user-text"] = (_oa = cssVars["--persona-components-message-user-text"]) != null ? _oa : cssVars["--persona-text-inverse"];
1003
+ cssVars["--persona-message-user-shadow"] = (_pa = cssVars["--persona-components-message-user-shadow"]) != null ? _pa : "0 5px 15px rgba(15, 23, 42, 0.08)";
1004
+ cssVars["--persona-message-assistant-bg"] = (_qa = cssVars["--persona-components-message-assistant-background"]) != null ? _qa : cssVars["--persona-surface"];
1005
+ cssVars["--persona-message-assistant-text"] = (_ra = cssVars["--persona-components-message-assistant-text"]) != null ? _ra : cssVars["--persona-text"];
1006
+ cssVars["--persona-message-assistant-border"] = (_sa = cssVars["--persona-components-message-assistant-border"]) != null ? _sa : cssVars["--persona-border"];
1007
+ cssVars["--persona-message-assistant-shadow"] = (_ta = cssVars["--persona-components-message-assistant-shadow"]) != null ? _ta : "0 1px 2px 0 rgb(0 0 0 / 0.05)";
1008
+ 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"];
1009
+ 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"];
1010
+ cssVars["--persona-scroll-to-bottom-border"] = (_ya = cssVars["--persona-components-scrollToBottom-border"]) != null ? _ya : cssVars["--persona-primary"];
1011
+ cssVars["--persona-scroll-to-bottom-size"] = (_za = cssVars["--persona-components-scrollToBottom-size"]) != null ? _za : "40px";
1012
+ 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";
1013
+ 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)";
1014
+ cssVars["--persona-scroll-to-bottom-padding"] = (_Fa = cssVars["--persona-components-scrollToBottom-padding"]) != null ? _Fa : "0.5rem 0.875rem";
1015
+ cssVars["--persona-scroll-to-bottom-gap"] = (_Ga = cssVars["--persona-components-scrollToBottom-gap"]) != null ? _Ga : "0.5rem";
1016
+ 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";
1017
+ cssVars["--persona-scroll-to-bottom-icon-size"] = (_Ja = cssVars["--persona-components-scrollToBottom-iconSize"]) != null ? _Ja : "14px";
1018
+ cssVars["--persona-tool-bubble-shadow"] = (_Ka = cssVars["--persona-components-toolBubble-shadow"]) != null ? _Ka : "0 5px 15px rgba(15, 23, 42, 0.08)";
1019
+ cssVars["--persona-reasoning-bubble-shadow"] = (_La = cssVars["--persona-components-reasoningBubble-shadow"]) != null ? _La : "0 5px 15px rgba(15, 23, 42, 0.08)";
1020
+ cssVars["--persona-composer-shadow"] = (_Ma = cssVars["--persona-components-composer-shadow"]) != null ? _Ma : "none";
1021
+ cssVars["--persona-md-inline-code-bg"] = (_Na = cssVars["--persona-components-markdown-inlineCode-background"]) != null ? _Na : cssVars["--persona-container"];
1022
+ cssVars["--persona-md-inline-code-color"] = (_Oa = cssVars["--persona-components-markdown-inlineCode-foreground"]) != null ? _Oa : cssVars["--persona-text"];
1023
+ cssVars["--persona-md-link-color"] = (_Qa = (_Pa = cssVars["--persona-components-markdown-link-foreground"]) != null ? _Pa : cssVars["--persona-accent"]) != null ? _Qa : "#0f0f0f";
980
1024
  const mdH1Size = cssVars["--persona-components-markdown-heading-h1-fontSize"];
981
1025
  if (mdH1Size) cssVars["--persona-md-h1-size"] = mdH1Size;
982
1026
  const mdH1Weight = cssVars["--persona-components-markdown-heading-h1-fontWeight"];
@@ -989,19 +1033,19 @@ function themeToCssVariables(theme) {
989
1033
  if (mdProseFont && mdProseFont !== "inherit") {
990
1034
  cssVars["--persona-md-prose-font-family"] = mdProseFont;
991
1035
  }
992
- cssVars["--persona-md-code-block-bg"] = (_La = cssVars["--persona-components-markdown-codeBlock-background"]) != null ? _La : cssVars["--persona-container"];
993
- cssVars["--persona-md-code-block-border-color"] = (_Ma = cssVars["--persona-components-markdown-codeBlock-borderColor"]) != null ? _Ma : cssVars["--persona-border"];
994
- cssVars["--persona-md-code-block-text-color"] = (_Na = cssVars["--persona-components-markdown-codeBlock-textColor"]) != null ? _Na : "inherit";
995
- cssVars["--persona-md-table-header-bg"] = (_Oa = cssVars["--persona-components-markdown-table-headerBackground"]) != null ? _Oa : cssVars["--persona-container"];
996
- cssVars["--persona-md-table-border-color"] = (_Pa = cssVars["--persona-components-markdown-table-borderColor"]) != null ? _Pa : cssVars["--persona-border"];
997
- cssVars["--persona-md-hr-color"] = (_Qa = cssVars["--persona-components-markdown-hr-color"]) != null ? _Qa : cssVars["--persona-divider"];
998
- cssVars["--persona-md-blockquote-border-color"] = (_Ra = cssVars["--persona-components-markdown-blockquote-borderColor"]) != null ? _Ra : cssVars["--persona-palette-colors-gray-900"];
999
- cssVars["--persona-md-blockquote-bg"] = (_Sa = cssVars["--persona-components-markdown-blockquote-background"]) != null ? _Sa : "transparent";
1000
- cssVars["--persona-md-blockquote-text-color"] = (_Ta = cssVars["--persona-components-markdown-blockquote-textColor"]) != null ? _Ta : cssVars["--persona-palette-colors-gray-500"];
1001
- cssVars["--cw-container"] = (_Ua = cssVars["--persona-components-collapsibleWidget-container"]) != null ? _Ua : cssVars["--persona-surface"];
1002
- cssVars["--cw-surface"] = (_Va = cssVars["--persona-components-collapsibleWidget-surface"]) != null ? _Va : cssVars["--persona-surface"];
1003
- cssVars["--cw-border"] = (_Wa = cssVars["--persona-components-collapsibleWidget-border"]) != null ? _Wa : cssVars["--persona-border"];
1004
- cssVars["--persona-message-border"] = (_Xa = cssVars["--persona-components-message-border"]) != null ? _Xa : cssVars["--persona-border"];
1036
+ cssVars["--persona-md-code-block-bg"] = (_Ra = cssVars["--persona-components-markdown-codeBlock-background"]) != null ? _Ra : cssVars["--persona-container"];
1037
+ cssVars["--persona-md-code-block-border-color"] = (_Sa = cssVars["--persona-components-markdown-codeBlock-borderColor"]) != null ? _Sa : cssVars["--persona-border"];
1038
+ cssVars["--persona-md-code-block-text-color"] = (_Ta = cssVars["--persona-components-markdown-codeBlock-textColor"]) != null ? _Ta : "inherit";
1039
+ cssVars["--persona-md-table-header-bg"] = (_Ua = cssVars["--persona-components-markdown-table-headerBackground"]) != null ? _Ua : cssVars["--persona-container"];
1040
+ cssVars["--persona-md-table-border-color"] = (_Va = cssVars["--persona-components-markdown-table-borderColor"]) != null ? _Va : cssVars["--persona-border"];
1041
+ cssVars["--persona-md-hr-color"] = (_Wa = cssVars["--persona-components-markdown-hr-color"]) != null ? _Wa : cssVars["--persona-divider"];
1042
+ cssVars["--persona-md-blockquote-border-color"] = (_Xa = cssVars["--persona-components-markdown-blockquote-borderColor"]) != null ? _Xa : cssVars["--persona-palette-colors-gray-900"];
1043
+ cssVars["--persona-md-blockquote-bg"] = (_Ya = cssVars["--persona-components-markdown-blockquote-background"]) != null ? _Ya : "transparent";
1044
+ cssVars["--persona-md-blockquote-text-color"] = (_Za = cssVars["--persona-components-markdown-blockquote-textColor"]) != null ? _Za : cssVars["--persona-palette-colors-gray-500"];
1045
+ cssVars["--cw-container"] = (__a = cssVars["--persona-components-collapsibleWidget-container"]) != null ? __a : cssVars["--persona-surface"];
1046
+ cssVars["--cw-surface"] = (_$a = cssVars["--persona-components-collapsibleWidget-surface"]) != null ? _$a : cssVars["--persona-surface"];
1047
+ cssVars["--cw-border"] = (_ab = cssVars["--persona-components-collapsibleWidget-border"]) != null ? _ab : cssVars["--persona-border"];
1048
+ cssVars["--persona-message-border"] = (_bb = cssVars["--persona-components-message-border"]) != null ? _bb : cssVars["--persona-border"];
1005
1049
  const components = theme.components;
1006
1050
  const iconBtn = components == null ? void 0 : components.iconButton;
1007
1051
  if (iconBtn) {
@@ -1048,23 +1092,23 @@ function themeToCssVariables(theme) {
1048
1092
  if (t.copyPadding) cssVars["--persona-artifact-toolbar-copy-padding"] = t.copyPadding;
1049
1093
  if (t.copyMenuBackground) {
1050
1094
  cssVars["--persona-artifact-toolbar-copy-menu-bg"] = t.copyMenuBackground;
1051
- cssVars["--persona-dropdown-bg"] = (_Ya = cssVars["--persona-dropdown-bg"]) != null ? _Ya : t.copyMenuBackground;
1095
+ cssVars["--persona-dropdown-bg"] = (_cb = cssVars["--persona-dropdown-bg"]) != null ? _cb : t.copyMenuBackground;
1052
1096
  }
1053
1097
  if (t.copyMenuBorder) {
1054
1098
  cssVars["--persona-artifact-toolbar-copy-menu-border"] = t.copyMenuBorder;
1055
- cssVars["--persona-dropdown-border"] = (_Za = cssVars["--persona-dropdown-border"]) != null ? _Za : t.copyMenuBorder;
1099
+ cssVars["--persona-dropdown-border"] = (_db = cssVars["--persona-dropdown-border"]) != null ? _db : t.copyMenuBorder;
1056
1100
  }
1057
1101
  if (t.copyMenuShadow) {
1058
1102
  cssVars["--persona-artifact-toolbar-copy-menu-shadow"] = t.copyMenuShadow;
1059
- cssVars["--persona-dropdown-shadow"] = (__a = cssVars["--persona-dropdown-shadow"]) != null ? __a : t.copyMenuShadow;
1103
+ cssVars["--persona-dropdown-shadow"] = (_eb = cssVars["--persona-dropdown-shadow"]) != null ? _eb : t.copyMenuShadow;
1060
1104
  }
1061
1105
  if (t.copyMenuBorderRadius) {
1062
1106
  cssVars["--persona-artifact-toolbar-copy-menu-radius"] = t.copyMenuBorderRadius;
1063
- cssVars["--persona-dropdown-radius"] = (_$a = cssVars["--persona-dropdown-radius"]) != null ? _$a : t.copyMenuBorderRadius;
1107
+ cssVars["--persona-dropdown-radius"] = (_fb = cssVars["--persona-dropdown-radius"]) != null ? _fb : t.copyMenuBorderRadius;
1064
1108
  }
1065
1109
  if (t.copyMenuItemHoverBackground) {
1066
1110
  cssVars["--persona-artifact-toolbar-copy-menu-item-hover-bg"] = t.copyMenuItemHoverBackground;
1067
- cssVars["--persona-dropdown-item-hover-bg"] = (_ab = cssVars["--persona-dropdown-item-hover-bg"]) != null ? _ab : t.copyMenuItemHoverBackground;
1111
+ cssVars["--persona-dropdown-item-hover-bg"] = (_gb = cssVars["--persona-dropdown-item-hover-bg"]) != null ? _gb : t.copyMenuItemHoverBackground;
1068
1112
  }
1069
1113
  if (t.iconBackground) cssVars["--persona-artifact-toolbar-icon-bg"] = t.iconBackground;
1070
1114
  if (t.toolbarBorder) cssVars["--persona-artifact-toolbar-border"] = t.toolbarBorder;
@@ -1084,7 +1128,7 @@ function themeToCssVariables(theme) {
1084
1128
  if (artifact == null ? void 0 : artifact.pane) {
1085
1129
  const t = artifact.pane;
1086
1130
  if (t.toolbarBackground) {
1087
- const toolbarBg = (_bb = resolveTokenValue(theme, t.toolbarBackground)) != null ? _bb : t.toolbarBackground;
1131
+ const toolbarBg = (_hb = resolveTokenValue(theme, t.toolbarBackground)) != null ? _hb : t.toolbarBackground;
1088
1132
  cssVars["--persona-artifact-toolbar-bg"] = toolbarBg;
1089
1133
  }
1090
1134
  }
@@ -2564,6 +2608,91 @@ var featuresSectionDef = {
2564
2608
  { id: "feat-scroll-bottom-label", label: "Scroll To Bottom Label", description: "Leave empty for icon-only mode", type: "text", path: "features.scrollToBottom.label", defaultValue: "" }
2565
2609
  ]
2566
2610
  };
2611
+ var streamAnimationSectionDef = {
2612
+ id: "stream-animation",
2613
+ title: "Stream Animation",
2614
+ description: "Control how assistant text appears while streaming.",
2615
+ collapsed: true,
2616
+ fields: [
2617
+ {
2618
+ id: "stream-anim-type",
2619
+ label: "Animation",
2620
+ description: "Reveal effect applied to each assistant reply as it streams.",
2621
+ type: "select",
2622
+ path: "features.streamAnimation.type",
2623
+ defaultValue: "none",
2624
+ options: [
2625
+ { value: "none", label: "None" },
2626
+ { value: "typewriter", label: "Typewriter" },
2627
+ { value: "word-fade", label: "Word fade" },
2628
+ { value: "letter-rise", label: "Letter rise" },
2629
+ { value: "glyph-cycle", label: "Glyph cycle" },
2630
+ { value: "wipe", label: "Wipe" },
2631
+ { value: "pop-bubble", label: "Pop bubble" }
2632
+ ]
2633
+ },
2634
+ {
2635
+ id: "stream-anim-placeholder",
2636
+ label: "Pre-first-token Placeholder",
2637
+ description: "What to show before the first token arrives.",
2638
+ type: "select",
2639
+ path: "features.streamAnimation.placeholder",
2640
+ defaultValue: "none",
2641
+ options: [
2642
+ { value: "none", label: "Typing indicator (default)" },
2643
+ { value: "skeleton", label: "Skeleton shimmer" }
2644
+ ]
2645
+ },
2646
+ {
2647
+ id: "stream-anim-buffer",
2648
+ label: "Content Buffering",
2649
+ description: "Trim in-progress units so only complete words/lines reveal.",
2650
+ type: "select",
2651
+ path: "features.streamAnimation.buffer",
2652
+ defaultValue: "none",
2653
+ options: [
2654
+ { value: "none", label: "None \u2014 stream every character" },
2655
+ { value: "word", label: "Word \u2014 hold until whitespace" },
2656
+ { value: "line", label: "Line \u2014 hold until newline" }
2657
+ ]
2658
+ },
2659
+ {
2660
+ id: "stream-anim-speed",
2661
+ label: "Per-unit Duration (ms)",
2662
+ description: "Animation length for each character or word.",
2663
+ type: "select",
2664
+ path: "features.streamAnimation.speed",
2665
+ defaultValue: 120,
2666
+ options: [
2667
+ { value: "40", label: "40ms \u2014 snappy" },
2668
+ { value: "80", label: "80ms" },
2669
+ { value: "120", label: "120ms (default)" },
2670
+ { value: "200", label: "200ms" },
2671
+ { value: "320", label: "320ms" },
2672
+ { value: "480", label: "480ms \u2014 slow" }
2673
+ ],
2674
+ formatValue: (v) => String(v != null ? v : 120),
2675
+ parseValue: (v) => Number(v)
2676
+ },
2677
+ {
2678
+ id: "stream-anim-duration",
2679
+ label: "Container Duration (ms)",
2680
+ description: "Length of container-level effects (pop-bubble, custom plugins).",
2681
+ type: "select",
2682
+ path: "features.streamAnimation.duration",
2683
+ defaultValue: 1800,
2684
+ options: [
2685
+ { value: "600", label: "600ms" },
2686
+ { value: "1200", label: "1200ms" },
2687
+ { value: "1800", label: "1800ms (default)" },
2688
+ { value: "2400", label: "2400ms" },
2689
+ { value: "3600", label: "3600ms \u2014 slow" }
2690
+ ],
2691
+ formatValue: (v) => String(v != null ? v : 1800),
2692
+ parseValue: (v) => Number(v)
2693
+ }
2694
+ ]
2695
+ };
2567
2696
  var attachmentsSectionDef = {
2568
2697
  id: "attachments-config",
2569
2698
  title: "Attachments",
@@ -2647,7 +2776,7 @@ var CONFIGURE_SUB_GROUPS = [
2647
2776
  { label: "Content", sections: [copySectionDef, suggestionsSectionDef] },
2648
2777
  { label: "Layout", sections: [generalLayoutSectionDef, headerLayoutSectionDef, messagesLayoutSectionDef, messageActionsSectionDef] },
2649
2778
  { label: "Widget", sections: [launcherBasicsSectionDef, launcherAdvancedSectionDef, sendButtonSectionDef, closeButtonSectionDef, clearChatSectionDef, statusIndicatorSectionDef] },
2650
- { label: "Features", sections: [featuresSectionDef, attachmentsSectionDef, artifactsSectionDef, artifactCustomizationSectionDef] },
2779
+ { label: "Features", sections: [featuresSectionDef, streamAnimationSectionDef, attachmentsSectionDef, artifactsSectionDef, artifactCustomizationSectionDef] },
2651
2780
  { label: "Developer", collapsedByDefault: true, sections: [apiIntegrationSectionDef, debugSectionDef, markdownSectionDef] }
2652
2781
  ];
2653
2782
  var CONFIGURE_SECTIONS = CONFIGURE_SUB_GROUPS.flatMap((g) => g.sections);
@@ -4136,6 +4265,40 @@ var AgentWidgetClient = class {
4136
4265
  })
4137
4266
  });
4138
4267
  }
4268
+ /**
4269
+ * Resume a paused flow execution by supplying outputs for LOCAL
4270
+ * (client-executed) tools. Used by the built-in `ask_user_question`
4271
+ * answer-pill sheet, but generic enough for any LOCAL tool.
4272
+ *
4273
+ * Posts to the upstream `/resume` endpoint (the dispatch URL with
4274
+ * `/dispatch` replaced by `/resume` — works for both direct-to-Runtype
4275
+ * and the persona proxy) and returns the raw Response so the caller can
4276
+ * pipe its SSE body through `connectStream()`.
4277
+ *
4278
+ * @param executionId - The paused execution id carried on `step_await`.
4279
+ * @param toolOutputs - Map keyed by tool name → the tool's result value.
4280
+ */
4281
+ async resumeFlow(executionId, toolOutputs, options) {
4282
+ var _a, _b;
4283
+ const trimmed = ((_a = this.config.apiUrl) == null ? void 0 : _a.replace(/\/+$/, "")) || DEFAULT_CLIENT_API_BASE;
4284
+ const url = `${trimmed}/resume`;
4285
+ let headers = {
4286
+ "Content-Type": "application/json",
4287
+ ...this.headers
4288
+ };
4289
+ if (this.getHeaders) {
4290
+ Object.assign(headers, await this.getHeaders());
4291
+ }
4292
+ return fetch(url, {
4293
+ method: "POST",
4294
+ headers,
4295
+ body: JSON.stringify({
4296
+ executionId,
4297
+ toolOutputs,
4298
+ streamResponse: (_b = options == null ? void 0 : options.streamResponse) != null ? _b : true
4299
+ })
4300
+ });
4301
+ }
4139
4302
  async buildAgentPayload(messages) {
4140
4303
  if (!this.config.agent) {
4141
4304
  throw new Error("Agent configuration required for agent mode");
@@ -4697,7 +4860,7 @@ var AgentWidgetClient = class {
4697
4860
  const agentIterationMessages = /* @__PURE__ */ new Map();
4698
4861
  const iterationDisplay = (_a = this.config.iterationDisplay) != null ? _a : "separate";
4699
4862
  drainReadyQueue = () => {
4700
- 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;
4863
+ 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;
4701
4864
  for (let i = 0; i < seqReadyQueue.length; i++) {
4702
4865
  const payloadType = seqReadyQueue[i].payloadType;
4703
4866
  const payload = seqReadyQueue[i].payload;
@@ -4869,8 +5032,26 @@ var AgentWidgetClient = class {
4869
5032
  if (callKey) {
4870
5033
  toolContext.byCall.delete(callKey);
4871
5034
  }
5035
+ } else if (payloadType === "step_await" && payload.awaitReason === "local_tool_required" && payload.toolName) {
5036
+ const toolId = (_X = payload.toolId) != null ? _X : `local-${nextSequence()}`;
5037
+ const toolMessage = ensureToolMessage(toolId);
5038
+ const tool = (_Y = toolMessage.toolCall) != null ? _Y : { id: toolId, status: "pending" };
5039
+ tool.name = payload.toolName;
5040
+ tool.args = payload.parameters;
5041
+ tool.status = "complete";
5042
+ tool.chunks = (_Z = tool.chunks) != null ? _Z : [];
5043
+ tool.startedAt = (_$ = tool.startedAt) != null ? _$ : resolveTimestamp((__ = payload.startedAt) != null ? __ : payload.timestamp);
5044
+ tool.completedAt = (_aa = tool.completedAt) != null ? _aa : tool.startedAt;
5045
+ toolMessage.toolCall = tool;
5046
+ toolMessage.streaming = false;
5047
+ toolMessage.agentMetadata = {
5048
+ ...toolMessage.agentMetadata,
5049
+ executionId: (_ca = payload.executionId) != null ? _ca : (_ba = toolMessage.agentMetadata) == null ? void 0 : _ba.executionId,
5050
+ awaitingLocalTool: true
5051
+ };
5052
+ emitMessage(toolMessage);
4872
5053
  } else if (payloadType === "text_start") {
4873
- if ((_X = payload.toolContext) == null ? void 0 : _X.toolId) {
5054
+ if ((_da = payload.toolContext) == null ? void 0 : _da.toolId) {
4874
5055
  continue;
4875
5056
  }
4876
5057
  const incomingPartId = payload.partId;
@@ -4888,7 +5069,7 @@ var AgentWidgetClient = class {
4888
5069
  partIdState.current = incomingPartId;
4889
5070
  }
4890
5071
  } else if (payloadType === "text_end") {
4891
- if ((_Y = payload.toolContext) == null ? void 0 : _Y.toolId) {
5072
+ if ((_ea = payload.toolContext) == null ? void 0 : _ea.toolId) {
4892
5073
  continue;
4893
5074
  }
4894
5075
  const prev = assistantMessage;
@@ -4908,7 +5089,7 @@ var AgentWidgetClient = class {
4908
5089
  const nestedToolCtx = payload.toolContext;
4909
5090
  if (nestedToolCtx == null ? void 0 : nestedToolCtx.toolId) {
4910
5091
  const nestedStepId = String(
4911
- (__ = (_Z = payload.id) != null ? _Z : nestedToolCtx.stepId) != null ? __ : `step-${nextSequence()}`
5092
+ (_ga = (_fa = payload.id) != null ? _fa : nestedToolCtx.stepId) != null ? _ga : `step-${nextSequence()}`
4912
5093
  );
4913
5094
  const incomingPartId2 = payload.partId !== void 0 && payload.partId !== null ? String(payload.partId) : "";
4914
5095
  const stepScopeKey = `${nestedToolCtx.toolId}::${nestedStepId}`;
@@ -4935,7 +5116,7 @@ var AgentWidgetClient = class {
4935
5116
  incomingPartId2,
4936
5117
  nestedToolCtx.executionId
4937
5118
  );
4938
- const nestedChunk = (_ca = (_ba = (_aa = (_$ = payload.text) != null ? _$ : payload.delta) != null ? _aa : payload.content) != null ? _ba : payload.chunk) != null ? _ca : "";
5119
+ const nestedChunk = (_ka = (_ja = (_ia = (_ha = payload.text) != null ? _ha : payload.delta) != null ? _ia : payload.content) != null ? _ja : payload.chunk) != null ? _ka : "";
4939
5120
  if (nestedChunk) {
4940
5121
  nestedMsg.content += String(nestedChunk);
4941
5122
  nestedMsg.streaming = true;
@@ -4961,18 +5142,18 @@ var AgentWidgetClient = class {
4961
5142
  if (incomingPartId !== void 0) {
4962
5143
  partIdState.current = incomingPartId;
4963
5144
  }
4964
- const assistant = incomingPartId !== void 0 ? (_da = assistantMessagesByPartId.get(incomingPartId)) != null ? _da : ensureAssistantMessage() : ensureAssistantMessage();
5145
+ const assistant = incomingPartId !== void 0 ? (_la = assistantMessagesByPartId.get(incomingPartId)) != null ? _la : ensureAssistantMessage() : ensureAssistantMessage();
4965
5146
  if (incomingPartId !== void 0) {
4966
5147
  if (!assistant.partId) {
4967
5148
  assistant.partId = incomingPartId;
4968
5149
  }
4969
5150
  assistantMessagesByPartId.set(incomingPartId, assistant);
4970
5151
  }
4971
- const chunk = (_ha = (_ga = (_fa = (_ea = payload.text) != null ? _ea : payload.delta) != null ? _fa : payload.content) != null ? _ga : payload.chunk) != null ? _ha : "";
5152
+ const chunk = (_pa = (_oa = (_na = (_ma = payload.text) != null ? _ma : payload.delta) != null ? _na : payload.content) != null ? _oa : payload.chunk) != null ? _pa : "";
4972
5153
  if (chunk) {
4973
5154
  const chunkSeq = typeof payload.seq === "number" ? payload.seq : void 0;
4974
5155
  const chunkBufferKey = incomingPartId != null ? incomingPartId : assistant.id;
4975
- const accumulatedRaw = chunkSeq !== void 0 ? insertOrderedChunk(chunkBufferKey, chunkSeq, String(chunk)) : ((_ia = rawContentBuffers.get(assistant.id)) != null ? _ia : "") + chunk;
5156
+ const accumulatedRaw = chunkSeq !== void 0 ? insertOrderedChunk(chunkBufferKey, chunkSeq, String(chunk)) : ((_qa = rawContentBuffers.get(assistant.id)) != null ? _qa : "") + chunk;
4976
5157
  assistant.rawContent = accumulatedRaw;
4977
5158
  if (!streamParsers.has(assistant.id)) {
4978
5159
  streamParsers.set(assistant.id, this.createStreamParser());
@@ -5018,7 +5199,7 @@ var AgentWidgetClient = class {
5018
5199
  emitMessage(assistant);
5019
5200
  });
5020
5201
  } else {
5021
- const text = typeof parsedResult === "string" ? parsedResult : (_ja = parsedResult == null ? void 0 : parsedResult.text) != null ? _ja : null;
5202
+ const text = typeof parsedResult === "string" ? parsedResult : (_ra = parsedResult == null ? void 0 : parsedResult.text) != null ? _ra : null;
5022
5203
  if (text !== null && text.trim() !== "") {
5023
5204
  assistant.content = text;
5024
5205
  emitMessage(assistant);
@@ -5032,7 +5213,7 @@ var AgentWidgetClient = class {
5032
5213
  }
5033
5214
  }
5034
5215
  if (payload.isComplete) {
5035
- const finalContent = (_la = (_ka = payload.result) == null ? void 0 : _ka.response) != null ? _la : assistant.content;
5216
+ const finalContent = (_ta = (_sa = payload.result) == null ? void 0 : _sa.response) != null ? _ta : assistant.content;
5036
5217
  if (finalContent) {
5037
5218
  const rawBuffer = rawContentBuffers.get(assistant.id);
5038
5219
  const contentToProcess = rawBuffer != null ? rawBuffer : ensureStringContent(finalContent);
@@ -5064,7 +5245,7 @@ var AgentWidgetClient = class {
5064
5245
  }
5065
5246
  });
5066
5247
  } else {
5067
- extractedText = typeof parsedResult === "string" ? parsedResult : (_ma = parsedResult == null ? void 0 : parsedResult.text) != null ? _ma : null;
5248
+ extractedText = typeof parsedResult === "string" ? parsedResult : (_ua = parsedResult == null ? void 0 : parsedResult.text) != null ? _ua : null;
5068
5249
  }
5069
5250
  }
5070
5251
  }
@@ -5076,7 +5257,7 @@ var AgentWidgetClient = class {
5076
5257
  }
5077
5258
  const parserToClose = streamParsers.get(assistant.id);
5078
5259
  if (parserToClose) {
5079
- const closeResult = (_na = parserToClose.close) == null ? void 0 : _na.call(parserToClose);
5260
+ const closeResult = (_va = parserToClose.close) == null ? void 0 : _va.call(parserToClose);
5080
5261
  if (closeResult instanceof Promise) {
5081
5262
  closeResult.catch(() => {
5082
5263
  });
@@ -5098,7 +5279,7 @@ var AgentWidgetClient = class {
5098
5279
  const nestedCompleteCtx = payload.toolContext;
5099
5280
  if (nestedCompleteCtx == null ? void 0 : nestedCompleteCtx.toolId) {
5100
5281
  const nestedStepId = String(
5101
- (_pa = (_oa = payload.id) != null ? _oa : nestedCompleteCtx.stepId) != null ? _pa : ""
5282
+ (_xa = (_wa = payload.id) != null ? _wa : nestedCompleteCtx.stepId) != null ? _xa : ""
5102
5283
  );
5103
5284
  if (nestedStepId) {
5104
5285
  const prefix = getNestedStepPrefix(
@@ -5117,9 +5298,11 @@ var AgentWidgetClient = class {
5117
5298
  }
5118
5299
  continue;
5119
5300
  }
5301
+ const stepStopReason = payload.stopReason;
5120
5302
  if (didSplitByPartId) {
5121
5303
  if (assistantMessage !== null) {
5122
5304
  const msg = assistantMessage;
5305
+ if (stepStopReason) msg.stopReason = stepStopReason;
5123
5306
  streamParsers.delete(msg.id);
5124
5307
  rawContentBuffers.delete(msg.id);
5125
5308
  if (msg.streaming !== false) {
@@ -5127,9 +5310,10 @@ var AgentWidgetClient = class {
5127
5310
  emitMessage(msg);
5128
5311
  }
5129
5312
  }
5130
- const splitFinalContent = (_qa = payload.result) == null ? void 0 : _qa.response;
5313
+ const splitFinalContent = (_ya = payload.result) == null ? void 0 : _ya.response;
5131
5314
  const sealedForReconcile = lastSealedTextSegment;
5132
5315
  if (sealedForReconcile) {
5316
+ if (stepStopReason) sealedForReconcile.stopReason = stepStopReason;
5133
5317
  if (splitFinalContent !== void 0 && splitFinalContent !== null) {
5134
5318
  reconcileSealedAssistantWithFinalResponse(sealedForReconcile, splitFinalContent);
5135
5319
  } else {
@@ -5140,8 +5324,9 @@ var AgentWidgetClient = class {
5140
5324
  lastSealedTextSegment = null;
5141
5325
  continue;
5142
5326
  }
5143
- const finalContent = (_ra = payload.result) == null ? void 0 : _ra.response;
5327
+ const finalContent = (_za = payload.result) == null ? void 0 : _za.response;
5144
5328
  const assistant = ensureAssistantMessage();
5329
+ if (stepStopReason) assistant.stopReason = stepStopReason;
5145
5330
  if (finalContent !== void 0 && finalContent !== null) {
5146
5331
  const parser = streamParsers.get(assistant.id);
5147
5332
  let hasExtractedText = false;
@@ -5192,7 +5377,7 @@ var AgentWidgetClient = class {
5192
5377
  }
5193
5378
  });
5194
5379
  } else {
5195
- const text = typeof parsedResult === "string" ? parsedResult : (_sa = parsedResult == null ? void 0 : parsedResult.text) != null ? _sa : null;
5380
+ const text = typeof parsedResult === "string" ? parsedResult : (_Aa = parsedResult == null ? void 0 : parsedResult.text) != null ? _Aa : null;
5196
5381
  if (text !== null && text.trim() !== "") {
5197
5382
  assistant.content = text;
5198
5383
  hasExtractedText = true;
@@ -5216,7 +5401,7 @@ var AgentWidgetClient = class {
5216
5401
  assistant.content = ensureStringContent(finalContent);
5217
5402
  }
5218
5403
  if (parser) {
5219
- const closeResult = (_ta = parser.close) == null ? void 0 : _ta.call(parser);
5404
+ const closeResult = (_Ba = parser.close) == null ? void 0 : _Ba.call(parser);
5220
5405
  if (closeResult instanceof Promise) {
5221
5406
  closeResult.catch(() => {
5222
5407
  });
@@ -5234,7 +5419,7 @@ var AgentWidgetClient = class {
5234
5419
  emitMessage(assistant);
5235
5420
  }
5236
5421
  } else if (payloadType === "flow_complete") {
5237
- const finalContent = (_ua = payload.result) == null ? void 0 : _ua.response;
5422
+ const finalContent = (_Ca = payload.result) == null ? void 0 : _Ca.response;
5238
5423
  if (didSplitByPartId) {
5239
5424
  if (assistantMessage !== null) {
5240
5425
  const msg = assistantMessage;
@@ -5301,11 +5486,11 @@ var AgentWidgetClient = class {
5301
5486
  } else if (payloadType === "agent_start") {
5302
5487
  agentExecution = {
5303
5488
  executionId: payload.executionId,
5304
- agentId: (_va = payload.agentId) != null ? _va : "virtual",
5305
- agentName: (_wa = payload.agentName) != null ? _wa : "",
5489
+ agentId: (_Da = payload.agentId) != null ? _Da : "virtual",
5490
+ agentName: (_Ea = payload.agentName) != null ? _Ea : "",
5306
5491
  status: "running",
5307
5492
  currentIteration: 0,
5308
- maxTurns: (_xa = payload.maxTurns) != null ? _xa : 1,
5493
+ maxTurns: (_Fa = payload.maxTurns) != null ? _Fa : 1,
5309
5494
  startedAt: resolveTimestamp(payload.startedAt)
5310
5495
  };
5311
5496
  } else if (payloadType === "agent_iteration_start") {
@@ -5325,7 +5510,7 @@ var AgentWidgetClient = class {
5325
5510
  } else if (payloadType === "agent_turn_delta") {
5326
5511
  if (payload.contentType === "text") {
5327
5512
  const assistant = ensureAssistantMessage();
5328
- assistant.content += (_ya = payload.delta) != null ? _ya : "";
5513
+ assistant.content += (_Ga = payload.delta) != null ? _Ga : "";
5329
5514
  assistant.agentMetadata = {
5330
5515
  executionId: payload.executionId,
5331
5516
  iteration: payload.iteration,
@@ -5334,14 +5519,14 @@ var AgentWidgetClient = class {
5334
5519
  };
5335
5520
  emitMessage(assistant);
5336
5521
  } else if (payload.contentType === "thinking") {
5337
- const reasoningId = (_za = payload.turnId) != null ? _za : `agent-think-${payload.iteration}`;
5522
+ const reasoningId = (_Ha = payload.turnId) != null ? _Ha : `agent-think-${payload.iteration}`;
5338
5523
  const reasoningMessage = ensureReasoningMessage(reasoningId);
5339
- reasoningMessage.reasoning = (_Aa = reasoningMessage.reasoning) != null ? _Aa : {
5524
+ reasoningMessage.reasoning = (_Ia = reasoningMessage.reasoning) != null ? _Ia : {
5340
5525
  id: reasoningId,
5341
5526
  status: "streaming",
5342
5527
  chunks: []
5343
5528
  };
5344
- reasoningMessage.reasoning.chunks.push((_Ba = payload.delta) != null ? _Ba : "");
5529
+ reasoningMessage.reasoning.chunks.push((_Ja = payload.delta) != null ? _Ja : "");
5345
5530
  reasoningMessage.agentMetadata = {
5346
5531
  executionId: payload.executionId,
5347
5532
  iteration: payload.iteration,
@@ -5349,12 +5534,12 @@ var AgentWidgetClient = class {
5349
5534
  };
5350
5535
  emitMessage(reasoningMessage);
5351
5536
  } else if (payload.contentType === "tool_input") {
5352
- const toolId = (_Ca = payload.toolCallId) != null ? _Ca : toolContext.lastId;
5537
+ const toolId = (_Ka = payload.toolCallId) != null ? _Ka : toolContext.lastId;
5353
5538
  if (toolId) {
5354
5539
  const toolMessage = toolMessages.get(toolId);
5355
5540
  if (toolMessage == null ? void 0 : toolMessage.toolCall) {
5356
- toolMessage.toolCall.chunks = (_Da = toolMessage.toolCall.chunks) != null ? _Da : [];
5357
- toolMessage.toolCall.chunks.push((_Ea = payload.delta) != null ? _Ea : "");
5541
+ toolMessage.toolCall.chunks = (_La = toolMessage.toolCall.chunks) != null ? _La : [];
5542
+ toolMessage.toolCall.chunks.push((_Ma = payload.delta) != null ? _Ma : "");
5358
5543
  emitMessage(toolMessage);
5359
5544
  }
5360
5545
  }
@@ -5366,20 +5551,29 @@ var AgentWidgetClient = class {
5366
5551
  if (reasoningMessage == null ? void 0 : reasoningMessage.reasoning) {
5367
5552
  reasoningMessage.reasoning.status = "complete";
5368
5553
  reasoningMessage.reasoning.completedAt = resolveTimestamp(payload.completedAt);
5369
- const start = (_Fa = reasoningMessage.reasoning.startedAt) != null ? _Fa : Date.now();
5554
+ const start = (_Na = reasoningMessage.reasoning.startedAt) != null ? _Na : Date.now();
5370
5555
  reasoningMessage.reasoning.durationMs = Math.max(
5371
5556
  0,
5372
- ((_Ga = reasoningMessage.reasoning.completedAt) != null ? _Ga : Date.now()) - start
5557
+ ((_Oa = reasoningMessage.reasoning.completedAt) != null ? _Oa : Date.now()) - start
5373
5558
  );
5374
5559
  reasoningMessage.streaming = false;
5375
5560
  emitMessage(reasoningMessage);
5376
5561
  }
5377
5562
  }
5563
+ const turnStopReason = payload.stopReason;
5564
+ if (turnStopReason && assistantMessage !== null) {
5565
+ const turnId = payload.turnId;
5566
+ const matchesTurn = !turnId || ((_Pa = assistantMessage.agentMetadata) == null ? void 0 : _Pa.turnId) === turnId;
5567
+ if (matchesTurn) {
5568
+ assistantMessage.stopReason = turnStopReason;
5569
+ emitMessage(assistantMessage);
5570
+ }
5571
+ }
5378
5572
  } else if (payloadType === "agent_tool_start") {
5379
- const toolId = (_Ha = payload.toolCallId) != null ? _Ha : `agent-tool-${nextSequence()}`;
5573
+ const toolId = (_Qa = payload.toolCallId) != null ? _Qa : `agent-tool-${nextSequence()}`;
5380
5574
  trackToolId(getToolCallKey(payload), toolId);
5381
5575
  const toolMessage = ensureToolMessage(toolId);
5382
- const tool = (_Ia = toolMessage.toolCall) != null ? _Ia : {
5576
+ const tool = (_Ra = toolMessage.toolCall) != null ? _Ra : {
5383
5577
  id: toolId,
5384
5578
  status: "pending",
5385
5579
  name: void 0,
@@ -5391,12 +5585,12 @@ var AgentWidgetClient = class {
5391
5585
  completedAt: void 0,
5392
5586
  durationMs: void 0
5393
5587
  };
5394
- tool.name = (_Ka = (_Ja = payload.toolName) != null ? _Ja : payload.name) != null ? _Ka : tool.name;
5588
+ tool.name = (_Ta = (_Sa = payload.toolName) != null ? _Sa : payload.name) != null ? _Ta : tool.name;
5395
5589
  tool.status = "running";
5396
5590
  if (payload.parameters !== void 0) {
5397
5591
  tool.args = payload.parameters;
5398
5592
  }
5399
- tool.startedAt = resolveTimestamp((_La = payload.startedAt) != null ? _La : payload.timestamp);
5593
+ tool.startedAt = resolveTimestamp((_Ua = payload.startedAt) != null ? _Ua : payload.timestamp);
5400
5594
  toolMessage.toolCall = tool;
5401
5595
  toolMessage.streaming = true;
5402
5596
  toolMessage.agentMetadata = {
@@ -5405,21 +5599,21 @@ var AgentWidgetClient = class {
5405
5599
  };
5406
5600
  emitMessage(toolMessage);
5407
5601
  } else if (payloadType === "agent_tool_delta") {
5408
- const toolId = (_Ma = payload.toolCallId) != null ? _Ma : toolContext.lastId;
5602
+ const toolId = (_Va = payload.toolCallId) != null ? _Va : toolContext.lastId;
5409
5603
  if (toolId) {
5410
- const toolMessage = (_Na = toolMessages.get(toolId)) != null ? _Na : ensureToolMessage(toolId);
5604
+ const toolMessage = (_Wa = toolMessages.get(toolId)) != null ? _Wa : ensureToolMessage(toolId);
5411
5605
  if (toolMessage.toolCall) {
5412
- toolMessage.toolCall.chunks = (_Oa = toolMessage.toolCall.chunks) != null ? _Oa : [];
5413
- toolMessage.toolCall.chunks.push((_Pa = payload.delta) != null ? _Pa : "");
5606
+ toolMessage.toolCall.chunks = (_Xa = toolMessage.toolCall.chunks) != null ? _Xa : [];
5607
+ toolMessage.toolCall.chunks.push((_Ya = payload.delta) != null ? _Ya : "");
5414
5608
  toolMessage.toolCall.status = "running";
5415
5609
  toolMessage.streaming = true;
5416
5610
  emitMessage(toolMessage);
5417
5611
  }
5418
5612
  }
5419
5613
  } else if (payloadType === "agent_tool_complete") {
5420
- const toolId = (_Qa = payload.toolCallId) != null ? _Qa : toolContext.lastId;
5614
+ const toolId = (_Za = payload.toolCallId) != null ? _Za : toolContext.lastId;
5421
5615
  if (toolId) {
5422
- const toolMessage = (_Ra = toolMessages.get(toolId)) != null ? _Ra : ensureToolMessage(toolId);
5616
+ const toolMessage = (__a = toolMessages.get(toolId)) != null ? __a : ensureToolMessage(toolId);
5423
5617
  if (toolMessage.toolCall) {
5424
5618
  toolMessage.toolCall.status = "complete";
5425
5619
  if (payload.result !== void 0) {
@@ -5428,7 +5622,7 @@ var AgentWidgetClient = class {
5428
5622
  if (typeof payload.executionTime === "number") {
5429
5623
  toolMessage.toolCall.durationMs = payload.executionTime;
5430
5624
  }
5431
- toolMessage.toolCall.completedAt = resolveTimestamp((_Sa = payload.completedAt) != null ? _Sa : payload.timestamp);
5625
+ toolMessage.toolCall.completedAt = resolveTimestamp((_$a = payload.completedAt) != null ? _$a : payload.timestamp);
5432
5626
  toolMessage.streaming = false;
5433
5627
  emitMessage(toolMessage);
5434
5628
  const callKey = getToolCallKey(payload);
@@ -5443,7 +5637,7 @@ var AgentWidgetClient = class {
5443
5637
  const reflectionMessage = {
5444
5638
  id: reflectionId,
5445
5639
  role: "assistant",
5446
- content: (_Ta = payload.reflection) != null ? _Ta : "",
5640
+ content: (_ab = payload.reflection) != null ? _ab : "",
5447
5641
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
5448
5642
  streaming: false,
5449
5643
  variant: "reasoning",
@@ -5451,7 +5645,7 @@ var AgentWidgetClient = class {
5451
5645
  reasoning: {
5452
5646
  id: reflectionId,
5453
5647
  status: "complete",
5454
- chunks: [(_Ua = payload.reflection) != null ? _Ua : ""]
5648
+ chunks: [(_bb = payload.reflection) != null ? _bb : ""]
5455
5649
  },
5456
5650
  agentMetadata: {
5457
5651
  executionId: payload.executionId,
@@ -5472,7 +5666,7 @@ var AgentWidgetClient = class {
5472
5666
  }
5473
5667
  onEvent({ type: "status", status: "idle" });
5474
5668
  } else if (payloadType === "agent_error") {
5475
- const errorMessage = typeof payload.error === "string" ? payload.error : (_Wa = (_Va = payload.error) == null ? void 0 : _Va.message) != null ? _Wa : "Agent execution error";
5669
+ const errorMessage = typeof payload.error === "string" ? payload.error : (_db = (_cb = payload.error) == null ? void 0 : _cb.message) != null ? _db : "Agent execution error";
5476
5670
  if (payload.recoverable) {
5477
5671
  if (typeof console !== "undefined") {
5478
5672
  console.warn("[AgentWidget] Recoverable agent error:", errorMessage);
@@ -5485,7 +5679,7 @@ var AgentWidgetClient = class {
5485
5679
  }
5486
5680
  } else if (payloadType === "agent_ping") {
5487
5681
  } else if (payloadType === "agent_approval_start") {
5488
- const approvalId = (_Xa = payload.approvalId) != null ? _Xa : `approval-${nextSequence()}`;
5682
+ const approvalId = (_eb = payload.approvalId) != null ? _eb : `approval-${nextSequence()}`;
5489
5683
  const approvalMessage = {
5490
5684
  id: `approval-${approvalId}`,
5491
5685
  role: "assistant",
@@ -5497,17 +5691,17 @@ var AgentWidgetClient = class {
5497
5691
  approval: {
5498
5692
  id: approvalId,
5499
5693
  status: "pending",
5500
- agentId: (_Ya = agentExecution == null ? void 0 : agentExecution.agentId) != null ? _Ya : "virtual",
5501
- executionId: (__a = (_Za = payload.executionId) != null ? _Za : agentExecution == null ? void 0 : agentExecution.executionId) != null ? __a : "",
5502
- toolName: (_$a = payload.toolName) != null ? _$a : "",
5694
+ agentId: (_fb = agentExecution == null ? void 0 : agentExecution.agentId) != null ? _fb : "virtual",
5695
+ executionId: (_hb = (_gb = payload.executionId) != null ? _gb : agentExecution == null ? void 0 : agentExecution.executionId) != null ? _hb : "",
5696
+ toolName: (_ib = payload.toolName) != null ? _ib : "",
5503
5697
  toolType: payload.toolType,
5504
- description: (_bb = payload.description) != null ? _bb : `Execute ${(_ab = payload.toolName) != null ? _ab : "tool"}`,
5698
+ description: (_kb = payload.description) != null ? _kb : `Execute ${(_jb = payload.toolName) != null ? _jb : "tool"}`,
5505
5699
  parameters: payload.parameters
5506
5700
  }
5507
5701
  };
5508
5702
  emitMessage(approvalMessage);
5509
5703
  } else if (payloadType === "step_await" && payload.awaitReason === "approval_required") {
5510
- const approvalId = (_cb = payload.approvalId) != null ? _cb : `approval-${nextSequence()}`;
5704
+ const approvalId = (_lb = payload.approvalId) != null ? _lb : `approval-${nextSequence()}`;
5511
5705
  const approvalMessage = {
5512
5706
  id: `approval-${approvalId}`,
5513
5707
  role: "assistant",
@@ -5519,11 +5713,11 @@ var AgentWidgetClient = class {
5519
5713
  approval: {
5520
5714
  id: approvalId,
5521
5715
  status: "pending",
5522
- agentId: (_db = agentExecution == null ? void 0 : agentExecution.agentId) != null ? _db : "virtual",
5523
- executionId: (_fb = (_eb = payload.executionId) != null ? _eb : agentExecution == null ? void 0 : agentExecution.executionId) != null ? _fb : "",
5524
- toolName: (_gb = payload.toolName) != null ? _gb : "",
5716
+ agentId: (_mb = agentExecution == null ? void 0 : agentExecution.agentId) != null ? _mb : "virtual",
5717
+ executionId: (_ob = (_nb = payload.executionId) != null ? _nb : agentExecution == null ? void 0 : agentExecution.executionId) != null ? _ob : "",
5718
+ toolName: (_pb = payload.toolName) != null ? _pb : "",
5525
5719
  toolType: payload.toolType,
5526
- description: (_ib = payload.description) != null ? _ib : `Execute ${(_hb = payload.toolName) != null ? _hb : "tool"}`,
5720
+ description: (_rb = payload.description) != null ? _rb : `Execute ${(_qb = payload.toolName) != null ? _qb : "tool"}`,
5527
5721
  parameters: payload.parameters
5528
5722
  }
5529
5723
  };
@@ -5542,11 +5736,11 @@ var AgentWidgetClient = class {
5542
5736
  sequence: nextSequence(),
5543
5737
  approval: {
5544
5738
  id: approvalId,
5545
- status: (_jb = payload.decision) != null ? _jb : "approved",
5546
- agentId: (_kb = agentExecution == null ? void 0 : agentExecution.agentId) != null ? _kb : "virtual",
5547
- executionId: (_mb = (_lb = payload.executionId) != null ? _lb : agentExecution == null ? void 0 : agentExecution.executionId) != null ? _mb : "",
5548
- toolName: (_nb = payload.toolName) != null ? _nb : "",
5549
- description: (_ob = payload.description) != null ? _ob : "",
5739
+ status: (_sb = payload.decision) != null ? _sb : "approved",
5740
+ agentId: (_tb = agentExecution == null ? void 0 : agentExecution.agentId) != null ? _tb : "virtual",
5741
+ executionId: (_vb = (_ub = payload.executionId) != null ? _ub : agentExecution == null ? void 0 : agentExecution.executionId) != null ? _vb : "",
5742
+ toolName: (_wb = payload.toolName) != null ? _wb : "",
5743
+ description: (_xb = payload.description) != null ? _xb : "",
5550
5744
  resolvedAt: Date.now()
5551
5745
  }
5552
5746
  };
@@ -5584,7 +5778,7 @@ var AgentWidgetClient = class {
5584
5778
  }
5585
5779
  } else if (payloadType === "artifact_delta") {
5586
5780
  const deltaId = String(payload.id);
5587
- const deltaText = typeof payload.delta === "string" ? payload.delta : String((_pb = payload.delta) != null ? _pb : "");
5781
+ const deltaText = typeof payload.delta === "string" ? payload.delta : String((_yb = payload.delta) != null ? _yb : "");
5588
5782
  onEvent({
5589
5783
  type: "artifact_delta",
5590
5784
  id: deltaId,
@@ -5607,7 +5801,7 @@ var AgentWidgetClient = class {
5607
5801
  if (refMsg) {
5608
5802
  refMsg.streaming = false;
5609
5803
  try {
5610
- const parsed = JSON.parse((_qb = refMsg.rawContent) != null ? _qb : "{}");
5804
+ const parsed = JSON.parse((_zb = refMsg.rawContent) != null ? _zb : "{}");
5611
5805
  if (parsed.props) {
5612
5806
  parsed.props.status = "complete";
5613
5807
  const acc = artifactContent.get(artCompleteId);
@@ -5628,7 +5822,7 @@ var AgentWidgetClient = class {
5628
5822
  if (!m || typeof m !== "object") {
5629
5823
  continue;
5630
5824
  }
5631
- const id = String((_rb = m.id) != null ? _rb : `msg-${nextSequence()}`);
5825
+ const id = String((_Ab = m.id) != null ? _Ab : `msg-${nextSequence()}`);
5632
5826
  const roleRaw = m.role;
5633
5827
  const role = roleRaw === "user" ? "user" : roleRaw === "system" ? "system" : "assistant";
5634
5828
  const msg = {
@@ -5647,7 +5841,7 @@ var AgentWidgetClient = class {
5647
5841
  if (msg.rawContent) {
5648
5842
  try {
5649
5843
  const parsed = JSON.parse(msg.rawContent);
5650
- const refArtId = (_sb = parsed == null ? void 0 : parsed.props) == null ? void 0 : _sb.artifactId;
5844
+ const refArtId = (_Bb = parsed == null ? void 0 : parsed.props) == null ? void 0 : _Bb.artifactId;
5651
5845
  if (typeof refArtId === "string") {
5652
5846
  artifactIdsWithCards.add(refArtId);
5653
5847
  }
@@ -5663,7 +5857,7 @@ var AgentWidgetClient = class {
5663
5857
  if (payload.error instanceof Error) {
5664
5858
  resolvedError = payload.error;
5665
5859
  } else if (payloadType === "dispatch_error") {
5666
- const msg = (_tb = payload.message) != null ? _tb : payload.error;
5860
+ const msg = (_Cb = payload.message) != null ? _Cb : payload.error;
5667
5861
  if (msg != null && msg !== "") {
5668
5862
  resolvedError = new Error(String(msg));
5669
5863
  }
@@ -5672,7 +5866,7 @@ var AgentWidgetClient = class {
5672
5866
  if (typeof e === "string" && e !== "") {
5673
5867
  resolvedError = new Error(e);
5674
5868
  } else if (e != null && typeof e === "object" && "message" in e) {
5675
- resolvedError = new Error(String((_ub = e.message) != null ? _ub : e));
5869
+ resolvedError = new Error(String((_Db = e.message) != null ? _Db : e));
5676
5870
  }
5677
5871
  } else if (payloadType === "error" && payload.error != null && payload.error !== "") {
5678
5872
  resolvedError = new Error(String(payload.error));
@@ -6776,7 +6970,7 @@ var AgentWidgetSession = class _AgentWidgetSession {
6776
6970
  this.applyArtifactStreamEvent(event);
6777
6971
  }
6778
6972
  };
6779
- var _a;
6973
+ var _a, _b;
6780
6974
  this.messages = [...(_a = config.initialMessages) != null ? _a : []].map((message) => {
6781
6975
  var _a2;
6782
6976
  return {
@@ -6786,9 +6980,18 @@ var AgentWidgetSession = class _AgentWidgetSession {
6786
6980
  });
6787
6981
  this.messages = this.sortMessages(this.messages);
6788
6982
  this.client = new AgentWidgetClient(config);
6983
+ for (const rec of (_b = config.initialArtifacts) != null ? _b : []) {
6984
+ this.artifacts.set(rec.id, { ...rec, status: "complete" });
6985
+ }
6986
+ if (config.initialSelectedArtifactId != null) {
6987
+ this.selectedArtifactId = config.initialSelectedArtifactId;
6988
+ }
6789
6989
  if (this.messages.length) {
6790
6990
  this.callbacks.onMessagesChanged([...this.messages]);
6791
6991
  }
6992
+ if (this.artifacts.size > 0) {
6993
+ this.emitArtifactsState();
6994
+ }
6792
6995
  this.callbacks.onStatusChanged(this.status);
6793
6996
  }
6794
6997
  /**
@@ -7513,10 +7716,147 @@ var AgentWidgetSession = class _AgentWidgetSession {
7513
7716
  );
7514
7717
  }
7515
7718
  }
7719
+ /**
7720
+ * Resolve a paused `ask_user_question` LOCAL tool call.
7721
+ *
7722
+ * When the server emits `step_await` for `ask_user_question`, the widget
7723
+ * renders the answer-pill sheet and calls this method once the user
7724
+ * picks. Steps:
7725
+ * 1. POST the answer to `/resume` via `client.resumeFlow`.
7726
+ * 2. Pipe the resulting SSE stream through `connectStream()` so the
7727
+ * paused agent execution continues.
7728
+ * 3. Append a user-visible bubble with the answer text so the
7729
+ * transcript reads naturally.
7730
+ */
7731
+ /**
7732
+ * Persist in-progress answers and the current page index for a multi-question
7733
+ * `ask_user_question` payload, so a refresh resumes on the same page with
7734
+ * prior answers intact. Called by ui.ts on every Back/Next/pick interaction.
7735
+ */
7736
+ persistAskUserQuestionProgress(toolMessage, progress) {
7737
+ const current = this.messages.find((m) => m.id === toolMessage.id);
7738
+ if (!current) return;
7739
+ this.upsertMessage({
7740
+ ...current,
7741
+ agentMetadata: {
7742
+ ...current.agentMetadata,
7743
+ askUserQuestionAnswers: progress.answers,
7744
+ askUserQuestionIndex: progress.currentIndex
7745
+ }
7746
+ });
7747
+ }
7748
+ /**
7749
+ * Flip an `ask_user_question` tool message from awaiting → answered so
7750
+ * render passes stop re-mounting its answer-pill sheet. Idempotent.
7751
+ * When `answers` is provided, persists the full structured answer Record
7752
+ * atomically with the answered flag — guarding against later events that
7753
+ * could re-emit the tool message and clobber the per-pick persisted
7754
+ * answers via top-level merge.
7755
+ */
7756
+ markAskUserQuestionResolved(toolMessage, answers) {
7757
+ const current = this.messages.find((m) => m.id === toolMessage.id);
7758
+ if (!current) return;
7759
+ this.upsertMessage({
7760
+ ...current,
7761
+ agentMetadata: {
7762
+ ...current.agentMetadata,
7763
+ awaitingLocalTool: false,
7764
+ askUserQuestionAnswered: true,
7765
+ ...answers ? { askUserQuestionAnswers: answers } : {}
7766
+ }
7767
+ });
7768
+ }
7769
+ async resolveAskUserQuestion(toolMessage, answer) {
7770
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
7771
+ const live = this.messages.find((m) => m.id === toolMessage.id);
7772
+ if (((_a = live == null ? void 0 : live.agentMetadata) == null ? void 0 : _a.askUserQuestionAnswered) === true) return;
7773
+ const executionId = (_b = toolMessage.agentMetadata) == null ? void 0 : _b.executionId;
7774
+ const toolName = (_c = toolMessage.toolCall) == null ? void 0 : _c.name;
7775
+ if (!executionId || !toolName) {
7776
+ (_e = (_d = this.callbacks).onError) == null ? void 0 : _e.call(
7777
+ _d,
7778
+ new Error(
7779
+ "resolveAskUserQuestion: message is missing executionId or toolCall.name"
7780
+ )
7781
+ );
7782
+ return;
7783
+ }
7784
+ let structuredAnswers = typeof answer === "string" ? void 0 : answer;
7785
+ if (structuredAnswers === void 0 && typeof answer === "string") {
7786
+ const args2 = (_f = toolMessage.toolCall) == null ? void 0 : _f.args;
7787
+ const questions2 = Array.isArray(args2 == null ? void 0 : args2.questions) ? args2.questions : [];
7788
+ if (questions2.length === 1) {
7789
+ const qText = typeof ((_g = questions2[0]) == null ? void 0 : _g.question) === "string" ? questions2[0].question : "";
7790
+ if (qText) structuredAnswers = { [qText]: answer };
7791
+ }
7792
+ }
7793
+ this.markAskUserQuestionResolved(toolMessage, structuredAnswers);
7794
+ const toolCallId = toolMessage.toolCall.id;
7795
+ const args = (_h = toolMessage.toolCall) == null ? void 0 : _h.args;
7796
+ const questions = Array.isArray(args == null ? void 0 : args.questions) ? args.questions : [];
7797
+ if (questions.length === 0) {
7798
+ const fallback = typeof answer === "string" ? answer : Object.entries(answer).map(
7799
+ ([q, v]) => `${q}: ${Array.isArray(v) ? v.join(", ") : v}`
7800
+ ).join(" | ");
7801
+ this.appendMessage({
7802
+ id: `ask-user-answer-${toolCallId}`,
7803
+ role: "user",
7804
+ content: fallback,
7805
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
7806
+ streaming: false,
7807
+ sequence: this.nextSequence()
7808
+ });
7809
+ } else {
7810
+ const stored = structuredAnswers != null ? structuredAnswers : {};
7811
+ questions.forEach((p, i) => {
7812
+ const qText = typeof (p == null ? void 0 : p.question) === "string" ? p.question : "";
7813
+ if (!qText) return;
7814
+ const ans = stored[qText];
7815
+ const answerStr = Array.isArray(ans) ? ans.join(", ") : typeof ans === "string" ? ans : "";
7816
+ this.appendMessage({
7817
+ id: `ask-user-q-${toolCallId}-${i}`,
7818
+ role: "assistant",
7819
+ content: qText,
7820
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
7821
+ streaming: false,
7822
+ sequence: this.nextSequence()
7823
+ });
7824
+ this.appendMessage({
7825
+ id: `ask-user-a-${toolCallId}-${i}`,
7826
+ role: "user",
7827
+ content: answerStr || "*Skipped*",
7828
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
7829
+ streaming: false,
7830
+ sequence: this.nextSequence()
7831
+ });
7832
+ });
7833
+ }
7834
+ try {
7835
+ const response = await this.client.resumeFlow(executionId, {
7836
+ [toolName]: answer
7837
+ });
7838
+ if (!response.ok) {
7839
+ const errorData = await response.json().catch(() => null);
7840
+ throw new Error(
7841
+ (_i = errorData == null ? void 0 : errorData.error) != null ? _i : `Resume failed: ${response.status}`
7842
+ );
7843
+ }
7844
+ if (response.body) {
7845
+ await this.connectStream(response.body);
7846
+ }
7847
+ } catch (error) {
7848
+ (_k = (_j = this.callbacks).onError) == null ? void 0 : _k.call(
7849
+ _j,
7850
+ error instanceof Error ? error : new Error(String(error))
7851
+ );
7852
+ }
7853
+ }
7516
7854
  cancel() {
7517
7855
  var _a;
7518
7856
  (_a = this.abortController) == null ? void 0 : _a.abort();
7519
7857
  this.abortController = null;
7858
+ this.stopSpeaking();
7859
+ this.stopVoicePlayback();
7520
7860
  this.setStreaming(false);
7521
7861
  this.setStatus("idle");
7522
7862
  }
@@ -7658,6 +7998,14 @@ var AgentWidgetSession = class _AgentWidgetSession {
7658
7998
  this.setStatus("idle");
7659
7999
  this.callbacks.onMessagesChanged([...this.messages]);
7660
8000
  }
8001
+ hydrateArtifacts(artifacts, selectedId = null) {
8002
+ this.artifacts.clear();
8003
+ for (const rec of artifacts) {
8004
+ this.artifacts.set(rec.id, { ...rec, status: "complete" });
8005
+ }
8006
+ this.selectedArtifactId = selectedId;
8007
+ this.emitArtifactsState();
8008
+ }
7661
8009
  setStatus(status) {
7662
8010
  if (this.status === status) return;
7663
8011
  this.status = status;
@@ -7764,9 +8112,24 @@ var AgentWidgetSession = class _AgentWidgetSession {
7764
8112
  this.appendMessage(withSequence);
7765
8113
  return;
7766
8114
  }
7767
- this.messages = this.messages.map(
7768
- (existing, idx) => idx === index ? { ...existing, ...withSequence } : existing
7769
- );
8115
+ this.messages = this.messages.map((existing, idx) => {
8116
+ var _a;
8117
+ if (idx !== index) return existing;
8118
+ const merged = { ...existing, ...withSequence };
8119
+ if (((_a = existing.agentMetadata) == null ? void 0 : _a.askUserQuestionAnswered) === true && withSequence.agentMetadata) {
8120
+ merged.agentMetadata = {
8121
+ ...withSequence.agentMetadata,
8122
+ askUserQuestionAnswered: true,
8123
+ ...existing.agentMetadata.askUserQuestionAnswers ? {
8124
+ askUserQuestionAnswers: existing.agentMetadata.askUserQuestionAnswers
8125
+ } : {},
8126
+ // Keep awaiting flag false once resolved — never let a stale
8127
+ // re-emit flip us back to awaiting.
8128
+ awaitingLocalTool: false
8129
+ };
8130
+ }
8131
+ return merged;
8132
+ });
7770
8133
  this.messages = this.sortMessages(this.messages);
7771
8134
  this.callbacks.onMessagesChanged([...this.messages]);
7772
8135
  }
@@ -8149,6 +8512,9 @@ var morphMessages = (container, newContent, options = {}) => {
8149
8512
  if (oldNode.classList.contains("persona-animate-typing")) {
8150
8513
  return false;
8151
8514
  }
8515
+ if (oldNode.hasAttribute("data-preserve-runtime")) {
8516
+ return false;
8517
+ }
8152
8518
  if (oldNode.hasAttribute("data-preserve-animation")) {
8153
8519
  if (newNode instanceof HTMLElement && !newNode.hasAttribute("data-preserve-animation")) {
8154
8520
  return;
@@ -8170,7 +8536,7 @@ var morphMessages = (container, newContent, options = {}) => {
8170
8536
 
8171
8537
  // src/utils/message-fingerprint.ts
8172
8538
  function computeMessageFingerprint(message, configVersion) {
8173
- 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;
8539
+ 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;
8174
8540
  return [
8175
8541
  message.id,
8176
8542
  message.role,
@@ -8188,6 +8554,7 @@ function computeMessageFingerprint(message, configVersion) {
8188
8554
  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,
8189
8555
  (_A = (_z = (_y = message.reasoning) == null ? void 0 : _y.chunks) == null ? void 0 : _z.length) != null ? _A : 0,
8190
8556
  (_C = (_B = message.contentParts) == null ? void 0 : _B.length) != null ? _C : 0,
8557
+ (_D = message.stopReason) != null ? _D : "",
8191
8558
  configVersion
8192
8559
  ].join("\0");
8193
8560
  }
@@ -8288,6 +8655,241 @@ var statusCopy = {
8288
8655
  var DEFAULT_OVERLAY_Z_INDEX = 1e5;
8289
8656
  var PORTALED_OVERLAY_Z_INDEX = DEFAULT_OVERLAY_Z_INDEX + 1;
8290
8657
 
8658
+ // src/utils/stream-animation.ts
8659
+ var DEFAULT_STREAM_ANIMATION = {
8660
+ type: "none",
8661
+ placeholder: "none",
8662
+ speed: 120,
8663
+ duration: 1800,
8664
+ buffer: "none"
8665
+ };
8666
+ var DEFAULT_SKIP_TAGS = ["pre", "code", "a", "script", "style"];
8667
+ var resolveStreamAnimation = (feature) => {
8668
+ var _a, _b, _c, _d, _e;
8669
+ return {
8670
+ type: (_a = feature == null ? void 0 : feature.type) != null ? _a : DEFAULT_STREAM_ANIMATION.type,
8671
+ placeholder: (_b = feature == null ? void 0 : feature.placeholder) != null ? _b : DEFAULT_STREAM_ANIMATION.placeholder,
8672
+ speed: (_c = feature == null ? void 0 : feature.speed) != null ? _c : DEFAULT_STREAM_ANIMATION.speed,
8673
+ duration: (_d = feature == null ? void 0 : feature.duration) != null ? _d : DEFAULT_STREAM_ANIMATION.duration,
8674
+ buffer: (_e = feature == null ? void 0 : feature.buffer) != null ? _e : DEFAULT_STREAM_ANIMATION.buffer
8675
+ };
8676
+ };
8677
+ var BUILTIN_PLUGINS = [
8678
+ {
8679
+ name: "typewriter",
8680
+ containerClass: "persona-stream-typewriter",
8681
+ wrap: "char",
8682
+ useCaret: true
8683
+ },
8684
+ {
8685
+ name: "pop-bubble",
8686
+ bubbleClass: "persona-stream-pop",
8687
+ wrap: "none"
8688
+ },
8689
+ {
8690
+ name: "letter-rise",
8691
+ containerClass: "persona-stream-letter-rise",
8692
+ wrap: "char"
8693
+ },
8694
+ {
8695
+ name: "word-fade",
8696
+ containerClass: "persona-stream-word-fade",
8697
+ wrap: "word"
8698
+ }
8699
+ ];
8700
+ var globalRegistry = /* @__PURE__ */ new Map();
8701
+ for (const plugin of BUILTIN_PLUGINS) globalRegistry.set(plugin.name, plugin);
8702
+ var resolveStreamAnimationPlugin = (type, overrides) => {
8703
+ var _a, _b;
8704
+ if (type === "none") return null;
8705
+ if (overrides && Object.prototype.hasOwnProperty.call(overrides, type)) {
8706
+ return (_a = overrides[type]) != null ? _a : null;
8707
+ }
8708
+ return (_b = globalRegistry.get(type)) != null ? _b : null;
8709
+ };
8710
+ var applyStreamBuffer = (content, buffer, plugin, message, streaming) => {
8711
+ if (!streaming) return content;
8712
+ if (plugin == null ? void 0 : plugin.bufferContent) return plugin.bufferContent(content, message);
8713
+ if (!content) return content;
8714
+ if (buffer === "word") {
8715
+ const lastSpace = content.search(/\s(?=\S*$)/);
8716
+ if (lastSpace < 0) return "";
8717
+ return content.slice(0, lastSpace);
8718
+ }
8719
+ if (buffer === "line") {
8720
+ const lastNewline = content.lastIndexOf("\n");
8721
+ if (lastNewline < 0) return "";
8722
+ return content.slice(0, lastNewline);
8723
+ }
8724
+ return content;
8725
+ };
8726
+ var makeCharSpan = (doc, ch, messageId, index) => {
8727
+ const span = doc.createElement("span");
8728
+ span.className = "persona-stream-char";
8729
+ span.id = `stream-c-${messageId}-${index}`;
8730
+ span.style.setProperty("--char-index", String(index));
8731
+ span.textContent = ch;
8732
+ return span;
8733
+ };
8734
+ var makeWordSpan = (doc, word, messageId, index) => {
8735
+ const span = doc.createElement("span");
8736
+ span.className = "persona-stream-word";
8737
+ span.id = `stream-w-${messageId}-${index}`;
8738
+ span.style.setProperty("--word-index", String(index));
8739
+ span.textContent = word;
8740
+ return span;
8741
+ };
8742
+ var WHITESPACE_RE = /\s/;
8743
+ var shouldSkipSubtree = (node, skipTags) => {
8744
+ let current = node.parentNode;
8745
+ while (current) {
8746
+ if (current.nodeType === 1) {
8747
+ const el = current;
8748
+ if (skipTags.has(el.tagName.toLowerCase())) return true;
8749
+ }
8750
+ current = current.parentNode;
8751
+ }
8752
+ return false;
8753
+ };
8754
+ var wrapTextNodeChars = (textNode, messageId, counterRef) => {
8755
+ var _a;
8756
+ const doc = textNode.ownerDocument;
8757
+ const parent = textNode.parentNode;
8758
+ if (!doc || !parent) return;
8759
+ const text = (_a = textNode.nodeValue) != null ? _a : "";
8760
+ if (!text) return;
8761
+ const fragment = doc.createDocumentFragment();
8762
+ let i = 0;
8763
+ while (i < text.length) {
8764
+ if (WHITESPACE_RE.test(text[i])) {
8765
+ let j = i;
8766
+ while (j < text.length && WHITESPACE_RE.test(text[j])) j += 1;
8767
+ fragment.appendChild(doc.createTextNode(text.slice(i, j)));
8768
+ i = j;
8769
+ } else {
8770
+ const group = doc.createElement("span");
8771
+ group.className = "persona-stream-word-group";
8772
+ let j = i;
8773
+ while (j < text.length && !WHITESPACE_RE.test(text[j])) {
8774
+ group.appendChild(makeCharSpan(doc, text[j], messageId, counterRef.value));
8775
+ counterRef.value += 1;
8776
+ j += 1;
8777
+ }
8778
+ fragment.appendChild(group);
8779
+ i = j;
8780
+ }
8781
+ }
8782
+ parent.replaceChild(fragment, textNode);
8783
+ };
8784
+ var wrapTextNodeWords = (textNode, messageId, counterRef) => {
8785
+ var _a;
8786
+ const doc = textNode.ownerDocument;
8787
+ const parent = textNode.parentNode;
8788
+ if (!doc || !parent) return;
8789
+ const text = (_a = textNode.nodeValue) != null ? _a : "";
8790
+ if (!text) return;
8791
+ const fragment = doc.createDocumentFragment();
8792
+ const tokens = text.split(/(\s+)/);
8793
+ for (const token of tokens) {
8794
+ if (!token) continue;
8795
+ if (/^\s+$/.test(token)) {
8796
+ fragment.appendChild(doc.createTextNode(token));
8797
+ } else {
8798
+ fragment.appendChild(makeWordSpan(doc, token, messageId, counterRef.value));
8799
+ counterRef.value += 1;
8800
+ }
8801
+ }
8802
+ parent.replaceChild(fragment, textNode);
8803
+ };
8804
+ var wrapStreamAnimation = (html, mode, messageId, options) => {
8805
+ var _a;
8806
+ if (!html) return html;
8807
+ if (typeof document === "undefined") return html;
8808
+ const scratch = document.createElement("div");
8809
+ scratch.innerHTML = html;
8810
+ const skipTags = new Set(((_a = options == null ? void 0 : options.skipTags) != null ? _a : DEFAULT_SKIP_TAGS).map((t) => t.toLowerCase()));
8811
+ const walker = document.createTreeWalker(scratch, NodeFilter.SHOW_TEXT, null);
8812
+ const textNodes = [];
8813
+ let node = walker.nextNode();
8814
+ while (node) {
8815
+ if (!shouldSkipSubtree(node, skipTags)) {
8816
+ textNodes.push(node);
8817
+ }
8818
+ node = walker.nextNode();
8819
+ }
8820
+ const counterRef = { value: 0 };
8821
+ const wrap = mode === "char" ? wrapTextNodeChars : wrapTextNodeWords;
8822
+ for (const textNode of textNodes) {
8823
+ wrap(textNode, messageId, counterRef);
8824
+ }
8825
+ return scratch.innerHTML;
8826
+ };
8827
+ var createStreamCaret = (doc = document) => {
8828
+ const caret = doc.createElement("span");
8829
+ caret.className = "persona-stream-caret";
8830
+ caret.setAttribute("aria-hidden", "true");
8831
+ caret.setAttribute("data-preserve-animation", "stream-caret");
8832
+ return caret;
8833
+ };
8834
+ var createSkeletonPlaceholder = (doc = document) => {
8835
+ const wrapper = doc.createElement("div");
8836
+ wrapper.className = "persona-stream-skeleton";
8837
+ wrapper.setAttribute("data-preserve-animation", "stream-skeleton");
8838
+ wrapper.setAttribute("aria-hidden", "true");
8839
+ const line = doc.createElement("div");
8840
+ line.className = "persona-stream-skeleton-line";
8841
+ wrapper.appendChild(line);
8842
+ return wrapper;
8843
+ };
8844
+ var injectedStyleRoots = /* @__PURE__ */ new WeakMap();
8845
+ var injectPluginStyles = (plugin, root) => {
8846
+ var _a;
8847
+ if (!plugin.styles) return;
8848
+ let names = injectedStyleRoots.get(root);
8849
+ if (!names) {
8850
+ names = /* @__PURE__ */ new Set();
8851
+ injectedStyleRoots.set(root, names);
8852
+ }
8853
+ if (names.has(plugin.name)) {
8854
+ const escaped = plugin.name.replace(/["\\]/g, "\\$&");
8855
+ const existing = root.querySelector(
8856
+ `style[data-persona-animation="${escaped}"]`
8857
+ );
8858
+ if (existing) return;
8859
+ names.delete(plugin.name);
8860
+ }
8861
+ names.add(plugin.name);
8862
+ const doc = root instanceof ShadowRoot ? root.ownerDocument : (_a = root.ownerDocument) != null ? _a : document;
8863
+ const style = doc.createElement("style");
8864
+ style.setAttribute("data-persona-animation", plugin.name);
8865
+ style.textContent = plugin.styles;
8866
+ root.appendChild(style);
8867
+ };
8868
+ var attachedCleanups = /* @__PURE__ */ new WeakMap();
8869
+ var attachPlugin = (plugin, root) => {
8870
+ if (!plugin.onAttach) return;
8871
+ let cleanups = attachedCleanups.get(root);
8872
+ if (!cleanups) {
8873
+ cleanups = /* @__PURE__ */ new Map();
8874
+ attachedCleanups.set(root, cleanups);
8875
+ }
8876
+ if (cleanups.has(plugin.name)) return;
8877
+ const cleanup = plugin.onAttach(root);
8878
+ cleanups.set(plugin.name, cleanup);
8879
+ };
8880
+ var detachAllPlugins = (root) => {
8881
+ const cleanups = attachedCleanups.get(root);
8882
+ if (!cleanups) return;
8883
+ for (const cleanup of cleanups.values()) {
8884
+ if (typeof cleanup === "function") cleanup();
8885
+ }
8886
+ cleanups.clear();
8887
+ };
8888
+ var ensurePluginActive = (plugin, root) => {
8889
+ injectPluginStyles(plugin, root);
8890
+ attachPlugin(plugin, root);
8891
+ };
8892
+
8291
8893
  // src/utils/overlay-host-stacking.ts
8292
8894
  function syncOverlayHostStacking(host, zIndex = DEFAULT_OVERLAY_Z_INDEX) {
8293
8895
  const originalPosition = host.style.position;
@@ -9373,7 +9975,7 @@ var buildHeaderWithLayout = (config, layoutConfig, context) => {
9373
9975
 
9374
9976
  // src/components/composer-builder.ts
9375
9977
  var buildComposer = (context) => {
9376
- 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;
9978
+ 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;
9377
9979
  const { config } = context;
9378
9980
  const footer = createElement(
9379
9981
  "div",
@@ -9429,9 +10031,13 @@ var buildComposer = (context) => {
9429
10031
  const useIcon = (_d = sendButtonConfig.useIcon) != null ? _d : false;
9430
10032
  const iconText = (_e = sendButtonConfig.iconText) != null ? _e : "\u2191";
9431
10033
  const iconName = sendButtonConfig.iconName;
9432
- const tooltipText = (_f = sendButtonConfig.tooltipText) != null ? _f : "Send message";
9433
- const showTooltip = (_g = sendButtonConfig.showTooltip) != null ? _g : false;
9434
- const buttonSize = (_h = sendButtonConfig.size) != null ? _h : "40px";
10034
+ const stopIconName = (_f = sendButtonConfig.stopIconName) != null ? _f : "square";
10035
+ const tooltipText = (_g = sendButtonConfig.tooltipText) != null ? _g : "Send message";
10036
+ const stopTooltipText = (_h = sendButtonConfig.stopTooltipText) != null ? _h : "Stop generating";
10037
+ const sendLabel = (_j = (_i = config == null ? void 0 : config.copy) == null ? void 0 : _i.sendButtonLabel) != null ? _j : "Send";
10038
+ const stopLabel = (_l = (_k = config == null ? void 0 : config.copy) == null ? void 0 : _k.stopButtonLabel) != null ? _l : "Stop";
10039
+ const showTooltip = (_m = sendButtonConfig.showTooltip) != null ? _m : false;
10040
+ const buttonSize = (_n = sendButtonConfig.size) != null ? _n : "40px";
9435
10041
  const backgroundColor = sendButtonConfig.backgroundColor;
9436
10042
  const textColor = sendButtonConfig.textColor;
9437
10043
  const sendButtonWrapper = createElement("div", "persona-send-button-wrapper");
@@ -9441,6 +10047,8 @@ var buildComposer = (context) => {
9441
10047
  );
9442
10048
  sendButton.type = "submit";
9443
10049
  sendButton.setAttribute("data-persona-composer-submit", "");
10050
+ let sendIcon = null;
10051
+ let stopIcon = null;
9444
10052
  if (useIcon) {
9445
10053
  sendButton.style.width = buttonSize;
9446
10054
  sendButton.style.height = buttonSize;
@@ -9454,25 +10062,26 @@ var buildComposer = (context) => {
9454
10062
  } else {
9455
10063
  sendButton.style.color = "var(--persona-button-primary-fg, #ffffff)";
9456
10064
  }
10065
+ const iconSize = parseFloat(buttonSize) || 24;
10066
+ const iconColor = (textColor == null ? void 0 : textColor.trim()) || "currentColor";
9457
10067
  if (iconName) {
9458
- const iconSize = parseFloat(buttonSize) || 24;
9459
- const iconColor = (textColor == null ? void 0 : textColor.trim()) || "currentColor";
9460
- const iconSvg = renderLucideIcon(iconName, iconSize, iconColor, 2);
9461
- if (iconSvg) {
9462
- sendButton.appendChild(iconSvg);
10068
+ sendIcon = renderLucideIcon(iconName, iconSize, iconColor, 2);
10069
+ if (sendIcon) {
10070
+ sendButton.appendChild(sendIcon);
9463
10071
  } else {
9464
10072
  sendButton.textContent = iconText;
9465
10073
  }
9466
10074
  } else {
9467
10075
  sendButton.textContent = iconText;
9468
10076
  }
10077
+ stopIcon = renderLucideIcon(stopIconName, iconSize, iconColor, 2);
9469
10078
  if (backgroundColor) {
9470
10079
  sendButton.style.backgroundColor = backgroundColor;
9471
10080
  } else {
9472
10081
  sendButton.classList.add("persona-bg-persona-primary");
9473
10082
  }
9474
10083
  } else {
9475
- sendButton.textContent = (_j = (_i = config == null ? void 0 : config.copy) == null ? void 0 : _i.sendButtonLabel) != null ? _j : "Send";
10084
+ sendButton.textContent = sendLabel;
9476
10085
  if (textColor) {
9477
10086
  sendButton.style.color = textColor;
9478
10087
  } else {
@@ -9500,18 +10109,43 @@ var buildComposer = (context) => {
9500
10109
  sendButton.style.paddingTop = "";
9501
10110
  sendButton.style.paddingBottom = "";
9502
10111
  }
10112
+ let sendTooltip = null;
9503
10113
  if (showTooltip && tooltipText) {
9504
- const tooltip = createElement("div", "persona-send-button-tooltip");
9505
- tooltip.textContent = tooltipText;
9506
- sendButtonWrapper.appendChild(tooltip);
10114
+ sendTooltip = createElement("div", "persona-send-button-tooltip");
10115
+ sendTooltip.textContent = tooltipText;
10116
+ sendButtonWrapper.appendChild(sendTooltip);
9507
10117
  }
10118
+ sendButton.setAttribute("aria-label", tooltipText);
9508
10119
  sendButtonWrapper.appendChild(sendButton);
9509
- const voiceRecognitionConfig = (_k = config == null ? void 0 : config.voiceRecognition) != null ? _k : {};
10120
+ let currentMode = "send";
10121
+ const setSendButtonMode = (mode) => {
10122
+ if (mode === currentMode) return;
10123
+ currentMode = mode;
10124
+ const label = mode === "stop" ? stopTooltipText : tooltipText;
10125
+ sendButton.setAttribute("aria-label", label);
10126
+ if (sendTooltip) {
10127
+ sendTooltip.textContent = label;
10128
+ }
10129
+ if (useIcon) {
10130
+ if (sendIcon && stopIcon) {
10131
+ const next = mode === "stop" ? stopIcon : sendIcon;
10132
+ const prev = mode === "stop" ? sendIcon : stopIcon;
10133
+ if (prev.parentNode === sendButton) {
10134
+ sendButton.replaceChild(next, prev);
10135
+ } else {
10136
+ sendButton.appendChild(next);
10137
+ }
10138
+ }
10139
+ } else {
10140
+ sendButton.textContent = mode === "stop" ? stopLabel : sendLabel;
10141
+ }
10142
+ };
10143
+ const voiceRecognitionConfig = (_o = config == null ? void 0 : config.voiceRecognition) != null ? _o : {};
9510
10144
  const voiceRecognitionEnabled = voiceRecognitionConfig.enabled === true;
9511
10145
  let micButton = null;
9512
10146
  let micButtonWrapper = null;
9513
10147
  const hasSpeechRecognition = typeof window !== "undefined" && (typeof window.webkitSpeechRecognition !== "undefined" || typeof window.SpeechRecognition !== "undefined");
9514
- const hasRuntypeProvider = ((_l = voiceRecognitionConfig.provider) == null ? void 0 : _l.type) === "runtype";
10148
+ const hasRuntypeProvider = ((_p = voiceRecognitionConfig.provider) == null ? void 0 : _p.type) === "runtype";
9515
10149
  const hasVoiceInput = hasSpeechRecognition || hasRuntypeProvider;
9516
10150
  if (voiceRecognitionEnabled && hasVoiceInput) {
9517
10151
  micButtonWrapper = createElement("div", "persona-send-button-wrapper");
@@ -9522,11 +10156,11 @@ var buildComposer = (context) => {
9522
10156
  micButton.type = "button";
9523
10157
  micButton.setAttribute("data-persona-composer-mic", "");
9524
10158
  micButton.setAttribute("aria-label", "Start voice recognition");
9525
- const micIconName = (_m = voiceRecognitionConfig.iconName) != null ? _m : "mic";
9526
- const micIconSize = (_n = voiceRecognitionConfig.iconSize) != null ? _n : buttonSize;
10159
+ const micIconName = (_q = voiceRecognitionConfig.iconName) != null ? _q : "mic";
10160
+ const micIconSize = (_r = voiceRecognitionConfig.iconSize) != null ? _r : buttonSize;
9527
10161
  const micIconSizeNum = parseFloat(micIconSize) || 24;
9528
- const micBackgroundColor = (_o = voiceRecognitionConfig.backgroundColor) != null ? _o : backgroundColor;
9529
- const micIconColor = (_p = voiceRecognitionConfig.iconColor) != null ? _p : textColor;
10162
+ const micBackgroundColor = (_s = voiceRecognitionConfig.backgroundColor) != null ? _s : backgroundColor;
10163
+ const micIconColor = (_t = voiceRecognitionConfig.iconColor) != null ? _t : textColor;
9530
10164
  micButton.style.width = micIconSize;
9531
10165
  micButton.style.height = micIconSize;
9532
10166
  micButton.style.minWidth = micIconSize;
@@ -9569,15 +10203,15 @@ var buildComposer = (context) => {
9569
10203
  micButton.style.paddingBottom = voiceRecognitionConfig.paddingY;
9570
10204
  }
9571
10205
  micButtonWrapper.appendChild(micButton);
9572
- const micTooltipText = (_q = voiceRecognitionConfig.tooltipText) != null ? _q : "Start voice recognition";
9573
- const showMicTooltip = (_r = voiceRecognitionConfig.showTooltip) != null ? _r : false;
10206
+ const micTooltipText = (_u = voiceRecognitionConfig.tooltipText) != null ? _u : "Start voice recognition";
10207
+ const showMicTooltip = (_v = voiceRecognitionConfig.showTooltip) != null ? _v : false;
9574
10208
  if (showMicTooltip && micTooltipText) {
9575
10209
  const tooltip = createElement("div", "persona-send-button-tooltip");
9576
10210
  tooltip.textContent = micTooltipText;
9577
10211
  micButtonWrapper.appendChild(tooltip);
9578
10212
  }
9579
10213
  }
9580
- const attachmentsConfig = (_s = config == null ? void 0 : config.attachments) != null ? _s : {};
10214
+ const attachmentsConfig = (_w = config == null ? void 0 : config.attachments) != null ? _w : {};
9581
10215
  const attachmentsEnabled = attachmentsConfig.enabled === true;
9582
10216
  let attachmentButton = null;
9583
10217
  let attachmentButtonWrapper = null;
@@ -9591,8 +10225,8 @@ var buildComposer = (context) => {
9591
10225
  attachmentPreviewsContainer.style.display = "none";
9592
10226
  attachmentInput = createElement("input");
9593
10227
  attachmentInput.type = "file";
9594
- attachmentInput.accept = ((_t = attachmentsConfig.allowedTypes) != null ? _t : ALL_SUPPORTED_MIME_TYPES).join(",");
9595
- attachmentInput.multiple = ((_u = attachmentsConfig.maxFiles) != null ? _u : 4) > 1;
10228
+ attachmentInput.accept = ((_x = attachmentsConfig.allowedTypes) != null ? _x : ALL_SUPPORTED_MIME_TYPES).join(",");
10229
+ attachmentInput.multiple = ((_y = attachmentsConfig.maxFiles) != null ? _y : 4) > 1;
9596
10230
  attachmentInput.style.display = "none";
9597
10231
  attachmentInput.setAttribute("aria-label", "Attach files");
9598
10232
  attachmentButtonWrapper = createElement("div", "persona-send-button-wrapper");
@@ -9601,8 +10235,8 @@ var buildComposer = (context) => {
9601
10235
  "persona-rounded-button persona-flex persona-items-center persona-justify-center disabled:persona-opacity-50 persona-cursor-pointer persona-attachment-button"
9602
10236
  );
9603
10237
  attachmentButton.type = "button";
9604
- attachmentButton.setAttribute("aria-label", (_v = attachmentsConfig.buttonTooltipText) != null ? _v : "Attach file");
9605
- const attachIconName = (_w = attachmentsConfig.buttonIconName) != null ? _w : "paperclip";
10238
+ attachmentButton.setAttribute("aria-label", (_z = attachmentsConfig.buttonTooltipText) != null ? _z : "Attach file");
10239
+ const attachIconName = (_A = attachmentsConfig.buttonIconName) != null ? _A : "paperclip";
9606
10240
  const attachIconSize = buttonSize;
9607
10241
  const buttonSizeNum = parseFloat(attachIconSize) || 40;
9608
10242
  const attachIconSizeNum = Math.round(buttonSizeNum * 0.6);
@@ -9639,7 +10273,7 @@ var buildComposer = (context) => {
9639
10273
  attachmentInput == null ? void 0 : attachmentInput.click();
9640
10274
  });
9641
10275
  attachmentButtonWrapper.appendChild(attachmentButton);
9642
- const attachTooltipText = (_x = attachmentsConfig.buttonTooltipText) != null ? _x : "Attach file";
10276
+ const attachTooltipText = (_B = attachmentsConfig.buttonTooltipText) != null ? _B : "Attach file";
9643
10277
  const tooltip = createElement("div", "persona-send-button-tooltip");
9644
10278
  tooltip.textContent = attachTooltipText;
9645
10279
  attachmentButtonWrapper.appendChild(tooltip);
@@ -9669,16 +10303,16 @@ var buildComposer = (context) => {
9669
10303
  rightActions.append(sendButtonWrapper);
9670
10304
  actionsRow.append(leftActions, rightActions);
9671
10305
  composerForm.append(actionsRow);
9672
- const statusConfig = (_y = config == null ? void 0 : config.statusIndicator) != null ? _y : {};
10306
+ const statusConfig = (_C = config == null ? void 0 : config.statusIndicator) != null ? _C : {};
9673
10307
  const alignClass = statusConfig.align === "left" ? "persona-text-left" : statusConfig.align === "center" ? "persona-text-center" : "persona-text-right";
9674
10308
  const statusText = createElement(
9675
10309
  "div",
9676
10310
  `persona-mt-2 ${alignClass} persona-text-xs persona-text-persona-muted`
9677
10311
  );
9678
10312
  statusText.setAttribute("data-persona-composer-status", "");
9679
- const isVisible = (_z = statusConfig.visible) != null ? _z : true;
10313
+ const isVisible = (_D = statusConfig.visible) != null ? _D : true;
9680
10314
  statusText.style.display = isVisible ? "" : "none";
9681
- const idleLabel = (_A = statusConfig.idleText) != null ? _A : "Online";
10315
+ const idleLabel = (_E = statusConfig.idleText) != null ? _E : "Online";
9682
10316
  if (statusConfig.idleLink) {
9683
10317
  const link = createElement("a");
9684
10318
  link.href = statusConfig.idleLink;
@@ -9710,7 +10344,8 @@ var buildComposer = (context) => {
9710
10344
  // Actions row layout elements
9711
10345
  actionsRow,
9712
10346
  leftActions,
9713
- rightActions
10347
+ rightActions,
10348
+ setSendButtonMode
9714
10349
  };
9715
10350
  };
9716
10351
 
@@ -9780,8 +10415,11 @@ var buildPanel = (config, showClose = true) => {
9780
10415
  );
9781
10416
  body.id = "persona-scroll-container";
9782
10417
  body.setAttribute("data-persona-theme-zone", "messages");
9783
- 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";
9784
- const introCard = createElement("div", introCardClasses);
10418
+ const introCard = createElement(
10419
+ "div",
10420
+ "persona-rounded-2xl persona-bg-persona-surface persona-p-6"
10421
+ );
10422
+ introCard.style.boxShadow = isDockedMountMode(config) ? "none" : "var(--persona-intro-card-shadow, 0 5px 15px rgba(15, 23, 42, 0.08))";
9785
10423
  const introTitle = createElement(
9786
10424
  "h2",
9787
10425
  "persona-text-lg persona-font-semibold persona-text-persona-primary"
@@ -9821,16 +10459,28 @@ var buildPanel = (config, showClose = true) => {
9821
10459
  attachHeaderToContainer(container, headerElements, config);
9822
10460
  }
9823
10461
  container.append(body);
10462
+ const composerOverlay = createElement(
10463
+ "div",
10464
+ "persona-composer-overlay persona-pointer-events-none"
10465
+ );
10466
+ composerOverlay.setAttribute("data-persona-composer-overlay", "");
10467
+ composerOverlay.style.position = "absolute";
10468
+ composerOverlay.style.left = "0";
10469
+ composerOverlay.style.right = "0";
10470
+ composerOverlay.style.bottom = "0";
10471
+ composerOverlay.style.zIndex = "20";
9824
10472
  if (showFooter) {
9825
10473
  container.append(composerElements.footer);
9826
10474
  } else {
9827
10475
  composerElements.footer.style.display = "none";
9828
10476
  container.append(composerElements.footer);
9829
10477
  }
10478
+ container.append(composerOverlay);
9830
10479
  return {
9831
10480
  container,
9832
10481
  body,
9833
10482
  messagesWrapper,
10483
+ composerOverlay,
9834
10484
  suggestions: composerElements.suggestions,
9835
10485
  textarea: composerElements.textarea,
9836
10486
  sendButton: composerElements.sendButton,
@@ -9858,11 +10508,48 @@ var buildPanel = (config, showClose = true) => {
9858
10508
  // Actions row layout elements
9859
10509
  actionsRow: composerElements.actionsRow,
9860
10510
  leftActions: composerElements.leftActions,
9861
- rightActions: composerElements.rightActions
10511
+ rightActions: composerElements.rightActions,
10512
+ setSendButtonMode: composerElements.setSendButtonMode
9862
10513
  };
9863
10514
  };
9864
10515
 
9865
10516
  // src/components/message-bubble.ts
10517
+ var getDefaultStopReasonNoticeCopy = (stopReason) => {
10518
+ switch (stopReason) {
10519
+ case "max_tool_calls":
10520
+ return "Stopped after calling a tool. Send a follow-up to continue.";
10521
+ case "length":
10522
+ return "Response cut off as max tokens reached. Ask for more to continue.";
10523
+ case "content_filter":
10524
+ return "The provider filtered this response.";
10525
+ case "error":
10526
+ return "Something went wrong generating this response.";
10527
+ case "end_turn":
10528
+ case "unknown":
10529
+ default:
10530
+ return null;
10531
+ }
10532
+ };
10533
+ var resolveStopReasonNoticeText = (stopReason, overrides) => {
10534
+ if (!stopReason) return null;
10535
+ const fallback = getDefaultStopReasonNoticeCopy(stopReason);
10536
+ if (fallback === null) return null;
10537
+ const override = overrides == null ? void 0 : overrides[stopReason];
10538
+ const text = override !== void 0 ? override : fallback;
10539
+ if (!text) return null;
10540
+ return text;
10541
+ };
10542
+ var createStopReasonNotice = (stopReason, text) => {
10543
+ const notice = createElement(
10544
+ "div",
10545
+ "persona-message-stop-reason persona-text-xs persona-mt-2 persona-italic"
10546
+ );
10547
+ notice.setAttribute("data-stop-reason", stopReason);
10548
+ notice.setAttribute("role", "note");
10549
+ notice.style.opacity = "0.75";
10550
+ notice.textContent = text;
10551
+ return notice;
10552
+ };
9866
10553
  var isSafeImageSrc = (src) => {
9867
10554
  const lower = src.toLowerCase();
9868
10555
  if (lower.startsWith("data:image/svg+xml")) return false;
@@ -10165,7 +10852,7 @@ var createMessageActions = (message, actionsConfig, _callbacks) => {
10165
10852
  return container;
10166
10853
  };
10167
10854
  var createStandardBubble = (message, transform, layoutConfig, actionsConfig, actionCallbacks, options) => {
10168
- var _a, _b, _c, _d, _e, _f, _g;
10855
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
10169
10856
  const config = layoutConfig != null ? layoutConfig : {};
10170
10857
  const layout = (_a = config.layout) != null ? _a : "bubble";
10171
10858
  const avatarConfig = config.avatar;
@@ -10190,22 +10877,73 @@ var createStandardBubble = (message, transform, layoutConfig, actionsConfig, act
10190
10877
  const messageContentText = (_g = (_f = message.content) == null ? void 0 : _f.trim()) != null ? _g : "";
10191
10878
  const isImageOnlyFallbackMessage = imageParts.length > 0 && messageContentText === IMAGE_ONLY_MESSAGE_FALLBACK_TEXT;
10192
10879
  const shouldHideTextUntilPreviewFails = isImageOnlyFallbackMessage;
10880
+ const streamAnimation = resolveStreamAnimation(
10881
+ (_i = (_h = options == null ? void 0 : options.widgetConfig) == null ? void 0 : _h.features) == null ? void 0 : _i.streamAnimation
10882
+ );
10883
+ 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;
10884
+ const streamPlugin = message.role === "assistant" && streamAnimation.type !== "none" ? resolveStreamAnimationPlugin(streamAnimation.type, streamPluginOverrides) : null;
10885
+ const pluginStillAnimating = message.role === "assistant" && ((_m = streamPlugin == null ? void 0 : streamPlugin.isAnimating) == null ? void 0 : _m.call(streamPlugin, message)) === true;
10886
+ const streamAnimationActive = message.role === "assistant" && streamPlugin !== null && (Boolean(message.streaming) || pluginStillAnimating);
10887
+ if (streamAnimationActive && (streamPlugin == null ? void 0 : streamPlugin.bubbleClass)) {
10888
+ bubble.classList.add(streamPlugin.bubbleClass);
10889
+ }
10193
10890
  const contentDiv = document.createElement("div");
10194
10891
  contentDiv.classList.add("persona-message-content");
10892
+ if (streamAnimationActive && streamPlugin) {
10893
+ if (streamPlugin.containerClass) {
10894
+ contentDiv.classList.add(streamPlugin.containerClass);
10895
+ }
10896
+ contentDiv.style.setProperty("--persona-stream-step", `${streamAnimation.speed}ms`);
10897
+ contentDiv.style.setProperty("--persona-stream-duration", `${streamAnimation.duration}ms`);
10898
+ }
10899
+ const bufferedContent = streamAnimationActive ? applyStreamBuffer(
10900
+ (_n = message.content) != null ? _n : "",
10901
+ streamAnimation.buffer,
10902
+ streamPlugin,
10903
+ message,
10904
+ Boolean(message.streaming)
10905
+ ) : (_o = message.content) != null ? _o : "";
10195
10906
  const transformedContent = transform({
10196
- text: message.content,
10907
+ text: bufferedContent,
10197
10908
  message,
10198
10909
  streaming: Boolean(message.streaming),
10199
10910
  raw: message.rawContent
10200
10911
  });
10912
+ let animatedContent = transformedContent;
10913
+ if (streamAnimationActive && (streamPlugin == null ? void 0 : streamPlugin.wrap) === "char") {
10914
+ animatedContent = wrapStreamAnimation(transformedContent, "char", message.id, {
10915
+ skipTags: streamPlugin.skipTags
10916
+ });
10917
+ } else if (streamAnimationActive && (streamPlugin == null ? void 0 : streamPlugin.wrap) === "word") {
10918
+ animatedContent = wrapStreamAnimation(transformedContent, "word", message.id, {
10919
+ skipTags: streamPlugin.skipTags
10920
+ });
10921
+ }
10201
10922
  let textContentDiv = null;
10202
10923
  if (shouldHideTextUntilPreviewFails) {
10203
10924
  textContentDiv = document.createElement("div");
10204
- textContentDiv.innerHTML = transformedContent;
10925
+ textContentDiv.innerHTML = animatedContent;
10205
10926
  textContentDiv.style.display = "none";
10206
10927
  contentDiv.appendChild(textContentDiv);
10207
10928
  } else {
10208
- contentDiv.innerHTML = transformedContent;
10929
+ contentDiv.innerHTML = animatedContent;
10930
+ }
10931
+ if (streamAnimationActive && (streamPlugin == null ? void 0 : streamPlugin.useCaret) && !shouldHideTextUntilPreviewFails && messageContentText) {
10932
+ const caret = createStreamCaret();
10933
+ const spans = contentDiv.querySelectorAll(
10934
+ ".persona-stream-char, .persona-stream-word"
10935
+ );
10936
+ const lastSpan = spans[spans.length - 1];
10937
+ if (lastSpan == null ? void 0 : lastSpan.parentNode) {
10938
+ lastSpan.parentNode.insertBefore(caret, lastSpan.nextSibling);
10939
+ } else {
10940
+ const lastChild = contentDiv.lastElementChild;
10941
+ if (lastChild) {
10942
+ lastChild.appendChild(caret);
10943
+ } else {
10944
+ contentDiv.appendChild(caret);
10945
+ }
10946
+ }
10209
10947
  }
10210
10948
  if (showTimestamp && timestampPosition === "inline" && message.createdAt) {
10211
10949
  const timestamp = createTimestamp(message, timestampConfig);
@@ -10234,18 +10972,37 @@ var createStandardBubble = (message, transform, layoutConfig, actionsConfig, act
10234
10972
  timestamp.classList.add("persona-mt-1");
10235
10973
  bubble.appendChild(timestamp);
10236
10974
  }
10975
+ const stopReasonNoticeText = message.role === "assistant" ? resolveStopReasonNoticeText(
10976
+ message.stopReason,
10977
+ (_q = (_p = options == null ? void 0 : options.widgetConfig) == null ? void 0 : _p.copy) == null ? void 0 : _q.stopReasonNotice
10978
+ ) : null;
10237
10979
  if (message.streaming && message.role === "assistant") {
10238
- if (!message.content || !message.content.trim()) {
10239
- const indicator = renderLoadingIndicatorWithFallback(
10240
- "inline",
10241
- options == null ? void 0 : options.loadingIndicatorRenderer,
10242
- options == null ? void 0 : options.widgetConfig
10243
- );
10244
- if (indicator) {
10245
- bubble.appendChild(indicator);
10980
+ const hasVisibleContent = Boolean(bufferedContent && bufferedContent.trim());
10981
+ const skeletonEnabled = streamAnimation.placeholder === "skeleton";
10982
+ const trailSkeleton = skeletonEnabled && streamAnimation.buffer === "line" && hasVisibleContent;
10983
+ if (!hasVisibleContent) {
10984
+ if (skeletonEnabled) {
10985
+ bubble.appendChild(createSkeletonPlaceholder());
10986
+ } else {
10987
+ const indicator = renderLoadingIndicatorWithFallback(
10988
+ "inline",
10989
+ options == null ? void 0 : options.loadingIndicatorRenderer,
10990
+ options == null ? void 0 : options.widgetConfig
10991
+ );
10992
+ if (indicator) {
10993
+ bubble.appendChild(indicator);
10994
+ }
10246
10995
  }
10996
+ } else if (trailSkeleton) {
10997
+ bubble.appendChild(createSkeletonPlaceholder());
10247
10998
  }
10248
10999
  }
11000
+ if (stopReasonNoticeText && message.stopReason && !message.streaming) {
11001
+ if (!messageContentText) {
11002
+ contentDiv.style.display = "none";
11003
+ }
11004
+ bubble.appendChild(createStopReasonNotice(message.stopReason, stopReasonNoticeText));
11005
+ }
10249
11006
  const shouldShowActions = message.role === "assistant" && !message.streaming && message.content && message.content.trim() && (actionsConfig == null ? void 0 : actionsConfig.enabled) !== false;
10250
11007
  if (shouldShowActions && actionsConfig) {
10251
11008
  const actions = createMessageActions(message, actionsConfig, actionCallbacks);
@@ -10989,6 +11746,582 @@ var createToolBubble = (message, config) => {
10989
11746
  return bubble;
10990
11747
  };
10991
11748
 
11749
+ // src/components/ask-user-question-bubble.ts
11750
+ import { parse as parsePartialJson2, ARR, OBJ as OBJ2, STR as STR2 } from "partial-json";
11751
+ var ASK_USER_QUESTION_TOOL_NAME = "ask_user_question";
11752
+ var ASK_USER_QUESTION_MAX = 8;
11753
+ var SHEET_SENTINEL = "data-persona-ask-sheet-for";
11754
+ var DEFAULT_FREE_TEXT_LABEL_ROWS = "Other";
11755
+ var DEFAULT_FREE_TEXT_LABEL_PILLS = "Other\u2026";
11756
+ var DEFAULT_FREE_TEXT_PLACEHOLDER = "Type your own answer here";
11757
+ var DEFAULT_SUBMIT_LABEL = "Send";
11758
+ var DEFAULT_NEXT_LABEL = "Next";
11759
+ var DEFAULT_BACK_LABEL = "Back";
11760
+ var DEFAULT_SUBMIT_ALL_LABEL = "Submit all";
11761
+ var DEFAULT_SKIP_LABEL = "Skip";
11762
+ var DEFAULT_SKELETON_PILLS = 3;
11763
+ var ATTR_CURRENT_INDEX = "data-ask-current-index";
11764
+ var ATTR_QUESTION_COUNT = "data-ask-question-count";
11765
+ var ATTR_ANSWERS = "data-ask-answers";
11766
+ var ATTR_GROUPED = "data-ask-grouped";
11767
+ var ATTR_LAYOUT = "data-ask-layout";
11768
+ var resolveLayout = (feature) => feature.layout === "pills" ? "pills" : "rows";
11769
+ var getLayout = (sheet) => sheet.getAttribute(ATTR_LAYOUT) === "pills" ? "pills" : "rows";
11770
+ var truncateWarned = false;
11771
+ var escapeAttrValue = (value) => value.replace(/["\\]/g, "\\$&");
11772
+ var isAskUserQuestionMessage = (message) => {
11773
+ return message.variant === "tool" && !!message.toolCall && message.toolCall.name === ASK_USER_QUESTION_TOOL_NAME;
11774
+ };
11775
+ var resolveFeature = (config) => {
11776
+ var _a, _b;
11777
+ return (_b = (_a = config == null ? void 0 : config.features) == null ? void 0 : _a.askUserQuestion) != null ? _b : {};
11778
+ };
11779
+ var parseAskUserQuestionPayload = (message) => {
11780
+ const toolCall = message.toolCall;
11781
+ if (!toolCall) return { payload: null, complete: false };
11782
+ const complete = toolCall.status === "complete";
11783
+ if (toolCall.args && typeof toolCall.args === "object") {
11784
+ return { payload: toolCall.args, complete };
11785
+ }
11786
+ const chunks = toolCall.chunks;
11787
+ if (!chunks || chunks.length === 0) return { payload: null, complete };
11788
+ try {
11789
+ const text = chunks.join("");
11790
+ const parsed = parsePartialJson2(text, STR2 | OBJ2 | ARR);
11791
+ if (parsed && typeof parsed === "object") {
11792
+ return { payload: parsed, complete };
11793
+ }
11794
+ } catch {
11795
+ }
11796
+ return { payload: null, complete };
11797
+ };
11798
+ var promptsFromPayload = (payload) => {
11799
+ const all = Array.isArray(payload == null ? void 0 : payload.questions) ? payload.questions : [];
11800
+ if (all.length > ASK_USER_QUESTION_MAX && !truncateWarned) {
11801
+ truncateWarned = true;
11802
+ if (typeof console !== "undefined") {
11803
+ console.warn(
11804
+ `[AgentWidget] ask_user_question received ${all.length} questions; truncating to ${ASK_USER_QUESTION_MAX}.`
11805
+ );
11806
+ }
11807
+ }
11808
+ return all.slice(0, ASK_USER_QUESTION_MAX);
11809
+ };
11810
+ var firstPrompt = (payload) => {
11811
+ var _a;
11812
+ return (_a = promptsFromPayload(payload)[0]) != null ? _a : null;
11813
+ };
11814
+ var promptAt = (payload, index) => {
11815
+ var _a;
11816
+ return (_a = promptsFromPayload(payload)[index]) != null ? _a : null;
11817
+ };
11818
+ var applyStyleVars = (root, feature) => {
11819
+ const s = feature.styles;
11820
+ if (!s) return;
11821
+ if (s.sheetBackground) root.style.setProperty("--persona-ask-sheet-bg", s.sheetBackground);
11822
+ if (s.sheetBorder) root.style.setProperty("--persona-ask-sheet-border", s.sheetBorder);
11823
+ if (s.sheetShadow) root.style.setProperty("--persona-ask-sheet-shadow", s.sheetShadow);
11824
+ if (s.pillBackground) root.style.setProperty("--persona-ask-pill-bg", s.pillBackground);
11825
+ if (s.pillBackgroundSelected)
11826
+ root.style.setProperty("--persona-ask-pill-bg-selected", s.pillBackgroundSelected);
11827
+ if (s.pillTextColor) root.style.setProperty("--persona-ask-pill-fg", s.pillTextColor);
11828
+ if (s.pillTextColorSelected)
11829
+ root.style.setProperty("--persona-ask-pill-fg-selected", s.pillTextColorSelected);
11830
+ if (s.pillBorderRadius) root.style.setProperty("--persona-ask-pill-radius", s.pillBorderRadius);
11831
+ if (s.customInputBackground)
11832
+ root.style.setProperty("--persona-ask-input-bg", s.customInputBackground);
11833
+ };
11834
+ var buildAffordance = (layout, multiSelect, index) => {
11835
+ if (layout !== "rows") return null;
11836
+ const wrap = createElement("span", "persona-ask-row-affordance");
11837
+ wrap.setAttribute("aria-hidden", "true");
11838
+ if (multiSelect) {
11839
+ const check = createElement("span", "persona-ask-row-check");
11840
+ wrap.appendChild(check);
11841
+ } else {
11842
+ const badge = createElement("span", "persona-ask-row-badge");
11843
+ badge.textContent = String(index + 1);
11844
+ wrap.appendChild(badge);
11845
+ }
11846
+ return wrap;
11847
+ };
11848
+ var buildPill = (option, index, layout, multiSelect) => {
11849
+ const cls = layout === "rows" ? "persona-ask-pill persona-ask-row persona-pointer-events-auto" : "persona-ask-pill persona-pointer-events-auto";
11850
+ const btn = createElement("button", cls);
11851
+ btn.type = "button";
11852
+ btn.setAttribute("role", multiSelect ? "checkbox" : "button");
11853
+ btn.setAttribute("aria-pressed", "false");
11854
+ btn.setAttribute("data-ask-user-action", "pick");
11855
+ btn.setAttribute("data-option-index", String(index));
11856
+ btn.setAttribute("data-option-label", option.label);
11857
+ if (layout === "rows") {
11858
+ const content = createElement("span", "persona-ask-row-content");
11859
+ const label = createElement("span", "persona-ask-row-label");
11860
+ label.textContent = option.label;
11861
+ content.appendChild(label);
11862
+ if (option.description) {
11863
+ const desc = createElement("span", "persona-ask-row-description");
11864
+ desc.textContent = option.description;
11865
+ content.appendChild(desc);
11866
+ }
11867
+ btn.appendChild(content);
11868
+ const aff = buildAffordance(layout, multiSelect, index);
11869
+ if (aff) btn.appendChild(aff);
11870
+ } else {
11871
+ btn.textContent = option.label;
11872
+ if (option.description) btn.title = option.description;
11873
+ }
11874
+ return btn;
11875
+ };
11876
+ var buildSkeletonPill = (layout) => {
11877
+ 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";
11878
+ const el = createElement("span", cls);
11879
+ el.setAttribute("aria-hidden", "true");
11880
+ return el;
11881
+ };
11882
+ var buildPillList = (prompt, feature, complete, layout) => {
11883
+ var _a, _b, _c;
11884
+ 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";
11885
+ const list = createElement("div", baseClass);
11886
+ list.setAttribute("role", "group");
11887
+ list.setAttribute("data-ask-pill-list", "true");
11888
+ const multiSelect = !!(prompt == null ? void 0 : prompt.multiSelect);
11889
+ const realOptions = Array.isArray(prompt == null ? void 0 : prompt.options) ? prompt.options : [];
11890
+ const cleanOptions = realOptions.filter((o) => o && typeof o.label === "string" && o.label.length > 0);
11891
+ if (cleanOptions.length === 0 && !complete) {
11892
+ for (let i = 0; i < DEFAULT_SKELETON_PILLS; i++) {
11893
+ list.appendChild(buildSkeletonPill(layout));
11894
+ }
11895
+ return list;
11896
+ }
11897
+ cleanOptions.forEach((option, index) => {
11898
+ list.appendChild(buildPill(option, index, layout, multiSelect));
11899
+ });
11900
+ const allowFreeText = (prompt == null ? void 0 : prompt.allowFreeText) !== false;
11901
+ if (allowFreeText) {
11902
+ const defaultLabel = layout === "rows" ? DEFAULT_FREE_TEXT_LABEL_ROWS : DEFAULT_FREE_TEXT_LABEL_PILLS;
11903
+ if (layout === "rows") {
11904
+ const otherRow = createElement(
11905
+ "div",
11906
+ "persona-ask-pill persona-ask-row persona-ask-row--other persona-ask-pill-custom persona-pointer-events-auto"
11907
+ );
11908
+ otherRow.setAttribute("data-ask-user-action", "focus-free-text");
11909
+ otherRow.setAttribute("data-option-index", String(cleanOptions.length));
11910
+ otherRow.setAttribute("data-ask-other-row", "true");
11911
+ const content = createElement("span", "persona-ask-row-content");
11912
+ const input = document.createElement("input");
11913
+ input.type = "text";
11914
+ input.className = "persona-ask-row-input persona-flex-1 persona-pointer-events-auto";
11915
+ input.placeholder = (_a = feature.freeTextPlaceholder) != null ? _a : DEFAULT_FREE_TEXT_PLACEHOLDER;
11916
+ input.setAttribute("data-ask-free-text-input", "true");
11917
+ input.setAttribute(
11918
+ "aria-label",
11919
+ (_b = feature.freeTextLabel) != null ? _b : defaultLabel
11920
+ );
11921
+ content.appendChild(input);
11922
+ otherRow.appendChild(content);
11923
+ const aff = buildAffordance(layout, multiSelect, cleanOptions.length);
11924
+ if (aff) otherRow.appendChild(aff);
11925
+ list.appendChild(otherRow);
11926
+ } else {
11927
+ const freeBtn = createElement(
11928
+ "button",
11929
+ "persona-ask-pill persona-ask-pill-custom persona-pointer-events-auto"
11930
+ );
11931
+ freeBtn.type = "button";
11932
+ freeBtn.setAttribute("data-ask-user-action", "open-free-text");
11933
+ freeBtn.textContent = (_c = feature.freeTextLabel) != null ? _c : defaultLabel;
11934
+ list.appendChild(freeBtn);
11935
+ }
11936
+ }
11937
+ return list;
11938
+ };
11939
+ var buildFreeTextRow = (feature, layout) => {
11940
+ var _a, _b;
11941
+ 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";
11942
+ const row = createElement("div", cls);
11943
+ row.setAttribute("data-ask-free-text-row", "true");
11944
+ const input = document.createElement("input");
11945
+ input.type = "text";
11946
+ input.className = "persona-ask-free-text-input persona-flex-1 persona-pointer-events-auto";
11947
+ input.placeholder = (_a = feature.freeTextPlaceholder) != null ? _a : DEFAULT_FREE_TEXT_PLACEHOLDER;
11948
+ input.setAttribute("data-ask-free-text-input", "true");
11949
+ row.appendChild(input);
11950
+ if (layout !== "rows") {
11951
+ const submit = createElement(
11952
+ "button",
11953
+ "persona-ask-free-text-submit persona-pointer-events-auto"
11954
+ );
11955
+ submit.type = "button";
11956
+ submit.textContent = (_b = feature.submitLabel) != null ? _b : DEFAULT_SUBMIT_LABEL;
11957
+ submit.setAttribute("data-ask-user-action", "submit-free-text");
11958
+ row.appendChild(submit);
11959
+ }
11960
+ return row;
11961
+ };
11962
+ var buildMultiSelectActions = (feature) => {
11963
+ var _a;
11964
+ const row = createElement(
11965
+ "div",
11966
+ "persona-ask-multi-actions persona-flex persona-justify-end persona-mt-2"
11967
+ );
11968
+ row.setAttribute("data-ask-multi-actions", "true");
11969
+ const submit = createElement(
11970
+ "button",
11971
+ "persona-ask-multi-submit persona-pointer-events-auto"
11972
+ );
11973
+ submit.type = "button";
11974
+ submit.textContent = (_a = feature.submitLabel) != null ? _a : DEFAULT_SUBMIT_LABEL;
11975
+ submit.setAttribute("data-ask-user-action", "submit-multi");
11976
+ submit.disabled = true;
11977
+ row.appendChild(submit);
11978
+ return row;
11979
+ };
11980
+ var buildNavRow = (index, count, feature) => {
11981
+ var _a, _b, _c, _d;
11982
+ const row = createElement(
11983
+ "div",
11984
+ "persona-ask-nav persona-flex persona-justify-between persona-items-center persona-gap-2 persona-mt-2"
11985
+ );
11986
+ row.setAttribute("data-ask-nav-row", "true");
11987
+ const back = createElement(
11988
+ "button",
11989
+ "persona-ask-nav-back persona-pointer-events-auto"
11990
+ );
11991
+ back.type = "button";
11992
+ back.textContent = (_a = feature.backLabel) != null ? _a : DEFAULT_BACK_LABEL;
11993
+ back.setAttribute("data-ask-user-action", "back");
11994
+ back.disabled = index === 0;
11995
+ row.appendChild(back);
11996
+ const rightGroup = createElement(
11997
+ "div",
11998
+ "persona-ask-nav-right persona-flex persona-items-center persona-gap-2"
11999
+ );
12000
+ const skip = createElement(
12001
+ "button",
12002
+ "persona-ask-nav-skip persona-pointer-events-auto"
12003
+ );
12004
+ skip.type = "button";
12005
+ skip.textContent = (_b = feature.skipLabel) != null ? _b : DEFAULT_SKIP_LABEL;
12006
+ skip.setAttribute("data-ask-user-action", "skip");
12007
+ rightGroup.appendChild(skip);
12008
+ const next = createElement(
12009
+ "button",
12010
+ "persona-ask-nav-next persona-pointer-events-auto"
12011
+ );
12012
+ next.type = "button";
12013
+ const isFinal = index === count - 1;
12014
+ next.textContent = isFinal ? (_c = feature.submitAllLabel) != null ? _c : DEFAULT_SUBMIT_ALL_LABEL : (_d = feature.nextLabel) != null ? _d : DEFAULT_NEXT_LABEL;
12015
+ next.setAttribute("data-ask-user-action", isFinal ? "submit-all" : "next");
12016
+ next.disabled = true;
12017
+ rightGroup.appendChild(next);
12018
+ row.appendChild(rightGroup);
12019
+ return row;
12020
+ };
12021
+ var readAnswersFromSheet = (sheet) => {
12022
+ const raw = sheet.getAttribute(ATTR_ANSWERS);
12023
+ if (!raw) return {};
12024
+ try {
12025
+ const parsed = JSON.parse(raw);
12026
+ return parsed && typeof parsed === "object" ? parsed : {};
12027
+ } catch {
12028
+ return {};
12029
+ }
12030
+ };
12031
+ var writeAnswersToSheet = (sheet, answers) => {
12032
+ sheet.setAttribute(ATTR_ANSWERS, JSON.stringify(answers));
12033
+ };
12034
+ var getCurrentIndex = (sheet) => {
12035
+ var _a;
12036
+ const raw = Number((_a = sheet.getAttribute(ATTR_CURRENT_INDEX)) != null ? _a : "0");
12037
+ return Number.isFinite(raw) ? Math.max(0, Math.floor(raw)) : 0;
12038
+ };
12039
+ var setCurrentIndex = (sheet, index) => {
12040
+ sheet.setAttribute(ATTR_CURRENT_INDEX, String(Math.max(0, Math.floor(index))));
12041
+ };
12042
+ var getQuestionCount = (sheet) => {
12043
+ var _a;
12044
+ const raw = Number((_a = sheet.getAttribute(ATTR_QUESTION_COUNT)) != null ? _a : "1");
12045
+ return Number.isFinite(raw) ? Math.max(1, Math.floor(raw)) : 1;
12046
+ };
12047
+ var isGroupedSheet = (sheet) => {
12048
+ return sheet.getAttribute(ATTR_GROUPED) === "true";
12049
+ };
12050
+ var restoreAnswersFromMessage = (message, prompts) => {
12051
+ var _a;
12052
+ const stored = (_a = message.agentMetadata) == null ? void 0 : _a.askUserQuestionAnswers;
12053
+ if (!stored || typeof stored !== "object") return {};
12054
+ const result = {};
12055
+ prompts.forEach((p, i) => {
12056
+ const q = typeof (p == null ? void 0 : p.question) === "string" ? p.question : "";
12057
+ if (q && Object.prototype.hasOwnProperty.call(stored, q)) {
12058
+ const v = stored[q];
12059
+ if (typeof v === "string" || Array.isArray(v)) {
12060
+ result[i] = v;
12061
+ }
12062
+ }
12063
+ });
12064
+ return result;
12065
+ };
12066
+ var restoreIndexFromMessage = (message, count) => {
12067
+ var _a;
12068
+ const stored = (_a = message.agentMetadata) == null ? void 0 : _a.askUserQuestionIndex;
12069
+ if (typeof stored !== "number" || !Number.isFinite(stored)) return 0;
12070
+ return Math.max(0, Math.min(count - 1, Math.floor(stored)));
12071
+ };
12072
+ var buildStructuredAnswers = (sheet, message) => {
12073
+ const { payload } = parseAskUserQuestionPayload(message);
12074
+ const prompts = promptsFromPayload(payload);
12075
+ const indexed = readAnswersFromSheet(sheet);
12076
+ const result = {};
12077
+ const seen = /* @__PURE__ */ new Set();
12078
+ prompts.forEach((p, i) => {
12079
+ const q = typeof (p == null ? void 0 : p.question) === "string" ? p.question : "";
12080
+ if (!q) return;
12081
+ if (seen.has(q) && typeof console !== "undefined") {
12082
+ console.warn(`[AgentWidget] ask_user_question has duplicate question text "${q}"; later answer wins.`);
12083
+ }
12084
+ seen.add(q);
12085
+ if (Object.prototype.hasOwnProperty.call(indexed, i)) {
12086
+ result[q] = indexed[i];
12087
+ }
12088
+ });
12089
+ return result;
12090
+ };
12091
+ var applySelectionState = (sheet) => {
12092
+ const answers = readAnswersFromSheet(sheet);
12093
+ const currentIndex = getCurrentIndex(sheet);
12094
+ const stored = answers[currentIndex];
12095
+ const selected = /* @__PURE__ */ new Set();
12096
+ if (typeof stored === "string") selected.add(stored);
12097
+ else if (Array.isArray(stored)) stored.forEach((s) => selected.add(s));
12098
+ const pills = sheet.querySelectorAll('[data-ask-user-action="pick"][data-option-label]');
12099
+ pills.forEach((pill) => {
12100
+ var _a;
12101
+ const label = (_a = pill.getAttribute("data-option-label")) != null ? _a : "";
12102
+ const on = selected.has(label);
12103
+ pill.setAttribute("aria-pressed", on ? "true" : "false");
12104
+ pill.classList.toggle("persona-ask-pill-selected", on);
12105
+ });
12106
+ const realPillLabels = new Set(
12107
+ Array.from(pills).map((p) => {
12108
+ var _a;
12109
+ return (_a = p.getAttribute("data-option-label")) != null ? _a : "";
12110
+ })
12111
+ );
12112
+ const freeInput = sheet.querySelector('[data-ask-free-text-input="true"]');
12113
+ if (freeInput) {
12114
+ if (typeof stored === "string" && stored.length > 0 && !realPillLabels.has(stored)) {
12115
+ freeInput.value = stored;
12116
+ const freeRow = freeInput.closest('[data-ask-free-text-row="true"]');
12117
+ freeRow == null ? void 0 : freeRow.classList.remove("persona-hidden");
12118
+ } else {
12119
+ freeInput.value = "";
12120
+ }
12121
+ }
12122
+ };
12123
+ var syncNavState = (sheet) => {
12124
+ if (!isGroupedSheet(sheet)) return;
12125
+ const answers = readAnswersFromSheet(sheet);
12126
+ const currentIndex = getCurrentIndex(sheet);
12127
+ const v = answers[currentIndex];
12128
+ const hasAnswer = typeof v === "string" && v.length > 0 || Array.isArray(v) && v.length > 0;
12129
+ const next = sheet.querySelector(
12130
+ '[data-ask-user-action="next"], [data-ask-user-action="submit-all"]'
12131
+ );
12132
+ if (next) next.disabled = !hasAnswer;
12133
+ const multi = sheet.querySelector('[data-ask-user-action="submit-multi"]');
12134
+ if (multi) {
12135
+ const labels = Array.from(
12136
+ sheet.querySelectorAll('[aria-pressed="true"][data-option-label]')
12137
+ );
12138
+ multi.disabled = labels.length === 0;
12139
+ }
12140
+ };
12141
+ var renderCurrentPage = (sheet, message, config) => {
12142
+ const feature = resolveFeature(config);
12143
+ const layout = getLayout(sheet);
12144
+ const { payload, complete } = parseAskUserQuestionPayload(message);
12145
+ const grouped = isGroupedSheet(sheet);
12146
+ const index = getCurrentIndex(sheet);
12147
+ const count = getQuestionCount(sheet);
12148
+ const prompt = grouped ? promptAt(payload, index) : firstPrompt(payload);
12149
+ const multiSelect = !!(prompt == null ? void 0 : prompt.multiSelect);
12150
+ const stepInline = sheet.querySelector('[data-ask-step-inline="true"]');
12151
+ if (stepInline) {
12152
+ stepInline.textContent = grouped ? `${index + 1}/${count}` : "";
12153
+ }
12154
+ const oldStepper = sheet.querySelector('[data-ask-stepper="true"]');
12155
+ if (oldStepper) oldStepper.remove();
12156
+ const qText = sheet.querySelector('[data-ask-question="true"]');
12157
+ if (qText) {
12158
+ const text = typeof (prompt == null ? void 0 : prompt.question) === "string" ? prompt.question : "";
12159
+ qText.textContent = text;
12160
+ qText.classList.toggle("persona-ask-question-skeleton", !text && !complete);
12161
+ }
12162
+ const pillList = sheet.querySelector('[data-ask-pill-list="true"]');
12163
+ if (pillList) {
12164
+ const fresh = buildPillList(prompt, feature, complete, layout);
12165
+ pillList.replaceWith(fresh);
12166
+ }
12167
+ if (layout !== "rows") {
12168
+ const oldFree = sheet.querySelector('[data-ask-free-text-row="true"]');
12169
+ if (oldFree) oldFree.replaceWith(buildFreeTextRow(feature, layout));
12170
+ }
12171
+ const oldMulti = sheet.querySelector('[data-ask-multi-actions="true"]');
12172
+ if (!grouped && multiSelect && !oldMulti) {
12173
+ sheet.appendChild(buildMultiSelectActions(feature));
12174
+ } else if ((!multiSelect || grouped) && oldMulti) {
12175
+ oldMulti.remove();
12176
+ }
12177
+ sheet.setAttribute("data-multi-select", multiSelect ? "true" : "false");
12178
+ const oldNav = sheet.querySelector('[data-ask-nav-row="true"]');
12179
+ if (grouped) {
12180
+ const fresh = buildNavRow(index, count, feature);
12181
+ if (oldNav) oldNav.replaceWith(fresh);
12182
+ else sheet.appendChild(fresh);
12183
+ } else if (oldNav) {
12184
+ oldNav.remove();
12185
+ }
12186
+ applySelectionState(sheet);
12187
+ syncNavState(sheet);
12188
+ };
12189
+ var buildSheet = (message, config, payload) => {
12190
+ const feature = resolveFeature(config);
12191
+ const layout = resolveLayout(feature);
12192
+ const toolCallId = message.toolCall.id;
12193
+ const prompts = promptsFromPayload(payload);
12194
+ const count = Math.max(1, prompts.length);
12195
+ const grouped = count > 1;
12196
+ const initialAnswers = restoreAnswersFromMessage(message, prompts);
12197
+ const initialIndex = grouped ? restoreIndexFromMessage(message, count) : 0;
12198
+ const sheet = createElement(
12199
+ "div",
12200
+ [
12201
+ "persona-ask-sheet",
12202
+ `persona-ask-sheet--${layout}`,
12203
+ "persona-pointer-events-auto",
12204
+ "persona-ask-sheet-enter"
12205
+ ].join(" ")
12206
+ );
12207
+ sheet.setAttribute(SHEET_SENTINEL, toolCallId);
12208
+ sheet.setAttribute("data-tool-call-id", toolCallId);
12209
+ sheet.setAttribute("data-message-id", message.id);
12210
+ sheet.setAttribute(ATTR_QUESTION_COUNT, String(count));
12211
+ sheet.setAttribute(ATTR_CURRENT_INDEX, String(initialIndex));
12212
+ sheet.setAttribute(ATTR_GROUPED, grouped ? "true" : "false");
12213
+ sheet.setAttribute(ATTR_LAYOUT, layout);
12214
+ writeAnswersToSheet(sheet, initialAnswers);
12215
+ sheet.setAttribute("role", "group");
12216
+ sheet.setAttribute("aria-label", "Suggested answers");
12217
+ if (feature.slideInMs !== void 0) {
12218
+ sheet.style.setProperty("--persona-ask-sheet-duration", `${feature.slideInMs}ms`);
12219
+ }
12220
+ applyStyleVars(sheet, feature);
12221
+ const header = createElement(
12222
+ "div",
12223
+ "persona-ask-sheet-header persona-flex persona-items-center persona-gap-3"
12224
+ );
12225
+ const qText = createElement("div", "persona-ask-sheet-question persona-flex-1");
12226
+ qText.setAttribute("data-ask-question", "true");
12227
+ qText.textContent = "";
12228
+ header.appendChild(qText);
12229
+ const stepInline = createElement(
12230
+ "span",
12231
+ "persona-ask-sheet-step-inline"
12232
+ );
12233
+ stepInline.setAttribute("data-ask-step-inline", "true");
12234
+ stepInline.textContent = "";
12235
+ header.appendChild(stepInline);
12236
+ sheet.appendChild(header);
12237
+ 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";
12238
+ const list = createElement("div", skeletonClass);
12239
+ list.setAttribute("data-ask-pill-list", "true");
12240
+ list.setAttribute("role", "group");
12241
+ sheet.appendChild(list);
12242
+ if (layout !== "rows") {
12243
+ sheet.appendChild(buildFreeTextRow(feature, layout));
12244
+ }
12245
+ renderCurrentPage(sheet, message, config);
12246
+ requestAnimationFrame(() => {
12247
+ requestAnimationFrame(() => sheet.classList.remove("persona-ask-sheet-enter"));
12248
+ });
12249
+ return sheet;
12250
+ };
12251
+ var syncSheetFromMessage = (sheet, message, config) => {
12252
+ const { payload } = parseAskUserQuestionPayload(message);
12253
+ const newCount = Math.max(1, promptsFromPayload(payload).length);
12254
+ if (newCount > getQuestionCount(sheet)) {
12255
+ sheet.setAttribute(ATTR_QUESTION_COUNT, String(newCount));
12256
+ if (newCount > 1 && !isGroupedSheet(sheet)) {
12257
+ sheet.setAttribute(ATTR_GROUPED, "true");
12258
+ }
12259
+ }
12260
+ renderCurrentPage(sheet, message, config);
12261
+ };
12262
+ var ensureAskUserQuestionSheet = (message, config, overlay) => {
12263
+ if (!overlay) return;
12264
+ if (!isAskUserQuestionMessage(message)) return;
12265
+ const feature = resolveFeature(config);
12266
+ if (feature.enabled === false) return;
12267
+ const toolCallId = message.toolCall.id;
12268
+ const siblings = overlay.querySelectorAll(`[${SHEET_SENTINEL}]`);
12269
+ siblings.forEach((el) => {
12270
+ if (el.getAttribute(SHEET_SENTINEL) !== toolCallId) {
12271
+ el.remove();
12272
+ }
12273
+ });
12274
+ const existing = overlay.querySelector(
12275
+ `[${SHEET_SENTINEL}="${escapeAttrValue(toolCallId)}"]`
12276
+ );
12277
+ if (existing) {
12278
+ syncSheetFromMessage(existing, message, config);
12279
+ return;
12280
+ }
12281
+ const { payload } = parseAskUserQuestionPayload(message);
12282
+ const sheet = buildSheet(message, config, payload);
12283
+ overlay.appendChild(sheet);
12284
+ };
12285
+ var removeAskUserQuestionSheet = (overlay, toolCallId) => {
12286
+ if (!overlay) return;
12287
+ const selector = toolCallId ? `[${SHEET_SENTINEL}="${escapeAttrValue(toolCallId)}"]` : `[${SHEET_SENTINEL}]`;
12288
+ const sheets = overlay.querySelectorAll(selector);
12289
+ sheets.forEach((sheet) => {
12290
+ sheet.classList.add("persona-ask-sheet-leave");
12291
+ const duration = Number.parseInt(
12292
+ getComputedStyle(sheet).getPropertyValue("--persona-ask-sheet-duration") || "180",
12293
+ 10
12294
+ );
12295
+ const remove = () => sheet.remove();
12296
+ setTimeout(remove, Number.isFinite(duration) ? duration : 180);
12297
+ });
12298
+ };
12299
+ var getSelectedLabels = (sheet) => {
12300
+ return Array.from(
12301
+ sheet.querySelectorAll('[aria-pressed="true"][data-option-label]')
12302
+ ).map((el) => el.getAttribute("data-option-label")).filter((label) => typeof label === "string" && label.length > 0);
12303
+ };
12304
+ var setCurrentAnswer = (sheet, answer) => {
12305
+ const answers = readAnswersFromSheet(sheet);
12306
+ const idx = getCurrentIndex(sheet);
12307
+ if (typeof answer === "string" && answer.length === 0) {
12308
+ delete answers[idx];
12309
+ } else if (Array.isArray(answer) && answer.length === 0) {
12310
+ delete answers[idx];
12311
+ } else {
12312
+ answers[idx] = answer;
12313
+ }
12314
+ writeAnswersToSheet(sheet, answers);
12315
+ applySelectionState(sheet);
12316
+ syncNavState(sheet);
12317
+ };
12318
+ var navigateToPage = (sheet, message, config, index) => {
12319
+ const count = getQuestionCount(sheet);
12320
+ const clamped = Math.max(0, Math.min(count - 1, index));
12321
+ setCurrentIndex(sheet, clamped);
12322
+ renderCurrentPage(sheet, message, config);
12323
+ };
12324
+
10992
12325
  // src/components/approval-bubble.ts
10993
12326
  var createApprovalBubble = (message, config) => {
10994
12327
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
@@ -13397,6 +14730,10 @@ var sanitizeMessages = (messages) => messages.map((message) => ({
13397
14730
  ...message,
13398
14731
  streaming: false
13399
14732
  }));
14733
+ var sanitizeArtifacts = (artifacts) => artifacts.map((artifact) => ({
14734
+ ...artifact,
14735
+ status: "complete"
14736
+ }));
13400
14737
  var createLocalStorageAdapter = (key = "persona-state") => {
13401
14738
  const getStorage = () => {
13402
14739
  if (typeof window === "undefined" || !window.localStorage) {
@@ -13416,7 +14753,8 @@ var createLocalStorageAdapter = (key = "persona-state") => {
13416
14753
  try {
13417
14754
  const payload = {
13418
14755
  ...state,
13419
- messages: state.messages ? sanitizeMessages(state.messages) : void 0
14756
+ messages: state.messages ? sanitizeMessages(state.messages) : void 0,
14757
+ artifacts: state.artifacts ? sanitizeArtifacts(state.artifacts) : void 0
13420
14758
  };
13421
14759
  storage.setItem(key, JSON.stringify(payload));
13422
14760
  } catch (error) {
@@ -13440,7 +14778,7 @@ var createLocalStorageAdapter = (key = "persona-state") => {
13440
14778
  };
13441
14779
 
13442
14780
  // src/utils/component-parser.ts
13443
- import { parse as parsePartialJson2, STR as STR2, OBJ as OBJ2 } from "partial-json";
14781
+ import { parse as parsePartialJson3, STR as STR3, OBJ as OBJ3 } from "partial-json";
13444
14782
 
13445
14783
  // src/utils/component-middleware.ts
13446
14784
  function renderComponentDirective(directive, options) {
@@ -13916,7 +15254,7 @@ function buildDropOverlay(dropCfg) {
13916
15254
  return overlay;
13917
15255
  }
13918
15256
  var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
13919
- 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;
15257
+ 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;
13920
15258
  if (mount == null) {
13921
15259
  throw new Error(
13922
15260
  'createAgentExperience: mount must be a non-null HTMLElement (e.g. pass document.getElementById("my-root") after the node exists).'
@@ -13975,6 +15313,13 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
13975
15313
  if ((_b = processedState.messages) == null ? void 0 : _b.length) {
13976
15314
  config = { ...config, initialMessages: processedState.messages };
13977
15315
  }
15316
+ if ((_c = processedState.artifacts) == null ? void 0 : _c.length) {
15317
+ config = {
15318
+ ...config,
15319
+ initialArtifacts: processedState.artifacts,
15320
+ initialSelectedArtifactId: (_d = processedState.selectedArtifactId) != null ? _d : null
15321
+ };
15322
+ }
13978
15323
  }
13979
15324
  } catch (error) {
13980
15325
  if (typeof console !== "undefined") {
@@ -13984,7 +15329,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
13984
15329
  } else if (config.onStateLoaded) {
13985
15330
  try {
13986
15331
  const processedState = applyStateLoadedHook({ messages: [], metadata: {} });
13987
- if ((_c = processedState.messages) == null ? void 0 : _c.length) {
15332
+ if ((_e = processedState.messages) == null ? void 0 : _e.length) {
13988
15333
  config = { ...config, initialMessages: processedState.messages };
13989
15334
  }
13990
15335
  } catch (error) {
@@ -14011,12 +15356,12 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
14011
15356
  documentRef: typeof document !== "undefined" ? document : null
14012
15357
  });
14013
15358
  actionManager.syncFromMetadata();
14014
- let launcherEnabled = (_e = (_d = config.launcher) == null ? void 0 : _d.enabled) != null ? _e : true;
14015
- let autoExpand = (_g = (_f = config.launcher) == null ? void 0 : _f.autoExpand) != null ? _g : false;
14016
- const autoFocusInput = (_h = config.autoFocusInput) != null ? _h : false;
15359
+ let launcherEnabled = (_g = (_f = config.launcher) == null ? void 0 : _f.enabled) != null ? _g : true;
15360
+ let autoExpand = (_i = (_h = config.launcher) == null ? void 0 : _h.autoExpand) != null ? _i : false;
15361
+ const autoFocusInput = (_j = config.autoFocusInput) != null ? _j : false;
14017
15362
  let prevAutoExpand = autoExpand;
14018
15363
  let prevLauncherEnabled = launcherEnabled;
14019
- let prevHeaderLayout = (_j = (_i = config.layout) == null ? void 0 : _i.header) == null ? void 0 : _j.layout;
15364
+ let prevHeaderLayout = (_l = (_k = config.layout) == null ? void 0 : _k.header) == null ? void 0 : _l.layout;
14020
15365
  let wasMobileFullscreen = false;
14021
15366
  let open = launcherEnabled ? autoExpand : true;
14022
15367
  let pendingResubmit = false;
@@ -14036,14 +15381,14 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
14036
15381
  }, 1e4);
14037
15382
  };
14038
15383
  let postprocess = buildPostprocessor(config, actionManager, handleResubmitRequested);
14039
- let showReasoning = (_l = (_k = config.features) == null ? void 0 : _k.showReasoning) != null ? _l : true;
14040
- let showToolCalls = (_n = (_m = config.features) == null ? void 0 : _m.showToolCalls) != null ? _n : true;
14041
- let showEventStreamToggle = (_p = (_o = config.features) == null ? void 0 : _o.showEventStreamToggle) != null ? _p : false;
14042
- let scrollToBottomFeature = (_r = (_q = config.features) == null ? void 0 : _q.scrollToBottom) != null ? _r : {};
14043
- const persistKeyPrefix = (_t = typeof config.persistState === "object" ? (_s = config.persistState) == null ? void 0 : _s.keyPrefix : void 0) != null ? _t : "persona-";
15384
+ let showReasoning = (_n = (_m = config.features) == null ? void 0 : _m.showReasoning) != null ? _n : true;
15385
+ let showToolCalls = (_p = (_o = config.features) == null ? void 0 : _o.showToolCalls) != null ? _p : true;
15386
+ let showEventStreamToggle = (_r = (_q = config.features) == null ? void 0 : _q.showEventStreamToggle) != null ? _r : false;
15387
+ let scrollToBottomFeature = (_t = (_s = config.features) == null ? void 0 : _s.scrollToBottom) != null ? _t : {};
15388
+ const persistKeyPrefix = (_v = typeof config.persistState === "object" ? (_u = config.persistState) == null ? void 0 : _u.keyPrefix : void 0) != null ? _v : "persona-";
14044
15389
  const eventStreamDbName = `${persistKeyPrefix}event-stream`;
14045
15390
  let eventStreamStore = showEventStreamToggle ? new EventStreamStore(eventStreamDbName) : null;
14046
- const eventStreamMaxEvents = (_w = (_v = (_u = config.features) == null ? void 0 : _u.eventStream) == null ? void 0 : _v.maxEvents) != null ? _w : 2e3;
15391
+ const eventStreamMaxEvents = (_y = (_x = (_w = config.features) == null ? void 0 : _w.eventStream) == null ? void 0 : _x.maxEvents) != null ? _y : 2e3;
14047
15392
  let eventStreamBuffer = showEventStreamToggle ? new EventStreamBuffer(eventStreamMaxEvents, eventStreamStore) : null;
14048
15393
  let eventStreamView = null;
14049
15394
  let eventStreamVisible = false;
@@ -14080,7 +15425,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
14080
15425
  (_b2 = (_a2 = config.messageActions) == null ? void 0 : _a2.onFeedback) == null ? void 0 : _b2.call(_a2, feedback);
14081
15426
  }
14082
15427
  };
14083
- const statusConfig = (_x = config.statusIndicator) != null ? _x : {};
15428
+ const statusConfig = (_z = config.statusIndicator) != null ? _z : {};
14084
15429
  const _getStatusText = (status) => {
14085
15430
  var _a2, _b2, _c2, _d2;
14086
15431
  if (status === "idle") return (_a2 = statusConfig.idleText) != null ? _a2 : statusCopy.idle;
@@ -14128,6 +15473,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
14128
15473
  leftActions,
14129
15474
  rightActions
14130
15475
  } = panelElements;
15476
+ let setSendButtonMode = panelElements.setSendButtonMode;
14131
15477
  let micButton = panelElements.micButton;
14132
15478
  let micButtonWrapper = panelElements.micButtonWrapper;
14133
15479
  let attachmentButton = panelElements.attachmentButton;
@@ -14260,7 +15606,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
14260
15606
  };
14261
15607
  let eventStreamToggleBtn = null;
14262
15608
  if (showEventStreamToggle) {
14263
- const esClassNames = (_z = (_y = config.features) == null ? void 0 : _y.eventStream) == null ? void 0 : _z.classNames;
15609
+ const esClassNames = (_B = (_A = config.features) == null ? void 0 : _A.eventStream) == null ? void 0 : _B.classNames;
14264
15610
  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 : "");
14265
15611
  eventStreamToggleBtn = createElement("button", toggleBtnClasses);
14266
15612
  eventStreamToggleBtn.style.width = "28px";
@@ -14356,7 +15702,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
14356
15702
  config.agent = { ...config.agent, model: modelId };
14357
15703
  }
14358
15704
  },
14359
- onVoiceToggle: ((_A = config.voiceRecognition) == null ? void 0 : _A.enabled) === true ? () => {
15705
+ onVoiceToggle: ((_C = config.voiceRecognition) == null ? void 0 : _C.enabled) === true ? () => {
14360
15706
  composerVoiceBridge == null ? void 0 : composerVoiceBridge();
14361
15707
  } : void 0
14362
15708
  });
@@ -14395,7 +15741,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
14395
15741
  };
14396
15742
  ensureComposerAttachmentSurface(footer);
14397
15743
  bindComposerRefsFromFooter(footer);
14398
- const contentMaxWidth = (_B = config.layout) == null ? void 0 : _B.contentMaxWidth;
15744
+ const contentMaxWidth = (_D = config.layout) == null ? void 0 : _D.contentMaxWidth;
14399
15745
  if (contentMaxWidth && composerForm) {
14400
15746
  composerForm.style.maxWidth = contentMaxWidth;
14401
15747
  composerForm.style.marginLeft = "auto";
@@ -14411,7 +15757,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
14411
15757
  attachmentPreviewsContainer.style.marginLeft = "auto";
14412
15758
  attachmentPreviewsContainer.style.marginRight = "auto";
14413
15759
  }
14414
- if (((_C = config.attachments) == null ? void 0 : _C.enabled) && attachmentInput && attachmentPreviewsContainer) {
15760
+ if (((_E = config.attachments) == null ? void 0 : _E.enabled) && attachmentInput && attachmentPreviewsContainer) {
14415
15761
  attachmentManager = AttachmentManager.fromConfig(config.attachments);
14416
15762
  attachmentManager.setPreviewsContainer(attachmentPreviewsContainer);
14417
15763
  attachmentInput.addEventListener("change", (e) => {
@@ -14723,6 +16069,300 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
14723
16069
  event.preventDefault();
14724
16070
  target.click();
14725
16071
  });
16072
+ const askUserOverlay = panelElements.composerOverlay;
16073
+ const submitAskUserAnswer = (sheet, text, meta) => {
16074
+ var _a2, _b2, _c2, _d2;
16075
+ const trimmed = text.trim();
16076
+ if (!trimmed || !sessionRef.current) return;
16077
+ const toolCallId = (_a2 = sheet.getAttribute("data-tool-call-id")) != null ? _a2 : "";
16078
+ const isFreeText = meta.source === "free-text";
16079
+ mount.dispatchEvent(
16080
+ new CustomEvent("persona:askUserQuestion:answered", {
16081
+ detail: {
16082
+ toolUseId: toolCallId,
16083
+ answer: trimmed,
16084
+ answers: meta.structured,
16085
+ values: (_b2 = meta.values) != null ? _b2 : meta.source === "multi" ? trimmed.split(", ") : [trimmed],
16086
+ isFreeText,
16087
+ source: meta.source
16088
+ },
16089
+ bubbles: true,
16090
+ composed: true
16091
+ })
16092
+ );
16093
+ removeAskUserQuestionSheet(askUserOverlay, toolCallId);
16094
+ const sourceMessage = sessionRef.current.getMessages().find((m) => {
16095
+ var _a3;
16096
+ return ((_a3 = m.toolCall) == null ? void 0 : _a3.id) === toolCallId;
16097
+ });
16098
+ if ((_c2 = sourceMessage == null ? void 0 : sourceMessage.agentMetadata) == null ? void 0 : _c2.awaitingLocalTool) {
16099
+ sessionRef.current.resolveAskUserQuestion(sourceMessage, (_d2 = meta.structured) != null ? _d2 : trimmed);
16100
+ } else {
16101
+ sessionRef.current.sendMessage(trimmed);
16102
+ }
16103
+ };
16104
+ const persistGroupedProgress = (sheet) => {
16105
+ var _a2;
16106
+ const session2 = sessionRef.current;
16107
+ if (!session2) return;
16108
+ const toolCallId = (_a2 = sheet.getAttribute("data-tool-call-id")) != null ? _a2 : "";
16109
+ const sourceMessage = session2.getMessages().find((m) => {
16110
+ var _a3;
16111
+ return ((_a3 = m.toolCall) == null ? void 0 : _a3.id) === toolCallId;
16112
+ });
16113
+ if (!sourceMessage) return;
16114
+ session2.persistAskUserQuestionProgress(sourceMessage, {
16115
+ answers: buildStructuredAnswers(sheet, sourceMessage),
16116
+ currentIndex: getCurrentIndex(sheet)
16117
+ });
16118
+ };
16119
+ const stringifyStructured = (answers) => {
16120
+ return Object.entries(answers).map(([q, v]) => `${q}: ${Array.isArray(v) ? v.join(", ") : v}`).join(" | ");
16121
+ };
16122
+ const maybeAutoAdvance = (sheet) => {
16123
+ var _a2, _b2, _c2;
16124
+ if (((_b2 = (_a2 = config.features) == null ? void 0 : _a2.askUserQuestion) == null ? void 0 : _b2.groupedAutoAdvance) === false) return;
16125
+ const idx = getCurrentIndex(sheet);
16126
+ const count = getQuestionCount(sheet);
16127
+ if (idx >= count - 1) return;
16128
+ const sourceMessage = (_c2 = sessionRef.current) == null ? void 0 : _c2.getMessages().find((m) => {
16129
+ var _a3;
16130
+ return ((_a3 = m.toolCall) == null ? void 0 : _a3.id) === sheet.getAttribute("data-tool-call-id");
16131
+ });
16132
+ if (!sourceMessage) return;
16133
+ navigateToPage(sheet, sourceMessage, config, idx + 1);
16134
+ persistGroupedProgress(sheet);
16135
+ };
16136
+ askUserOverlay.addEventListener("click", (event) => {
16137
+ var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2, _i2, _j2, _k2, _l2, _m2, _n2;
16138
+ const target = event.target;
16139
+ const trigger = target.closest("[data-ask-user-action]");
16140
+ if (!trigger) return;
16141
+ const sheet = trigger.closest("[data-persona-ask-sheet-for]");
16142
+ if (!sheet) return;
16143
+ const action = trigger.getAttribute("data-ask-user-action");
16144
+ event.preventDefault();
16145
+ event.stopPropagation();
16146
+ if (action === "dismiss") {
16147
+ const toolCallId = (_a2 = sheet.getAttribute("data-tool-call-id")) != null ? _a2 : "";
16148
+ mount.dispatchEvent(
16149
+ new CustomEvent("persona:askUserQuestion:dismissed", {
16150
+ detail: { toolUseId: toolCallId },
16151
+ bubbles: true,
16152
+ composed: true
16153
+ })
16154
+ );
16155
+ removeAskUserQuestionSheet(askUserOverlay, toolCallId);
16156
+ const sourceMessage = (_b2 = sessionRef.current) == null ? void 0 : _b2.getMessages().find((m) => {
16157
+ var _a3;
16158
+ return ((_a3 = m.toolCall) == null ? void 0 : _a3.id) === toolCallId;
16159
+ });
16160
+ if ((_c2 = sourceMessage == null ? void 0 : sourceMessage.agentMetadata) == null ? void 0 : _c2.awaitingLocalTool) {
16161
+ (_d2 = sessionRef.current) == null ? void 0 : _d2.markAskUserQuestionResolved(sourceMessage);
16162
+ (_e2 = sessionRef.current) == null ? void 0 : _e2.resolveAskUserQuestion(sourceMessage, "(dismissed)");
16163
+ }
16164
+ return;
16165
+ }
16166
+ if (action === "pick") {
16167
+ const label = trigger.getAttribute("data-option-label");
16168
+ if (!label) return;
16169
+ const multiSelect = sheet.getAttribute("data-multi-select") === "true";
16170
+ const grouped = isGroupedSheet(sheet);
16171
+ if (grouped && multiSelect) {
16172
+ const stored = readAnswersFromSheet(sheet)[getCurrentIndex(sheet)];
16173
+ const set = new Set(Array.isArray(stored) ? stored : []);
16174
+ if (set.has(label)) set.delete(label);
16175
+ else set.add(label);
16176
+ setCurrentAnswer(sheet, Array.from(set));
16177
+ persistGroupedProgress(sheet);
16178
+ return;
16179
+ }
16180
+ if (grouped) {
16181
+ setCurrentAnswer(sheet, label);
16182
+ persistGroupedProgress(sheet);
16183
+ maybeAutoAdvance(sheet);
16184
+ return;
16185
+ }
16186
+ if (multiSelect) {
16187
+ const pressed = trigger.getAttribute("aria-pressed") === "true";
16188
+ trigger.setAttribute("aria-pressed", pressed ? "false" : "true");
16189
+ trigger.classList.toggle("persona-ask-pill-selected", !pressed);
16190
+ const submitBtn = sheet.querySelector(
16191
+ '[data-ask-user-action="submit-multi"]'
16192
+ );
16193
+ if (submitBtn) {
16194
+ submitBtn.disabled = getSelectedLabels(sheet).length === 0;
16195
+ }
16196
+ return;
16197
+ }
16198
+ submitAskUserAnswer(sheet, label, { source: "pick", values: [label] });
16199
+ return;
16200
+ }
16201
+ if (action === "submit-multi") {
16202
+ const labels = getSelectedLabels(sheet);
16203
+ if (labels.length === 0) return;
16204
+ submitAskUserAnswer(sheet, labels.join(", "), {
16205
+ source: "multi",
16206
+ values: labels
16207
+ });
16208
+ return;
16209
+ }
16210
+ if (action === "open-free-text") {
16211
+ const row = sheet.querySelector('[data-ask-free-text-row="true"]');
16212
+ if (row) {
16213
+ row.classList.remove("persona-hidden");
16214
+ const input = row.querySelector('[data-ask-free-text-input="true"]');
16215
+ input == null ? void 0 : input.focus();
16216
+ }
16217
+ return;
16218
+ }
16219
+ if (action === "focus-free-text") {
16220
+ const input = sheet.querySelector('[data-ask-free-text-input="true"]');
16221
+ input == null ? void 0 : input.focus();
16222
+ return;
16223
+ }
16224
+ if (action === "submit-free-text") {
16225
+ const input = sheet.querySelector('[data-ask-free-text-input="true"]');
16226
+ const text = (_f2 = input == null ? void 0 : input.value) != null ? _f2 : "";
16227
+ if (!text.trim()) return;
16228
+ if (isGroupedSheet(sheet)) {
16229
+ setCurrentAnswer(sheet, text.trim());
16230
+ persistGroupedProgress(sheet);
16231
+ maybeAutoAdvance(sheet);
16232
+ return;
16233
+ }
16234
+ submitAskUserAnswer(sheet, text, { source: "free-text" });
16235
+ return;
16236
+ }
16237
+ if (action === "next" || action === "back") {
16238
+ if (!sessionRef.current) return;
16239
+ const toolCallId = (_g2 = sheet.getAttribute("data-tool-call-id")) != null ? _g2 : "";
16240
+ const sourceMessage = sessionRef.current.getMessages().find((m) => {
16241
+ var _a3;
16242
+ return ((_a3 = m.toolCall) == null ? void 0 : _a3.id) === toolCallId;
16243
+ });
16244
+ if (!sourceMessage) return;
16245
+ const freeInput = sheet.querySelector('[data-ask-free-text-input="true"]');
16246
+ const pending = (_i2 = (_h2 = freeInput == null ? void 0 : freeInput.value) == null ? void 0 : _h2.trim()) != null ? _i2 : "";
16247
+ if (pending) {
16248
+ const stored = readAnswersFromSheet(sheet)[getCurrentIndex(sheet)];
16249
+ if (typeof stored !== "string" || stored !== pending) {
16250
+ setCurrentAnswer(sheet, pending);
16251
+ }
16252
+ }
16253
+ const direction = action === "next" ? 1 : -1;
16254
+ const nextIdx = getCurrentIndex(sheet) + direction;
16255
+ navigateToPage(sheet, sourceMessage, config, nextIdx);
16256
+ persistGroupedProgress(sheet);
16257
+ return;
16258
+ }
16259
+ if (action === "submit-all") {
16260
+ if (!sessionRef.current) return;
16261
+ const toolCallId = (_j2 = sheet.getAttribute("data-tool-call-id")) != null ? _j2 : "";
16262
+ const sourceMessage = sessionRef.current.getMessages().find((m) => {
16263
+ var _a3;
16264
+ return ((_a3 = m.toolCall) == null ? void 0 : _a3.id) === toolCallId;
16265
+ });
16266
+ if (!sourceMessage) return;
16267
+ const freeInput = sheet.querySelector('[data-ask-free-text-input="true"]');
16268
+ const pending = (_l2 = (_k2 = freeInput == null ? void 0 : freeInput.value) == null ? void 0 : _k2.trim()) != null ? _l2 : "";
16269
+ if (pending) setCurrentAnswer(sheet, pending);
16270
+ const structured = buildStructuredAnswers(sheet, sourceMessage);
16271
+ sessionRef.current.persistAskUserQuestionProgress(sourceMessage, {
16272
+ answers: structured,
16273
+ currentIndex: getCurrentIndex(sheet)
16274
+ });
16275
+ const summary = stringifyStructured(structured);
16276
+ submitAskUserAnswer(sheet, summary || "(submitted)", {
16277
+ source: "submit-all",
16278
+ structured
16279
+ });
16280
+ return;
16281
+ }
16282
+ if (action === "skip") {
16283
+ if (!sessionRef.current) return;
16284
+ const toolCallId = (_m2 = sheet.getAttribute("data-tool-call-id")) != null ? _m2 : "";
16285
+ const sourceMessage = sessionRef.current.getMessages().find((m) => {
16286
+ var _a3;
16287
+ return ((_a3 = m.toolCall) == null ? void 0 : _a3.id) === toolCallId;
16288
+ });
16289
+ if (!sourceMessage) return;
16290
+ const grouped = isGroupedSheet(sheet);
16291
+ const idx = getCurrentIndex(sheet);
16292
+ const count = getQuestionCount(sheet);
16293
+ const isFinal = idx >= count - 1;
16294
+ if (!grouped) {
16295
+ mount.dispatchEvent(
16296
+ new CustomEvent("persona:askUserQuestion:dismissed", {
16297
+ detail: { toolUseId: toolCallId },
16298
+ bubbles: true,
16299
+ composed: true
16300
+ })
16301
+ );
16302
+ removeAskUserQuestionSheet(askUserOverlay, toolCallId);
16303
+ if ((_n2 = sourceMessage.agentMetadata) == null ? void 0 : _n2.awaitingLocalTool) {
16304
+ sessionRef.current.markAskUserQuestionResolved(sourceMessage);
16305
+ sessionRef.current.resolveAskUserQuestion(sourceMessage, "(dismissed)");
16306
+ }
16307
+ return;
16308
+ }
16309
+ setCurrentAnswer(sheet, "");
16310
+ const freeInput = sheet.querySelector('[data-ask-free-text-input="true"]');
16311
+ if (freeInput) freeInput.value = "";
16312
+ if (isFinal) {
16313
+ const structured = buildStructuredAnswers(sheet, sourceMessage);
16314
+ const summary = stringifyStructured(structured);
16315
+ submitAskUserAnswer(sheet, summary || "(skipped)", {
16316
+ source: "submit-all",
16317
+ structured
16318
+ });
16319
+ return;
16320
+ }
16321
+ navigateToPage(sheet, sourceMessage, config, idx + 1);
16322
+ persistGroupedProgress(sheet);
16323
+ return;
16324
+ }
16325
+ });
16326
+ askUserOverlay.addEventListener("keydown", (event) => {
16327
+ var _a2;
16328
+ if (event.key !== "Enter") return;
16329
+ const target = event.target;
16330
+ const input = target;
16331
+ if (!((_a2 = input.matches) == null ? void 0 : _a2.call(input, '[data-ask-free-text-input="true"]'))) return;
16332
+ const sheet = input.closest("[data-persona-ask-sheet-for]");
16333
+ if (!sheet) return;
16334
+ event.preventDefault();
16335
+ const text = input.value;
16336
+ if (!text.trim()) return;
16337
+ if (isGroupedSheet(sheet)) {
16338
+ setCurrentAnswer(sheet, text.trim());
16339
+ persistGroupedProgress(sheet);
16340
+ maybeAutoAdvance(sheet);
16341
+ return;
16342
+ }
16343
+ submitAskUserAnswer(sheet, text, { source: "free-text" });
16344
+ });
16345
+ const handleAskUserDigitKey = (event) => {
16346
+ if (!/^[1-9]$/.test(event.key)) return;
16347
+ if (event.metaKey || event.ctrlKey || event.altKey) return;
16348
+ const target = event.target;
16349
+ if ((target == null ? void 0 : target.tagName) === "INPUT" || (target == null ? void 0 : target.tagName) === "TEXTAREA" || (target == null ? void 0 : target.isContentEditable)) {
16350
+ return;
16351
+ }
16352
+ const sheet = askUserOverlay.querySelector("[data-persona-ask-sheet-for]");
16353
+ if (!sheet) return;
16354
+ if (sheet.getAttribute("data-ask-layout") !== "rows") return;
16355
+ if (sheet.getAttribute("data-multi-select") === "true") return;
16356
+ const n = Number(event.key);
16357
+ const pills = sheet.querySelectorAll(
16358
+ '[data-ask-pill-list="true"] [data-ask-user-action="pick"], [data-ask-pill-list="true"] [data-ask-user-action="focus-free-text"]'
16359
+ );
16360
+ const target_pill = pills[n - 1];
16361
+ if (!target_pill) return;
16362
+ event.preventDefault();
16363
+ target_pill.click();
16364
+ };
16365
+ document.addEventListener("keydown", handleAskUserDigitKey);
14726
16366
  let artifactSplitRoot = null;
14727
16367
  let artifactResizeHandle = null;
14728
16368
  let artifactResizeUnbind = null;
@@ -14960,12 +16600,24 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
14960
16600
  const panelBorder = resolvePanelChrome(panelPartial == null ? void 0 : panelPartial.border, defaultPanelBorder);
14961
16601
  const panelShadow = resolvePanelChrome(panelPartial == null ? void 0 : panelPartial.shadow, defaultPanelShadow);
14962
16602
  const panelBorderRadius = resolvePanelChrome(panelPartial == null ? void 0 : panelPartial.borderRadius, defaultPanelBorderRadius);
16603
+ const prevBodyScrollTop = body.scrollTop;
14963
16604
  mount.style.cssText = "";
14964
16605
  wrapper.style.cssText = "";
14965
16606
  panel.style.cssText = "";
14966
16607
  container.style.cssText = "";
14967
16608
  body.style.cssText = "";
14968
16609
  footer.style.cssText = "";
16610
+ const restoreBodyScrollTop = () => {
16611
+ var _a3;
16612
+ if (prevBodyScrollTop <= 0) return;
16613
+ const ownerWindow3 = (_a3 = body.ownerDocument.defaultView) != null ? _a3 : window;
16614
+ ownerWindow3.requestAnimationFrame(() => {
16615
+ if (body.scrollTop === prevBodyScrollTop) return;
16616
+ const maxScrollTop = body.scrollHeight - body.clientHeight;
16617
+ if (maxScrollTop <= 0) return;
16618
+ body.scrollTop = Math.min(prevBodyScrollTop, maxScrollTop);
16619
+ });
16620
+ };
14969
16621
  if (shouldGoFullscreen) {
14970
16622
  wrapper.classList.remove(
14971
16623
  "persona-bottom-6",
@@ -15021,6 +16673,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
15021
16673
  body.style.overflowY = "auto";
15022
16674
  footer.style.flexShrink = "0";
15023
16675
  wasMobileFullscreen = true;
16676
+ restoreBodyScrollTop();
15024
16677
  return;
15025
16678
  }
15026
16679
  const launcherWidth = (_r2 = (_q2 = config == null ? void 0 : config.launcher) == null ? void 0 : _q2.width) != null ? _r2 : config == null ? void 0 : config.launcherWidth;
@@ -15163,12 +16816,16 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
15163
16816
  const zIndexStyles = !sidebarMode ? `z-index: ${(_w2 = (_v2 = config.launcher) == null ? void 0 : _v2.zIndex) != null ? _w2 : DEFAULT_OVERLAY_Z_INDEX} !important;` : "";
15164
16817
  wrapper.style.cssText += maxHeightStyles + paddingStyles + zIndexStyles;
15165
16818
  }
16819
+ restoreBodyScrollTop();
15166
16820
  };
15167
16821
  applyFullHeightStyles();
15168
16822
  applyThemeVariables(mount, config);
15169
16823
  applyArtifactLayoutCssVars(mount, config);
15170
16824
  applyArtifactPaneAppearance(mount, config);
15171
16825
  const destroyCallbacks = [];
16826
+ destroyCallbacks.push(() => {
16827
+ document.removeEventListener("keydown", handleAskUserDigitKey);
16828
+ });
15172
16829
  let teardownHostStacking = null;
15173
16830
  let releaseScrollLock = null;
15174
16831
  destroyCallbacks.push(() => {
@@ -15226,11 +16883,23 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
15226
16883
  cleanupThemeObserver = null;
15227
16884
  }
15228
16885
  });
16886
+ const streamAnimationConfig = (_F = config.features) == null ? void 0 : _F.streamAnimation;
16887
+ if ((streamAnimationConfig == null ? void 0 : streamAnimationConfig.type) && streamAnimationConfig.type !== "none") {
16888
+ const plugin = resolveStreamAnimationPlugin(
16889
+ streamAnimationConfig.type,
16890
+ streamAnimationConfig.plugins
16891
+ );
16892
+ if (plugin) {
16893
+ ensurePluginActive(plugin, mount);
16894
+ destroyCallbacks.push(() => detachAllPlugins(mount));
16895
+ }
16896
+ }
15229
16897
  const suggestionsManager = createSuggestions(suggestions);
15230
16898
  let closeHandler = null;
15231
16899
  let session;
15232
16900
  let isStreaming = false;
15233
16901
  const messageCache = createMessageCache();
16902
+ const lastAskBubbleFingerprint = /* @__PURE__ */ new Map();
15234
16903
  let configVersion = 0;
15235
16904
  const autoFollow = createFollowStateController();
15236
16905
  let lastScrollTop = 0;
@@ -15247,7 +16916,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
15247
16916
  lastUserMessageWasVoice: false,
15248
16917
  lastUserMessageId: null
15249
16918
  };
15250
- const voiceAutoResumeMode = (_E = (_D = config.voiceRecognition) == null ? void 0 : _D.autoResume) != null ? _E : false;
16919
+ const voiceAutoResumeMode = (_H = (_G = config.voiceRecognition) == null ? void 0 : _G.autoResume) != null ? _H : false;
15251
16920
  const emitVoiceState = (source) => {
15252
16921
  eventBus.emit("voice:state", {
15253
16922
  active: voiceState.active,
@@ -15296,7 +16965,9 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
15296
16965
  const messages = messagesOverride ? stripStreamingFromMessages(messagesOverride) : session ? getMessagesForPersistence() : [];
15297
16966
  const payload = {
15298
16967
  messages,
15299
- metadata: persistentMetadata
16968
+ metadata: persistentMetadata,
16969
+ artifacts: lastArtifactsState.artifacts,
16970
+ selectedArtifactId: lastArtifactsState.selectedId
15300
16971
  };
15301
16972
  try {
15302
16973
  const result = storageAdapter.save(payload);
@@ -15473,13 +17144,22 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
15473
17144
  return true;
15474
17145
  };
15475
17146
  const activeMessageIds = /* @__PURE__ */ new Set();
17147
+ const liveAskToolIds = /* @__PURE__ */ new Set();
17148
+ const hasAskPlugin = plugins.some((p) => p.renderAskUserQuestion);
17149
+ const askPluginHydrate = [];
15476
17150
  messages.forEach((message) => {
15477
- var _a3, _b3;
17151
+ var _a3, _b3, _c3, _d3, _e3, _f3, _g2, _h2, _i2, _j2, _k2, _l2, _m2, _n2;
15478
17152
  activeMessageIds.add(message.id);
15479
- const fingerprint = computeMessageFingerprint(message, configVersion);
15480
- const cachedWrapper = getCachedWrapper(messageCache, message.id, fingerprint);
17153
+ const askWithPlugin = hasAskPlugin && isAskUserQuestionMessage(message);
17154
+ 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}` : "";
17155
+ const fingerprint = computeMessageFingerprint(message, configVersion) + askMeta;
17156
+ const cachedWrapper = askWithPlugin ? null : getCachedWrapper(messageCache, message.id, fingerprint);
15481
17157
  if (cachedWrapper) {
15482
17158
  tempContainer.appendChild(cachedWrapper.cloneNode(true));
17159
+ 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)) {
17160
+ liveAskToolIds.add(message.toolCall.id);
17161
+ ensureAskUserQuestionSheet(message, config, panelElements.composerOverlay);
17162
+ }
15483
17163
  return;
15484
17164
  }
15485
17165
  let bubble = null;
@@ -15498,8 +17178,75 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
15498
17178
  }
15499
17179
  return false;
15500
17180
  });
15501
- const messageLayoutConfig = (_a3 = config.layout) == null ? void 0 : _a3.messages;
15502
- if (matchingPlugin) {
17181
+ const messageLayoutConfig = (_f3 = config.layout) == null ? void 0 : _f3.messages;
17182
+ if (isAskUserQuestionMessage(message) && ((_g2 = message.agentMetadata) == null ? void 0 : _g2.askUserQuestionAnswered) === true) {
17183
+ lastAskBubbleFingerprint.delete(message.id);
17184
+ const existing = container2.querySelector(`#wrapper-${message.id}`);
17185
+ existing == null ? void 0 : existing.removeAttribute("data-preserve-runtime");
17186
+ return;
17187
+ }
17188
+ if (isAskUserQuestionMessage(message) && ((_i2 = (_h2 = config.features) == null ? void 0 : _h2.askUserQuestion) == null ? void 0 : _i2.enabled) !== false) {
17189
+ const askPlugin = plugins.find((p) => typeof p.renderAskUserQuestion === "function");
17190
+ if (askPlugin && sessionRef.current) {
17191
+ const lastFp = lastAskBubbleFingerprint.get(message.id);
17192
+ const needsRebuild = lastFp !== fingerprint;
17193
+ let pluginBubble = null;
17194
+ if (needsRebuild) {
17195
+ const { payload, complete } = parseAskUserQuestionPayload(message);
17196
+ const messageId = message.id;
17197
+ const liveMessage = () => {
17198
+ var _a4;
17199
+ return (_a4 = sessionRef.current) == null ? void 0 : _a4.getMessages().find((m) => m.id === messageId);
17200
+ };
17201
+ pluginBubble = askPlugin.renderAskUserQuestion({
17202
+ message,
17203
+ payload,
17204
+ complete,
17205
+ resolve: (answer) => {
17206
+ var _a4;
17207
+ const live = liveMessage();
17208
+ if (live) (_a4 = sessionRef.current) == null ? void 0 : _a4.resolveAskUserQuestion(live, answer);
17209
+ },
17210
+ dismiss: () => {
17211
+ var _a4, _b4, _c4;
17212
+ const live = liveMessage();
17213
+ if ((_a4 = live == null ? void 0 : live.agentMetadata) == null ? void 0 : _a4.awaitingLocalTool) {
17214
+ (_b4 = sessionRef.current) == null ? void 0 : _b4.markAskUserQuestionResolved(live);
17215
+ (_c4 = sessionRef.current) == null ? void 0 : _c4.resolveAskUserQuestion(live, "(dismissed)");
17216
+ }
17217
+ },
17218
+ config
17219
+ });
17220
+ }
17221
+ const previouslyMounted = lastFp != null;
17222
+ if (needsRebuild && pluginBubble === null && !previouslyMounted) {
17223
+ if (((_j2 = message.agentMetadata) == null ? void 0 : _j2.awaitingLocalTool) === true && !((_k2 = message.agentMetadata) == null ? void 0 : _k2.askUserQuestionAnswered)) {
17224
+ liveAskToolIds.add(message.toolCall.id);
17225
+ ensureAskUserQuestionSheet(message, config, panelElements.composerOverlay);
17226
+ }
17227
+ return;
17228
+ }
17229
+ const stub = document.createElement("div");
17230
+ stub.className = "persona-flex";
17231
+ stub.id = `wrapper-${message.id}`;
17232
+ stub.setAttribute("data-wrapper-id", message.id);
17233
+ stub.setAttribute("data-ask-plugin-stub", "true");
17234
+ stub.setAttribute("data-preserve-runtime", "true");
17235
+ tempContainer.appendChild(stub);
17236
+ askPluginHydrate.push({
17237
+ messageId: message.id,
17238
+ fingerprint,
17239
+ bubble: pluginBubble
17240
+ });
17241
+ return;
17242
+ } else {
17243
+ if (((_l2 = message.agentMetadata) == null ? void 0 : _l2.awaitingLocalTool) === true && !((_m2 = message.agentMetadata) == null ? void 0 : _m2.askUserQuestionAnswered)) {
17244
+ liveAskToolIds.add(message.toolCall.id);
17245
+ ensureAskUserQuestionSheet(message, config, panelElements.composerOverlay);
17246
+ }
17247
+ return;
17248
+ }
17249
+ } else if (matchingPlugin) {
15503
17250
  if (message.variant === "reasoning" && message.reasoning && matchingPlugin.renderReasoning) {
15504
17251
  if (!showReasoning) return;
15505
17252
  bubble = matchingPlugin.renderReasoning({
@@ -15618,7 +17365,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
15618
17365
  if (config.approval === false) return;
15619
17366
  bubble = createApprovalBubble(message, config);
15620
17367
  } else {
15621
- const messageLayoutConfig2 = (_b3 = config.layout) == null ? void 0 : _b3.messages;
17368
+ const messageLayoutConfig2 = (_n2 = config.layout) == null ? void 0 : _n2.messages;
15622
17369
  if ((messageLayoutConfig2 == null ? void 0 : messageLayoutConfig2.renderUserMessage) && message.role === "user") {
15623
17370
  bubble = messageLayoutConfig2.renderUserMessage({
15624
17371
  message,
@@ -15663,6 +17410,17 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
15663
17410
  setCachedWrapper(messageCache, message.id, fingerprint, wrapper2);
15664
17411
  tempContainer.appendChild(wrapper2);
15665
17412
  });
17413
+ if (panelElements.composerOverlay) {
17414
+ const sheets = panelElements.composerOverlay.querySelectorAll(
17415
+ "[data-persona-ask-sheet-for]"
17416
+ );
17417
+ sheets.forEach((sheet) => {
17418
+ const id = sheet.getAttribute("data-persona-ask-sheet-for");
17419
+ if (id && !liveAskToolIds.has(id)) {
17420
+ removeAskUserQuestionSheet(panelElements.composerOverlay, id);
17421
+ }
17422
+ });
17423
+ }
15666
17424
  if ((_b2 = (_a2 = config.features) == null ? void 0 : _a2.toolCallDisplay) == null ? void 0 : _b2.grouped) {
15667
17425
  const toolGroups = [];
15668
17426
  let currentGroup = [];
@@ -15827,6 +17585,23 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
15827
17585
  }
15828
17586
  }
15829
17587
  morphMessages(container2, tempContainer);
17588
+ if (askPluginHydrate.length > 0) {
17589
+ for (const { messageId, fingerprint, bubble } of askPluginHydrate) {
17590
+ const wrapper2 = container2.querySelector(`#wrapper-${messageId}`);
17591
+ if (!wrapper2) continue;
17592
+ if (bubble === null) {
17593
+ continue;
17594
+ }
17595
+ wrapper2.replaceChildren(bubble);
17596
+ wrapper2.setAttribute("data-bubble-fp", fingerprint);
17597
+ lastAskBubbleFingerprint.set(messageId, fingerprint);
17598
+ }
17599
+ }
17600
+ if (lastAskBubbleFingerprint.size > 0) {
17601
+ for (const id of lastAskBubbleFingerprint.keys()) {
17602
+ if (!activeMessageIds.has(id)) lastAskBubbleFingerprint.delete(id);
17603
+ }
17604
+ }
15830
17605
  };
15831
17606
  const renderMessagesWithPlugins = renderMessagesWithPluginsImpl;
15832
17607
  const updateOpenState = () => {
@@ -15935,7 +17710,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
15935
17710
  });
15936
17711
  };
15937
17712
  const setComposerDisabled = (disabled) => {
15938
- sendButton.disabled = disabled;
17713
+ setSendButtonMode(disabled ? "stop" : "send");
15939
17714
  if (micButton) {
15940
17715
  micButton.disabled = disabled;
15941
17716
  }
@@ -15975,7 +17750,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
15975
17750
  }
15976
17751
  }
15977
17752
  const useIcon = (_i2 = (_h2 = config.sendButton) == null ? void 0 : _h2.useIcon) != null ? _i2 : false;
15978
- if (!useIcon) {
17753
+ if (!useIcon && !(session == null ? void 0 : session.isStreaming())) {
15979
17754
  sendButton.textContent = (_k2 = (_j2 = config.copy) == null ? void 0 : _j2.sendButtonLabel) != null ? _k2 : "Send";
15980
17755
  }
15981
17756
  textarea.style.fontFamily = 'var(--persona-input-font-family, var(--persona-font-family, -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Arial, sans-serif))';
@@ -16091,10 +17866,11 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
16091
17866
  onArtifactsState(state) {
16092
17867
  lastArtifactsState = state;
16093
17868
  syncArtifactPane();
17869
+ persistState();
16094
17870
  }
16095
17871
  });
16096
17872
  sessionRef.current = session;
16097
- if (((_G = (_F = config.voiceRecognition) == null ? void 0 : _F.provider) == null ? void 0 : _G.type) === "runtype") {
17873
+ if (((_J = (_I = config.voiceRecognition) == null ? void 0 : _I.provider) == null ? void 0 : _J.type) === "runtype") {
16098
17874
  try {
16099
17875
  session.setupVoice();
16100
17876
  } catch (err) {
@@ -16124,7 +17900,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
16124
17900
  }
16125
17901
  if (pendingStoredState) {
16126
17902
  pendingStoredState.then((state) => {
16127
- var _a2;
17903
+ var _a2, _b2, _c2;
16128
17904
  if (!state) return;
16129
17905
  if (state.metadata) {
16130
17906
  persistentMetadata = ensureRecord(state.metadata);
@@ -16133,6 +17909,12 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
16133
17909
  if ((_a2 = state.messages) == null ? void 0 : _a2.length) {
16134
17910
  session.hydrateMessages(state.messages);
16135
17911
  }
17912
+ if ((_b2 = state.artifacts) == null ? void 0 : _b2.length) {
17913
+ session.hydrateArtifacts(
17914
+ state.artifacts,
17915
+ (_c2 = state.selectedArtifactId) != null ? _c2 : null
17916
+ );
17917
+ }
16136
17918
  }).catch((error) => {
16137
17919
  if (typeof console !== "undefined") {
16138
17920
  console.error("[AgentWidget] Failed to hydrate stored state:", error);
@@ -16142,6 +17924,10 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
16142
17924
  const handleSubmit = (event) => {
16143
17925
  var _a2;
16144
17926
  event.preventDefault();
17927
+ if (session.isStreaming()) {
17928
+ session.cancel();
17929
+ return;
17930
+ }
16145
17931
  const value = textarea.value.trim();
16146
17932
  const hasAttachments = (_a2 = attachmentManager == null ? void 0 : attachmentManager.hasAttachments()) != null ? _a2 : false;
16147
17933
  if (!value && !hasAttachments) return;
@@ -16696,7 +18482,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
16696
18482
  }
16697
18483
  };
16698
18484
  recalcPanelHeight();
16699
- const ownerWindow = (_H = mount.ownerDocument.defaultView) != null ? _H : window;
18485
+ const ownerWindow = (_K = mount.ownerDocument.defaultView) != null ? _K : window;
16700
18486
  ownerWindow.addEventListener("resize", recalcPanelHeight);
16701
18487
  destroyCallbacks.push(() => ownerWindow.removeEventListener("resize", recalcPanelHeight));
16702
18488
  if (typeof ResizeObserver !== "undefined") {
@@ -16707,15 +18493,19 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
16707
18493
  destroyCallbacks.push(() => footerResizeObserver.disconnect());
16708
18494
  }
16709
18495
  lastScrollTop = body.scrollTop;
18496
+ let lastScrollHeight = body.scrollHeight;
16710
18497
  const handleScroll = () => {
16711
18498
  const scrollTop = body.scrollTop;
18499
+ const currentScrollHeight = body.scrollHeight;
18500
+ const scrollHeightShrank = currentScrollHeight < lastScrollHeight;
18501
+ lastScrollHeight = currentScrollHeight;
16712
18502
  const { action, nextLastScrollTop } = resolveFollowStateFromScroll({
16713
18503
  following: autoFollow.isFollowing(),
16714
18504
  currentScrollTop: scrollTop,
16715
18505
  lastScrollTop,
16716
18506
  nearBottom: isElementNearBottom(body, BOTTOM_THRESHOLD),
16717
18507
  userScrollThreshold: USER_SCROLL_THRESHOLD,
16718
- isAutoScrolling: isAutoScrolling || hasPendingAutoScroll,
18508
+ isAutoScrolling: isAutoScrolling || hasPendingAutoScroll || scrollHeightShrank,
16719
18509
  pauseOnUpwardScroll: true,
16720
18510
  pauseWhenAwayFromBottom: false,
16721
18511
  resumeRequiresDownwardScroll: true
@@ -16780,6 +18570,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
16780
18570
  session.clearMessages();
16781
18571
  messageCache.clear();
16782
18572
  resumeAutoScroll();
18573
+ removeAskUserQuestionSheet(panelElements.composerOverlay);
16783
18574
  try {
16784
18575
  localStorage.removeItem(DEFAULT_CHAT_HISTORY_STORAGE_KEY);
16785
18576
  if (config.debug) {
@@ -16915,7 +18706,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
16915
18706
  }
16916
18707
  const controller = {
16917
18708
  update(nextConfig) {
16918
- 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;
18709
+ 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;
16919
18710
  const previousToolCallConfig = config.toolCall;
16920
18711
  const previousMessageActions = config.messageActions;
16921
18712
  const previousLayoutMessages = (_a2 = config.layout) == null ? void 0 : _a2.messages;
@@ -17126,10 +18917,10 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17126
18917
  }
17127
18918
  const launcher = (_L2 = config.launcher) != null ? _L2 : {};
17128
18919
  const headerIconHidden = (_M2 = launcher.headerIconHidden) != null ? _M2 : false;
17129
- const layoutShowIcon = (_O = (_N2 = config.layout) == null ? void 0 : _N2.header) == null ? void 0 : _O.showIcon;
18920
+ const layoutShowIcon = (_O2 = (_N2 = config.layout) == null ? void 0 : _N2.header) == null ? void 0 : _O2.showIcon;
17130
18921
  const shouldHideIcon = headerIconHidden || layoutShowIcon === false;
17131
18922
  const headerIconName = launcher.headerIconName;
17132
- const headerIconSize = (_P = launcher.headerIconSize) != null ? _P : "48px";
18923
+ const headerIconSize = (_P2 = launcher.headerIconSize) != null ? _P2 : "48px";
17133
18924
  if (iconHolder) {
17134
18925
  const headerEl = container.querySelector(".persona-border-b-persona-divider");
17135
18926
  const headerCopy = headerEl == null ? void 0 : headerEl.querySelector(".persona-flex-col");
@@ -17156,7 +18947,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
17156
18947
  if (iconSvg) {
17157
18948
  iconHolder.replaceChildren(iconSvg);
17158
18949
  } else {
17159
- iconHolder.textContent = (_Q = launcher.agentIconText) != null ? _Q : "\u{1F4AC}";
18950
+ iconHolder.textContent = (_Q2 = launcher.agentIconText) != null ? _Q2 : "\u{1F4AC}";
17160
18951
  }
17161
18952
  } else if (launcher.iconUrl) {
17162
18953
  const img2 = iconHolder.querySelector("img");
@@ -18080,6 +19871,14 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
18080
19871
  if (!artifactsSidebarEnabled(config)) return;
18081
19872
  session.clearArtifacts();
18082
19873
  },
19874
+ getArtifacts() {
19875
+ var _a2;
19876
+ return (_a2 = session == null ? void 0 : session.getArtifacts()) != null ? _a2 : [];
19877
+ },
19878
+ getSelectedArtifactId() {
19879
+ var _a2;
19880
+ return (_a2 = session == null ? void 0 : session.getSelectedArtifactId()) != null ? _a2 : null;
19881
+ },
18083
19882
  focusInput() {
18084
19883
  if (launcherEnabled && !open) return false;
18085
19884
  if (!textarea) return false;
@@ -18197,7 +19996,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
18197
19996
  }
18198
19997
  }
18199
19998
  };
18200
- const shouldExposeDebugApi = ((_I = runtimeOptions == null ? void 0 : runtimeOptions.debugTools) != null ? _I : false) || Boolean(config.debug);
19999
+ const shouldExposeDebugApi = ((_L = runtimeOptions == null ? void 0 : runtimeOptions.debugTools) != null ? _L : false) || Boolean(config.debug);
18201
20000
  if (shouldExposeDebugApi && typeof window !== "undefined") {
18202
20001
  const previousDebug = window.AgentWidgetBrowser;
18203
20002
  const debugApi = {
@@ -18300,9 +20099,9 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
18300
20099
  const voiceKey = `${persistConfig.keyPrefix}widget-voice`;
18301
20100
  const voiceModeKey = `${persistConfig.keyPrefix}widget-voice-mode`;
18302
20101
  if (storage) {
18303
- const wasOpen = ((_J = persistConfig.persist) == null ? void 0 : _J.openState) && storage.getItem(openKey) === "true";
18304
- const wasVoiceActive = ((_K = persistConfig.persist) == null ? void 0 : _K.voiceState) && storage.getItem(voiceKey) === "true";
18305
- const wasInVoiceMode = ((_L = persistConfig.persist) == null ? void 0 : _L.voiceState) && storage.getItem(voiceModeKey) === "true";
20102
+ const wasOpen = ((_M = persistConfig.persist) == null ? void 0 : _M.openState) && storage.getItem(openKey) === "true";
20103
+ const wasVoiceActive = ((_N = persistConfig.persist) == null ? void 0 : _N.voiceState) && storage.getItem(voiceKey) === "true";
20104
+ const wasInVoiceMode = ((_O = persistConfig.persist) == null ? void 0 : _O.voiceState) && storage.getItem(voiceModeKey) === "true";
18306
20105
  if (wasOpen) {
18307
20106
  setTimeout(() => {
18308
20107
  controller.open();
@@ -18319,7 +20118,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
18319
20118
  }, 100);
18320
20119
  }, 0);
18321
20120
  }
18322
- if ((_M = persistConfig.persist) == null ? void 0 : _M.openState) {
20121
+ if ((_P = persistConfig.persist) == null ? void 0 : _P.openState) {
18323
20122
  eventBus.on("widget:opened", () => {
18324
20123
  storage.setItem(openKey, "true");
18325
20124
  });
@@ -18327,7 +20126,7 @@ var createAgentExperience = (mount, initialConfig, runtimeOptions) => {
18327
20126
  storage.setItem(openKey, "false");
18328
20127
  });
18329
20128
  }
18330
- if ((_N = persistConfig.persist) == null ? void 0 : _N.voiceState) {
20129
+ if ((_Q = persistConfig.persist) == null ? void 0 : _Q.voiceState) {
18331
20130
  eventBus.on("voice:state", (event) => {
18332
20131
  storage.setItem(voiceKey, event.active ? "true" : "false");
18333
20132
  });
@@ -18901,6 +20700,9 @@ function buildSrcdoc(mountId, shellMode, docked, widgetCssPath) {
18901
20700
  var PREVIEW_TRANSCRIPT_PRESET_LABELS = {
18902
20701
  "user-message": "User message",
18903
20702
  "assistant-message": "Assistant message",
20703
+ "assistant-code-block": "Assistant \u2014 code block",
20704
+ "assistant-markdown-table": "Assistant \u2014 markdown table",
20705
+ "assistant-image": "Assistant \u2014 image",
18904
20706
  "reasoning-streaming": "Reasoning (streaming)",
18905
20707
  "reasoning-complete": "Reasoning (complete)",
18906
20708
  "tool-running": "Tool call (running)",
@@ -18927,6 +20729,56 @@ function createPreviewTranscriptEntry(preset, index = 0) {
18927
20729
  content: "Absolutely. I can keep going and explain what happens next.",
18928
20730
  createdAt
18929
20731
  };
20732
+ case "assistant-code-block":
20733
+ return {
20734
+ id: `preview-seq-assistant-code-${suffix}`,
20735
+ role: "assistant",
20736
+ content: [
20737
+ "Here's how you'd wire up a streaming animation:",
20738
+ "",
20739
+ "```ts",
20740
+ "import { createAgentExperience } from '@runtypelabs/persona';",
20741
+ "",
20742
+ "createAgentExperience(el, {",
20743
+ " features: {",
20744
+ ' streamAnimation: { type: "letter-rise", speed: 120 },',
20745
+ " },",
20746
+ "});",
20747
+ "```",
20748
+ "",
20749
+ "Swap the `type` value to try the other presets."
20750
+ ].join("\n"),
20751
+ createdAt
20752
+ };
20753
+ case "assistant-markdown-table":
20754
+ return {
20755
+ id: `preview-seq-assistant-table-${suffix}`,
20756
+ role: "assistant",
20757
+ content: [
20758
+ "Here are the built-in streaming animations at a glance:",
20759
+ "",
20760
+ "| Preset | Wrap unit | Best for |",
20761
+ "| ------------ | --------- | --------------------------- |",
20762
+ "| Typewriter | Character | Classic terminal feel |",
20763
+ "| Letter rise | Character | Soft, staggered entrance |",
20764
+ "| Word fade | Word | Longer-form assistant replies |",
20765
+ "| Pop bubble | Bubble | Short, punchy affirmations |"
20766
+ ].join("\n"),
20767
+ createdAt
20768
+ };
20769
+ case "assistant-image":
20770
+ return {
20771
+ id: `preview-seq-assistant-image-${suffix}`,
20772
+ role: "assistant",
20773
+ content: [
20774
+ "Here's the reference diagram you asked for \u2014 let me know if you'd like a different view:",
20775
+ "",
20776
+ "![Stream animation reference](https://placehold.co/320x200/png?text=Stream+Animation)",
20777
+ "",
20778
+ "The gradient shows how per-unit delays stagger across the reply."
20779
+ ].join("\n"),
20780
+ createdAt
20781
+ };
18930
20782
  case "reasoning-streaming":
18931
20783
  return {
18932
20784
  id: `preview-seq-reasoning-stream-${suffix}`,
@@ -18994,6 +20846,38 @@ function createPreviewTranscriptEntry(preset, index = 0) {
18994
20846
  function appendPreviewTranscriptEntry(messages, preset) {
18995
20847
  return [...messages, createPreviewTranscriptEntry(preset, messages.length)];
18996
20848
  }
20849
+ function presetStreamsText(preset) {
20850
+ return preset === "assistant-message" || preset === "assistant-code-block" || preset === "assistant-markdown-table" || preset === "assistant-image";
20851
+ }
20852
+ function buildTranscriptStreamFrames(preset, suffix, options) {
20853
+ var _a, _b;
20854
+ const completed = createPreviewTranscriptEntry(preset, suffix);
20855
+ if (!presetStreamsText(preset) || typeof completed.content !== "string") {
20856
+ return [{ message: completed, delayMs: 0, done: true }];
20857
+ }
20858
+ const chunkSize = Math.max(1, (_a = options == null ? void 0 : options.chunkSize) != null ? _a : 24);
20859
+ const delayMs = Math.max(0, (_b = options == null ? void 0 : options.delayMs) != null ? _b : 42);
20860
+ const fullText = completed.content;
20861
+ const frames = [];
20862
+ frames.push({
20863
+ message: { ...completed, content: "", streaming: true },
20864
+ delayMs: 0,
20865
+ done: false
20866
+ });
20867
+ for (let i = chunkSize; i < fullText.length; i += chunkSize) {
20868
+ frames.push({
20869
+ message: { ...completed, content: fullText.slice(0, i), streaming: true },
20870
+ delayMs,
20871
+ done: false
20872
+ });
20873
+ }
20874
+ frames.push({
20875
+ message: { ...completed, content: fullText, streaming: false },
20876
+ delayMs,
20877
+ done: true
20878
+ });
20879
+ return frames;
20880
+ }
18997
20881
  var createAdvancedTranscriptPreviewMessages = () => [
18998
20882
  {
18999
20883
  id: "preview-adv-1",
@@ -19443,6 +21327,7 @@ export {
19443
21327
  buildPreviewConfigWithMessages,
19444
21328
  buildShellCss,
19445
21329
  buildSrcdoc,
21330
+ buildTranscriptStreamFrames,
19446
21331
  convertFromPx,
19447
21332
  convertToPx,
19448
21333
  createPreviewMessages,
@@ -19462,6 +21347,7 @@ export {
19462
21347
  normalizeColorValue,
19463
21348
  paletteColorPath,
19464
21349
  parseCssValue,
21350
+ presetStreamsText,
19465
21351
  resolveRoleAssignment,
19466
21352
  resolveThemeColorPath,
19467
21353
  scopeSection,