@runtypelabs/persona 4.23.1 → 4.24.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 (158) hide show
  1. package/dist/animations/glyph-cycle.d.cts +1 -1
  2. package/dist/animations/glyph-cycle.d.ts +1 -1
  3. package/dist/animations/{types-9Vxm-PPz.d.cts → types-Db61aI9J.d.cts} +25 -2
  4. package/dist/animations/{types-9Vxm-PPz.d.ts → types-Db61aI9J.d.ts} +25 -2
  5. package/dist/animations/wipe.d.cts +1 -1
  6. package/dist/animations/wipe.d.ts +1 -1
  7. package/dist/animations-extra.d.cts +25 -2
  8. package/dist/animations-extra.d.ts +25 -2
  9. package/dist/approval-ui-3NMYNXBD.js +1 -0
  10. package/dist/approval-ui.cjs +2 -2
  11. package/dist/approval-ui.d.cts +261 -40
  12. package/dist/approval-ui.d.ts +261 -40
  13. package/dist/approval-ui.js +2 -2
  14. package/dist/{artifacts-ui-F4N6VMKF.js → artifacts-ui-IGB5YKLO.js} +4 -4
  15. package/dist/artifacts-ui.d.cts +256 -28
  16. package/dist/artifacts-ui.d.ts +256 -28
  17. package/dist/{chunk-NIKYKSNZ.js → chunk-7CO4T5KB.js} +1 -1
  18. package/dist/codegen.cjs +11 -11
  19. package/dist/codegen.js +13 -13
  20. package/dist/context-mentions.d.cts +256 -28
  21. package/dist/context-mentions.d.ts +256 -28
  22. package/dist/event-stream-view.d.cts +256 -28
  23. package/dist/event-stream-view.d.ts +256 -28
  24. package/dist/forms-ui.d.cts +291 -30
  25. package/dist/forms-ui.d.ts +291 -30
  26. package/dist/history-view.d.cts +25 -2
  27. package/dist/history-view.d.ts +25 -2
  28. package/dist/index.cjs +70 -69
  29. package/dist/index.cjs.map +1 -1
  30. package/dist/index.d.cts +337 -51
  31. package/dist/index.d.ts +337 -51
  32. package/dist/index.global.js +57 -54
  33. package/dist/index.global.js.map +1 -1
  34. package/dist/index.js +70 -69
  35. package/dist/index.js.map +1 -1
  36. package/dist/install.global.js +1 -1
  37. package/dist/install.global.js.map +1 -1
  38. package/dist/launcher.global.js +2 -2
  39. package/dist/launcher.global.js.map +1 -1
  40. package/dist/session-reconnect.d.cts +256 -28
  41. package/dist/session-reconnect.d.ts +256 -28
  42. package/dist/smart-dom-reader.d.cts +256 -28
  43. package/dist/smart-dom-reader.d.ts +256 -28
  44. package/dist/theme-editor-preview.cjs +74 -73
  45. package/dist/theme-editor-preview.d.cts +263 -28
  46. package/dist/theme-editor-preview.d.ts +263 -28
  47. package/dist/theme-editor-preview.js +51 -50
  48. package/dist/theme-editor.cjs +10 -10
  49. package/dist/theme-editor.d.cts +276 -30
  50. package/dist/theme-editor.d.ts +276 -30
  51. package/dist/theme-editor.js +10 -10
  52. package/dist/theme-reference.cjs +1 -1
  53. package/dist/theme-reference.d.cts +1522 -11
  54. package/dist/theme-reference.d.ts +1522 -11
  55. package/dist/theme-reference.js +1 -1
  56. package/dist/widget.css +1 -1
  57. package/package.json +3 -2
  58. package/src/__fixtures__/defaults-parity.v4.json +776 -0
  59. package/src/approval-ui-entry.ts +0 -1
  60. package/src/approval-ui-loader.ts +5 -4
  61. package/src/approval-ui.ts +0 -1
  62. package/src/client-identity-proof.test.ts +193 -0
  63. package/src/client-session-warm.test.ts +216 -0
  64. package/src/client-visitor-history.test.ts +6 -0
  65. package/src/client.tool-pair-replay.test.ts +325 -0
  66. package/src/client.ts +154 -61
  67. package/src/codegen.test.ts +24 -0
  68. package/src/components/activity-row.test.ts +100 -0
  69. package/src/components/activity-row.ts +136 -0
  70. package/src/components/approval-actions.test.ts +8 -5
  71. package/src/components/approval-actions.ts +19 -6
  72. package/src/components/approval-bubble.test.ts +56 -9
  73. package/src/components/approval-bubble.ts +36 -41
  74. package/src/components/composer-builder.ts +5 -2
  75. package/src/components/composer-parts.ts +10 -2
  76. package/src/components/header-builder.test.ts +32 -0
  77. package/src/components/header-builder.ts +7 -4
  78. package/src/components/header-layouts.test.ts +12 -0
  79. package/src/components/header-layouts.ts +3 -2
  80. package/src/components/launcher.ts +11 -2
  81. package/src/components/message-bubble.test.ts +22 -0
  82. package/src/components/message-bubble.ts +7 -3
  83. package/src/components/panel.test.ts +52 -1
  84. package/src/components/panel.ts +47 -8
  85. package/src/components/pill-composer-builder.test.ts +2 -0
  86. package/src/components/pill-composer-builder.ts +0 -1
  87. package/src/components/reasoning-bubble.ts +29 -17
  88. package/src/components/suggestions.test.ts +1 -0
  89. package/src/components/suggestions.ts +0 -16
  90. package/src/components/tool-bubble.ts +131 -114
  91. package/src/components/tool-details.test.ts +87 -0
  92. package/src/components/tool-details.ts +102 -0
  93. package/src/components/welcome.test.ts +8 -0
  94. package/src/components/welcome.ts +4 -2
  95. package/src/defaults-parity.test.ts +158 -0
  96. package/src/defaults.test.ts +69 -0
  97. package/src/defaults.ts +128 -49
  98. package/src/generated/runtype-openapi-contract.ts +28 -13
  99. package/src/index-core.ts +2 -0
  100. package/src/install.test.ts +24 -0
  101. package/src/install.ts +3 -1
  102. package/src/launcher-global.ts +2 -1
  103. package/src/launcher-variants.test.ts +52 -0
  104. package/src/runtime/init-update-reset.test.ts +21 -0
  105. package/src/session.ts +61 -9
  106. package/src/styles/widget-styles.test.ts +19 -0
  107. package/src/styles/widget.css +295 -23
  108. package/src/theme-editor/index.ts +2 -0
  109. package/src/theme-editor/preview-utils.test.ts +8 -0
  110. package/src/theme-editor/preview-utils.ts +7 -3
  111. package/src/theme-editor/sections.test.ts +31 -0
  112. package/src/theme-editor/sections.ts +55 -1
  113. package/src/theme-editor/state-preferences.test.ts +49 -0
  114. package/src/theme-editor/state.ts +73 -15
  115. package/src/theme-reference.test.ts +20 -0
  116. package/src/theme-reference.ts +11 -5
  117. package/src/tool-call-display-defaults.test.ts +33 -1
  118. package/src/types/theme.ts +80 -3
  119. package/src/types.ts +179 -23
  120. package/src/ui.activity-row.test.ts +91 -0
  121. package/src/ui.approval-plugin.test.ts +63 -0
  122. package/src/ui.composer-compact.test.ts +24 -2
  123. package/src/ui.composer-placement.test.ts +23 -0
  124. package/src/ui.detached-panel.test.ts +33 -6
  125. package/src/ui.docked.test.ts +19 -0
  126. package/src/ui.header-update-stability.test.ts +25 -0
  127. package/src/ui.identity-proof.test.ts +58 -0
  128. package/src/ui.launcher-teaser.test.ts +25 -0
  129. package/src/ui.message-width.test.ts +17 -2
  130. package/src/ui.reasoning-display.test.ts +92 -0
  131. package/src/ui.rebuild-composer.test.ts +20 -3
  132. package/src/ui.scroll.test.ts +32 -0
  133. package/src/ui.session-init.test.ts +312 -0
  134. package/src/ui.status-indicator.test.ts +82 -0
  135. package/src/ui.suggest-replies.test.ts +11 -0
  136. package/src/ui.ts +363 -74
  137. package/src/ui.v5-defaults.test.ts +144 -0
  138. package/src/ui.welcome.test.ts +92 -3
  139. package/src/utils/__snapshots__/tokens-parity.test.ts.snap +811 -140
  140. package/src/utils/code-generators.ts +14 -0
  141. package/src/utils/composer-compact.test.ts +0 -2
  142. package/src/utils/composer-compact.ts +2 -4
  143. package/src/utils/composer-placement.ts +2 -3
  144. package/src/utils/config-merge.test.ts +81 -5
  145. package/src/utils/config-merge.ts +13 -3
  146. package/src/utils/defaults-provenance.ts +67 -0
  147. package/src/utils/dock.ts +7 -1
  148. package/src/utils/launcher-variant.ts +16 -0
  149. package/src/utils/panel-config.ts +97 -0
  150. package/src/utils/status-indicator.ts +39 -0
  151. package/src/utils/theme.test.ts +182 -0
  152. package/src/utils/theme.ts +131 -18
  153. package/src/utils/tokens.test.ts +122 -1
  154. package/src/utils/tokens.ts +177 -17
  155. package/src/utils/tool-pair-replay.ts +100 -0
  156. package/src/welcome.test.ts +23 -0
  157. package/src/welcome.ts +16 -9
  158. package/dist/approval-ui-K7R5Q5OC.js +0 -1
@@ -21,6 +21,7 @@ interface ResolvedWelcomeConfig {
21
21
  * Optional on the interface, always populated by `resolveWelcomeConfig`:
22
22
  * a plugin literal built against an older minor must still type-check.
23
23
  */
24
+ layout?: "top" | "centered";
24
25
  anchor?: AgentWidgetWelcomeAnchor;
25
26
  /** Percentage string; validated, falls back to "44%". */
26
27
  anchorComposerTop?: string;
@@ -792,6 +793,8 @@ interface InputTokens extends ComponentTokenSet {
792
793
  backdropFilter?: string;
793
794
  }
794
795
  interface LauncherTokens extends ComponentTokenSet {
796
+ /** Distance from the viewport edges. Circle default: 20px; pill: 24px. */
797
+ offset?: string;
795
798
  size: string;
796
799
  iconSize: string;
797
800
  shadow: TokenReference<'shadow'>;
@@ -814,6 +817,15 @@ interface PanelTokens extends ComponentTokenSet {
814
817
  inset?: string;
815
818
  /** Background of the region revealed behind a detached panel. */
816
819
  canvasBackground?: string;
820
+ /** Chrome defaults by rendered panel mode. */
821
+ modes?: Partial<Record<'floating' | 'inline' | 'sidebar' | 'docked' | 'mobile', {
822
+ /** Full border shorthand (for example, `"1px solid var(--persona-border)"`). */
823
+ border?: string;
824
+ /** Box-shadow token reference or raw CSS shadow. */
825
+ shadow?: string;
826
+ /** Corner radius token reference or raw CSS radius. */
827
+ borderRadius?: TokenReference<'radius'>;
828
+ }>>;
817
829
  }
818
830
  /** Per-element text styling shared by themable text surfaces. */
819
831
  interface TextStyleTokens {
@@ -840,10 +852,16 @@ interface HeaderTokens extends ComponentTokenSet {
840
852
  */
841
853
  border?: TokenReference<'color'>;
842
854
  borderRadius: TokenReference<'radius'>;
855
+ /** Standard-header padding. @default "20px 24px" */
856
+ padding?: string;
857
+ /** Minimal-header padding. Explicitly wins over `padding`. @default "16px 24px" */
858
+ minimalPadding?: string;
843
859
  /** Background of the rounded avatar tile next to the title (Lucide / emoji / image). */
844
860
  iconBackground: TokenReference<'color'>;
845
861
  /** Foreground (glyph stroke or emoji text) on the header avatar tile. */
846
862
  iconForeground: TokenReference<'color'>;
863
+ /** Header identity glyph size as a fraction of its icon box. @default "0.6" */
864
+ iconScale?: string;
847
865
  /**
848
866
  * Legacy alias of `title.color`; `title.color` wins when both are set.
849
867
  * Unset, the title takes `foreground`, then the primary color.
@@ -882,6 +900,14 @@ interface HeaderTokens extends ComponentTokenSet {
882
900
  * sibling. @default "1.5"
883
901
  */
884
902
  controlStrokeWidth?: string;
903
+ /** Header control corner radius. Per-control radius overrides win. */
904
+ controlBorderRadius?: string;
905
+ /** Default control hover/focus fill. Explicit button backgrounds win. */
906
+ controlHoverBackground?: TokenReference<'color'>;
907
+ /** Default control hover/focus icon color. Explicit button colors win. */
908
+ controlHoverForeground?: TokenReference<'color'>;
909
+ /** Keyboard focus outline; unset preserves the browser default. */
910
+ controlFocusOutline?: string;
885
911
  /** Box-shadow on the header (e.g., a fade shadow to replace the default border). */
886
912
  shadow?: string;
887
913
  /** Override the header bottom border (e.g., `none`). */
@@ -1056,6 +1082,12 @@ interface MessageGeometryTokens {
1056
1082
  lineHeight?: string;
1057
1083
  }
1058
1084
  interface MessageTokens {
1085
+ /** Height of the optional transcript top fade. Default 18px. */
1086
+ topFadeHeight?: string;
1087
+ /** Vertical gap between transcript turns. @default "12px" */
1088
+ gap?: string;
1089
+ /** Gap between turns in fullscreen mode; falls back to `gap`. */
1090
+ fullscreenGap?: string;
1059
1091
  user: MessageGeometryTokens & {
1060
1092
  background: TokenReference<'color'>;
1061
1093
  text: TokenReference<'color'>;
@@ -1069,6 +1101,8 @@ interface MessageTokens {
1069
1101
  borderRadius: TokenReference<'radius'>;
1070
1102
  /** Assistant bubble border color (CSS color). */
1071
1103
  border?: TokenReference<'color'>;
1104
+ /** Border width; set to 0px for a flat assistant response. @default "1px" */
1105
+ borderWidth?: string;
1072
1106
  /** Assistant bubble box-shadow (token ref or raw CSS, e.g. `none`). */
1073
1107
  shadow?: string;
1074
1108
  };
@@ -1187,12 +1221,40 @@ interface AttachmentTokens {
1187
1221
  };
1188
1222
  }
1189
1223
  /** Tool-call row chrome (collapsible tool bubbles). */
1190
- interface ToolBubbleTokens {
1224
+ interface ActivityTokens {
1225
+ /** Minimum activity row height. */
1226
+ rowHeight?: string;
1227
+ /** Group child indentation; falls back to indent when unset. V5: 0px. */
1228
+ groupIndent?: string;
1229
+ /** Extra vertical gap between grouped rows. V5: 0px. */
1230
+ groupGap?: string;
1231
+ /** Padding around expanded group children. V5: 0px. */
1232
+ groupPadding?: string;
1233
+ /** Gap between consecutive activity entries. V5: 0px. */
1234
+ transcriptGap?: string;
1235
+ /** Gap from activity to an assistant response. V5: 12px. */
1236
+ responseGap?: string;
1237
+ /** Expanded body padding. V5: 4px 0. */
1238
+ bodyPadding?: string;
1239
+ /** Expanded reasoning text size. V5: 13px. */
1240
+ bodySize?: string;
1241
+ /** Expanded reasoning line height. V5: 1.5. */
1242
+ bodyLineHeight?: string;
1243
+ /** Expanded reasoning font weight. V5: 400. */
1244
+ bodyFontWeight?: string;
1245
+ /** Gap between expanded detail sections. V5: 8px. */
1246
+ sectionGap?: string;
1247
+ labelSize?: string;
1248
+ iconSize?: string;
1249
+ indent?: string;
1250
+ bodySurface?: TokenReference<'color'>;
1251
+ }
1252
+ interface ToolBubbleTokens extends ActivityTokens {
1191
1253
  /** Box-shadow for tool bubbles (token ref or raw CSS, e.g. `none`). */
1192
1254
  shadow: string;
1193
1255
  }
1194
1256
  /** Reasoning / “thinking” row chrome. */
1195
- interface ReasoningBubbleTokens {
1257
+ interface ReasoningBubbleTokens extends ActivityTokens {
1196
1258
  shadow: string;
1197
1259
  }
1198
1260
  /** One event-stream badge chip: fill + text pair. The chip border derives
@@ -1326,6 +1388,10 @@ interface ComposerChromeTokens {
1326
1388
  shadow: string;
1327
1389
  /** Border color of the composer form. @default semantic.colors.border */
1328
1390
  borderColor?: TokenReference<'color'>;
1391
+ /** Focused form border color; falls back to borderColor. V5: a stronger neutral border. */
1392
+ focusBorderColor?: TokenReference<'color'>;
1393
+ /** Outer focus ring (CSS outline shorthand). V4: none; V5: a thin neutral ring. */
1394
+ focusRing?: string;
1329
1395
  /** Inner padding of the composer form (raw CSS shorthand). @default "0.75rem 1rem" */
1330
1396
  padding?: string;
1331
1397
  /** Gap between the textarea row and the actions row. @default "0.5rem" */
@@ -1344,12 +1410,18 @@ interface ComposerChromeTokens {
1344
1410
  controlSize?: string;
1345
1411
  /** Glyph box inside those controls. @default "24px" */
1346
1412
  controlIconSize?: string;
1413
+ /** Send/stop glyph size. Explicit sendButton.iconSize wins. V5: 18px. */
1414
+ sendIconSize?: string;
1415
+ /** Icon-mode submit button radius. V4 inherits the primary button; V5: 9999px. */
1416
+ sendButtonRadius?: string;
1417
+ /** Footer top border (CSS shorthand). V4: 1px solid divider; V5: none. */
1418
+ footerBorder?: string;
1347
1419
  /**
1348
1420
  * Background painted behind an overlaid composer footer
1349
1421
  * (`composer.placement: "overlay"`). Any CSS `background` value, gradients
1350
1422
  * included — same convention as the shadow tokens. Inert under
1351
1423
  * `placement: "block"`.
1352
- * @default "transparent"
1424
+ * @default "transparent" (V4); a theme-aware 24px fade (V5)
1353
1425
  */
1354
1426
  overlayBand?: string;
1355
1427
  /** Segmented mode-group track. */
@@ -1525,6 +1597,8 @@ interface ScrollToBottomTokens extends ComponentTokenSet {
1525
1597
  }
1526
1598
  /** Visual tokens shared by one suggestion presentation variant. */
1527
1599
  interface SuggestionVariantTokens extends ComponentTokenSet {
1600
+ /** Label weight. V4: 500; V5: 400. */
1601
+ fontWeight?: string;
1528
1602
  /** Space inside one item, between its icon and its copy. */
1529
1603
  gap?: string;
1530
1604
  /** Space between suggestion items in the container. */
@@ -1573,6 +1647,7 @@ interface ComponentTokens {
1573
1647
  voice: VoiceTokens;
1574
1648
  approval: ApprovalTokens;
1575
1649
  attachment: AttachmentTokens;
1650
+ activity?: ActivityTokens;
1576
1651
  toolBubble: ToolBubbleTokens;
1577
1652
  reasoningBubble: ReasoningBubbleTokens;
1578
1653
  /** Event-stream inspector badge chips. */
@@ -1702,6 +1777,7 @@ type RuntypeExecutionStreamEvent = ({
1702
1777
  turnIndex?: number;
1703
1778
  type: "turn_start";
1704
1779
  }) | ({
1780
+ attributes?: Record<string, string | number | boolean>;
1705
1781
  completedAt?: string;
1706
1782
  content?: string;
1707
1783
  cost?: number;
@@ -1760,7 +1836,8 @@ type RuntypeExecutionStreamEvent = ({
1760
1836
  };
1761
1837
  turnId?: string;
1762
1838
  type: "model_call_start";
1763
- } | {
1839
+ } | ({
1840
+ attributes?: Record<string, string | number | boolean>;
1764
1841
  completedAt?: string;
1765
1842
  cost?: number;
1766
1843
  durationMs?: number;
@@ -1784,10 +1861,11 @@ type RuntypeExecutionStreamEvent = ({
1784
1861
  cacheWrite?: number;
1785
1862
  input: number;
1786
1863
  output: number;
1864
+ reasoning?: number;
1787
1865
  };
1788
1866
  turnId?: string;
1789
1867
  type: "model_call_complete";
1790
- } | {
1868
+ }) | {
1791
1869
  executionId: string;
1792
1870
  id: string;
1793
1871
  index?: number;
@@ -2954,10 +3032,32 @@ type AgentWidgetContextMentionTokenRenderContext = {
2954
3032
  ref: AgentWidgetContextMentionRef;
2955
3033
  readonly: boolean;
2956
3034
  };
3035
+ /** One earlier client-tool call replayed to the model, in `/v1/dispatch` shape. */
3036
+ type AgentWidgetReplayedToolCall = {
3037
+ toolCallId: string;
3038
+ /** Model-facing (sanitized) name, e.g. `webmcp_search`. */
3039
+ toolName: string;
3040
+ args: Record<string, unknown>;
3041
+ };
3042
+ /** The browser's answer to an {@link AgentWidgetReplayedToolCall}. */
3043
+ type AgentWidgetReplayedToolResult = {
3044
+ toolCallId: string;
3045
+ toolName: string;
3046
+ result: unknown;
3047
+ };
3048
+ /**
3049
+ * A message in the proxy/agent request payload. Earlier client-tool calls the
3050
+ * browser answered replay as an assistant message carrying `toolCalls`,
3051
+ * followed by a `tool` message carrying the matching `toolResults`; both have
3052
+ * empty `content`. Client-token mode never sends them: the server replays
3053
+ * from its own stored transcript there.
3054
+ */
2957
3055
  type AgentWidgetRequestPayloadMessage = {
2958
- role: AgentWidgetMessageRole;
3056
+ role: AgentWidgetMessageRole | "tool";
2959
3057
  content: MessageContent;
2960
3058
  createdAt: string;
3059
+ toolCalls?: AgentWidgetReplayedToolCall[];
3060
+ toolResults?: AgentWidgetReplayedToolResult[];
2961
3061
  };
2962
3062
  type AgentWidgetRequestPayload = {
2963
3063
  messages: AgentWidgetRequestPayloadMessage[];
@@ -3353,6 +3453,24 @@ type AgentMessageMetadata = {
3353
3453
  * never re-resume the call.
3354
3454
  */
3355
3455
  suggestRepliesResolved?: boolean;
3456
+ /**
3457
+ * The client-tool answer the server accepted through `/resume`, kept so
3458
+ * later proxy/agent turns can replay the call and its result to the model.
3459
+ * `toolName` is the widget's internal name (`webmcp:<name>` or a bare
3460
+ * built-in). Set only after the resume succeeds; preserved across
3461
+ * re-emissions of the tool message.
3462
+ */
3463
+ clientToolAnswer?: {
3464
+ toolCallId: string;
3465
+ toolName: string;
3466
+ args: unknown;
3467
+ result: unknown;
3468
+ /**
3469
+ * Shared by the answers posted in one `/resume`, i.e. one assistant
3470
+ * turn's parallel calls; a chained call gets a new batch.
3471
+ */
3472
+ batch?: string;
3473
+ };
3356
3474
  };
3357
3475
  type AgentWidgetRequestMiddlewareContext = {
3358
3476
  payload: AgentWidgetRequestPayload;
@@ -4350,6 +4468,14 @@ type AgentWidgetToolCallCollapsedMode = "tool-call" | "tool-name" | "tool-previe
4350
4468
  */
4351
4469
  type AgentWidgetToolCallLoadingAnimation = "none" | "pulse" | "shimmer" | "shimmer-color" | "rainbow";
4352
4470
  type AgentWidgetToolCallDisplayFeature = {
4471
+ /** Activity chrome. Defaults to card in V4 and row with future.v5Defaults. */
4472
+ variant?: "card" | "row";
4473
+ /** Row status icons: always, active/attention-needed only, or never. V5 defaults to active; V4 to always. */
4474
+ iconVisibility?: "always" | "active" | "never";
4475
+ /** Row variant: open when the first content chunk arrives. Default false in V5; true in V4. */
4476
+ autoExpand?: boolean;
4477
+ /** Row variant: collapse once after completion, in ms; false disables. Default 1000. */
4478
+ autoCollapseDelay?: number | false;
4353
4479
  /**
4354
4480
  * Controls what collapsed tool call rows show in their header/summary area.
4355
4481
  * @default "tool-call"
@@ -4380,9 +4506,10 @@ type AgentWidgetToolCallDisplayFeature = {
4380
4506
  * Controls how a grouped tool sequence is rendered.
4381
4507
  * - `"stack"`: show the group summary and each child tool row.
4382
4508
  * - `"summary"`: show one consolidated summary row only.
4509
+ * - `"collapsible"`: expandable activity group (V5 default).
4383
4510
  * @default "stack"
4384
4511
  */
4385
- groupedMode?: "stack" | "summary";
4512
+ groupedMode?: "stack" | "summary" | "collapsible";
4386
4513
  /**
4387
4514
  * What happens to a tool call row once it completes.
4388
4515
  *
@@ -4413,6 +4540,14 @@ type AgentWidgetToolCallDisplayFeature = {
4413
4540
  /** See `features.toolCallDisplay.completedVisibility`. */
4414
4541
  type AgentWidgetToolCallCompletedVisibility = "kept" | "removed";
4415
4542
  type AgentWidgetReasoningDisplayFeature = {
4543
+ /** Activity chrome. Defaults to card in V4 and row with future.v5Defaults. */
4544
+ variant?: "card" | "row";
4545
+ /** Row status icons: always, active/attention-needed only, or never. V5 defaults to active; V4 to always. */
4546
+ iconVisibility?: "always" | "active" | "never";
4547
+ /** Row variant: open when the first content chunk arrives. Default false in V5; true in V4. */
4548
+ autoExpand?: boolean;
4549
+ /** Row variant: collapse once after completion, in ms; false disables. Default 1000. */
4550
+ autoCollapseDelay?: number | false;
4416
4551
  /**
4417
4552
  * When true, active collapsed reasoning rows can render a lightweight preview block.
4418
4553
  * @default false
@@ -5108,8 +5243,8 @@ interface AgentWidgetHistoryFeature {
5108
5243
  * otherwise `"browser"`) and narrows it to what the provider advertises, so a
5109
5244
  * browser-only provider is never asked for a scope it cannot serve. An
5110
5245
  * explicit `features.history.scope` is a hard request and still fails closed
5111
- * with `unsupported_scope`. `getIdentityProof` is never called for a supplied
5112
- * provider, and `HistoryOperationContext` carries only the resolved scope;
5246
+ * with `unsupported_scope`. History operations on a supplied provider never
5247
+ * call `getIdentityProof`, and `HistoryOperationContext` carries only the resolved scope;
5113
5248
  * report your own identity through `getIdentityStatus()` /
5114
5249
  * `subscribeIdentityStatus()`, which is what the scope banner and its retry
5115
5250
  * affordance read.
@@ -5493,7 +5628,7 @@ type EventStreamConfig = {
5493
5628
  /**
5494
5629
  * Fields to extract from event payloads for description text.
5495
5630
  * The first matching field value is displayed after the badge.
5496
- * @default ["flowName", "stepName", "name", "tool", "toolName"]
5631
+ * @default ["flowName", "stepName", "reasoningText", "text", "name", "tool", "toolName"]
5497
5632
  */
5498
5633
  descriptionFields?: string[];
5499
5634
  /**
@@ -5704,6 +5839,8 @@ type AgentWidgetComposerBarPeekConfig = {
5704
5839
  streamAnimation?: AgentWidgetStreamAnimationFeature;
5705
5840
  };
5706
5841
  type AgentWidgetLauncherConfig = {
5842
+ /** Collapsed launcher shape. V4 defaults to pill; V5 defaults to circle. */
5843
+ variant?: "pill" | "circle";
5707
5844
  enabled?: boolean;
5708
5845
  title?: string;
5709
5846
  subtitle?: string;
@@ -6459,9 +6596,9 @@ type AgentWidgetComposerConfig = {
6459
6596
  /**
6460
6597
  * Where the composer footer sits relative to the transcript.
6461
6598
  *
6462
- * - `"block"` (default): the footer is a flex sibling below the scroll body.
6599
+ * - `"block"` (V4 default): the footer is a flex sibling below the scroll body.
6463
6600
  * Nothing scrolls behind it.
6464
- * - `"overlay"`: the footer is absolutely overlaid on the scroll body, so the
6601
+ * - `"overlay"` (V5 default): the footer is absolutely overlaid on the scroll body, so the
6465
6602
  * transcript scrolls behind it (the chatgpt.com / claude.ai model, where the
6466
6603
  * composer is sticky inside the scroller). The widget reserves the footer's
6467
6604
  * live height as bottom padding on the scroll body and on a plugin welcome
@@ -6473,7 +6610,7 @@ type AgentWidgetComposerConfig = {
6473
6610
  * included) and `theme.components.input.backdropFilter`.
6474
6611
  *
6475
6612
  * Ignored in composer-bar mount mode, which owns its own geometry.
6476
- * @default "block"
6613
+ * @default "block" (V4), "overlay" (V5)
6477
6614
  */
6478
6615
  placement?: ComposerPlacement;
6479
6616
  /**
@@ -6487,8 +6624,9 @@ type AgentWidgetComposerConfig = {
6487
6624
  *
6488
6625
  * `"single-row"` describes the IDLE composer only. It composes with the
6489
6626
  * compact state, so a wrapped draft, chips, attachment previews, a quote, a
6490
- * pending card, or live dictation all fall back to the stacked card, exactly
6491
- * as `data-persona-composer-compact` does today.
6627
+ * pending card all fall back to the stacked card, exactly
6628
+ * as `data-persona-composer-compact` does today. Recording alone does not
6629
+ * expand the composer; dictated text expands it when it wraps.
6492
6630
  *
6493
6631
  * Ignored in composer-bar mount mode, whose pill is already one row.
6494
6632
  * @default "stacked"
@@ -6530,7 +6668,14 @@ type AgentWidgetClearChatConfig = {
6530
6668
  showTooltip?: boolean;
6531
6669
  };
6532
6670
  type AgentWidgetStatusIndicatorConfig = {
6671
+ /** Show the indicator. Explicit false also hides transient connection states. */
6533
6672
  visible?: boolean;
6673
+ /**
6674
+ * "always" shows status beneath the composer; "transient" shows connecting,
6675
+ * reconnecting, and error status above it, hiding normal idle/streaming status.
6676
+ * Available in both defaults states. Default: "always" in v4, "transient" in v5.
6677
+ */
6678
+ mode?: "always" | "transient";
6534
6679
  /** Text alignment. Default: 'right'. */
6535
6680
  align?: 'left' | 'center' | 'right';
6536
6681
  idleText?: string;
@@ -7350,7 +7495,8 @@ type AgentWidgetResolvedSuggestion = {
7350
7495
  };
7351
7496
  /** Presentation keys shared by every suggestion surface. */
7352
7497
  type AgentWidgetSuggestionSurfaceConfig = {
7353
- /** Item density. Defaults to `card` for starters and `chip` for follow-ups. */
7498
+ /** Item density. V4 starters: card. V5 starters: chip, or card in fullscreen.
7499
+ * Follow-ups default to chip. */
7354
7500
  variant?: AgentWidgetSuggestionVariant;
7355
7501
  /** Default click behavior, overridable per item. Defaults to `send`. */
7356
7502
  behavior?: AgentWidgetSuggestionBehavior;
@@ -7361,7 +7507,7 @@ type AgentWidgetSuggestionSurfaceConfig = {
7361
7507
  * own stacking.
7362
7508
  */
7363
7509
  overflow?: "scroll" | "wrap";
7364
- /** Maximum visible items. Defaults to 4. */
7510
+ /** Maximum visible items. Defaults to 4, or 3 for V5 non-fullscreen starters. */
7365
7511
  maxItems?: number;
7366
7512
  };
7367
7513
  type AgentWidgetStarterSuggestionsConfig = AgentWidgetSuggestionSurfaceConfig & {
@@ -7415,8 +7561,8 @@ type AgentWidgetSuggestionsConfig = {
7415
7561
  type AgentWidgetWelcomeVariant = "card" | "hero" | "none";
7416
7562
  /**
7417
7563
  * When the welcome surface goes away. `"never"` is the default for `"card"`;
7418
- * `"on-first-message"` is the default for `"hero"` and cannot be overridden
7419
- * there.
7564
+ * `"on-first-message"` is forced for legacy V4 `"hero"`. V5 defaults every
7565
+ * variant to `"on-first-message"`. Explicit layout opts into overridable dismissal.
7420
7566
  */
7421
7567
  type AgentWidgetWelcomeDismiss = "never" | "on-first-message";
7422
7568
  /**
@@ -7470,7 +7616,10 @@ type AgentWidgetWelcomeAlign = "start" | "center";
7470
7616
  * host-set value from a filled-in default.
7471
7617
  */
7472
7618
  interface AgentWidgetWelcomeConfig {
7473
- /** Card or hero title. Defaults to "Hello 👋". */
7619
+ /** Vertical placement: V4 defaults to top; V5 to centered. Fullscreen centered
7620
+ * welcomes also raise the empty composer unless `anchor` is explicitly set. */
7621
+ layout?: "top" | "centered";
7622
+ /** Card or hero title. V4: "Hello 👋". V5: "What can I help with?". */
7474
7623
  title?: string;
7475
7624
  /**
7476
7625
  * Small muted line above the title, e.g. a section name. Omitted when unset
@@ -7483,19 +7632,22 @@ interface AgentWidgetWelcomeConfig {
7483
7632
  icon?: AgentWidgetWelcomeIcon;
7484
7633
  /**
7485
7634
  * Horizontal alignment of the kicker, title, subtitle, and starter
7486
- * suggestions. Unset follows the variant: `card` starts, `hero` centers.
7635
+ * suggestions. Centered layouts default to center. Otherwise unset follows
7636
+ * the variant: `card` starts, `hero` centers.
7487
7637
  */
7488
7638
  align?: AgentWidgetWelcomeAlign;
7489
7639
  /** @default "card" */
7490
7640
  variant?: AgentWidgetWelcomeVariant;
7491
- /** @default "never" for `card`, always `"on-first-message"` for `hero`. */
7641
+ /** V4: never for card, forced on-first-message for hero. V5: on-first-message
7642
+ * for all variants; explicit values win. Explicit layout also allows overriding
7643
+ * the legacy hero dismissal in V4. */
7492
7644
  dismiss?: AgentWidgetWelcomeDismiss;
7493
7645
  /**
7494
7646
  * Vertical anchoring of the greeting-plus-composer pair in the EMPTY
7495
7647
  * conversation only. On the first message the pair drops to the bottom
7496
7648
  * (animated; see `data-persona-conversation-state`).
7497
7649
  *
7498
- * - `"bottom"` (default): the composer stays pinned at the bottom.
7650
+ * - `"bottom"`: the composer stays pinned at the bottom.
7499
7651
  * - `"center"`: greeting and composer float together so the composer's top
7500
7652
  * edge lands at `anchorComposerTop` of the panel column, and the welcome
7501
7653
  * surface is end-anchored `composerGap` above it.
@@ -7503,7 +7655,8 @@ interface AgentWidgetWelcomeConfig {
7503
7655
  * Composes with either `composer.placement`. Ignored in composer-bar mount
7504
7656
  * mode. `renderWelcome` plugin content inherits the anchor: the widget
7505
7657
  * positions the overlay host and reserves the composer zone.
7506
- * @default "bottom"
7658
+ * Defaults to bottom, except centered fullscreen layouts, which center the
7659
+ * measured greeting/composer group when no anchor override is supplied.
7507
7660
  */
7508
7661
  anchor?: AgentWidgetWelcomeAnchor;
7509
7662
  /**
@@ -8093,6 +8246,9 @@ type AgentWidgetLayoutConfig = {
8093
8246
  * `launcher.composerBar.contentMaxWidth`)
8094
8247
  */
8095
8248
  contentMaxWidth?: string;
8249
+ /** Fade the transcript's top edge when content is scrolled above it.
8250
+ * Defaults to false in V4 and true with future.v5Defaults. */
8251
+ topFade?: boolean;
8096
8252
  };
8097
8253
  /**
8098
8254
  * Token types for marked renderer methods
@@ -8706,7 +8862,30 @@ type AgentWidgetLoadingIndicatorConfig = {
8706
8862
  */
8707
8863
  renderIdle?: (context: IdleIndicatorRenderContext) => HTMLElement | null;
8708
8864
  };
8865
+ /** Built-in `sessionInit` triggers. See {@link AgentWidgetConfig.sessionInit}. */
8866
+ type AgentWidgetSessionInitTrigger = 'input' | 'focus' | 'mount' | 'send';
8867
+ /**
8868
+ * Custom `sessionInit` trigger. Runs when the widget mounts in client token mode,
8869
+ * and again if `update()` swaps in a different function. Call `warm()` whenever
8870
+ * the visitor shows intent (it is safe to call repeatedly). Return a cleanup to
8871
+ * run when the widget is destroyed or the hook is replaced.
8872
+ */
8873
+ type AgentWidgetSessionInitHook = (context: {
8874
+ /** Fire-and-forget early session init; latched and error-swallowing. */
8875
+ warm: () => void;
8876
+ /** The widget's mount element. */
8877
+ mount: HTMLElement;
8878
+ }) => void | (() => void);
8709
8879
  type AgentWidgetConfig = {
8880
+ /** Opt in to upcoming major-version defaults without changing explicit settings. */
8881
+ future?: {
8882
+ /**
8883
+ * Use the v5 default styling as it rolls out in 4.x. Every affected setting
8884
+ * remains independently configurable. Explicit options and theme tokens win.
8885
+ * @default false
8886
+ */
8887
+ v5Defaults?: boolean;
8888
+ };
8710
8889
  apiUrl?: string;
8711
8890
  flowId?: string;
8712
8891
  /**
@@ -8861,6 +9040,46 @@ type AgentWidgetConfig = {
8861
9040
  * ```
8862
9041
  */
8863
9042
  onSessionExpired?: () => void;
9043
+ /**
9044
+ * When the widget calls `/v1/client/init` in client token mode, ahead of the
9045
+ * first send. Ignored outside client token mode.
9046
+ *
9047
+ * - `'input'` (default): on the composer's first user keystroke that leaves
9048
+ * non-empty text. Programmatic value changes (restored drafts,
9049
+ * `setMessage()`, history recall) do not count.
9050
+ * - `'focus'`: when the visitor focuses the composer by pointer or Tab (and
9051
+ * on first input, as a fallback). Programmatic focus, such as
9052
+ * `autoFocusInput` on open or mount, does not count.
9053
+ * - `'mount'`: as soon as the widget mounts (the behavior before this option
9054
+ * existed). Use it when a server-configured welcome message, which arrives
9055
+ * with the init response, must show before the visitor types.
9056
+ * - `'send'`: no early init; the first send initializes the session.
9057
+ * - A function: custom trigger. Called on mount (and when `update()` swaps
9058
+ * in a different function) with a `warm` callback to call whenever you
9059
+ * decide (e.g. on hover); may return a cleanup that runs on destroy or
9060
+ * replacement. Replaces the built-in triggers.
9061
+ *
9062
+ * The early init is fire-and-forget: it runs at most once per session
9063
+ * lifetime (re-armed after expiry or a new conversation), sends exactly the
9064
+ * same request the send would, and swallows errors. A failure resurfaces
9065
+ * when the send retries init. A send during an in-flight early init reuses
9066
+ * it, so only one `/v1/client/init` is issued. When visitor history is
9067
+ * enabled the widget still initializes on mount to restore the conversation.
9068
+ * Hosts can also trigger it imperatively with `controller.warmSession()`.
9069
+ *
9070
+ * @default 'input'
9071
+ *
9072
+ * @example
9073
+ * ```typescript
9074
+ * config: {
9075
+ * clientToken: 'ct_live_...',
9076
+ * sessionInit: ({ warm, mount }) => {
9077
+ * mount.addEventListener('pointerenter', warm, { once: true });
9078
+ * }
9079
+ * }
9080
+ * ```
9081
+ */
9082
+ sessionInit?: AgentWidgetSessionInitTrigger | AgentWidgetSessionInitHook;
8864
9083
  /**
8865
9084
  * Get stored session ID for session resumption (client token mode only).
8866
9085
  * Called when initializing a new session to check if there's a previous session_id
@@ -8893,13 +9112,20 @@ type AgentWidgetConfig = {
8893
9112
  */
8894
9113
  setStoredSessionId?: (sessionId: string) => void;
8895
9114
  /**
8896
- * Called immediately before any cross-device history request and before a
9115
+ * With identityProvider, called before every client-token chat POST, including retries, independently of history.
9116
+ * Also called immediately before any cross-device history request and before a
8897
9117
  * conversationId resume of a conversation discovered on another device.
8898
- * Return a fresh end-user access token (rt_eu_… / JWT). Null uses exact-browser
8899
- * scope only for a never-bound visitor; a previously bound visitor fails closed
8900
- * until resetHistoryIdentity() runs. Never cached by the widget.
9118
+ * Return a fresh end-user access token (rt_eu_… / JWT). Null stops identity-enabled chat.
9119
+ * For history only, null uses exact-browser scope for a never-bound visitor;
9120
+ * a bound visitor fails closed until resetHistoryIdentity(). Never cached.
8901
9121
  */
8902
9122
  getIdentityProof?: () => string | null | Promise<string | null>;
9123
+ /**
9124
+ * Provider name registered with Runtype, for example "clerk". Enables per-request
9125
+ * chat identity through getIdentityProof without enabling history. A missing or
9126
+ * failed proof stops the turn; omitting this preserves history-only callbacks.
9127
+ */
9128
+ identityProvider?: string;
8903
9129
  /**
8904
9130
  * Read the persisted active conversation id (client token mode only).
8905
9131
  * Called only after the internal stored-state bootstrap gate resolves.
@@ -9573,6 +9799,8 @@ type AgentWidgetReasoning = {
9573
9799
  durationMs?: number;
9574
9800
  };
9575
9801
  type AgentWidgetToolCall = {
9802
+ /** Optional approval state for activity-row status chrome. */
9803
+ approvalStatus?: "pending" | "approved" | "denied" | "timeout";
9576
9804
  id: string;
9577
9805
  name?: string;
9578
9806
  status: "pending" | "running" | "complete";
@@ -10042,6 +10270,14 @@ declare class AgentWidgetClient {
10042
10270
  private currentClientTurnId;
10043
10271
  private clientSession;
10044
10272
  private sessionInitPromise;
10273
+ /**
10274
+ * Early-init latch for `warmSession()`. `false` = armed. Otherwise it holds
10275
+ * the session value (`null` or an expired session) the one early attempt was
10276
+ * made against, so a failed attempt is not retried on every keystroke. It is
10277
+ * re-armed when a session is installed or cleared, so each session lifetime
10278
+ * gets one early init.
10279
+ */
10280
+ private sessionWarmLatch;
10045
10281
  private lastSentClientToolsFingerprint;
10046
10282
  private clientToolsFingerprintSessionId;
10047
10283
  private sentNonEmptyClientToolsSessionId;
@@ -10150,9 +10386,27 @@ declare class AgentWidgetClient {
10150
10386
  after: string;
10151
10387
  signal: AbortSignal;
10152
10388
  }): Promise<Response>;
10389
+ /**
10390
+ * Fire-and-forget early `initSession()` for client-token mode, driven by the
10391
+ * widget's `sessionInit` trigger (or a host calling it directly, e.g. on
10392
+ * hover). It fires at most once per session lifetime and is a no-op while a
10393
+ * session is live or an init is already in flight. Errors are swallowed, with
10394
+ * no `onSessionExpired` and no UI: a send calls `initSession()` again and
10395
+ * reuses the in-flight promise, so any failure resurfaces there exactly as it
10396
+ * would without the early init. Sends nothing new on the wire. Outside
10397
+ * client-token mode this does nothing.
10398
+ *
10399
+ * Resolves with the session this call initialized, or `null` when it was
10400
+ * skipped or failed. It never rejects.
10401
+ */
10402
+ warmSession(): Promise<ClientSession | null>;
10153
10403
  /**
10154
10404
  * Initialize session for client token mode.
10155
- * Called automatically on first message if not already initialized.
10405
+ * Called by the send if no live session exists. The widget normally calls
10406
+ * it earlier, when the visitor shows intent to send (see the `sessionInit`
10407
+ * config option and `warmSession()`), and concurrent calls share one
10408
+ * in-flight request, so a send racing an early init issues a single
10409
+ * `/v1/client/init`.
10156
10410
  */
10157
10411
  initSession(): Promise<ClientSession>;
10158
10412
  /** Visitor history rides on client-token init only, and latches off after a 403 degrade. */
@@ -10297,6 +10551,7 @@ declare class AgentWidgetClient {
10297
10551
  private historyUrl;
10298
10552
  /** Explicit per-operation scope wins; otherwise config, then evidence. */
10299
10553
  private resolveHistoryScope;
10554
+ private resolveChatIdentityProof;
10300
10555
  /**
10301
10556
  * Resolve the proof for one logical request. `null` is an intentional
10302
10557
  * browser-scope fallback only while the visitor has never been bound.
@@ -10752,10 +11007,16 @@ declare class AgentWidgetSession {
10752
11007
  * explicitly to pre-initialize the session and get config from server.
10753
11008
  */
10754
11009
  initClientSession(): Promise<ClientSession | null>;
11010
+ /**
11011
+ * Early, fire-and-forget client-token init (`sessionInit` trigger or
11012
+ * `controller.initSession()`). Failures stay silent here: no `onError`, no
11013
+ * UI. The send re-runs `initSession()` and reports them as it always has.
11014
+ */
11015
+ warmClientSession(): void;
10755
11016
  /**
10756
11017
  * Set the client session after initialization
10757
11018
  */
10758
- setClientSession(session: ClientSession): void;
11019
+ setClientSession(session: ClientSession, pristine?: boolean): void;
10759
11020
  /**
10760
11021
  * Welcome injection is skipped while `suppressWelcomeInjection` is latched:
10761
11022
  * reopening a stored conversation is not a new thread, and the hydrated