@runtypelabs/persona 4.23.2 → 4.25.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 (166) 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-CI7OckWI.d.cts → types-Db61aI9J.d.cts} +2 -0
  4. package/dist/animations/{types-CI7OckWI.d.ts → types-Db61aI9J.d.ts} +2 -0
  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 +2 -0
  8. package/dist/animations-extra.d.ts +2 -0
  9. package/dist/approval-ui-3NMYNXBD.js +1 -0
  10. package/dist/approval-ui.cjs +2 -2
  11. package/dist/approval-ui.d.cts +278 -37
  12. package/dist/approval-ui.d.ts +278 -37
  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 +273 -25
  16. package/dist/artifacts-ui.d.ts +273 -25
  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 +273 -25
  21. package/dist/context-mentions.d.ts +273 -25
  22. package/dist/event-stream-view.d.cts +273 -25
  23. package/dist/event-stream-view.d.ts +273 -25
  24. package/dist/forms-ui.d.cts +319 -27
  25. package/dist/forms-ui.d.ts +319 -27
  26. package/dist/history-view.d.cts +2 -0
  27. package/dist/history-view.d.ts +2 -0
  28. package/dist/index.cjs +70 -69
  29. package/dist/index.cjs.map +1 -1
  30. package/dist/index.d.cts +344 -39
  31. package/dist/index.d.ts +344 -39
  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 +273 -25
  41. package/dist/session-reconnect.d.ts +273 -25
  42. package/dist/smart-dom-reader.d.cts +273 -25
  43. package/dist/smart-dom-reader.d.ts +273 -25
  44. package/dist/theme-editor-preview.cjs +74 -73
  45. package/dist/theme-editor-preview.d.cts +280 -25
  46. package/dist/theme-editor-preview.d.ts +280 -25
  47. package/dist/theme-editor-preview.js +51 -50
  48. package/dist/theme-editor.cjs +10 -10
  49. package/dist/theme-editor.d.cts +293 -27
  50. package/dist/theme-editor.d.ts +293 -27
  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/voice-runtime-7DA7MJH4.js +1 -0
  57. package/dist/voice-runtime.cjs +1 -1
  58. package/dist/voice-runtime.d.cts +33 -0
  59. package/dist/voice-runtime.d.ts +33 -0
  60. package/dist/voice-runtime.js +1 -1
  61. package/dist/widget.css +1 -1
  62. package/package.json +3 -2
  63. package/src/__fixtures__/defaults-parity.v4.json +776 -0
  64. package/src/approval-ui-entry.ts +0 -1
  65. package/src/approval-ui-loader.ts +5 -4
  66. package/src/approval-ui.ts +0 -1
  67. package/src/client-identity-proof.test.ts +193 -0
  68. package/src/client-session-warm.test.ts +216 -0
  69. package/src/client-visitor-history.test.ts +6 -0
  70. package/src/client.ts +122 -30
  71. package/src/codegen.test.ts +24 -0
  72. package/src/components/activity-row.test.ts +100 -0
  73. package/src/components/activity-row.ts +136 -0
  74. package/src/components/approval-actions.test.ts +8 -5
  75. package/src/components/approval-actions.ts +19 -6
  76. package/src/components/approval-bubble.test.ts +56 -9
  77. package/src/components/approval-bubble.ts +36 -41
  78. package/src/components/composer-builder.ts +5 -2
  79. package/src/components/composer-parts.ts +10 -2
  80. package/src/components/header-builder.test.ts +32 -0
  81. package/src/components/header-builder.ts +7 -4
  82. package/src/components/header-layouts.test.ts +12 -0
  83. package/src/components/header-layouts.ts +3 -2
  84. package/src/components/launcher.ts +11 -2
  85. package/src/components/message-bubble.test.ts +22 -0
  86. package/src/components/message-bubble.ts +7 -3
  87. package/src/components/panel.test.ts +52 -1
  88. package/src/components/panel.ts +47 -8
  89. package/src/components/pill-composer-builder.test.ts +2 -0
  90. package/src/components/pill-composer-builder.ts +0 -1
  91. package/src/components/reasoning-bubble.ts +29 -17
  92. package/src/components/suggestions.test.ts +1 -0
  93. package/src/components/suggestions.ts +0 -16
  94. package/src/components/tool-bubble.ts +131 -114
  95. package/src/components/tool-details.test.ts +87 -0
  96. package/src/components/tool-details.ts +102 -0
  97. package/src/components/welcome.test.ts +8 -0
  98. package/src/components/welcome.ts +4 -2
  99. package/src/defaults-parity.test.ts +158 -0
  100. package/src/defaults.test.ts +69 -0
  101. package/src/defaults.ts +128 -49
  102. package/src/generated/runtype-openapi-contract.ts +2 -2
  103. package/src/index-core.ts +4 -0
  104. package/src/install.test.ts +24 -0
  105. package/src/install.ts +3 -1
  106. package/src/launcher-global.ts +2 -1
  107. package/src/launcher-variants.test.ts +52 -0
  108. package/src/runtime/init-update-reset.test.ts +21 -0
  109. package/src/session.ts +59 -7
  110. package/src/session.voice.test.ts +72 -1
  111. package/src/styles/widget-styles.test.ts +19 -0
  112. package/src/styles/widget.css +295 -23
  113. package/src/theme-editor/index.ts +2 -0
  114. package/src/theme-editor/preview-utils.test.ts +8 -0
  115. package/src/theme-editor/preview-utils.ts +7 -3
  116. package/src/theme-editor/sections.test.ts +31 -0
  117. package/src/theme-editor/sections.ts +55 -1
  118. package/src/theme-editor/state-preferences.test.ts +49 -0
  119. package/src/theme-editor/state.ts +73 -15
  120. package/src/theme-reference.test.ts +20 -0
  121. package/src/theme-reference.ts +11 -5
  122. package/src/tool-call-display-defaults.test.ts +33 -1
  123. package/src/types/theme.ts +80 -3
  124. package/src/types.ts +207 -22
  125. package/src/ui.activity-row.test.ts +91 -0
  126. package/src/ui.approval-plugin.test.ts +63 -0
  127. package/src/ui.composer-compact.test.ts +24 -2
  128. package/src/ui.composer-placement.test.ts +23 -0
  129. package/src/ui.detached-panel.test.ts +33 -6
  130. package/src/ui.docked.test.ts +19 -0
  131. package/src/ui.header-update-stability.test.ts +25 -0
  132. package/src/ui.identity-proof.test.ts +58 -0
  133. package/src/ui.launcher-teaser.test.ts +25 -0
  134. package/src/ui.message-width.test.ts +17 -2
  135. package/src/ui.reasoning-display.test.ts +92 -0
  136. package/src/ui.rebuild-composer.test.ts +20 -3
  137. package/src/ui.scroll.test.ts +32 -0
  138. package/src/ui.session-init.test.ts +312 -0
  139. package/src/ui.status-indicator.test.ts +82 -0
  140. package/src/ui.suggest-replies.test.ts +11 -0
  141. package/src/ui.ts +422 -74
  142. package/src/ui.v5-defaults.test.ts +144 -0
  143. package/src/ui.voice-prewarm.test.ts +222 -0
  144. package/src/ui.welcome.test.ts +92 -3
  145. package/src/utils/__snapshots__/tokens-parity.test.ts.snap +811 -140
  146. package/src/utils/code-generators.ts +14 -0
  147. package/src/utils/composer-compact.test.ts +0 -2
  148. package/src/utils/composer-compact.ts +2 -4
  149. package/src/utils/composer-placement.ts +2 -3
  150. package/src/utils/config-merge.test.ts +81 -5
  151. package/src/utils/config-merge.ts +13 -3
  152. package/src/utils/defaults-provenance.ts +67 -0
  153. package/src/utils/dock.ts +7 -1
  154. package/src/utils/launcher-variant.ts +16 -0
  155. package/src/utils/panel-config.ts +97 -0
  156. package/src/utils/status-indicator.ts +39 -0
  157. package/src/utils/theme.test.ts +182 -0
  158. package/src/utils/theme.ts +131 -18
  159. package/src/utils/tokens.test.ts +122 -1
  160. package/src/utils/tokens.ts +177 -17
  161. package/src/voice/runtype-voice-provider.ts +238 -27
  162. package/src/voice/voice.test.ts +272 -2
  163. package/src/welcome.test.ts +23 -0
  164. package/src/welcome.ts +16 -9
  165. package/dist/approval-ui-K7R5Q5OC.js +0 -1
  166. package/dist/voice-runtime-EFR3R5ES.js +0 -1
@@ -196,6 +196,8 @@ interface InputTokens extends ComponentTokenSet {
196
196
  backdropFilter?: string;
197
197
  }
198
198
  interface LauncherTokens extends ComponentTokenSet {
199
+ /** Distance from the viewport edges. Circle default: 20px; pill: 24px. */
200
+ offset?: string;
199
201
  size: string;
200
202
  iconSize: string;
201
203
  shadow: TokenReference<'shadow'>;
@@ -218,6 +220,15 @@ interface PanelTokens extends ComponentTokenSet {
218
220
  inset?: string;
219
221
  /** Background of the region revealed behind a detached panel. */
220
222
  canvasBackground?: string;
223
+ /** Chrome defaults by rendered panel mode. */
224
+ modes?: Partial<Record<'floating' | 'inline' | 'sidebar' | 'docked' | 'mobile', {
225
+ /** Full border shorthand (for example, `"1px solid var(--persona-border)"`). */
226
+ border?: string;
227
+ /** Box-shadow token reference or raw CSS shadow. */
228
+ shadow?: string;
229
+ /** Corner radius token reference or raw CSS radius. */
230
+ borderRadius?: TokenReference<'radius'>;
231
+ }>>;
221
232
  }
222
233
  /** Per-element text styling shared by themable text surfaces. */
223
234
  interface TextStyleTokens {
@@ -244,10 +255,16 @@ interface HeaderTokens extends ComponentTokenSet {
244
255
  */
245
256
  border?: TokenReference<'color'>;
246
257
  borderRadius: TokenReference<'radius'>;
258
+ /** Standard-header padding. @default "20px 24px" */
259
+ padding?: string;
260
+ /** Minimal-header padding. Explicitly wins over `padding`. @default "16px 24px" */
261
+ minimalPadding?: string;
247
262
  /** Background of the rounded avatar tile next to the title (Lucide / emoji / image). */
248
263
  iconBackground: TokenReference<'color'>;
249
264
  /** Foreground (glyph stroke or emoji text) on the header avatar tile. */
250
265
  iconForeground: TokenReference<'color'>;
266
+ /** Header identity glyph size as a fraction of its icon box. @default "0.6" */
267
+ iconScale?: string;
251
268
  /**
252
269
  * Legacy alias of `title.color`; `title.color` wins when both are set.
253
270
  * Unset, the title takes `foreground`, then the primary color.
@@ -286,6 +303,14 @@ interface HeaderTokens extends ComponentTokenSet {
286
303
  * sibling. @default "1.5"
287
304
  */
288
305
  controlStrokeWidth?: string;
306
+ /** Header control corner radius. Per-control radius overrides win. */
307
+ controlBorderRadius?: string;
308
+ /** Default control hover/focus fill. Explicit button backgrounds win. */
309
+ controlHoverBackground?: TokenReference<'color'>;
310
+ /** Default control hover/focus icon color. Explicit button colors win. */
311
+ controlHoverForeground?: TokenReference<'color'>;
312
+ /** Keyboard focus outline; unset preserves the browser default. */
313
+ controlFocusOutline?: string;
289
314
  /** Box-shadow on the header (e.g., a fade shadow to replace the default border). */
290
315
  shadow?: string;
291
316
  /** Override the header bottom border (e.g., `none`). */
@@ -460,6 +485,12 @@ interface MessageGeometryTokens {
460
485
  lineHeight?: string;
461
486
  }
462
487
  interface MessageTokens {
488
+ /** Height of the optional transcript top fade. Default 18px. */
489
+ topFadeHeight?: string;
490
+ /** Vertical gap between transcript turns. @default "12px" */
491
+ gap?: string;
492
+ /** Gap between turns in fullscreen mode; falls back to `gap`. */
493
+ fullscreenGap?: string;
463
494
  user: MessageGeometryTokens & {
464
495
  background: TokenReference<'color'>;
465
496
  text: TokenReference<'color'>;
@@ -473,6 +504,8 @@ interface MessageTokens {
473
504
  borderRadius: TokenReference<'radius'>;
474
505
  /** Assistant bubble border color (CSS color). */
475
506
  border?: TokenReference<'color'>;
507
+ /** Border width; set to 0px for a flat assistant response. @default "1px" */
508
+ borderWidth?: string;
476
509
  /** Assistant bubble box-shadow (token ref or raw CSS, e.g. `none`). */
477
510
  shadow?: string;
478
511
  };
@@ -591,12 +624,40 @@ interface AttachmentTokens {
591
624
  };
592
625
  }
593
626
  /** Tool-call row chrome (collapsible tool bubbles). */
594
- interface ToolBubbleTokens {
627
+ interface ActivityTokens {
628
+ /** Minimum activity row height. */
629
+ rowHeight?: string;
630
+ /** Group child indentation; falls back to indent when unset. V5: 0px. */
631
+ groupIndent?: string;
632
+ /** Extra vertical gap between grouped rows. V5: 0px. */
633
+ groupGap?: string;
634
+ /** Padding around expanded group children. V5: 0px. */
635
+ groupPadding?: string;
636
+ /** Gap between consecutive activity entries. V5: 0px. */
637
+ transcriptGap?: string;
638
+ /** Gap from activity to an assistant response. V5: 12px. */
639
+ responseGap?: string;
640
+ /** Expanded body padding. V5: 4px 0. */
641
+ bodyPadding?: string;
642
+ /** Expanded reasoning text size. V5: 13px. */
643
+ bodySize?: string;
644
+ /** Expanded reasoning line height. V5: 1.5. */
645
+ bodyLineHeight?: string;
646
+ /** Expanded reasoning font weight. V5: 400. */
647
+ bodyFontWeight?: string;
648
+ /** Gap between expanded detail sections. V5: 8px. */
649
+ sectionGap?: string;
650
+ labelSize?: string;
651
+ iconSize?: string;
652
+ indent?: string;
653
+ bodySurface?: TokenReference<'color'>;
654
+ }
655
+ interface ToolBubbleTokens extends ActivityTokens {
595
656
  /** Box-shadow for tool bubbles (token ref or raw CSS, e.g. `none`). */
596
657
  shadow: string;
597
658
  }
598
659
  /** Reasoning / “thinking” row chrome. */
599
- interface ReasoningBubbleTokens {
660
+ interface ReasoningBubbleTokens extends ActivityTokens {
600
661
  shadow: string;
601
662
  }
602
663
  /** One event-stream badge chip: fill + text pair. The chip border derives
@@ -730,6 +791,10 @@ interface ComposerChromeTokens {
730
791
  shadow: string;
731
792
  /** Border color of the composer form. @default semantic.colors.border */
732
793
  borderColor?: TokenReference<'color'>;
794
+ /** Focused form border color; falls back to borderColor. V5: a stronger neutral border. */
795
+ focusBorderColor?: TokenReference<'color'>;
796
+ /** Outer focus ring (CSS outline shorthand). V4: none; V5: a thin neutral ring. */
797
+ focusRing?: string;
733
798
  /** Inner padding of the composer form (raw CSS shorthand). @default "0.75rem 1rem" */
734
799
  padding?: string;
735
800
  /** Gap between the textarea row and the actions row. @default "0.5rem" */
@@ -748,12 +813,18 @@ interface ComposerChromeTokens {
748
813
  controlSize?: string;
749
814
  /** Glyph box inside those controls. @default "24px" */
750
815
  controlIconSize?: string;
816
+ /** Send/stop glyph size. Explicit sendButton.iconSize wins. V5: 18px. */
817
+ sendIconSize?: string;
818
+ /** Icon-mode submit button radius. V4 inherits the primary button; V5: 9999px. */
819
+ sendButtonRadius?: string;
820
+ /** Footer top border (CSS shorthand). V4: 1px solid divider; V5: none. */
821
+ footerBorder?: string;
751
822
  /**
752
823
  * Background painted behind an overlaid composer footer
753
824
  * (`composer.placement: "overlay"`). Any CSS `background` value, gradients
754
825
  * included — same convention as the shadow tokens. Inert under
755
826
  * `placement: "block"`.
756
- * @default "transparent"
827
+ * @default "transparent" (V4); a theme-aware 24px fade (V5)
757
828
  */
758
829
  overlayBand?: string;
759
830
  /** Segmented mode-group track. */
@@ -929,6 +1000,8 @@ interface ScrollToBottomTokens extends ComponentTokenSet {
929
1000
  }
930
1001
  /** Visual tokens shared by one suggestion presentation variant. */
931
1002
  interface SuggestionVariantTokens extends ComponentTokenSet {
1003
+ /** Label weight. V4: 500; V5: 400. */
1004
+ fontWeight?: string;
932
1005
  /** Space inside one item, between its icon and its copy. */
933
1006
  gap?: string;
934
1007
  /** Space between suggestion items in the container. */
@@ -977,6 +1050,7 @@ interface ComponentTokens {
977
1050
  voice: VoiceTokens;
978
1051
  approval: ApprovalTokens;
979
1052
  attachment: AttachmentTokens;
1053
+ activity?: ActivityTokens;
980
1054
  toolBubble: ToolBubbleTokens;
981
1055
  reasoningBubble: ReasoningBubbleTokens;
982
1056
  /** Event-stream inspector badge chips. */
@@ -1035,12 +1109,1444 @@ type DeepPartial<T> = T extends object ? {
1035
1109
  [P in keyof T]?: DeepPartial<T[P]>;
1036
1110
  } : T;
1037
1111
 
1112
+ type RuntypeExecutionStreamEvent = ({
1113
+ agentId?: string;
1114
+ agentName?: string;
1115
+ config?: Record<string, unknown>;
1116
+ executionId: string;
1117
+ flowId?: string;
1118
+ flowName?: string;
1119
+ kind: "agent" | "flow";
1120
+ maxTurns?: number;
1121
+ resumed?: boolean;
1122
+ seq: number;
1123
+ source?: string;
1124
+ startedAt: string;
1125
+ totalSteps?: number;
1126
+ type: "execution_start";
1127
+ }) | ({
1128
+ claudeManagedAgentId?: string;
1129
+ completedAt?: string;
1130
+ durationMs?: number;
1131
+ executionId: string;
1132
+ externalAgent?: {
1133
+ contextId?: string;
1134
+ taskId?: string;
1135
+ };
1136
+ failedSteps?: number;
1137
+ finalOutput?: string;
1138
+ iterations?: number;
1139
+ kind: "agent" | "flow";
1140
+ seq: number;
1141
+ stepErrorCount?: number;
1142
+ stopReason?: string;
1143
+ success: boolean;
1144
+ successfulSteps?: number;
1145
+ totalCost?: number;
1146
+ totalSteps?: number;
1147
+ totalTokens?: {
1148
+ input: number;
1149
+ output: number;
1150
+ };
1151
+ totalTokensUsed?: number;
1152
+ type: "execution_complete";
1153
+ }) | ({
1154
+ blockReason?: string;
1155
+ code?: string;
1156
+ completedAt?: string;
1157
+ error: string | {
1158
+ code: string;
1159
+ details?: Record<string, unknown>;
1160
+ message: string;
1161
+ };
1162
+ executionId: string;
1163
+ finalOutput?: string;
1164
+ kind: "agent" | "flow";
1165
+ seq: number;
1166
+ stopReason?: string;
1167
+ type: "execution_error";
1168
+ upgradeUrl?: string;
1169
+ }) | ({
1170
+ executionId: string;
1171
+ id: string;
1172
+ iteration?: number;
1173
+ role: "user" | "assistant" | "system";
1174
+ seq: number;
1175
+ subagent?: {
1176
+ agentName?: string;
1177
+ parentToolCallId?: string;
1178
+ toolName: string;
1179
+ };
1180
+ turnIndex?: number;
1181
+ type: "turn_start";
1182
+ }) | ({
1183
+ attributes?: Record<string, string | number | boolean>;
1184
+ completedAt?: string;
1185
+ content?: string;
1186
+ cost?: number;
1187
+ estimatedContextBreakdown?: {
1188
+ categories: Record<string, {
1189
+ chars: number;
1190
+ estimatedTokens: number;
1191
+ }>;
1192
+ contextWindowSize?: number;
1193
+ estimatedTotalTokens: number;
1194
+ estimatedUtilizationPercent?: number;
1195
+ };
1196
+ executionId: string;
1197
+ fallback?: {
1198
+ attempts: Array<{
1199
+ attempt: number;
1200
+ error?: string;
1201
+ model?: string;
1202
+ success: boolean;
1203
+ type: "retry" | "model" | "message" | "flow";
1204
+ }>;
1205
+ exhausted: boolean;
1206
+ model?: string;
1207
+ reason?: string | null;
1208
+ used: boolean;
1209
+ };
1210
+ id: string;
1211
+ iteration?: number;
1212
+ role: "user" | "assistant" | "system";
1213
+ seq: number;
1214
+ stopReason?: "end_turn" | "max_tool_calls" | "length" | "content_filter" | "error" | "unknown";
1215
+ subagent?: {
1216
+ agentName?: string;
1217
+ parentToolCallId?: string;
1218
+ toolName: string;
1219
+ };
1220
+ tokens?: {
1221
+ input: number;
1222
+ output: number;
1223
+ };
1224
+ type: "turn_complete";
1225
+ }) | {
1226
+ executionId: string;
1227
+ id: string;
1228
+ iteration?: number;
1229
+ model?: string;
1230
+ ordinal: number;
1231
+ provider?: string;
1232
+ seq: number;
1233
+ startedAt?: string;
1234
+ stepId?: string;
1235
+ subagent?: {
1236
+ agentName?: string;
1237
+ parentToolCallId?: string;
1238
+ toolName: string;
1239
+ };
1240
+ turnId?: string;
1241
+ type: "model_call_start";
1242
+ } | ({
1243
+ attributes?: Record<string, string | number | boolean>;
1244
+ completedAt?: string;
1245
+ cost?: number;
1246
+ durationMs?: number;
1247
+ executionId: string;
1248
+ finishReason?: string;
1249
+ id: string;
1250
+ iteration?: number;
1251
+ model?: string;
1252
+ ordinal: number;
1253
+ provider?: string;
1254
+ responseModel?: string;
1255
+ seq: number;
1256
+ subagent?: {
1257
+ agentName?: string;
1258
+ parentToolCallId?: string;
1259
+ toolName: string;
1260
+ };
1261
+ success?: boolean;
1262
+ tokens?: {
1263
+ cacheRead?: number;
1264
+ cacheWrite?: number;
1265
+ input: number;
1266
+ output: number;
1267
+ reasoning?: number;
1268
+ };
1269
+ turnId?: string;
1270
+ type: "model_call_complete";
1271
+ }) | {
1272
+ executionId: string;
1273
+ id: string;
1274
+ index?: number;
1275
+ name?: string;
1276
+ outputVariable?: string;
1277
+ seq: number;
1278
+ startedAt?: string;
1279
+ stepType?: string;
1280
+ subagent?: {
1281
+ agentName?: string;
1282
+ parentToolCallId?: string;
1283
+ toolName: string;
1284
+ };
1285
+ totalSteps?: number;
1286
+ type: "step_start";
1287
+ } | ({
1288
+ completedAt?: string;
1289
+ cost?: number;
1290
+ durationMs?: number;
1291
+ error?: string;
1292
+ executionId: string;
1293
+ fallback?: {
1294
+ attempts: Array<{
1295
+ attempt: number;
1296
+ error?: string;
1297
+ model?: string;
1298
+ success: boolean;
1299
+ type: "retry" | "model" | "message" | "flow";
1300
+ }>;
1301
+ exhausted: boolean;
1302
+ model?: string;
1303
+ reason?: string | null;
1304
+ used: boolean;
1305
+ };
1306
+ id: string;
1307
+ name?: string;
1308
+ result?: unknown;
1309
+ seq: number;
1310
+ stepType?: string;
1311
+ stopReason?: "end_turn" | "max_tool_calls" | "length" | "content_filter" | "error" | "unknown";
1312
+ subagent?: {
1313
+ agentName?: string;
1314
+ parentToolCallId?: string;
1315
+ toolName: string;
1316
+ };
1317
+ success?: boolean;
1318
+ tokensUsed?: number;
1319
+ type: "step_complete";
1320
+ unresolvedVariables?: Array<string>;
1321
+ }) | {
1322
+ executionId: string;
1323
+ id: string;
1324
+ index?: number;
1325
+ name?: string;
1326
+ seq: number;
1327
+ skippedAt?: string;
1328
+ stepType?: string;
1329
+ totalSteps?: number;
1330
+ type: "step_skip";
1331
+ when?: string;
1332
+ } | ({
1333
+ executionId: string;
1334
+ id: string;
1335
+ parentToolCallId?: string;
1336
+ role?: "user" | "assistant" | "system";
1337
+ seq: number;
1338
+ stepId?: string;
1339
+ subagent?: {
1340
+ agentName?: string;
1341
+ parentToolCallId?: string;
1342
+ toolName: string;
1343
+ };
1344
+ turnId?: string;
1345
+ type: "text_start";
1346
+ }) | {
1347
+ delta: string;
1348
+ executionId: string;
1349
+ id: string;
1350
+ seq: number;
1351
+ subagent?: {
1352
+ agentName?: string;
1353
+ parentToolCallId?: string;
1354
+ toolName: string;
1355
+ };
1356
+ type: "text_delta";
1357
+ } | {
1358
+ executionId: string;
1359
+ id: string;
1360
+ seq: number;
1361
+ subagent?: {
1362
+ agentName?: string;
1363
+ parentToolCallId?: string;
1364
+ toolName: string;
1365
+ };
1366
+ text?: string;
1367
+ type: "text_complete";
1368
+ } | ({
1369
+ executionId: string;
1370
+ id: string;
1371
+ parentToolCallId?: string;
1372
+ scope?: "turn" | "loop";
1373
+ seq: number;
1374
+ subagent?: {
1375
+ agentName?: string;
1376
+ parentToolCallId?: string;
1377
+ toolName: string;
1378
+ };
1379
+ type: "reasoning_start";
1380
+ }) | {
1381
+ delta: string;
1382
+ executionId: string;
1383
+ id: string;
1384
+ seq: number;
1385
+ subagent?: {
1386
+ agentName?: string;
1387
+ parentToolCallId?: string;
1388
+ toolName: string;
1389
+ };
1390
+ type: "reasoning_delta";
1391
+ } | ({
1392
+ executionId: string;
1393
+ id: string;
1394
+ scope?: "turn" | "loop";
1395
+ seq: number;
1396
+ subagent?: {
1397
+ agentName?: string;
1398
+ parentToolCallId?: string;
1399
+ toolName: string;
1400
+ };
1401
+ text?: string;
1402
+ type: "reasoning_complete";
1403
+ }) | ({
1404
+ executionId: string;
1405
+ id: string;
1406
+ mediaType: string;
1407
+ role?: "user" | "assistant" | "system";
1408
+ seq: number;
1409
+ toolCallId?: string;
1410
+ type: "media_start";
1411
+ }) | {
1412
+ delta: string;
1413
+ executionId: string;
1414
+ id: string;
1415
+ seq: number;
1416
+ type: "media_delta";
1417
+ } | {
1418
+ data?: string;
1419
+ executionId: string;
1420
+ id: string;
1421
+ mediaType?: string;
1422
+ seq: number;
1423
+ toolCallId?: string;
1424
+ type: "media_complete";
1425
+ url?: string;
1426
+ } | ({
1427
+ artifactType: "markdown" | "component";
1428
+ component?: string;
1429
+ executionId?: string;
1430
+ file?: {
1431
+ language?: string;
1432
+ mimeType: string;
1433
+ path: string;
1434
+ };
1435
+ id: string;
1436
+ seq?: number;
1437
+ title?: string;
1438
+ type: "artifact_start";
1439
+ }) | {
1440
+ delta: string;
1441
+ executionId?: string;
1442
+ id: string;
1443
+ seq?: number;
1444
+ type: "artifact_delta";
1445
+ } | {
1446
+ component: string;
1447
+ executionId?: string;
1448
+ id: string;
1449
+ props: Record<string, unknown>;
1450
+ seq?: number;
1451
+ type: "artifact_update";
1452
+ } | {
1453
+ executionId?: string;
1454
+ id: string;
1455
+ seq?: number;
1456
+ type: "artifact_complete";
1457
+ } | {
1458
+ executionId: string;
1459
+ id?: string;
1460
+ seq: number;
1461
+ sourceType?: string;
1462
+ title?: string;
1463
+ type: "source";
1464
+ url?: string;
1465
+ [key: string]: unknown;
1466
+ } | {
1467
+ executionId: string;
1468
+ iteration?: number;
1469
+ seq: number;
1470
+ state: Record<string, unknown>;
1471
+ type: "state_snapshot";
1472
+ } | ({
1473
+ executionId: string;
1474
+ iteration?: number;
1475
+ patch: Array<{
1476
+ from?: string;
1477
+ op: "add" | "remove" | "replace" | "move" | "copy" | "test";
1478
+ path: string;
1479
+ value?: unknown;
1480
+ }>;
1481
+ seq: number;
1482
+ type: "state_delta";
1483
+ }) | ({
1484
+ executionId: string;
1485
+ hiddenParameterNames?: Array<string>;
1486
+ iteration?: number;
1487
+ origin?: "webmcp" | "sdk";
1488
+ pageOrigin?: string;
1489
+ parameters?: Record<string, unknown>;
1490
+ seq: number;
1491
+ startedAt?: string;
1492
+ stepId?: string;
1493
+ subagent?: {
1494
+ agentName?: string;
1495
+ parentToolCallId?: string;
1496
+ toolName: string;
1497
+ };
1498
+ toolCallId: string;
1499
+ toolName: string;
1500
+ toolType: string;
1501
+ type: "tool_start";
1502
+ }) | {
1503
+ delta: string;
1504
+ executionId: string;
1505
+ seq: number;
1506
+ subagent?: {
1507
+ agentName?: string;
1508
+ parentToolCallId?: string;
1509
+ toolName: string;
1510
+ };
1511
+ toolCallId: string;
1512
+ type: "tool_input_delta";
1513
+ } | {
1514
+ executionId: string;
1515
+ hiddenParameterNames?: Array<string>;
1516
+ parameters: Record<string, unknown>;
1517
+ seq: number;
1518
+ subagent?: {
1519
+ agentName?: string;
1520
+ parentToolCallId?: string;
1521
+ toolName: string;
1522
+ };
1523
+ toolCallId: string;
1524
+ toolName?: string;
1525
+ type: "tool_input_complete";
1526
+ } | {
1527
+ delta: string;
1528
+ executionId: string;
1529
+ seq: number;
1530
+ toolCallId: string;
1531
+ type: "tool_output_delta";
1532
+ } | {
1533
+ error?: string;
1534
+ executionId: string;
1535
+ executionTime?: number;
1536
+ iteration?: number;
1537
+ result?: unknown;
1538
+ seq: number;
1539
+ stepId?: string;
1540
+ subagent?: {
1541
+ agentName?: string;
1542
+ parentToolCallId?: string;
1543
+ toolName: string;
1544
+ };
1545
+ success: boolean;
1546
+ toolCallId: string;
1547
+ toolCost?: number;
1548
+ toolName?: string;
1549
+ type: "tool_complete";
1550
+ } | {
1551
+ approvalId: string;
1552
+ description?: string;
1553
+ executionId: string;
1554
+ externalAgent?: {
1555
+ contextId?: string;
1556
+ taskId?: string;
1557
+ };
1558
+ iteration?: number;
1559
+ parameters?: Record<string, unknown>;
1560
+ reason?: string;
1561
+ seq: number;
1562
+ startedAt?: string;
1563
+ subagent?: {
1564
+ agentName?: string;
1565
+ parentToolCallId?: string;
1566
+ toolName: string;
1567
+ };
1568
+ timeout?: number;
1569
+ toolCallId?: string;
1570
+ toolName: string;
1571
+ toolType?: string;
1572
+ type: "approval_start";
1573
+ } | ({
1574
+ approvalId: string;
1575
+ completedAt?: string;
1576
+ decision: "approved" | "denied" | "timeout";
1577
+ executionId: string;
1578
+ resolvedBy?: "user" | "system";
1579
+ seq: number;
1580
+ type: "approval_complete";
1581
+ }) | ({
1582
+ awaitReason?: string;
1583
+ awaitedAt?: string;
1584
+ crawlId?: string;
1585
+ elicitation?: {
1586
+ message: string;
1587
+ mode: "form" | "url";
1588
+ pauseCount?: number;
1589
+ requestedSchema?: Record<string, unknown>;
1590
+ requests?: Array<{
1591
+ message: string;
1592
+ mode: "form" | "url";
1593
+ name: string;
1594
+ requestedSchema?: Record<string, unknown>;
1595
+ url?: string;
1596
+ }>;
1597
+ serverName?: string;
1598
+ url?: string;
1599
+ };
1600
+ executionId: string;
1601
+ externalAgent?: {
1602
+ contextId?: string;
1603
+ taskId?: string;
1604
+ };
1605
+ origin?: "webmcp" | "sdk";
1606
+ pageOrigin?: string;
1607
+ parameters?: Record<string, unknown>;
1608
+ seq: number;
1609
+ stepId?: string;
1610
+ toolCallId?: string;
1611
+ toolId?: string;
1612
+ toolName?: string;
1613
+ type: "await";
1614
+ }) | ({
1615
+ error: string | {
1616
+ code: string;
1617
+ details?: Record<string, unknown>;
1618
+ message: string;
1619
+ };
1620
+ executionId: string;
1621
+ recoverable?: boolean;
1622
+ seq: number;
1623
+ type: "error";
1624
+ }) | ({
1625
+ epoch: number;
1626
+ executionId: string;
1627
+ kind: "compaction";
1628
+ outcome?: "ok" | "failed" | "gap" | "skipped";
1629
+ phase: "start" | "complete";
1630
+ reason: "threshold" | "overflow" | "manual" | "surface_policy" | "provider_mismatch";
1631
+ seq: number;
1632
+ strategy: "provider_native" | "summary";
1633
+ tier: number;
1634
+ tokensAfter?: number;
1635
+ tokensBefore?: number;
1636
+ type: "context_notice";
1637
+ }) | {
1638
+ executionId: string;
1639
+ seq: number;
1640
+ timestamp: string;
1641
+ type: "ping";
1642
+ } | {
1643
+ executionId?: string;
1644
+ name: string;
1645
+ seq?: number;
1646
+ type: "custom";
1647
+ value?: unknown;
1648
+ };
1649
+ type RuntypeStreamEventOf<U, T extends string> = Extract<U, {
1650
+ type: T;
1651
+ }>;
1652
+ type RuntypeTurnCompleteEvent = RuntypeStreamEventOf<RuntypeExecutionStreamEvent, "turn_complete">;
1653
+ type RuntypeStepCompleteEvent = RuntypeStreamEventOf<RuntypeExecutionStreamEvent, "step_complete">;
1654
+ type RuntypeStopReasonKind = NonNullable<RuntypeTurnCompleteEvent["stopReason"] | RuntypeStepCompleteEvent["stopReason"]>;
1655
+
1656
+ /**
1657
+ * Text content part for multi-modal messages
1658
+ */
1659
+ type TextContentPart = {
1660
+ type: 'text';
1661
+ text: string;
1662
+ };
1663
+ /**
1664
+ * Image content part for multi-modal messages
1665
+ * Supports base64 data URIs or URLs
1666
+ */
1667
+ type ImageContentPart = {
1668
+ type: 'image';
1669
+ image: string;
1670
+ mimeType?: string;
1671
+ alt?: string;
1672
+ };
1673
+ /**
1674
+ * File content part for multi-modal messages
1675
+ * Supports PDF, TXT, DOCX, and other document types
1676
+ */
1677
+ type FileContentPart = {
1678
+ type: 'file';
1679
+ data: string;
1680
+ mimeType: string;
1681
+ filename: string;
1682
+ };
1683
+ /**
1684
+ * Audio content part for multi-modal messages
1685
+ * Supports base64 data URIs or URLs
1686
+ */
1687
+ type AudioContentPart = {
1688
+ type: 'audio';
1689
+ audio: string;
1690
+ mimeType?: string;
1691
+ };
1692
+ /**
1693
+ * Video content part for multi-modal messages
1694
+ * Supports base64 data URIs or URLs
1695
+ */
1696
+ type VideoContentPart = {
1697
+ type: 'video';
1698
+ video: string;
1699
+ mimeType?: string;
1700
+ };
1701
+ /**
1702
+ * Union type for all content part types
1703
+ */
1704
+ type ContentPart = TextContentPart | ImageContentPart | FileContentPart | AudioContentPart | VideoContentPart;
1705
+ /** Reference stored on a sent message for transcript fidelity + chip rendering. */
1706
+ type AgentWidgetContextMentionRef = {
1707
+ sourceId: string;
1708
+ itemId: string;
1709
+ label: string;
1710
+ iconName?: string;
1711
+ /** Accent color for the inline token (see `AgentWidgetContextMentionItem.color`). */
1712
+ color?: string;
1713
+ };
1714
+ /**
1715
+ * One ordered segment of a sent message's prose, for inline mention rendering
1716
+ * (`contextMentions.display: "inline"`). Text runs and atomic mention tokens
1717
+ * interleave in document order so the sent bubble re-renders `@tokens` in place
1718
+ * and composer history can round-trip them. Display/transcript concern only —
1719
+ * the model still sees resolved bodies via `llmContent`/`contentParts`.
1720
+ */
1721
+ type AgentWidgetContentSegment = {
1722
+ kind: "text";
1723
+ text: string;
1724
+ } | {
1725
+ kind: "mention";
1726
+ ref: AgentWidgetContextMentionRef;
1727
+ };
1728
+ /** Wire shape for the per-turn composer selections. */
1729
+ type ComposerOptionsPayload = {
1730
+ selectedModelId?: string;
1731
+ activeModeIds?: string[];
1732
+ };
1733
+ /**
1734
+ * Metadata attached to messages created during agent execution.
1735
+ */
1736
+ type AgentMessageMetadata = {
1737
+ executionId?: string;
1738
+ iteration?: number;
1739
+ turnId?: string;
1740
+ agentName?: string;
1741
+ /**
1742
+ * When this message was produced by a step inside a nested flow executed
1743
+ * as a tool, identifies the parent tool call id. Enables renderers to
1744
+ * visually group or indent nested-flow output under its parent tool.
1745
+ */
1746
+ parentToolId?: string;
1747
+ /**
1748
+ * Nested flow step id that produced this message (e.g. a `send-stream`
1749
+ * or `prompt` step inside the nested flow). Stable key for that step.
1750
+ */
1751
+ parentStepId?: string;
1752
+ /**
1753
+ * Set to `true` on a tool-variant message produced from an `await`
1754
+ * event (`awaitReason: "local_tool_required"`). Signals to UI code that
1755
+ * the tool call is a LOCAL tool and the server is paused waiting for a
1756
+ * `POST /v1/dispatch/resume` with the user's answer keyed by tool name.
1757
+ */
1758
+ awaitingLocalTool?: boolean;
1759
+ /**
1760
+ * The provider per-call id (`toolu_…`) carried on the `await`
1761
+ * event for a LOCAL tool (core#3878). Present only when the
1762
+ * server emits it. Two PARALLEL calls to the same tool in one turn share a
1763
+ * `toolName` (and a collapsed `toolId`) but get DISTINCT `webMcpToolCallId`s,
1764
+ * so this is the key the widget batches a single `/resume` on: preferred
1765
+ * over tool name, which collides for same-tool parallel calls. Absent →
1766
+ * fall back to the legacy name-keyed resume contract.
1767
+ */
1768
+ webMcpToolCallId?: string;
1769
+ /**
1770
+ * Set to `true` once the user has picked / typed / dismissed an answer for
1771
+ * an `ask_user_question` tool call, so renderers stop re-mounting the
1772
+ * answer-pill sheet for this tool call on subsequent render passes.
1773
+ */
1774
+ askUserQuestionAnswered?: boolean;
1775
+ /**
1776
+ * In-progress answers for a multi-question `ask_user_question` payload,
1777
+ * keyed by question text. Persisted across refresh so the user lands back
1778
+ * where they were if the page reloads mid-flow. Cleared once
1779
+ * `askUserQuestionAnswered` flips to `true`.
1780
+ */
1781
+ askUserQuestionAnswers?: Record<string, string | string[]>;
1782
+ /**
1783
+ * Current page index for a multi-question `ask_user_question` payload's
1784
+ * paginated stepper. Persists alongside `askUserQuestionAnswers`.
1785
+ */
1786
+ askUserQuestionIndex?: number;
1787
+ /**
1788
+ * Set to `true` once a `suggest_replies` tool call's fire-and-forget
1789
+ * `/resume` has been accepted by the server. Persisted belt-and-suspenders
1790
+ * mirror of the in-memory resolved-key dedupe, so hydration/re-emit paths
1791
+ * never re-resume the call.
1792
+ */
1793
+ suggestRepliesResolved?: boolean;
1794
+ /**
1795
+ * The client-tool answer the server accepted through `/resume`, kept so
1796
+ * later proxy/agent turns can replay the call and its result to the model.
1797
+ * `toolName` is the widget's internal name (`webmcp:<name>` or a bare
1798
+ * built-in). Set only after the resume succeeds; preserved across
1799
+ * re-emissions of the tool message.
1800
+ */
1801
+ clientToolAnswer?: {
1802
+ toolCallId: string;
1803
+ toolName: string;
1804
+ args: unknown;
1805
+ result: unknown;
1806
+ /**
1807
+ * Shared by the answers posted in one `/resume`, i.e. one assistant
1808
+ * turn's parallel calls; a chained call gets a new batch.
1809
+ */
1810
+ batch?: string;
1811
+ };
1812
+ };
1813
+ /**
1814
+ * Reveal animation applied to assistant message text while it is streaming.
1815
+ *
1816
+ * Built-in types always available:
1817
+ * - `none`: text appears as tokens arrive (default).
1818
+ * - `typewriter`: characters fade in with a blinking caret.
1819
+ * - `pop-bubble`: the bubble scales in; text streams normally afterward.
1820
+ * - `letter-rise`: per-char translateY + fade reveal.
1821
+ * - `word-fade`: per-word blur + translateY fade-in.
1822
+ *
1823
+ * Subpath plugins (import from `@runtypelabs/persona/animations/*` to register):
1824
+ * - `wipe`, `glyph-cycle`.
1825
+ *
1826
+ * Custom types are allowed: register a plugin with any string name and
1827
+ * reference it by that name in `type`.
1828
+ */
1829
+ type AgentWidgetStreamAnimationBuiltinType = "none" | "typewriter" | "word-fade" | "letter-rise" | "glyph-cycle" | "wipe" | "pop-bubble";
1830
+ type AgentWidgetStreamAnimationType = AgentWidgetStreamAnimationBuiltinType | (string & {});
1831
+ /**
1832
+ * Placeholder shown inside a streaming assistant bubble before the first token arrives.
1833
+ * - `none`: use the default typing-dots indicator (existing behavior).
1834
+ * - `skeleton`: shimmer bars, replaced by streaming content once it starts.
1835
+ */
1836
+ type AgentWidgetStreamAnimationPlaceholder = "none" | "skeleton";
1837
+ /**
1838
+ * How much of the accumulated streaming content to display while tokens are
1839
+ * still arriving. Trimming to a boundary means in-progress words or lines
1840
+ * stay hidden until they complete: useful for animations that benefit from
1841
+ * unit-complete reveals (e.g. wipe, glyph-cycle).
1842
+ * - `none`: show every character as it arrives (default).
1843
+ * - `word`: trim to the last whitespace boundary.
1844
+ * - `line`: trim to the last newline boundary.
1845
+ */
1846
+ type AgentWidgetStreamAnimationBuffer = "none" | "word" | "line";
1847
+ /**
1848
+ * Context passed to plugin lifecycle hooks. Carries the live DOM references
1849
+ * and resolved animation settings for the currently-streaming message.
1850
+ */
1851
+ type StreamAnimationContext = {
1852
+ /** The `.persona-message-content` element owning the streamed text. */
1853
+ container: HTMLElement;
1854
+ /** The outer message bubble element. */
1855
+ bubble: HTMLElement;
1856
+ /** ID of the streaming message. */
1857
+ messageId: string;
1858
+ /** Read-only reference to the message being streamed. */
1859
+ message: AgentWidgetMessage;
1860
+ /** Effective `speed` from `streamAnimation.speed`. */
1861
+ speed: number;
1862
+ /** Effective `duration` from `streamAnimation.duration`. */
1863
+ duration: number;
1864
+ };
1038
1865
  /**
1039
- * Theme Reference: Structured documentation and examples for the Persona v2 theme system.
1866
+ * Pluggable stream animation. Third-party packages and inline registrations
1867
+ * implement this interface to add custom reveal effects.
1040
1868
  *
1041
- * Exported via the `@runtypelabs/persona/theme-reference` entry point so it stays
1042
- * out of the IIFE widget bundle. Intended for AI/MCP tool consumption.
1869
+ * Lifecycle:
1870
+ * - When the widget mounts and detects a plugin (either passed via config or
1871
+ * auto-registered in the IIFE bundle), it injects `styles` once into the
1872
+ * widget's style host.
1873
+ * - For each streaming assistant message whose `type` matches `name`, the
1874
+ * widget applies `containerClass` / `bubbleClass`, wraps text per `wrap`,
1875
+ * and, if `useCaret` is true, appends a blinking caret.
1876
+ * - Hooks fire after the live DOM is morphed; plugins use stable element IDs
1877
+ * and `data-preserve-animation` to safely mutate per-char or per-word spans
1878
+ * without idiomorph clobbering in-flight work.
1043
1879
  */
1880
+ type StreamAnimationPlugin = {
1881
+ /** Plugin identifier. Matches the `type` field in `streamAnimation`. */
1882
+ name: string;
1883
+ /** Class added to `.persona-message-content` while streaming. */
1884
+ containerClass?: string;
1885
+ /** Class added to the bubble element (e.g. a one-shot scale animation). */
1886
+ bubbleClass?: string;
1887
+ /** Wrap mode applied to text nodes during streaming. @default "none" */
1888
+ wrap?: "none" | "char" | "word";
1889
+ /**
1890
+ * HTML tags whose descendant text is skipped during wrapping. Defaults to
1891
+ * `["pre", "code", "a", "script", "style"]`: useful for keeping code
1892
+ * blocks legible and link click-targets intact. Plugins that want to
1893
+ * animate characters inside inline code (e.g. `glyph-cycle`) can narrow
1894
+ * the list.
1895
+ */
1896
+ skipTags?: string[];
1897
+ /** Append a blinking caret after the last rendered char/word. */
1898
+ useCaret?: boolean;
1899
+ /** CSS string injected into the widget style host on first activation. */
1900
+ styles?: string;
1901
+ /**
1902
+ * Optional custom buffering strategy. Returns the portion of `content`
1903
+ * that should be rendered during streaming. Use this for buffering
1904
+ * schemes beyond the built-in `word` / `line` strategies.
1905
+ */
1906
+ bufferContent?: (content: string, message: AgentWidgetMessage) => string;
1907
+ /**
1908
+ * Fires once when the plugin is first activated inside a widget instance.
1909
+ * Use this to set up MutationObservers or other long-lived listeners.
1910
+ * Return an optional cleanup function that runs on widget destroy.
1911
+ */
1912
+ onAttach?: (root: HTMLElement | ShadowRoot) => (() => void) | void;
1913
+ /** Fires after each render that reaches the live DOM. */
1914
+ onAfterRender?: (ctx: StreamAnimationContext) => void;
1915
+ /** Fires when a streamed message's `streaming` flag flips to false. */
1916
+ onStreamComplete?: (ctx: StreamAnimationContext) => void;
1917
+ /**
1918
+ * Report whether the plugin still has in-flight animation work for a
1919
+ * message. When `true`, the widget keeps rendering the message in its
1920
+ * "streaming-animated" mode even after `message.streaming` flips false: * preventing the final non-animated render from yanking the rug out from
1921
+ * under unfinished per-char cycles or reveals.
1922
+ */
1923
+ isAnimating?: (message: AgentWidgetMessage) => boolean;
1924
+ };
1925
+ type AgentWidgetStreamAnimationFeature = {
1926
+ /** Reveal animation to apply while streaming. @default "none" */
1927
+ type?: AgentWidgetStreamAnimationType;
1928
+ /** Pre-first-token placeholder. @default "none" */
1929
+ placeholder?: AgentWidgetStreamAnimationPlaceholder;
1930
+ /**
1931
+ * Per-unit animation duration (ms) for `typewriter`, `letter-rise`, `word-fade`,
1932
+ * and per-unit plugin animations. Each arriving character/word animates from
1933
+ * invisible to visible over this duration, independent of its position: the
1934
+ * streaming cadence itself provides the visible stagger.
1935
+ * @default 120
1936
+ */
1937
+ speed?: number;
1938
+ /**
1939
+ * Total duration of container-level animations (`pop-bubble` and custom
1940
+ * plugin animations), in milliseconds.
1941
+ * @default 1800
1942
+ */
1943
+ duration?: number;
1944
+ /**
1945
+ * Trim the accumulated streaming content to a word or line boundary before
1946
+ * rendering. Hides in-progress units until they complete.
1947
+ * @default "none"
1948
+ */
1949
+ buffer?: AgentWidgetStreamAnimationBuffer;
1950
+ /**
1951
+ * Extra animation plugins available to this widget instance. Keys are
1952
+ * plugin names; the matching plugin activates when `type` is set to that
1953
+ * name. Built-in types (`typewriter`, `pop-bubble`) are always registered.
1954
+ */
1955
+ plugins?: Record<string, StreamAnimationPlugin>;
1956
+ };
1957
+ type AgentWidgetDockConfig = {
1958
+ /**
1959
+ * Side of the wrapped container where the docked panel should render.
1960
+ * @default "right"
1961
+ */
1962
+ side?: "left" | "right";
1963
+ /**
1964
+ * Expanded width of the docked panel.
1965
+ * @default "420px"
1966
+ */
1967
+ width?: string;
1968
+ /**
1969
+ * When false, the dock column snaps between `0` and `width` with no CSS transition so main
1970
+ * content does not reflow during the open/close animation.
1971
+ * @default true
1972
+ */
1973
+ animate?: boolean;
1974
+ /**
1975
+ * How the dock panel is shown.
1976
+ * - `"resize"` (default): a flex column grows/shrinks between `0` and `width` (main content reflows).
1977
+ * - `"overlay"`: panel is absolutely positioned and translates in/out **over** full-width content.
1978
+ * - `"push"`: a wide inner track `[content at shell width][panel]` translates horizontally so the panel
1979
+ * appears to push the workspace aside **without** animating the content column width (Shopify-style).
1980
+ * - `"emerge"`: like `"resize"`, the flex column animates so **page content reflows**; the chat
1981
+ * panel keeps a **fixed** `dock.width` (not squeezed while the column grows), clipped by the slot so
1982
+ * it appears to emerge at full width like a floating widget.
1983
+ */
1984
+ reveal?: "resize" | "overlay" | "push" | "emerge";
1985
+ /**
1986
+ * Maximum height of the dock panel, applied as a viewport-overflow guard.
1987
+ *
1988
+ * The docked shell sizes itself with `height: 100%`, which only resolves when
1989
+ * an ancestor (usually `html, body { height: 100% }`) provides a definite
1990
+ * height. Without one, the dock column would otherwise grow with the
1991
+ * conversation and scroll off the page. This cap clamps the panel to the
1992
+ * viewport (and keeps the `resize`/`emerge` reveals pinned with
1993
+ * `position: sticky`; `push`/`overlay` get the cap only, since their
1994
+ * transform/absolute contexts defeat sticky) so a missing height chain
1995
+ * degrades gracefully instead of breaking the chat.
1996
+ *
1997
+ * - Set a CSS length (e.g. `"600px"`, `"80vh"`) to override the cap.
1998
+ * - Set `false` to disable the guard entirely (the panel then sizes purely
1999
+ * from the surrounding layout: make sure your page provides a definite
2000
+ * height all the way down to the dock target's parent).
2001
+ *
2002
+ * @default "100dvh"
2003
+ */
2004
+ maxHeight?: string | false;
2005
+ };
2006
+ /**
2007
+ * Layout configuration for `mountMode: "composer-bar"`. Controls how the
2008
+ * collapsed pill is positioned and sized, and how the panel expands when
2009
+ * the user opens it.
2010
+ */
2011
+ type AgentWidgetComposerBarConfig = {
2012
+ /**
2013
+ * Max-width of the collapsed pill composer at the bottom of the viewport.
2014
+ * @default "720px"
2015
+ */
2016
+ collapsedMaxWidth?: string;
2017
+ /**
2018
+ * Bottom offset (CSS length) from the viewport edge in the collapsed state.
2019
+ * @default "16px"
2020
+ */
2021
+ bottomOffset?: string;
2022
+ /**
2023
+ * Auto-expand the panel when the user submits a message while the composer
2024
+ * is collapsed. When false, the message still sends but the panel remains
2025
+ * collapsed (the host can drive expansion programmatically).
2026
+ * @default true
2027
+ */
2028
+ expandOnSubmit?: boolean;
2029
+ /**
2030
+ * Size of the expanded chat panel.
2031
+ * - `"anchored"` (default): the pill stays at the bottom of the viewport
2032
+ * and the chat history grows upward into a centered column above it.
2033
+ * Width is driven by `expandedMaxWidth`; the panel's top edge sits at
2034
+ * `expandedTopOffset` from the viewport top.
2035
+ * - `"fullscreen"`: covers the entire viewport (mobile-app style). Inner
2036
+ * content is centered horizontally via `contentMaxWidth`.
2037
+ * - `"modal"`: centered sheet with margins; size driven by
2038
+ * `modalMaxWidth` / `modalMaxHeight`.
2039
+ * @default "anchored"
2040
+ */
2041
+ expandedSize?: "anchored" | "fullscreen" | "modal";
2042
+ /**
2043
+ * When `expandedSize === "anchored"`, max-width of the expanded panel
2044
+ * column. Capped at `calc(100vw - 32px)` on narrow viewports.
2045
+ * @default "880px"
2046
+ */
2047
+ expandedMaxWidth?: string;
2048
+ /**
2049
+ * When `expandedSize === "anchored"`, distance from the viewport top to
2050
+ * the panel's top edge. Accepts any CSS length.
2051
+ * @default "5vh"
2052
+ */
2053
+ expandedTopOffset?: string;
2054
+ /**
2055
+ * Max-width applied to messages, composer form, suggestions, and
2056
+ * attachment previews so they center horizontally inside the expanded
2057
+ * panel. Falls back to `layout.contentMaxWidth` when set; otherwise
2058
+ * defaults to this value.
2059
+ * @default "720px"
2060
+ */
2061
+ contentMaxWidth?: string;
2062
+ /**
2063
+ * When `expandedSize === "modal"`, max-width of the expanded sheet.
2064
+ * @default "880px"
2065
+ */
2066
+ modalMaxWidth?: string;
2067
+ /**
2068
+ * When `expandedSize === "modal"`, max-height of the expanded sheet.
2069
+ * @default "min(90vh, 800px)"
2070
+ */
2071
+ modalMaxHeight?: string;
2072
+ /**
2073
+ * Configuration for the "peek" banner: the chrome-less row above the
2074
+ * collapsed pill that previews the most recent assistant message.
2075
+ */
2076
+ peek?: AgentWidgetComposerBarPeekConfig;
2077
+ };
2078
+ /**
2079
+ * Configuration for the composer-bar peek banner. Reuses the same
2080
+ * `streamAnimation` shape developers already configure for the main message
2081
+ * stream, so the surface for animations is identical across both contexts.
2082
+ *
2083
+ * Resolution order:
2084
+ * - If `peek.streamAnimation` is set, those values apply to the peek.
2085
+ * - Otherwise the peek inherits from `features.streamAnimation`.
2086
+ *
2087
+ * Per-surface carve-outs:
2088
+ * - `bubbleClass` from a plugin (used by `pop-bubble`) is ignored: the peek
2089
+ * has no bubble analog.
2090
+ * - `containerClass`, `wrap` ("char" | "word"), `useCaret`, `placeholder`
2091
+ * ("skeleton"), `buffer` ("word" | "line"), `speed`, `duration`, and
2092
+ * custom plugins all apply unchanged.
2093
+ */
2094
+ type AgentWidgetComposerBarPeekConfig = {
2095
+ /**
2096
+ * Reveal animation for the peek's trailing-message preview. Same shape as
2097
+ * `features.streamAnimation`. Omit to inherit from the main stream config.
2098
+ */
2099
+ streamAnimation?: AgentWidgetStreamAnimationFeature;
2100
+ };
2101
+ type AgentWidgetLauncherConfig = {
2102
+ /** Collapsed launcher shape. V4 defaults to pill; V5 defaults to circle. */
2103
+ variant?: "pill" | "circle";
2104
+ enabled?: boolean;
2105
+ title?: string;
2106
+ subtitle?: string;
2107
+ textHidden?: boolean;
2108
+ iconUrl?: string;
2109
+ agentIconText?: string;
2110
+ agentIconName?: string;
2111
+ agentIconHidden?: boolean;
2112
+ /**
2113
+ * Background color for the agent icon circle in the launcher button. Accepts
2114
+ * any CSS color value. When set, overrides the default primary-color
2115
+ * background (the `persona-bg-persona-primary` utility).
2116
+ */
2117
+ agentIconBackgroundColor?: string;
2118
+ position?: "bottom-right" | "bottom-left" | "top-right" | "top-left";
2119
+ /**
2120
+ * Controls how the launcher panel is mounted relative to the host page.
2121
+ * - "floating": default floating launcher / panel behavior
2122
+ * - "docked": wraps the target container and renders as a sibling dock
2123
+ * - "composer-bar": persistent rounded-pill composer fixed to the bottom of
2124
+ * the viewport that morphs into a fullscreen (or modal) chat panel on
2125
+ * submit and minimizes back to the pill on close.
2126
+ *
2127
+ * @default "floating"
2128
+ */
2129
+ mountMode?: "floating" | "docked" | "composer-bar";
2130
+ /**
2131
+ * Layout configuration for docked mode.
2132
+ */
2133
+ dock?: AgentWidgetDockConfig;
2134
+ /**
2135
+ * Layout configuration for composer-bar mode.
2136
+ * Only applies when `mountMode === "composer-bar"`.
2137
+ */
2138
+ composerBar?: AgentWidgetComposerBarConfig;
2139
+ autoExpand?: boolean;
2140
+ width?: string;
2141
+ /**
2142
+ * When true, the widget panel will fill the full height of its container.
2143
+ * Useful for sidebar layouts where the chat should take up the entire viewport height.
2144
+ * The widget will use flex layout to ensure header stays at top, messages scroll in middle,
2145
+ * and composer stays fixed at bottom.
2146
+ *
2147
+ * @default false
2148
+ */
2149
+ fullHeight?: boolean;
2150
+ /**
2151
+ * When true, the widget panel will be positioned as a sidebar flush with the viewport edges.
2152
+ * The panel will have:
2153
+ * - No border-radius (square corners)
2154
+ * - No margins (flush with top, left/right, and bottom edges)
2155
+ * - Full viewport height
2156
+ * - Subtle shadow on the edge facing the content
2157
+ * - No border between footer and messages
2158
+ *
2159
+ * Use with `position` to control which side ('bottom-left' for left sidebar, 'bottom-right' for right sidebar).
2160
+ * Automatically enables fullHeight when true.
2161
+ *
2162
+ * @default false
2163
+ */
2164
+ sidebarMode?: boolean;
2165
+ /**
2166
+ * When true, the widget panel renders as a detached card inset within its region,
2167
+ * with rounded corners on all sides and elevation (shadow plus hairline border),
2168
+ * instead of sitting flush against the region edges.
2169
+ *
2170
+ * The gap around the card is themed via `theme.components.panel.inset`. The
2171
+ * background revealed behind it is themed via `theme.components.panel.canvasBackground`
2172
+ * in docked and inline embed modes. In sidebar mode the gap stays click-through, so the
2173
+ * host page shows through it the same way it does in floating mode, and canvasBackground
2174
+ * is a no-op there.
2175
+ *
2176
+ * Applies to sidebar, docked, and inline embed modes. Ignored in mobile fullscreen,
2177
+ * where chrome is already suppressed. Floating mode is unchanged, since it already
2178
+ * renders as a detached card.
2179
+ *
2180
+ * @default false
2181
+ */
2182
+ detachedPanel?: boolean;
2183
+ /**
2184
+ * Width of the sidebar panel when sidebarMode is true.
2185
+ * @default "420px"
2186
+ */
2187
+ sidebarWidth?: string;
2188
+ /**
2189
+ * Offset (in pixels) to subtract from the calculated panel height.
2190
+ * Useful for adjusting the panel height when there are other fixed elements on the page.
2191
+ * Only applies when not in fullHeight or sidebarMode.
2192
+ *
2193
+ * @default 0
2194
+ */
2195
+ heightOffset?: number;
2196
+ /**
2197
+ * When true, the widget panel expands to fill the full viewport on mobile devices.
2198
+ * Removes border-radius, margins, and shadows for a native app-like experience.
2199
+ * Applies when viewport width is at or below `mobileBreakpoint`.
2200
+ *
2201
+ * @default true
2202
+ */
2203
+ mobileFullscreen?: boolean;
2204
+ /**
2205
+ * Viewport width (in pixels) at or below which the widget enters mobile fullscreen mode.
2206
+ * Only applies when `mobileFullscreen` is true.
2207
+ *
2208
+ * @default 640
2209
+ */
2210
+ mobileBreakpoint?: number;
2211
+ /**
2212
+ * CSS z-index applied to the widget wrapper and launcher button in all
2213
+ * positioned modes (floating panel, mobile fullscreen, sidebar, docked
2214
+ * mobile fullscreen). Increase this value if other elements on the host
2215
+ * page appear on top of the widget.
2216
+ *
2217
+ * In viewport-covering modes (sidebar, mobile fullscreen), the widget
2218
+ * also elevates the host element's stacking context and locks
2219
+ * document scroll to prevent background scrolling.
2220
+ *
2221
+ * @default 100000
2222
+ */
2223
+ zIndex?: number;
2224
+ callToActionIconText?: string;
2225
+ callToActionIconName?: string;
2226
+ callToActionIconColor?: string;
2227
+ callToActionIconBackgroundColor?: string;
2228
+ callToActionIconHidden?: boolean;
2229
+ callToActionIconPadding?: string;
2230
+ agentIconSize?: string;
2231
+ callToActionIconSize?: string;
2232
+ headerIconSize?: string;
2233
+ headerIconName?: string;
2234
+ headerIconHidden?: boolean;
2235
+ closeButtonSize?: string;
2236
+ closeButtonColor?: string;
2237
+ closeButtonBackgroundColor?: string;
2238
+ closeButtonBorderWidth?: string;
2239
+ closeButtonBorderColor?: string;
2240
+ closeButtonBorderRadius?: string;
2241
+ closeButtonPaddingX?: string;
2242
+ closeButtonPaddingY?: string;
2243
+ closeButtonPlacement?: "inline" | "top-right";
2244
+ closeButtonIconName?: string;
2245
+ closeButtonIconText?: string;
2246
+ closeButtonTooltipText?: string;
2247
+ closeButtonShowTooltip?: boolean;
2248
+ clearChat?: AgentWidgetClearChatConfig;
2249
+ /**
2250
+ * Border style for the launcher button.
2251
+ * @example "1px solid #e5e7eb" | "2px solid #3b82f6" | "none"
2252
+ * @default "1px solid #e5e7eb"
2253
+ */
2254
+ border?: string;
2255
+ /**
2256
+ * Box shadow for the launcher button.
2257
+ * @example "0 10px 15px -3px rgba(0,0,0,0.1)" | "none"
2258
+ * @default "0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1)"
2259
+ */
2260
+ shadow?: string;
2261
+ /**
2262
+ * CSS `max-width` for the floating launcher button when the panel is closed.
2263
+ * Title and subtitle each truncate with an ellipsis when space is tight; full strings are available via the native `title` tooltip. Does not affect the open chat panel (`width` / `launcherWidth`).
2264
+ *
2265
+ * @example "min(380px, calc(100vw - 48px))"
2266
+ */
2267
+ collapsedMaxWidth?: string;
2268
+ /**
2269
+ * Proactive nudge bubble anchored above the collapsed floating launcher.
2270
+ * Omit it (the default) and no teaser renders.
2271
+ */
2272
+ teaser?: AgentWidgetLauncherTeaserConfig;
2273
+ };
2274
+ /**
2275
+ * Launcher teaser: a small bubble above the collapsed launcher. Clicking it
2276
+ * opens the panel and consumes the teaser exactly like an explicit dismissal.
2277
+ * Within a single page load the teaser appears at most once under either
2278
+ * frequency.
2279
+ *
2280
+ * @example
2281
+ * ```typescript
2282
+ * launcher: {
2283
+ * teaser: { text: "Need a hand picking a plan?", delayMs: 3000 }
2284
+ * }
2285
+ * ```
2286
+ */
2287
+ type AgentWidgetLauncherTeaserConfig = {
2288
+ /** Bubble copy. An empty string renders no teaser. */
2289
+ text: string;
2290
+ /**
2291
+ * Delay before the bubble appears, in milliseconds.
2292
+ * @default 0
2293
+ */
2294
+ delayMs?: number;
2295
+ /**
2296
+ * How often the teaser may return.
2297
+ *
2298
+ * `"once"`: a dismissal or a click-through is remembered in `localStorage`
2299
+ * under `` `${persistState.keyPrefix ?? "persona-"}teaser-dismissed` `` and
2300
+ * the teaser never returns on that browser. `"always"`: shows on every page
2301
+ * load, tracked in memory only. `persistState: false` downgrades `"once"` to
2302
+ * in-memory too, so the teaser reappears each load.
2303
+ *
2304
+ * Custom `storageAdapter` implementations do not participate in teaser state.
2305
+ *
2306
+ * @default "once"
2307
+ */
2308
+ frequency?: "once" | "always";
2309
+ /**
2310
+ * Render an x affordance that dismisses the teaser without opening the panel.
2311
+ * @default true
2312
+ */
2313
+ dismissible?: boolean;
2314
+ /**
2315
+ * Accessible label for the dismiss affordance.
2316
+ * @default "Dismiss message"
2317
+ */
2318
+ dismissLabel?: string;
2319
+ };
2320
+ /**
2321
+ * Structured quote/reply-to state.
2322
+ * Set through `controller.setQuote()`; cleared by `controller.clearQuote()`, a
2323
+ * send, or the banner's dismiss button.
2324
+ */
2325
+ type ComposerQuote = {
2326
+ text: string;
2327
+ /** Transcript message the quote came from, when it came from one. */
2328
+ messageId?: string;
2329
+ /** Attribution shown in the banner (e.g. a page title or author). */
2330
+ sourceLabel?: string;
2331
+ };
2332
+ type AgentWidgetClearChatConfig = {
2333
+ enabled?: boolean;
2334
+ placement?: "inline" | "top-right";
2335
+ iconName?: string;
2336
+ iconColor?: string;
2337
+ backgroundColor?: string;
2338
+ borderWidth?: string;
2339
+ borderColor?: string;
2340
+ borderRadius?: string;
2341
+ size?: string;
2342
+ paddingX?: string;
2343
+ paddingY?: string;
2344
+ tooltipText?: string;
2345
+ showTooltip?: boolean;
2346
+ };
2347
+ type AgentWidgetMessageRole = "user" | "assistant" | "system";
2348
+ type AgentWidgetReasoning = {
2349
+ id: string;
2350
+ status: "pending" | "streaming" | "complete";
2351
+ chunks: string[];
2352
+ /**
2353
+ * Reasoning channel scope (wire spec). `"turn"` is ordinary per-turn
2354
+ * thinking; `"loop"` is a cross-iteration agent reflection (the fold that
2355
+ * replaced the legacy `agent_reflection` event). Optional when the stream does not specify a scope.
2356
+ */
2357
+ scope?: "turn" | "loop";
2358
+ startedAt?: number;
2359
+ completedAt?: number;
2360
+ durationMs?: number;
2361
+ };
2362
+ type AgentWidgetToolCall = {
2363
+ /** Optional approval state for activity-row status chrome. */
2364
+ approvalStatus?: "pending" | "approved" | "denied" | "timeout";
2365
+ id: string;
2366
+ name?: string;
2367
+ status: "pending" | "running" | "complete";
2368
+ args?: unknown;
2369
+ chunks?: string[];
2370
+ result?: unknown;
2371
+ /** Whether the tool succeeded; failure does not necessarily end the execution. */
2372
+ success?: boolean;
2373
+ error?: string;
2374
+ duration?: number;
2375
+ startedAt?: number;
2376
+ completedAt?: number;
2377
+ durationMs?: number;
2378
+ };
2379
+ /**
2380
+ * Represents a tool approval request in the chat conversation.
2381
+ * Created when the agent requires human approval before executing a tool.
2382
+ */
2383
+ type AgentWidgetApproval = {
2384
+ id: string;
2385
+ status: "pending" | "approved" | "denied" | "timeout";
2386
+ agentId: string;
2387
+ executionId: string;
2388
+ toolName: string;
2389
+ toolType?: string;
2390
+ description: string;
2391
+ /**
2392
+ * Agent-authored justification for this specific call (the agent's own
2393
+ * claim about its intent, extracted server-side from the reserved
2394
+ * `_approvalReason` parameter). Render it attributed to the agent and as
2395
+ * plain text: it is approver context, not a system statement.
2396
+ */
2397
+ reason?: string;
2398
+ parameters?: unknown;
2399
+ resolvedAt?: number;
2400
+ };
2401
+ type AgentWidgetMessageVariant = "assistant" | "reasoning" | "tool" | "approval";
2402
+ /**
2403
+ * Per-turn / per-step stop reason emitted by the runtime on
2404
+ * `turn_complete` and `step_complete` SSE events. The vocabulary is
2405
+ * owned by the upstream Runtype API: do not extend without coordination.
2406
+ *
2407
+ * - `end_turn`: natural completion (no affordance needed)
2408
+ * - `max_tool_calls`: agent loop tripped the configured tool-call ceiling
2409
+ * - `length`: provider hit max output tokens
2410
+ * - `content_filter`: provider content filter intervened
2411
+ * - `error`: provider/runtime error (prefer existing error rendering)
2412
+ * - `unknown`: explicitly reported but uninformative
2413
+ *
2414
+ * Absent (`undefined`) means "not reported": distinct from `'unknown'`.
2415
+ */
2416
+ type StopReasonKind = RuntypeStopReasonKind;
2417
+ /**
2418
+ * Represents a message in the chat conversation.
2419
+ *
2420
+ * @property id - Unique message identifier
2421
+ * @property role - Message role: "user", "assistant", or "system"
2422
+ * @property content - Message text content (for display)
2423
+ * @property contentParts - Original multi-modal content parts (for API requests)
2424
+ * @property createdAt - ISO timestamp when message was created
2425
+ * @property streaming - Whether message is still streaming (for assistant messages)
2426
+ * @property variant - Message variant for assistant messages: "assistant", "reasoning", or "tool"
2427
+ * @property sequence - Message ordering number
2428
+ * @property reasoning - Reasoning data for assistant reasoning messages
2429
+ * @property toolCall - Tool call data for assistant tool messages
2430
+ * @property tools - Array of tool calls
2431
+ * @property viaVoice - Set to `true` when a user message is sent via voice recognition.
2432
+ * Useful for implementing voice-specific behaviors like auto-reactivation.
2433
+ */
2434
+ type AgentWidgetMessage = {
2435
+ id: string;
2436
+ role: AgentWidgetMessageRole;
2437
+ content: string;
2438
+ createdAt: string;
2439
+ /**
2440
+ * Original multi-modal content parts for this message.
2441
+ * When present, this is sent to the API instead of `content`.
2442
+ * The `content` field contains the text-only representation for display.
2443
+ */
2444
+ contentParts?: ContentPart[];
2445
+ /**
2446
+ * Context mentions attached to this (user) message, for transcript fidelity +
2447
+ * chip rendering in the sent bubble. Refs only — the resolved payloads are
2448
+ * merged into `llmContent`/`contentParts` (model-visible) at send time.
2449
+ */
2450
+ contextMentions?: AgentWidgetContextMentionRef[];
2451
+ /**
2452
+ * Ordered prose + mention blocks for inline-mode rendering and composer history
2453
+ * recall (`contextMentions.display: "inline"`). Present only on inline-mode user
2454
+ * messages; when omitted the sent bubble falls back to the chip row derived from
2455
+ * `contextMentions`. Display/transcript concern only — not the model channel.
2456
+ */
2457
+ contentSegments?: AgentWidgetContentSegment[];
2458
+ /**
2459
+ * Resolved opt-in structured mention context for this (user) message, merged
2460
+ * into the request `context` under `mentions.<sourceId>.<itemId>` by the
2461
+ * client. Internal: set at send time from each source's `resolve().context`.
2462
+ */
2463
+ mentionContext?: Record<string, unknown>;
2464
+ /**
2465
+ * Quote/reply-to this (user) message was sent with, for transcript fidelity.
2466
+ * The model-visible copy is a delimited text part ahead of the user's text;
2467
+ * this field keeps the structured source separately.
2468
+ */
2469
+ quote?: ComposerQuote;
2470
+ /**
2471
+ * Per-turn composer selections this (user) message was sent with. Retained so
2472
+ * `session.resubmitFrom(..., { reason: "retry" })` replays the same model and
2473
+ * mode selection the original turn used.
2474
+ */
2475
+ composerOptions?: ComposerOptionsPayload;
2476
+ streaming?: boolean;
2477
+ variant?: AgentWidgetMessageVariant;
2478
+ sequence?: number;
2479
+ reasoning?: AgentWidgetReasoning;
2480
+ toolCall?: AgentWidgetToolCall;
2481
+ tools?: AgentWidgetToolCall[];
2482
+ /** Approval data for messages with variant "approval" */
2483
+ approval?: AgentWidgetApproval;
2484
+ viaVoice?: boolean;
2485
+ /**
2486
+ * Set to `true` on placeholder messages injected during Runtype voice processing.
2487
+ * Use this in `messageTransform` to detect and customize voice processing placeholders.
2488
+ *
2489
+ * @example
2490
+ * messageTransform: ({ text, message }) => {
2491
+ * if (message.voiceProcessing && message.role === 'user') {
2492
+ * return '<div class="my-voice-spinner">Transcribing...</div>';
2493
+ * }
2494
+ * return text;
2495
+ * }
2496
+ */
2497
+ voiceProcessing?: boolean;
2498
+ /**
2499
+ * Raw structured payload for this message (e.g., JSON action response).
2500
+ * Populated automatically when structured parsers run.
2501
+ */
2502
+ rawContent?: string;
2503
+ /**
2504
+ * LLM-specific content for API requests.
2505
+ * When present, this is sent to the LLM instead of `content`.
2506
+ *
2507
+ * Priority for API payload:
2508
+ * 1. `contentParts` (if present, used as-is for multi-modal)
2509
+ * 2. `llmContent` (if present, sent as string)
2510
+ * 3. `rawContent` (backward compatibility with structured parsers)
2511
+ * 4. `content` (fallback - display content)
2512
+ *
2513
+ * The `content` field is always used for UI display.
2514
+ *
2515
+ * @example
2516
+ * // Show full details to user, send summary to LLM
2517
+ * {
2518
+ * content: "**Product:** iPhone 15 Pro\n**Price:** $1,199\n**SKU:** IP15P-256",
2519
+ * llmContent: "[Product search: iPhone 15 Pro, $1199]"
2520
+ * }
2521
+ */
2522
+ llmContent?: string;
2523
+ /**
2524
+ * Text segment identity for chronological ordering.
2525
+ * When present, identifies which text segment this message represents
2526
+ * (e.g., "text_0", "text_1") for messages split at tool boundaries.
2527
+ */
2528
+ partId?: string;
2529
+ /**
2530
+ * Metadata for messages created during agent loop execution.
2531
+ * Contains execution context like iteration number and turn ID.
2532
+ */
2533
+ agentMetadata?: AgentMessageMetadata;
2534
+ /**
2535
+ * Per-turn stop reason reported by the runtime on `turn_complete`
2536
+ * (agent-loop path) or the last `step_complete` for a prompt step
2537
+ * (dispatch / flow path). Absent when the API did not report a value.
2538
+ *
2539
+ * When set to a non-natural value (`max_tool_calls`, `length`,
2540
+ * `content_filter`, `error`), the widget renders an inline notice on
2541
+ * the assistant bubble. See `config.copy.stopReasonNotice` to override
2542
+ * the default copy.
2543
+ */
2544
+ stopReason?: StopReasonKind;
2545
+ };
2546
+
2547
+ type ThemeDefaultsVersion = 'v4' | 'v5';
2548
+
2549
+ type DefaultsVersion = "v4" | "v5";
1044
2550
 
1045
2551
  declare const THEME_TOKEN_DOCS: {
1046
2552
  overview: string;
@@ -1300,7 +2806,9 @@ declare const THEME_EXAMPLES: Record<string, ThemeExample>;
1300
2806
  * Returns token system docs, the default color palette and radius scale,
1301
2807
  * example themes, and a list of SDK-bundled presets.
1302
2808
  */
1303
- declare function getThemeReference(): {
2809
+ declare function getThemeReference(future?: {
2810
+ v5Defaults?: boolean;
2811
+ }): {
1304
2812
  tokenDocs: {
1305
2813
  overview: string;
1306
2814
  layers: {
@@ -1547,8 +3055,10 @@ declare function getThemeReference(): {
1547
3055
  };
1548
3056
  };
1549
3057
  };
3058
+ defaultsVersion: DefaultsVersion;
3059
+ themeDefaultsVersion: ThemeDefaultsVersion;
1550
3060
  defaultColorPalette: {
1551
- primary: {
3061
+ gray: {
1552
3062
  50: string;
1553
3063
  100: string;
1554
3064
  200: string;
@@ -1561,7 +3071,7 @@ declare function getThemeReference(): {
1561
3071
  900: string;
1562
3072
  950: string;
1563
3073
  };
1564
- secondary: {
3074
+ primary: {
1565
3075
  50: string;
1566
3076
  100: string;
1567
3077
  200: string;
@@ -1574,7 +3084,7 @@ declare function getThemeReference(): {
1574
3084
  900: string;
1575
3085
  950: string;
1576
3086
  };
1577
- accent: {
3087
+ secondary: {
1578
3088
  50: string;
1579
3089
  100: string;
1580
3090
  200: string;
@@ -1587,7 +3097,7 @@ declare function getThemeReference(): {
1587
3097
  900: string;
1588
3098
  950: string;
1589
3099
  };
1590
- gray: {
3100
+ accent: {
1591
3101
  50: string;
1592
3102
  100: string;
1593
3103
  200: string;
@@ -1685,6 +3195,7 @@ declare function getThemeReference(): {
1685
3195
  '2xl': string;
1686
3196
  full: string;
1687
3197
  };
3198
+ defaultLauncher: AgentWidgetLauncherConfig | undefined;
1688
3199
  examples: Record<string, ThemeExample>;
1689
3200
  sdkPresets: string[];
1690
3201
  };