@runtypelabs/persona 3.29.1 → 3.30.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 (53) hide show
  1. package/README.md +55 -0
  2. package/dist/codegen.cjs +6 -6
  3. package/dist/codegen.js +4 -4
  4. package/dist/index.cjs +47 -47
  5. package/dist/index.cjs.map +1 -1
  6. package/dist/index.d.cts +112 -7
  7. package/dist/index.d.ts +112 -7
  8. package/dist/index.global.js +59 -59
  9. package/dist/index.global.js.map +1 -1
  10. package/dist/index.js +47 -47
  11. package/dist/index.js.map +1 -1
  12. package/dist/launcher.global.js +2 -2
  13. package/dist/launcher.global.js.map +1 -1
  14. package/dist/plugin-kit.cjs +1 -0
  15. package/dist/plugin-kit.d.cts +98 -0
  16. package/dist/plugin-kit.d.ts +98 -0
  17. package/dist/plugin-kit.js +1 -0
  18. package/dist/smart-dom-reader.d.cts +107 -4
  19. package/dist/smart-dom-reader.d.ts +107 -4
  20. package/dist/theme-editor.cjs +38 -38
  21. package/dist/theme-editor.d.cts +111 -6
  22. package/dist/theme-editor.d.ts +111 -6
  23. package/dist/theme-editor.js +38 -38
  24. package/dist/theme-reference.cjs +1 -1
  25. package/dist/theme-reference.d.cts +2 -0
  26. package/dist/theme-reference.d.ts +2 -0
  27. package/dist/theme-reference.js +1 -1
  28. package/package.json +8 -2
  29. package/src/components/approval-bubble.test.ts +268 -0
  30. package/src/components/approval-bubble.ts +170 -20
  31. package/src/components/launcher.ts +6 -3
  32. package/src/components/tool-bubble.test.ts +39 -0
  33. package/src/components/tool-bubble.ts +4 -0
  34. package/src/index-core.ts +1 -0
  35. package/src/plugin-kit.test.ts +230 -0
  36. package/src/plugin-kit.ts +294 -0
  37. package/src/plugins/types.ts +49 -2
  38. package/src/session.test.ts +99 -0
  39. package/src/session.ts +14 -3
  40. package/src/theme-editor/preview-utils.test.ts +10 -0
  41. package/src/theme-editor/preview-utils.ts +29 -1
  42. package/src/theme-editor/sections.test.ts +17 -0
  43. package/src/theme-editor/sections.ts +31 -0
  44. package/src/theme-reference.ts +1 -1
  45. package/src/types/theme.ts +2 -0
  46. package/src/types.ts +59 -2
  47. package/src/ui.approval-plugin.test.ts +204 -0
  48. package/src/ui.ts +149 -16
  49. package/src/utils/theme.test.ts +6 -2
  50. package/src/utils/theme.ts +0 -8
  51. package/src/utils/tokens.ts +6 -1
  52. package/src/webmcp-bridge.test.ts +66 -0
  53. package/src/webmcp-bridge.ts +49 -0
@@ -306,6 +306,8 @@ interface ApprovalTokens {
306
306
  background: TokenReference<'color'>;
307
307
  border: TokenReference<'color'>;
308
308
  text: TokenReference<'color'>;
309
+ /** Box-shadow for the approval bubble (token ref or raw CSS, e.g. `none`). */
310
+ shadow: string;
309
311
  };
310
312
  approve: ComponentTokenSet;
311
313
  deny: ComponentTokenSet;
@@ -628,13 +630,59 @@ interface AgentWidgetPlugin {
628
630
  config: AgentWidgetConfig;
629
631
  }) => HTMLElement | null;
630
632
  /**
631
- * Custom renderer for approval bubbles
632
- * Return null to use default renderer
633
+ * Custom renderer for approval bubbles.
634
+ *
635
+ * Return an `HTMLElement` to fully own the approval UI, `defaultRenderer()`
636
+ * to render (or wrap) the built-in bubble, or `null` to fall through to the
637
+ * default. Unlike the built-in bubble — whose Approve/Deny buttons are wired
638
+ * via delegation — a fully custom element resolves the approval by calling
639
+ * the `approve`/`deny` callbacks. Both route through the same path the
640
+ * built-in buttons use (optimistic update, `onDecision`, in-place anchoring).
641
+ *
642
+ * An approval is a single binary gate, so there are exactly two outcomes.
643
+ * Pass `{ remember: true }` to flag a "remember this" affordance (e.g. an
644
+ * "Always allow" button); the current approval resolves identically, but the
645
+ * flag is forwarded to `config.approval.onDecision` so you can persist a
646
+ * don't-ask-again policy for future approvals.
647
+ *
648
+ * `renderApproval` is called again whenever the approval's status changes, so
649
+ * branch on `message.approval?.status` to render the resolved state (and tear
650
+ * down any global listeners you added while pending).
651
+ *
652
+ * @example
653
+ * ```typescript
654
+ * // An alternative prompt: "Always allow" / "Allow once" / "Deny".
655
+ * renderApproval: ({ message, approve, deny }) => {
656
+ * const approval = message.approval;
657
+ * if (!approval || approval.status !== "pending") return null; // default renders resolved state
658
+ * const root = document.createElement("div");
659
+ * root.textContent = `${approval.toolName} requires approval`;
660
+ *
661
+ * const always = document.createElement("button");
662
+ * always.textContent = "Always allow";
663
+ * always.addEventListener("click", () => approve({ remember: true }));
664
+ *
665
+ * const once = document.createElement("button");
666
+ * once.textContent = "Allow once";
667
+ * once.addEventListener("click", () => approve());
668
+ *
669
+ * const no = document.createElement("button");
670
+ * no.textContent = "Deny";
671
+ * no.addEventListener("click", () => deny());
672
+ *
673
+ * root.append(always, once, no);
674
+ * return root;
675
+ * }
676
+ * ```
633
677
  */
634
678
  renderApproval?: (context: {
635
679
  message: AgentWidgetMessage;
636
680
  defaultRenderer: () => HTMLElement;
637
681
  config: AgentWidgetConfig;
682
+ /** Resolve this approval as approved. Pass `{ remember: true }` for an "Always allow" affordance. */
683
+ approve: (options?: AgentWidgetApprovalDecisionOptions) => void;
684
+ /** Resolve this approval as denied. Pass `{ remember: true }` for an "Always deny" affordance. */
685
+ deny: (options?: AgentWidgetApprovalDecisionOptions) => void;
638
686
  }) => HTMLElement | null;
639
687
  /**
640
688
  * Custom renderer for loading indicator
@@ -1446,6 +1494,12 @@ type WebMcpConfirmInfo = {
1446
1494
  toolName: string;
1447
1495
  args: unknown;
1448
1496
  description?: string;
1497
+ /**
1498
+ * Display title the tool declared via the WebMCP spec's
1499
+ * `ToolDescriptor.title` (e.g. `"Add to Cart"`). Absent when the tool
1500
+ * didn't declare one.
1501
+ */
1502
+ title?: string;
1449
1503
  annotations?: {
1450
1504
  readOnlyHint?: boolean;
1451
1505
  untrustedContentHint?: boolean;
@@ -2807,6 +2861,22 @@ type TextToSpeechConfig = {
2807
2861
  /** Speech pitch (0 - 2). Default: 1 */
2808
2862
  pitch?: number;
2809
2863
  };
2864
+ /**
2865
+ * Extra context for an approval decision, surfaced to `onDecision` and to the
2866
+ * `approve`/`deny` callbacks passed to the `renderApproval` plugin hook.
2867
+ */
2868
+ type AgentWidgetApprovalDecisionOptions = {
2869
+ /**
2870
+ * The user chose a "remember this" affordance (e.g. an "Always allow"
2871
+ * button) rather than a one-time decision. The widget resolves the *current*
2872
+ * approval identically whether or not this is set — an approval bubble is a
2873
+ * single binary gate (`approved`/`denied`). Persisting a don't-ask-again
2874
+ * policy for *future* approvals (auto-resolving them, or not surfacing them)
2875
+ * is the integrator's responsibility, typically inside `onDecision`.
2876
+ * Defaults to absent/`false`.
2877
+ */
2878
+ remember?: boolean;
2879
+ };
2810
2880
  /**
2811
2881
  * Configuration for tool approval bubbles.
2812
2882
  * Controls styling, labels, and behavior of the approval UI.
@@ -2816,6 +2886,8 @@ type AgentWidgetApprovalConfig = {
2816
2886
  backgroundColor?: string;
2817
2887
  /** Border color of the approval bubble */
2818
2888
  borderColor?: string;
2889
+ /** Box-shadow for the approval bubble; pass `"none"` to remove it. Overrides the default `persona-shadow-sm`. */
2890
+ shadow?: string;
2819
2891
  /** Color for the title text */
2820
2892
  titleColor?: string;
2821
2893
  /** Color for the description text */
@@ -2838,20 +2910,51 @@ type AgentWidgetApprovalConfig = {
2838
2910
  approveLabel?: string;
2839
2911
  /** Label for the deny button */
2840
2912
  denyLabel?: string;
2913
+ /**
2914
+ * How the technical details (the tool's agent-facing description and the
2915
+ * raw parameters JSON) are presented:
2916
+ * - `"collapsed"` (default) — hidden behind a "Show details" toggle
2917
+ * - `"expanded"` — visible, with the toggle available to hide them
2918
+ * - `"hidden"` — never rendered
2919
+ */
2920
+ detailsDisplay?: "collapsed" | "expanded" | "hidden";
2921
+ /** Label for the toggle that reveals the technical details */
2922
+ showDetailsLabel?: string;
2923
+ /** Label for the toggle that hides the technical details */
2924
+ hideDetailsLabel?: string;
2925
+ /**
2926
+ * Build the user-facing summary line for an approval request. Overrides the
2927
+ * default "The assistant wants to use “Tool name”." copy. Return a falsy
2928
+ * value to fall back to the default for that approval. `displayTitle` is
2929
+ * the display name the tool declared via the WebMCP spec's
2930
+ * `ToolDescriptor.title`, when one exists.
2931
+ */
2932
+ formatDescription?: (approval: {
2933
+ toolName: string;
2934
+ toolType?: string;
2935
+ description: string;
2936
+ parameters?: unknown;
2937
+ displayTitle?: string;
2938
+ }) => string | undefined;
2841
2939
  /**
2842
2940
  * Custom handler for approval decisions.
2843
2941
  * Return void to let the SDK auto-resolve via the API,
2844
2942
  * or return a Response/ReadableStream for custom handling.
2943
+ *
2944
+ * `options.remember` is `true` when the decision came from a "remember this"
2945
+ * affordance (e.g. an "Always allow" button in a custom `renderApproval`
2946
+ * plugin). Use it to persist a don't-ask-again policy for future approvals;
2947
+ * the current approval resolves the same way regardless.
2845
2948
  */
2846
2949
  onDecision?: (data: {
2847
2950
  approvalId: string;
2848
2951
  executionId: string;
2849
2952
  agentId: string;
2850
2953
  toolName: string;
2851
- }, decision: 'approved' | 'denied') => Promise<Response | ReadableStream<Uint8Array> | void>;
2954
+ }, decision: 'approved' | 'denied', options?: AgentWidgetApprovalDecisionOptions) => Promise<Response | ReadableStream<Uint8Array> | void>;
2852
2955
  };
2853
2956
  type AgentWidgetToolCallConfig$1 = {
2854
- /** Box-shadow for tool-call bubbles; overrides `theme.toolBubbleShadow` when set. */
2957
+ /** Box-shadow for tool-call bubbles; pass `"none"` to remove it. Overrides the `components.toolBubble.shadow` token / `--persona-tool-bubble-shadow`. */
2855
2958
  shadow?: string;
2856
2959
  /** Background color of the tool call bubble container. */
2857
2960
  backgroundColor?: string;
@@ -5337,8 +5440,10 @@ type Controller = {
5337
5440
  * Programmatically resolve a pending approval.
5338
5441
  * @param approvalId - The approval ID to resolve
5339
5442
  * @param decision - "approved" or "denied"
5443
+ * @param options - Optional decision context (e.g. `{ remember: true }`),
5444
+ * forwarded to `config.approval.onDecision`.
5340
5445
  */
5341
- resolveApproval: (approvalId: string, decision: 'approved' | 'denied') => Promise<void>;
5446
+ resolveApproval: (approvalId: string, decision: 'approved' | 'denied', options?: AgentWidgetApprovalDecisionOptions) => Promise<void>;
5342
5447
  };
5343
5448
  type AgentWidgetController = Controller;
5344
5449
 
@@ -5385,7 +5490,7 @@ declare const MOCK_WORKSPACE_CONTENT = "\n <div class=\"preview-workspace-con
5385
5490
  */
5386
5491
  declare function buildSrcdoc(mountId: string, shellMode: 'light' | 'dark', docked: boolean, widgetCssPath: string): string;
5387
5492
  type PreviewScene = 'home' | 'conversation' | 'minimized' | 'artifact';
5388
- type PreviewTranscriptEntryPreset = 'user-message' | 'assistant-message' | 'assistant-code-block' | 'assistant-markdown-table' | 'assistant-image' | 'reasoning-streaming' | 'reasoning-complete' | 'tool-running' | 'tool-complete';
5493
+ type PreviewTranscriptEntryPreset = 'user-message' | 'assistant-message' | 'assistant-code-block' | 'assistant-markdown-table' | 'assistant-image' | 'reasoning-streaming' | 'reasoning-complete' | 'tool-running' | 'tool-complete' | 'approval-request';
5389
5494
  declare function getPreviewTranscriptPresetLabel(preset: PreviewTranscriptEntryPreset): string;
5390
5495
  declare function createPreviewTranscriptEntry(preset: PreviewTranscriptEntryPreset, index?: number): AgentWidgetMessage;
5391
5496
  declare function appendPreviewTranscriptEntry(messages: AgentWidgetMessage[], preset: PreviewTranscriptEntryPreset): AgentWidgetMessage[];
@@ -306,6 +306,8 @@ interface ApprovalTokens {
306
306
  background: TokenReference<'color'>;
307
307
  border: TokenReference<'color'>;
308
308
  text: TokenReference<'color'>;
309
+ /** Box-shadow for the approval bubble (token ref or raw CSS, e.g. `none`). */
310
+ shadow: string;
309
311
  };
310
312
  approve: ComponentTokenSet;
311
313
  deny: ComponentTokenSet;
@@ -628,13 +630,59 @@ interface AgentWidgetPlugin {
628
630
  config: AgentWidgetConfig;
629
631
  }) => HTMLElement | null;
630
632
  /**
631
- * Custom renderer for approval bubbles
632
- * Return null to use default renderer
633
+ * Custom renderer for approval bubbles.
634
+ *
635
+ * Return an `HTMLElement` to fully own the approval UI, `defaultRenderer()`
636
+ * to render (or wrap) the built-in bubble, or `null` to fall through to the
637
+ * default. Unlike the built-in bubble — whose Approve/Deny buttons are wired
638
+ * via delegation — a fully custom element resolves the approval by calling
639
+ * the `approve`/`deny` callbacks. Both route through the same path the
640
+ * built-in buttons use (optimistic update, `onDecision`, in-place anchoring).
641
+ *
642
+ * An approval is a single binary gate, so there are exactly two outcomes.
643
+ * Pass `{ remember: true }` to flag a "remember this" affordance (e.g. an
644
+ * "Always allow" button); the current approval resolves identically, but the
645
+ * flag is forwarded to `config.approval.onDecision` so you can persist a
646
+ * don't-ask-again policy for future approvals.
647
+ *
648
+ * `renderApproval` is called again whenever the approval's status changes, so
649
+ * branch on `message.approval?.status` to render the resolved state (and tear
650
+ * down any global listeners you added while pending).
651
+ *
652
+ * @example
653
+ * ```typescript
654
+ * // An alternative prompt: "Always allow" / "Allow once" / "Deny".
655
+ * renderApproval: ({ message, approve, deny }) => {
656
+ * const approval = message.approval;
657
+ * if (!approval || approval.status !== "pending") return null; // default renders resolved state
658
+ * const root = document.createElement("div");
659
+ * root.textContent = `${approval.toolName} requires approval`;
660
+ *
661
+ * const always = document.createElement("button");
662
+ * always.textContent = "Always allow";
663
+ * always.addEventListener("click", () => approve({ remember: true }));
664
+ *
665
+ * const once = document.createElement("button");
666
+ * once.textContent = "Allow once";
667
+ * once.addEventListener("click", () => approve());
668
+ *
669
+ * const no = document.createElement("button");
670
+ * no.textContent = "Deny";
671
+ * no.addEventListener("click", () => deny());
672
+ *
673
+ * root.append(always, once, no);
674
+ * return root;
675
+ * }
676
+ * ```
633
677
  */
634
678
  renderApproval?: (context: {
635
679
  message: AgentWidgetMessage;
636
680
  defaultRenderer: () => HTMLElement;
637
681
  config: AgentWidgetConfig;
682
+ /** Resolve this approval as approved. Pass `{ remember: true }` for an "Always allow" affordance. */
683
+ approve: (options?: AgentWidgetApprovalDecisionOptions) => void;
684
+ /** Resolve this approval as denied. Pass `{ remember: true }` for an "Always deny" affordance. */
685
+ deny: (options?: AgentWidgetApprovalDecisionOptions) => void;
638
686
  }) => HTMLElement | null;
639
687
  /**
640
688
  * Custom renderer for loading indicator
@@ -1446,6 +1494,12 @@ type WebMcpConfirmInfo = {
1446
1494
  toolName: string;
1447
1495
  args: unknown;
1448
1496
  description?: string;
1497
+ /**
1498
+ * Display title the tool declared via the WebMCP spec's
1499
+ * `ToolDescriptor.title` (e.g. `"Add to Cart"`). Absent when the tool
1500
+ * didn't declare one.
1501
+ */
1502
+ title?: string;
1449
1503
  annotations?: {
1450
1504
  readOnlyHint?: boolean;
1451
1505
  untrustedContentHint?: boolean;
@@ -2807,6 +2861,22 @@ type TextToSpeechConfig = {
2807
2861
  /** Speech pitch (0 - 2). Default: 1 */
2808
2862
  pitch?: number;
2809
2863
  };
2864
+ /**
2865
+ * Extra context for an approval decision, surfaced to `onDecision` and to the
2866
+ * `approve`/`deny` callbacks passed to the `renderApproval` plugin hook.
2867
+ */
2868
+ type AgentWidgetApprovalDecisionOptions = {
2869
+ /**
2870
+ * The user chose a "remember this" affordance (e.g. an "Always allow"
2871
+ * button) rather than a one-time decision. The widget resolves the *current*
2872
+ * approval identically whether or not this is set — an approval bubble is a
2873
+ * single binary gate (`approved`/`denied`). Persisting a don't-ask-again
2874
+ * policy for *future* approvals (auto-resolving them, or not surfacing them)
2875
+ * is the integrator's responsibility, typically inside `onDecision`.
2876
+ * Defaults to absent/`false`.
2877
+ */
2878
+ remember?: boolean;
2879
+ };
2810
2880
  /**
2811
2881
  * Configuration for tool approval bubbles.
2812
2882
  * Controls styling, labels, and behavior of the approval UI.
@@ -2816,6 +2886,8 @@ type AgentWidgetApprovalConfig = {
2816
2886
  backgroundColor?: string;
2817
2887
  /** Border color of the approval bubble */
2818
2888
  borderColor?: string;
2889
+ /** Box-shadow for the approval bubble; pass `"none"` to remove it. Overrides the default `persona-shadow-sm`. */
2890
+ shadow?: string;
2819
2891
  /** Color for the title text */
2820
2892
  titleColor?: string;
2821
2893
  /** Color for the description text */
@@ -2838,20 +2910,51 @@ type AgentWidgetApprovalConfig = {
2838
2910
  approveLabel?: string;
2839
2911
  /** Label for the deny button */
2840
2912
  denyLabel?: string;
2913
+ /**
2914
+ * How the technical details (the tool's agent-facing description and the
2915
+ * raw parameters JSON) are presented:
2916
+ * - `"collapsed"` (default) — hidden behind a "Show details" toggle
2917
+ * - `"expanded"` — visible, with the toggle available to hide them
2918
+ * - `"hidden"` — never rendered
2919
+ */
2920
+ detailsDisplay?: "collapsed" | "expanded" | "hidden";
2921
+ /** Label for the toggle that reveals the technical details */
2922
+ showDetailsLabel?: string;
2923
+ /** Label for the toggle that hides the technical details */
2924
+ hideDetailsLabel?: string;
2925
+ /**
2926
+ * Build the user-facing summary line for an approval request. Overrides the
2927
+ * default "The assistant wants to use “Tool name”." copy. Return a falsy
2928
+ * value to fall back to the default for that approval. `displayTitle` is
2929
+ * the display name the tool declared via the WebMCP spec's
2930
+ * `ToolDescriptor.title`, when one exists.
2931
+ */
2932
+ formatDescription?: (approval: {
2933
+ toolName: string;
2934
+ toolType?: string;
2935
+ description: string;
2936
+ parameters?: unknown;
2937
+ displayTitle?: string;
2938
+ }) => string | undefined;
2841
2939
  /**
2842
2940
  * Custom handler for approval decisions.
2843
2941
  * Return void to let the SDK auto-resolve via the API,
2844
2942
  * or return a Response/ReadableStream for custom handling.
2943
+ *
2944
+ * `options.remember` is `true` when the decision came from a "remember this"
2945
+ * affordance (e.g. an "Always allow" button in a custom `renderApproval`
2946
+ * plugin). Use it to persist a don't-ask-again policy for future approvals;
2947
+ * the current approval resolves the same way regardless.
2845
2948
  */
2846
2949
  onDecision?: (data: {
2847
2950
  approvalId: string;
2848
2951
  executionId: string;
2849
2952
  agentId: string;
2850
2953
  toolName: string;
2851
- }, decision: 'approved' | 'denied') => Promise<Response | ReadableStream<Uint8Array> | void>;
2954
+ }, decision: 'approved' | 'denied', options?: AgentWidgetApprovalDecisionOptions) => Promise<Response | ReadableStream<Uint8Array> | void>;
2852
2955
  };
2853
2956
  type AgentWidgetToolCallConfig$1 = {
2854
- /** Box-shadow for tool-call bubbles; overrides `theme.toolBubbleShadow` when set. */
2957
+ /** Box-shadow for tool-call bubbles; pass `"none"` to remove it. Overrides the `components.toolBubble.shadow` token / `--persona-tool-bubble-shadow`. */
2855
2958
  shadow?: string;
2856
2959
  /** Background color of the tool call bubble container. */
2857
2960
  backgroundColor?: string;
@@ -5337,8 +5440,10 @@ type Controller = {
5337
5440
  * Programmatically resolve a pending approval.
5338
5441
  * @param approvalId - The approval ID to resolve
5339
5442
  * @param decision - "approved" or "denied"
5443
+ * @param options - Optional decision context (e.g. `{ remember: true }`),
5444
+ * forwarded to `config.approval.onDecision`.
5340
5445
  */
5341
- resolveApproval: (approvalId: string, decision: 'approved' | 'denied') => Promise<void>;
5446
+ resolveApproval: (approvalId: string, decision: 'approved' | 'denied', options?: AgentWidgetApprovalDecisionOptions) => Promise<void>;
5342
5447
  };
5343
5448
  type AgentWidgetController = Controller;
5344
5449
 
@@ -5385,7 +5490,7 @@ declare const MOCK_WORKSPACE_CONTENT = "\n <div class=\"preview-workspace-con
5385
5490
  */
5386
5491
  declare function buildSrcdoc(mountId: string, shellMode: 'light' | 'dark', docked: boolean, widgetCssPath: string): string;
5387
5492
  type PreviewScene = 'home' | 'conversation' | 'minimized' | 'artifact';
5388
- type PreviewTranscriptEntryPreset = 'user-message' | 'assistant-message' | 'assistant-code-block' | 'assistant-markdown-table' | 'assistant-image' | 'reasoning-streaming' | 'reasoning-complete' | 'tool-running' | 'tool-complete';
5493
+ type PreviewTranscriptEntryPreset = 'user-message' | 'assistant-message' | 'assistant-code-block' | 'assistant-markdown-table' | 'assistant-image' | 'reasoning-streaming' | 'reasoning-complete' | 'tool-running' | 'tool-complete' | 'approval-request';
5389
5494
  declare function getPreviewTranscriptPresetLabel(preset: PreviewTranscriptEntryPreset): string;
5390
5495
  declare function createPreviewTranscriptEntry(preset: PreviewTranscriptEntryPreset, index?: number): AgentWidgetMessage;
5391
5496
  declare function appendPreviewTranscriptEntry(messages: AgentWidgetMessage[], preset: PreviewTranscriptEntryPreset): AgentWidgetMessage[];