@runtypelabs/persona 4.12.0 → 4.14.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 (68) hide show
  1. package/dist/codegen.cjs +1 -1
  2. package/dist/codegen.js +1 -1
  3. package/dist/context-mentions.d.cts +98 -6
  4. package/dist/context-mentions.d.ts +98 -6
  5. package/dist/index.cjs +64 -64
  6. package/dist/index.cjs.map +1 -1
  7. package/dist/index.d.cts +183 -8
  8. package/dist/index.d.ts +183 -8
  9. package/dist/index.global.js +54 -54
  10. package/dist/index.global.js.map +1 -1
  11. package/dist/index.js +67 -67
  12. package/dist/index.js.map +1 -1
  13. package/dist/launcher.global.js +1 -1
  14. package/dist/launcher.global.js.map +1 -1
  15. package/dist/smart-dom-reader.d.cts +98 -6
  16. package/dist/smart-dom-reader.d.ts +98 -6
  17. package/dist/theme-editor-preview.cjs +66 -66
  18. package/dist/theme-editor-preview.d.cts +100 -6
  19. package/dist/theme-editor-preview.d.ts +100 -6
  20. package/dist/theme-editor-preview.js +75 -75
  21. package/dist/theme-editor.cjs +10 -10
  22. package/dist/theme-editor.d.cts +134 -7
  23. package/dist/theme-editor.d.ts +134 -7
  24. package/dist/theme-editor.js +10 -10
  25. package/dist/theme-reference.cjs +1 -1
  26. package/dist/widget.css +1 -1
  27. package/package.json +1 -1
  28. package/src/artifacts-session.test.ts +106 -0
  29. package/src/client.test.ts +2 -2
  30. package/src/client.ts +4 -1
  31. package/src/components/artifact-card.ts +13 -2
  32. package/src/components/artifact-inline.ts +11 -2
  33. package/src/components/composer-builder.test.ts +2 -0
  34. package/src/components/composer-builder.ts +1 -1
  35. package/src/components/composer-parts.test.ts +2 -0
  36. package/src/components/composer-parts.ts +1 -1
  37. package/src/components/message-bubble.test.ts +7 -1
  38. package/src/components/message-bubble.ts +11 -8
  39. package/src/index-core.ts +34 -0
  40. package/src/session.ts +45 -4
  41. package/src/styles/widget.css +10 -1
  42. package/src/theme-editor/index.ts +5 -0
  43. package/src/theme-editor/presets.test.ts +43 -0
  44. package/src/theme-editor/presets.ts +101 -87
  45. package/src/theme-editor/sections.test.ts +39 -7
  46. package/src/theme-editor/sections.ts +60 -8
  47. package/src/theme-editor/state-preferences.test.ts +15 -0
  48. package/src/theme-editor/state.ts +46 -0
  49. package/src/theme-editor/types.ts +15 -1
  50. package/src/theme-editor/webmcp/tools.test.ts +13 -0
  51. package/src/theme-editor/webmcp/tools.ts +5 -0
  52. package/src/types.ts +139 -9
  53. package/src/ui.artifact-pane-gating.test.ts +5 -5
  54. package/src/ui.config-preferences.test.ts +166 -0
  55. package/src/ui.scroll-additive.test.ts +365 -0
  56. package/src/ui.scroll.test.ts +19 -6
  57. package/src/ui.ts +158 -53
  58. package/src/ui.typing-indicator.test.ts +135 -0
  59. package/src/utils/artifact-display.test.ts +180 -16
  60. package/src/utils/artifact-display.ts +155 -14
  61. package/src/utils/auto-follow.test.ts +38 -0
  62. package/src/utils/auto-follow.ts +35 -0
  63. package/src/utils/config-merge.test.ts +60 -0
  64. package/src/utils/config-merge.ts +6 -1
  65. package/src/utils/feature-preferences.test.ts +326 -0
  66. package/src/utils/feature-preferences.ts +498 -0
  67. package/src/utils/theme.test.ts +92 -0
  68. package/src/utils/tokens.ts +7 -7
@@ -1968,6 +1968,14 @@ type AgentToolsConfig = {
1968
1968
  };
1969
1969
  /** Artifact kinds for the Persona sidebar and dispatch payload */
1970
1970
  type PersonaArtifactKind = "markdown" | "component";
1971
+ type PersonaArtifactPresentation = {
1972
+ /**
1973
+ * Producer hint for where this artifact renders (content-disposition
1974
+ * model). Beats configured defaults; loses to explicit `files`/`byKind`
1975
+ * rules. Persona never infers it; the producer or host supplies it.
1976
+ */
1977
+ preferredMode?: PersonaArtifactDisplayModeInput;
1978
+ };
1971
1979
  /**
1972
1980
  * Agent configuration for agent execution mode.
1973
1981
  * When provided in the widget config, enables agent loop execution instead of flow dispatch.
@@ -2586,7 +2594,48 @@ type AgentWidgetArtifactsLayoutConfig = {
2586
2594
  jsonPayload: string;
2587
2595
  }) => void | Promise<void>;
2588
2596
  };
2589
- type PersonaArtifactDisplayMode = "card" | "panel" | "inline";
2597
+ /**
2598
+ * Where the artifact body renders by default. Every mode shows the compact
2599
+ * reference in the transcript; the mode names where the body goes:
2600
+ * nowhere yet (`collapsed`), the side panel (`panel`), or the conversation
2601
+ * itself (`inline`).
2602
+ */
2603
+ type PersonaArtifactDisplayMode = "collapsed" | "panel" | "inline";
2604
+ /**
2605
+ * Accepted wherever a display mode is written. `"card"` is a deprecated
2606
+ * alias of `"collapsed"` (the old name described the reference card, which
2607
+ * every mode shows, instead of where the body renders). Resolution and
2608
+ * parsing always canonicalize to `"collapsed"`.
2609
+ */
2610
+ type PersonaArtifactDisplayModeInput = PersonaArtifactDisplayMode | "card";
2611
+ /**
2612
+ * Display rules for file-backed artifacts. `byMediaType` keys are exact MIME
2613
+ * types (`"text/html"`) or major-type wildcards (`"image/*"`), matched
2614
+ * case-insensitively without parameters; exact beats wildcard.
2615
+ */
2616
+ type PersonaArtifactFilesDisplayRules = {
2617
+ default?: PersonaArtifactDisplayModeInput;
2618
+ byMediaType?: Record<string, PersonaArtifactDisplayModeInput>;
2619
+ };
2620
+ /**
2621
+ * Scoped artifact display rules. Matching resolves from the most specific
2622
+ * selector to `default`; see `resolveArtifactDisplay`.
2623
+ *
2624
+ * Across preference layers, one merge rule applies everywhere: a string value
2625
+ * replaces the whole subtree it names; an object refines it per key. So
2626
+ * `files: "inline"` overrides every lower-layer file rule, while
2627
+ * `files: { default: "inline" }` keeps lower-layer MIME exceptions.
2628
+ */
2629
+ type PersonaArtifactDisplayRules = {
2630
+ default?: PersonaArtifactDisplayModeInput;
2631
+ byKind?: Partial<Record<PersonaArtifactKind, PersonaArtifactDisplayModeInput>>;
2632
+ /**
2633
+ * @deprecated Use `byKind`. When both are present, `byKind` wins.
2634
+ */
2635
+ byType?: Partial<Record<PersonaArtifactKind, PersonaArtifactDisplayModeInput>>;
2636
+ /** Rules for any artifact carrying file metadata. */
2637
+ files?: PersonaArtifactDisplayModeInput | PersonaArtifactFilesDisplayRules;
2638
+ };
2590
2639
  /** Context handed to custom artifact actions. Content fields are best-effort: resolved from live session state or, after a refresh, from the persisted reference-card payload. */
2591
2640
  type PersonaArtifactActionContext = {
2592
2641
  artifactId: string | null;
@@ -2643,13 +2692,10 @@ type AgentWidgetArtifactsFeature = {
2643
2692
  allowedTypes?: PersonaArtifactKind[];
2644
2693
  /**
2645
2694
  * Where artifact bodies render. A single mode applies to all artifacts;
2646
- * the object form sets a default plus per-type overrides.
2695
+ * the object form sets a default plus scoped overrides.
2647
2696
  * Defaults to "panel" (current behavior).
2648
2697
  */
2649
- display?: PersonaArtifactDisplayMode | {
2650
- default?: PersonaArtifactDisplayMode;
2651
- byType?: Partial<Record<PersonaArtifactKind, PersonaArtifactDisplayMode>>;
2652
- };
2698
+ display?: PersonaArtifactDisplayModeInput | PersonaArtifactDisplayRules;
2653
2699
  /** Split / drawer dimensions and launcher widen behavior */
2654
2700
  layout?: AgentWidgetArtifactsLayoutConfig;
2655
2701
  /**
@@ -3378,6 +3424,41 @@ type AgentWidgetFeatureFlags = {
3378
3424
  */
3379
3425
  suggestReplies?: AgentWidgetSuggestRepliesFeature;
3380
3426
  };
3427
+ /**
3428
+ * Persistable artifact-layout choices. The full layout config deliberately is
3429
+ * not exposed because it also contains callbacks and embedder-owned chrome.
3430
+ */
3431
+ type WidgetArtifactLayoutPreference = Pick<AgentWidgetArtifactsLayoutConfig, "paneWidth" | "paneMaxWidth" | "paneMinWidth" | "expandLauncherPanelWhenOpen" | "expandedPanelWidth" | "resizable" | "resizableMinWidth" | "resizableMaxWidth">;
3432
+ /**
3433
+ * Curated, JSON-serializable display preferences in native `features` shape.
3434
+ *
3435
+ * Absence means inherit the next preference layer and ultimately Persona's
3436
+ * current default. Persist only explicit choices; resetting a choice deletes
3437
+ * its key.
3438
+ *
3439
+ * Capability facts (`artifacts.enabled`, `allowedTypes`), trusted iframe
3440
+ * security, callbacks, actions, renderers, labels, and theme styling are
3441
+ * intentionally excluded because they remain embedder/code-owned.
3442
+ */
3443
+ type WidgetPreferenceSlice = {
3444
+ showToolCalls?: boolean;
3445
+ showReasoning?: boolean;
3446
+ toolCallDisplay?: Pick<AgentWidgetToolCallDisplayFeature, "collapsedMode" | "expandable" | "grouped" | "groupedMode" | "loadingAnimation">;
3447
+ reasoningDisplay?: Pick<AgentWidgetReasoningDisplayFeature, "expandable" | "activePreview">;
3448
+ artifacts?: {
3449
+ /**
3450
+ * String and object forms are both persistable and mean different things
3451
+ * when layers merge: a string replaces every lower-layer display rule; an
3452
+ * object refines lower layers per selector key (same rule applies to
3453
+ * `display.files`).
3454
+ */
3455
+ display?: PersonaArtifactDisplayModeInput | PersonaArtifactDisplayRules;
3456
+ filePreview?: {
3457
+ enabled?: boolean;
3458
+ };
3459
+ layout?: WidgetArtifactLayoutPreference;
3460
+ };
3461
+ };
3381
3462
  /**
3382
3463
  * Feature config for the built-in `suggest_replies` quick-reply chips.
3383
3464
  * Chips render in the existing suggestions slot above the composer and are
@@ -5828,6 +5909,15 @@ type AgentWidgetConfig = {
5828
5909
  */
5829
5910
  colorScheme?: 'auto' | 'light' | 'dark';
5830
5911
  features?: AgentWidgetFeatureFlags;
5912
+ /**
5913
+ * Per-instance display overrides, applied over `features` through the
5914
+ * preference allowlist (security/capability keys cannot pass). String
5915
+ * `display` values replace the base rule subtree; objects refine it per
5916
+ * key. Each `controller.update({ preferences })` replaces the previous
5917
+ * slice wholesale (dropped keys revert to the base `features`); an
5918
+ * explicit-undefined patch clears it entirely.
5919
+ */
5920
+ preferences?: WidgetPreferenceSlice;
5831
5921
  /**
5832
5922
  * When true, focus the chat input after the panel opens and the open animation completes.
5833
5923
  * Applies to launcher mode (user click, controller.open(), autoExpand) and inline mode (on init).
@@ -6749,6 +6839,8 @@ type PersonaArtifactRecord = {
6749
6839
  props?: Record<string, unknown>;
6750
6840
  /** Present when this markdown artifact is a previewable file (see PersonaArtifactFileMeta). */
6751
6841
  file?: PersonaArtifactFileMeta;
6842
+ /** Optional presentation metadata such as the producer's display-mode hint. */
6843
+ presentation?: PersonaArtifactPresentation;
6752
6844
  };
6753
6845
  /** Programmatic artifact upsert (controller / window API) */
6754
6846
  type PersonaArtifactManualUpsert = {
@@ -6758,6 +6850,7 @@ type PersonaArtifactManualUpsert = {
6758
6850
  content: string;
6759
6851
  /** Optional file metadata for previewable file artifacts. */
6760
6852
  file?: PersonaArtifactFileMeta;
6853
+ presentation?: PersonaArtifactPresentation;
6761
6854
  /** Set false to update the registry/pane without a transcript block (pre-4.x behavior). */
6762
6855
  transcript?: boolean;
6763
6856
  } | {
@@ -6766,6 +6859,7 @@ type PersonaArtifactManualUpsert = {
6766
6859
  title?: string;
6767
6860
  component: string;
6768
6861
  props?: Record<string, unknown>;
6862
+ presentation?: PersonaArtifactPresentation;
6769
6863
  /** Set false to update the registry/pane without a transcript block (pre-4.x behavior). */
6770
6864
  transcript?: boolean;
6771
6865
  };
@@ -1968,6 +1968,14 @@ type AgentToolsConfig = {
1968
1968
  };
1969
1969
  /** Artifact kinds for the Persona sidebar and dispatch payload */
1970
1970
  type PersonaArtifactKind = "markdown" | "component";
1971
+ type PersonaArtifactPresentation = {
1972
+ /**
1973
+ * Producer hint for where this artifact renders (content-disposition
1974
+ * model). Beats configured defaults; loses to explicit `files`/`byKind`
1975
+ * rules. Persona never infers it; the producer or host supplies it.
1976
+ */
1977
+ preferredMode?: PersonaArtifactDisplayModeInput;
1978
+ };
1971
1979
  /**
1972
1980
  * Agent configuration for agent execution mode.
1973
1981
  * When provided in the widget config, enables agent loop execution instead of flow dispatch.
@@ -2586,7 +2594,48 @@ type AgentWidgetArtifactsLayoutConfig = {
2586
2594
  jsonPayload: string;
2587
2595
  }) => void | Promise<void>;
2588
2596
  };
2589
- type PersonaArtifactDisplayMode = "card" | "panel" | "inline";
2597
+ /**
2598
+ * Where the artifact body renders by default. Every mode shows the compact
2599
+ * reference in the transcript; the mode names where the body goes:
2600
+ * nowhere yet (`collapsed`), the side panel (`panel`), or the conversation
2601
+ * itself (`inline`).
2602
+ */
2603
+ type PersonaArtifactDisplayMode = "collapsed" | "panel" | "inline";
2604
+ /**
2605
+ * Accepted wherever a display mode is written. `"card"` is a deprecated
2606
+ * alias of `"collapsed"` (the old name described the reference card, which
2607
+ * every mode shows, instead of where the body renders). Resolution and
2608
+ * parsing always canonicalize to `"collapsed"`.
2609
+ */
2610
+ type PersonaArtifactDisplayModeInput = PersonaArtifactDisplayMode | "card";
2611
+ /**
2612
+ * Display rules for file-backed artifacts. `byMediaType` keys are exact MIME
2613
+ * types (`"text/html"`) or major-type wildcards (`"image/*"`), matched
2614
+ * case-insensitively without parameters; exact beats wildcard.
2615
+ */
2616
+ type PersonaArtifactFilesDisplayRules = {
2617
+ default?: PersonaArtifactDisplayModeInput;
2618
+ byMediaType?: Record<string, PersonaArtifactDisplayModeInput>;
2619
+ };
2620
+ /**
2621
+ * Scoped artifact display rules. Matching resolves from the most specific
2622
+ * selector to `default`; see `resolveArtifactDisplay`.
2623
+ *
2624
+ * Across preference layers, one merge rule applies everywhere: a string value
2625
+ * replaces the whole subtree it names; an object refines it per key. So
2626
+ * `files: "inline"` overrides every lower-layer file rule, while
2627
+ * `files: { default: "inline" }` keeps lower-layer MIME exceptions.
2628
+ */
2629
+ type PersonaArtifactDisplayRules = {
2630
+ default?: PersonaArtifactDisplayModeInput;
2631
+ byKind?: Partial<Record<PersonaArtifactKind, PersonaArtifactDisplayModeInput>>;
2632
+ /**
2633
+ * @deprecated Use `byKind`. When both are present, `byKind` wins.
2634
+ */
2635
+ byType?: Partial<Record<PersonaArtifactKind, PersonaArtifactDisplayModeInput>>;
2636
+ /** Rules for any artifact carrying file metadata. */
2637
+ files?: PersonaArtifactDisplayModeInput | PersonaArtifactFilesDisplayRules;
2638
+ };
2590
2639
  /** Context handed to custom artifact actions. Content fields are best-effort: resolved from live session state or, after a refresh, from the persisted reference-card payload. */
2591
2640
  type PersonaArtifactActionContext = {
2592
2641
  artifactId: string | null;
@@ -2643,13 +2692,10 @@ type AgentWidgetArtifactsFeature = {
2643
2692
  allowedTypes?: PersonaArtifactKind[];
2644
2693
  /**
2645
2694
  * Where artifact bodies render. A single mode applies to all artifacts;
2646
- * the object form sets a default plus per-type overrides.
2695
+ * the object form sets a default plus scoped overrides.
2647
2696
  * Defaults to "panel" (current behavior).
2648
2697
  */
2649
- display?: PersonaArtifactDisplayMode | {
2650
- default?: PersonaArtifactDisplayMode;
2651
- byType?: Partial<Record<PersonaArtifactKind, PersonaArtifactDisplayMode>>;
2652
- };
2698
+ display?: PersonaArtifactDisplayModeInput | PersonaArtifactDisplayRules;
2653
2699
  /** Split / drawer dimensions and launcher widen behavior */
2654
2700
  layout?: AgentWidgetArtifactsLayoutConfig;
2655
2701
  /**
@@ -3378,6 +3424,41 @@ type AgentWidgetFeatureFlags = {
3378
3424
  */
3379
3425
  suggestReplies?: AgentWidgetSuggestRepliesFeature;
3380
3426
  };
3427
+ /**
3428
+ * Persistable artifact-layout choices. The full layout config deliberately is
3429
+ * not exposed because it also contains callbacks and embedder-owned chrome.
3430
+ */
3431
+ type WidgetArtifactLayoutPreference = Pick<AgentWidgetArtifactsLayoutConfig, "paneWidth" | "paneMaxWidth" | "paneMinWidth" | "expandLauncherPanelWhenOpen" | "expandedPanelWidth" | "resizable" | "resizableMinWidth" | "resizableMaxWidth">;
3432
+ /**
3433
+ * Curated, JSON-serializable display preferences in native `features` shape.
3434
+ *
3435
+ * Absence means inherit the next preference layer and ultimately Persona's
3436
+ * current default. Persist only explicit choices; resetting a choice deletes
3437
+ * its key.
3438
+ *
3439
+ * Capability facts (`artifacts.enabled`, `allowedTypes`), trusted iframe
3440
+ * security, callbacks, actions, renderers, labels, and theme styling are
3441
+ * intentionally excluded because they remain embedder/code-owned.
3442
+ */
3443
+ type WidgetPreferenceSlice = {
3444
+ showToolCalls?: boolean;
3445
+ showReasoning?: boolean;
3446
+ toolCallDisplay?: Pick<AgentWidgetToolCallDisplayFeature, "collapsedMode" | "expandable" | "grouped" | "groupedMode" | "loadingAnimation">;
3447
+ reasoningDisplay?: Pick<AgentWidgetReasoningDisplayFeature, "expandable" | "activePreview">;
3448
+ artifacts?: {
3449
+ /**
3450
+ * String and object forms are both persistable and mean different things
3451
+ * when layers merge: a string replaces every lower-layer display rule; an
3452
+ * object refines lower layers per selector key (same rule applies to
3453
+ * `display.files`).
3454
+ */
3455
+ display?: PersonaArtifactDisplayModeInput | PersonaArtifactDisplayRules;
3456
+ filePreview?: {
3457
+ enabled?: boolean;
3458
+ };
3459
+ layout?: WidgetArtifactLayoutPreference;
3460
+ };
3461
+ };
3381
3462
  /**
3382
3463
  * Feature config for the built-in `suggest_replies` quick-reply chips.
3383
3464
  * Chips render in the existing suggestions slot above the composer and are
@@ -5828,6 +5909,15 @@ type AgentWidgetConfig = {
5828
5909
  */
5829
5910
  colorScheme?: 'auto' | 'light' | 'dark';
5830
5911
  features?: AgentWidgetFeatureFlags;
5912
+ /**
5913
+ * Per-instance display overrides, applied over `features` through the
5914
+ * preference allowlist (security/capability keys cannot pass). String
5915
+ * `display` values replace the base rule subtree; objects refine it per
5916
+ * key. Each `controller.update({ preferences })` replaces the previous
5917
+ * slice wholesale (dropped keys revert to the base `features`); an
5918
+ * explicit-undefined patch clears it entirely.
5919
+ */
5920
+ preferences?: WidgetPreferenceSlice;
5831
5921
  /**
5832
5922
  * When true, focus the chat input after the panel opens and the open animation completes.
5833
5923
  * Applies to launcher mode (user click, controller.open(), autoExpand) and inline mode (on init).
@@ -6749,6 +6839,8 @@ type PersonaArtifactRecord = {
6749
6839
  props?: Record<string, unknown>;
6750
6840
  /** Present when this markdown artifact is a previewable file (see PersonaArtifactFileMeta). */
6751
6841
  file?: PersonaArtifactFileMeta;
6842
+ /** Optional presentation metadata such as the producer's display-mode hint. */
6843
+ presentation?: PersonaArtifactPresentation;
6752
6844
  };
6753
6845
  /** Programmatic artifact upsert (controller / window API) */
6754
6846
  type PersonaArtifactManualUpsert = {
@@ -6758,6 +6850,7 @@ type PersonaArtifactManualUpsert = {
6758
6850
  content: string;
6759
6851
  /** Optional file metadata for previewable file artifacts. */
6760
6852
  file?: PersonaArtifactFileMeta;
6853
+ presentation?: PersonaArtifactPresentation;
6761
6854
  /** Set false to update the registry/pane without a transcript block (pre-4.x behavior). */
6762
6855
  transcript?: boolean;
6763
6856
  } | {
@@ -6766,6 +6859,7 @@ type PersonaArtifactManualUpsert = {
6766
6859
  title?: string;
6767
6860
  component: string;
6768
6861
  props?: Record<string, unknown>;
6862
+ presentation?: PersonaArtifactPresentation;
6769
6863
  /** Set false to update the registry/pane without a transcript block (pre-4.x behavior). */
6770
6864
  transcript?: boolean;
6771
6865
  };