@runtypelabs/persona 4.7.0 → 4.9.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.
- package/README.md +1 -0
- package/dist/animations/glyph-cycle.cjs +2 -2
- package/dist/animations/glyph-cycle.d.cts +1 -1
- package/dist/animations/glyph-cycle.d.ts +1 -1
- package/dist/animations/glyph-cycle.js +2 -2
- package/dist/animations/{types-CSmiKRVa.d.cts → types-4ROVJ1gA.d.cts} +85 -3
- package/dist/animations/{types-CSmiKRVa.d.ts → types-4ROVJ1gA.d.ts} +85 -3
- package/dist/animations/wipe.cjs +2 -2
- package/dist/animations/wipe.d.cts +1 -1
- package/dist/animations/wipe.d.ts +1 -1
- package/dist/chunk-5EIIHQLQ.js +1 -0
- package/dist/chunk-IO5VVUKP.js +3 -0
- package/dist/chunk-IPVK3KOM.js +1 -0
- package/dist/chunk-UPO4GUFC.js +1 -0
- package/dist/codegen.cjs +13 -13
- package/dist/codegen.js +14 -14
- package/dist/context-mentions-7S5KVUTG.js +169 -0
- package/dist/context-mentions-inline-TTCN7ZM2.js +4 -0
- package/dist/context-mentions-inline.cjs +4 -0
- package/dist/context-mentions-inline.d.cts +203 -0
- package/dist/context-mentions-inline.d.ts +203 -0
- package/dist/context-mentions-inline.js +4 -0
- package/dist/context-mentions.cjs +295 -0
- package/dist/context-mentions.d.cts +7025 -0
- package/dist/context-mentions.d.ts +7025 -0
- package/dist/context-mentions.js +295 -0
- package/dist/index.cjs +99 -68
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1507 -182
- package/dist/index.d.ts +1507 -182
- package/dist/index.global.js +88 -56
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +99 -68
- package/dist/index.js.map +1 -1
- package/dist/install.global.js +1 -1
- package/dist/install.global.js.map +1 -1
- package/dist/launcher.global.js +3 -2
- package/dist/launcher.global.js.map +1 -1
- package/dist/markdown-parsers.js +24 -24
- package/dist/plugin-kit.cjs +1 -1
- package/dist/plugin-kit.d.cts +17 -0
- package/dist/plugin-kit.d.ts +17 -0
- package/dist/plugin-kit.js +1 -1
- package/dist/runtype-tts-entry-UJAEF7NZ.js +1 -0
- package/dist/runtype-tts.js +1 -1
- package/dist/session-reconnect-JKIJBHS5.js +1 -0
- package/dist/smart-dom-reader.cjs +18 -17
- package/dist/smart-dom-reader.d.cts +1260 -16
- package/dist/smart-dom-reader.d.ts +1260 -16
- package/dist/smart-dom-reader.js +18 -17
- package/dist/testing.cjs +3 -3
- package/dist/testing.js +3 -3
- package/dist/theme-editor-preview.cjs +260 -58
- package/dist/theme-editor-preview.d.cts +1234 -15
- package/dist/theme-editor-preview.d.ts +1234 -15
- package/dist/theme-editor-preview.js +87 -58
- package/dist/theme-editor.cjs +10 -10
- package/dist/theme-editor.d.cts +1226 -15
- package/dist/theme-editor.d.ts +1226 -15
- package/dist/theme-editor.js +10 -10
- package/dist/theme-reference.cjs +1 -1
- package/dist/theme-reference.d.cts +76 -0
- package/dist/theme-reference.d.ts +76 -0
- package/dist/theme-reference.js +1 -1
- package/dist/voice-worklet-player.cjs +2 -2
- package/dist/voice-worklet-player.js +2 -2
- package/dist/webmcp-polyfill.js +2 -2
- package/dist/widget.css +1 -1
- package/package.json +16 -5
- package/src/artifacts-session.test.ts +178 -0
- package/src/client.test.ts +255 -1
- package/src/client.ts +157 -60
- package/src/components/artifact-card.test.ts +333 -0
- package/src/components/artifact-card.ts +75 -28
- package/src/components/artifact-inline.test.ts +1328 -0
- package/src/components/artifact-inline.ts +920 -0
- package/src/components/artifact-pane.test.ts +1042 -0
- package/src/components/artifact-pane.ts +440 -131
- package/src/components/artifact-preview.test.ts +1155 -0
- package/src/components/artifact-preview.ts +994 -0
- package/src/components/composer-parts.ts +3 -12
- package/src/components/context-mention-button.test.ts +70 -0
- package/src/components/context-mention-button.ts +82 -0
- package/src/components/context-mention-chip.ts +134 -0
- package/src/components/context-mention-menu.test.ts +508 -0
- package/src/components/context-mention-menu.ts +0 -0
- package/src/components/message-bubble.test.ts +175 -0
- package/src/components/message-bubble.ts +177 -19
- package/src/components/panel.ts +7 -10
- package/src/components/pill-composer-builder.test.ts +6 -2
- package/src/components/pill-composer-builder.ts +6 -6
- package/src/components/reasoning-bubble.ts +1 -13
- package/src/components/registry.ts +38 -3
- package/src/components/tool-bubble.ts +1 -13
- package/src/context-mentions-bundle.test.ts +163 -0
- package/src/context-mentions-entry.ts +185 -0
- package/src/context-mentions-inline-entry.test.ts +136 -0
- package/src/context-mentions-inline-entry.ts +226 -0
- package/src/context-mentions-inline-loader.test.ts +30 -0
- package/src/context-mentions-inline-loader.ts +36 -0
- package/src/context-mentions-inline.ts +15 -0
- package/src/context-mentions-loader.ts +32 -0
- package/src/context-mentions.ts +16 -0
- package/src/defaults.ts +1 -0
- package/src/generated/runtype-openapi-contract.ts +55 -3
- package/src/index-core.ts +46 -1
- package/src/index-global.ts +51 -0
- package/src/index.ts +8 -0
- package/src/markdown-parsers-loader.test.ts +158 -0
- package/src/markdown-parsers-loader.ts +83 -27
- package/src/plugin-kit.test.ts +40 -0
- package/src/plugin-kit.ts +39 -5
- package/src/runtime/host-layout.test.ts +163 -0
- package/src/runtime/host-layout.ts +110 -7
- package/src/runtime/init.ts +18 -61
- package/src/session.mentions.test.ts +175 -0
- package/src/session.test.ts +52 -4
- package/src/session.ts +197 -27
- package/src/smart-dom-reader.test.ts +129 -2
- package/src/smart-dom-reader.ts +127 -1
- package/src/styles/context-mention-menu-css.ts +176 -0
- package/src/styles/widget.css +1002 -152
- package/src/theme-editor/preview.ts +2 -0
- package/src/theme-editor/sections.test.ts +26 -1
- package/src/theme-editor/sections.ts +13 -5
- package/src/theme-reference.ts +2 -2
- package/src/tool-call-display-defaults.test.ts +1 -0
- package/src/types/theme.ts +79 -0
- package/src/types.ts +1041 -17
- package/src/ui.artifact-pane-gating.test.ts +636 -0
- package/src/ui.component-directive.test.ts +104 -0
- package/src/ui.composer-bar.test.ts +60 -2
- package/src/ui.detached-panel.test.ts +1049 -0
- package/src/ui.mention-submit.test.ts +235 -0
- package/src/ui.tool-display.test.ts +51 -0
- package/src/ui.ts +998 -159
- package/src/utils/artifact-custom-actions.ts +128 -0
- package/src/utils/artifact-display.test.ts +42 -0
- package/src/utils/artifact-display.ts +84 -0
- package/src/utils/artifact-file.test.ts +116 -0
- package/src/utils/artifact-file.ts +117 -0
- package/src/utils/artifact-gate.test.ts +112 -5
- package/src/utils/artifact-gate.ts +39 -14
- package/src/utils/artifact-loading-status.ts +55 -0
- package/src/utils/artifact-status-label.ts +190 -0
- package/src/utils/buttons.ts +7 -1
- package/src/utils/chunk-loader.test.ts +97 -0
- package/src/utils/chunk-loader.ts +88 -0
- package/src/utils/code-highlight.test.ts +186 -0
- package/src/utils/code-highlight.ts +400 -0
- package/src/utils/composer-contenteditable.test.ts +507 -0
- package/src/utils/composer-contenteditable.ts +626 -0
- package/src/utils/composer-document.test.ts +280 -0
- package/src/utils/composer-document.ts +293 -0
- package/src/utils/composer-history.test.ts +35 -7
- package/src/utils/composer-history.ts +30 -20
- package/src/utils/composer-input.ts +159 -0
- package/src/utils/context-mention-controller.test.ts +1215 -0
- package/src/utils/context-mention-controller.ts +1186 -0
- package/src/utils/context-mention-manager.test.ts +422 -0
- package/src/utils/context-mention-manager.ts +410 -0
- package/src/utils/context-mention-orchestrator.test.ts +538 -0
- package/src/utils/context-mention-orchestrator.ts +348 -0
- package/src/utils/icons.ts +2 -0
- package/src/utils/live-region.test.ts +108 -0
- package/src/utils/live-region.ts +94 -0
- package/src/utils/mention-channels.ts +63 -0
- package/src/utils/mention-llm-format.test.ts +91 -0
- package/src/utils/mention-llm-format.ts +79 -0
- package/src/utils/mention-matcher.test.ts +86 -0
- package/src/utils/mention-matcher.ts +221 -0
- package/src/utils/mention-token.ts +72 -0
- package/src/utils/mention-trigger.test.ts +155 -0
- package/src/utils/mention-trigger.ts +156 -0
- package/src/utils/roving-tablist.test.ts +152 -0
- package/src/utils/roving-tablist.ts +111 -0
- package/src/utils/spinner.ts +45 -0
- package/src/utils/theme.test.ts +76 -4
- package/src/utils/theme.ts +7 -0
- package/src/utils/tokens.ts +118 -11
- package/src/utils/tool-loading-animation.test.ts +32 -0
- package/src/utils/tool-loading-animation.ts +24 -0
- package/dist/chunk-DFBSCFYN.js +0 -1
- package/dist/runtype-tts-entry-HFUV2UF7.js +0 -1
- package/dist/session-reconnect-U77QFUR7.js +0 -1
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { IconNode } from 'lucide';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Plugin interface for customizing widget components
|
|
3
5
|
*/
|
|
@@ -421,6 +423,8 @@ interface ComponentTokenSet {
|
|
|
421
423
|
margin?: TokenReference<'spacing'>;
|
|
422
424
|
shadow?: TokenReference<'shadow'>;
|
|
423
425
|
opacity?: number;
|
|
426
|
+
/** Hover background — used by transparent variants like `button.ghost`. */
|
|
427
|
+
hoverBackground?: TokenReference<'color'>;
|
|
424
428
|
}
|
|
425
429
|
interface ButtonTokens extends ComponentTokenSet {
|
|
426
430
|
primary: ComponentTokenSet;
|
|
@@ -445,6 +449,10 @@ interface PanelTokens extends ComponentTokenSet {
|
|
|
445
449
|
maxWidth: string;
|
|
446
450
|
height: string;
|
|
447
451
|
maxHeight: string;
|
|
452
|
+
/** Gap between the detached panel and its region edges. Only used when detached. */
|
|
453
|
+
inset?: string;
|
|
454
|
+
/** Background of the region revealed behind a detached panel. */
|
|
455
|
+
canvasBackground?: string;
|
|
448
456
|
}
|
|
449
457
|
interface HeaderTokens extends ComponentTokenSet {
|
|
450
458
|
background: TokenReference<'color'>;
|
|
@@ -609,6 +617,14 @@ interface ArtifactToolbarTokens {
|
|
|
609
617
|
iconBorder?: string;
|
|
610
618
|
toggleGroupGap?: string;
|
|
611
619
|
toggleBorderRadius?: string;
|
|
620
|
+
/** Inner padding of the segmented view/source toggle pill. */
|
|
621
|
+
toggleGroupPadding?: string;
|
|
622
|
+
/** Border of the segmented view/source toggle pill (e.g., `none`). */
|
|
623
|
+
toggleGroupBorder?: string;
|
|
624
|
+
/** Corner radius of the segmented view/source toggle pill. */
|
|
625
|
+
toggleGroupBorderRadius?: string;
|
|
626
|
+
/** Background of the segmented view/source toggle pill. */
|
|
627
|
+
toggleGroupBackground?: string;
|
|
612
628
|
copyBackground?: string;
|
|
613
629
|
copyBorder?: string;
|
|
614
630
|
copyColor?: string;
|
|
@@ -640,6 +656,16 @@ interface ArtifactTabTokens {
|
|
|
640
656
|
/** Tab list container padding (CSS shorthand). */
|
|
641
657
|
listPadding?: string;
|
|
642
658
|
}
|
|
659
|
+
/** Artifact reference card (chat thread) chrome. */
|
|
660
|
+
interface ArtifactCardTokens {
|
|
661
|
+
background?: string;
|
|
662
|
+
/** Full border shorthand (e.g. `1px solid #e5e7eb`). */
|
|
663
|
+
border?: string;
|
|
664
|
+
borderRadius?: string;
|
|
665
|
+
hoverBackground?: string;
|
|
666
|
+
/** Border color on hover. */
|
|
667
|
+
hoverBorderColor?: string;
|
|
668
|
+
}
|
|
643
669
|
/** Artifact pane chrome. */
|
|
644
670
|
interface ArtifactPaneTokens {
|
|
645
671
|
/**
|
|
@@ -650,6 +676,54 @@ interface ArtifactPaneTokens {
|
|
|
650
676
|
background?: string;
|
|
651
677
|
toolbarBackground?: string;
|
|
652
678
|
}
|
|
679
|
+
/** Inline artifact block chrome (`display: "inline"` file preview). */
|
|
680
|
+
interface ArtifactInlineTokens {
|
|
681
|
+
/** Background of the inline preview frame. */
|
|
682
|
+
background?: string;
|
|
683
|
+
/** Full border shorthand for the frame (e.g. `1px solid #e5e7eb`). */
|
|
684
|
+
border?: string;
|
|
685
|
+
/** Border radius of the inline preview frame. */
|
|
686
|
+
borderRadius?: string;
|
|
687
|
+
/** Background of the title/toolbar chrome bar. */
|
|
688
|
+
chromeBackground?: string;
|
|
689
|
+
/** Bottom border of the title bar. */
|
|
690
|
+
chromeBorder?: string;
|
|
691
|
+
/** Title text color in the chrome bar (artifact basename). */
|
|
692
|
+
titleColor?: string;
|
|
693
|
+
/** Muted text color for the type label / streaming status. */
|
|
694
|
+
mutedColor?: string;
|
|
695
|
+
/** Preview iframe height inside the inline body. */
|
|
696
|
+
frameHeight?: string;
|
|
697
|
+
}
|
|
698
|
+
/**
|
|
699
|
+
* Syntax-highlighted artifact source view (pane + inline), rendered by
|
|
700
|
+
* `utils/code-highlight.ts`. One Light defaults ship in `widget.css`, with a
|
|
701
|
+
* One Dark override keyed off the widget's resolved color scheme (the
|
|
702
|
+
* `data-persona-color-scheme` root attribute, not the OS preference); set any
|
|
703
|
+
* of these to retheme the tokenizer palette and the line-number gutter.
|
|
704
|
+
*/
|
|
705
|
+
interface CodeTokens {
|
|
706
|
+
/** Keywords, booleans, null (e.g. `const`, `true`). */
|
|
707
|
+
keywordColor?: string;
|
|
708
|
+
/** String and template literals; HTML attribute values. */
|
|
709
|
+
stringColor?: string;
|
|
710
|
+
/** Line and block comments. */
|
|
711
|
+
commentColor?: string;
|
|
712
|
+
/** Numeric literals; CSS hex colors / units. */
|
|
713
|
+
numberColor?: string;
|
|
714
|
+
/** HTML tag brackets + names; doctype. */
|
|
715
|
+
tagColor?: string;
|
|
716
|
+
/** HTML attribute names. */
|
|
717
|
+
attrColor?: string;
|
|
718
|
+
/** CSS property names; JSON object keys. */
|
|
719
|
+
propertyColor?: string;
|
|
720
|
+
/** Line-number gutter digits. */
|
|
721
|
+
lineNumberColor?: string;
|
|
722
|
+
/** Right border of the line-number gutter. */
|
|
723
|
+
gutterBorderColor?: string;
|
|
724
|
+
/** Background of the source-view code sheet (defaults to One Light/Dark editor background). */
|
|
725
|
+
background?: string;
|
|
726
|
+
}
|
|
653
727
|
/** Icon button chrome (used by createIconButton). */
|
|
654
728
|
interface IconButtonTokens {
|
|
655
729
|
background?: string;
|
|
@@ -719,9 +793,13 @@ interface ComponentTokens {
|
|
|
719
793
|
toolbar?: ArtifactToolbarTokens;
|
|
720
794
|
tab?: ArtifactTabTokens;
|
|
721
795
|
pane?: ArtifactPaneTokens;
|
|
796
|
+
card?: ArtifactCardTokens;
|
|
797
|
+
inline?: ArtifactInlineTokens;
|
|
722
798
|
};
|
|
723
799
|
/** Collapsible widget chrome (tool/reasoning/approval bubbles). */
|
|
724
800
|
collapsibleWidget?: CollapsibleWidgetTokens;
|
|
801
|
+
/** Syntax-highlighted artifact source view (tokenizer palette + gutter). */
|
|
802
|
+
code?: CodeTokens;
|
|
725
803
|
}
|
|
726
804
|
interface PaletteExtras {
|
|
727
805
|
transitions?: Record<string, string>;
|
|
@@ -764,6 +842,7 @@ type RuntypeExecutionStreamEvent = ({
|
|
|
764
842
|
totalSteps?: number;
|
|
765
843
|
type: "execution_start";
|
|
766
844
|
}) | ({
|
|
845
|
+
claudeManagedAgentId?: string;
|
|
767
846
|
completedAt?: string;
|
|
768
847
|
durationMs?: number;
|
|
769
848
|
executionId: string;
|
|
@@ -808,6 +887,15 @@ type RuntypeExecutionStreamEvent = ({
|
|
|
808
887
|
completedAt?: string;
|
|
809
888
|
content?: string;
|
|
810
889
|
cost?: number;
|
|
890
|
+
estimatedContextBreakdown?: {
|
|
891
|
+
categories: Record<string, {
|
|
892
|
+
chars: number;
|
|
893
|
+
estimatedTokens: number;
|
|
894
|
+
}>;
|
|
895
|
+
contextWindowSize?: number;
|
|
896
|
+
estimatedTotalTokens: number;
|
|
897
|
+
estimatedUtilizationPercent?: number;
|
|
898
|
+
};
|
|
811
899
|
executionId: string;
|
|
812
900
|
fallback?: {
|
|
813
901
|
attempts: Array<{
|
|
@@ -845,6 +933,7 @@ type RuntypeExecutionStreamEvent = ({
|
|
|
845
933
|
type: "step_start";
|
|
846
934
|
} | ({
|
|
847
935
|
completedAt?: string;
|
|
936
|
+
cost?: number;
|
|
848
937
|
durationMs?: number;
|
|
849
938
|
error?: string;
|
|
850
939
|
executionId: string;
|
|
@@ -950,6 +1039,11 @@ type RuntypeExecutionStreamEvent = ({
|
|
|
950
1039
|
artifactType: "markdown" | "component";
|
|
951
1040
|
component?: string;
|
|
952
1041
|
executionId?: string;
|
|
1042
|
+
file?: {
|
|
1043
|
+
language?: string;
|
|
1044
|
+
mimeType: string;
|
|
1045
|
+
path: string;
|
|
1046
|
+
};
|
|
953
1047
|
id: string;
|
|
954
1048
|
seq?: number;
|
|
955
1049
|
title?: string;
|
|
@@ -1058,6 +1152,14 @@ type RuntypeExecutionStreamEvent = ({
|
|
|
1058
1152
|
awaitReason?: string;
|
|
1059
1153
|
awaitedAt?: string;
|
|
1060
1154
|
crawlId?: string;
|
|
1155
|
+
elicitation?: {
|
|
1156
|
+
message: string;
|
|
1157
|
+
mode: "form" | "url";
|
|
1158
|
+
pauseCount?: number;
|
|
1159
|
+
requestedSchema?: Record<string, unknown>;
|
|
1160
|
+
serverName?: string;
|
|
1161
|
+
url?: string;
|
|
1162
|
+
};
|
|
1061
1163
|
executionId: string;
|
|
1062
1164
|
origin?: "webmcp" | "sdk";
|
|
1063
1165
|
pageOrigin?: string;
|
|
@@ -1157,6 +1259,14 @@ type RuntypeFlowSSEEvent = {
|
|
|
1157
1259
|
awaitReason?: string;
|
|
1158
1260
|
awaitedAt: string;
|
|
1159
1261
|
crawlId?: string;
|
|
1262
|
+
elicitation?: {
|
|
1263
|
+
message: string;
|
|
1264
|
+
mode: "form" | "url";
|
|
1265
|
+
pauseCount?: number;
|
|
1266
|
+
requestedSchema?: Record<string, unknown>;
|
|
1267
|
+
serverName?: string;
|
|
1268
|
+
url?: string;
|
|
1269
|
+
};
|
|
1160
1270
|
executionId?: string;
|
|
1161
1271
|
flowId: string;
|
|
1162
1272
|
origin?: "webmcp" | "sdk";
|
|
@@ -1207,7 +1317,7 @@ type RuntypeFlowSSEEvent = {
|
|
|
1207
1317
|
completedAt?: string;
|
|
1208
1318
|
duration?: number;
|
|
1209
1319
|
durationMs?: number;
|
|
1210
|
-
error?: string;
|
|
1320
|
+
error?: string | null;
|
|
1211
1321
|
executionId?: string;
|
|
1212
1322
|
executionTime?: number;
|
|
1213
1323
|
id?: string;
|
|
@@ -1251,13 +1361,21 @@ type RuntypeFlowSSEEvent = {
|
|
|
1251
1361
|
totalSteps: number;
|
|
1252
1362
|
type: "step_skip";
|
|
1253
1363
|
when: string;
|
|
1254
|
-
} | {
|
|
1364
|
+
} | ({
|
|
1365
|
+
elicitation?: {
|
|
1366
|
+
message: string;
|
|
1367
|
+
mode: "form" | "url";
|
|
1368
|
+
pauseCount?: number;
|
|
1369
|
+
requestedSchema?: Record<string, unknown>;
|
|
1370
|
+
serverName?: string;
|
|
1371
|
+
url?: string;
|
|
1372
|
+
};
|
|
1255
1373
|
executionId?: string;
|
|
1256
1374
|
reason?: string;
|
|
1257
1375
|
seq?: number;
|
|
1258
1376
|
type: "step_await";
|
|
1259
1377
|
[key: string]: unknown;
|
|
1260
|
-
} | ({
|
|
1378
|
+
}) | ({
|
|
1261
1379
|
agentContext?: {
|
|
1262
1380
|
executionId: string;
|
|
1263
1381
|
iteration: number;
|
|
@@ -1422,6 +1540,149 @@ type TargetResolver = (id: string) => {
|
|
|
1422
1540
|
payload: Record<string, unknown>;
|
|
1423
1541
|
};
|
|
1424
1542
|
|
|
1543
|
+
/**
|
|
1544
|
+
* Curated registry of lucide icons available to `renderLucideIcon`.
|
|
1545
|
+
*
|
|
1546
|
+
* The widget used to do `import * as icons from "lucide"` and look up
|
|
1547
|
+
* icons dynamically by string. That defeated tree-shaking, so the IIFE
|
|
1548
|
+
* (CDN/script-tag) bundle shipped all 1640 lucide icons (~400KB of icon
|
|
1549
|
+
* data) regardless of which we actually used. This explicit registry
|
|
1550
|
+
* lets the bundler drop any icon not listed here.
|
|
1551
|
+
*
|
|
1552
|
+
* Trade-off: `renderLucideIcon(name)` is now a *closed set*. Names not
|
|
1553
|
+
* in this map return `null` and log a warning, exactly as a typo did
|
|
1554
|
+
* before. The registry is intentionally generous (~110 icons) so that
|
|
1555
|
+
* custom `ComponentRenderer` authors rarely hit a missing-icon dead end.
|
|
1556
|
+
*
|
|
1557
|
+
* To add icons: add a named import above and a row in `LUCIDE_ICONS`,
|
|
1558
|
+
* keyed by the lucide kebab-case name (matches their filename and
|
|
1559
|
+
* https://lucide.dev/icons).
|
|
1560
|
+
*
|
|
1561
|
+
* See `packages/widget/docs/icon-registry-shortlist.md` for the full
|
|
1562
|
+
* curation rationale and which icons were considered but excluded.
|
|
1563
|
+
*/
|
|
1564
|
+
declare const LUCIDE_ICONS: {
|
|
1565
|
+
readonly activity: IconNode;
|
|
1566
|
+
readonly "arrow-down": IconNode;
|
|
1567
|
+
readonly "arrow-up": IconNode;
|
|
1568
|
+
readonly "arrow-up-right": IconNode;
|
|
1569
|
+
readonly bot: IconNode;
|
|
1570
|
+
readonly "chevron-down": IconNode;
|
|
1571
|
+
readonly "chevron-up": IconNode;
|
|
1572
|
+
readonly "chevron-right": IconNode;
|
|
1573
|
+
readonly "chevron-left": IconNode;
|
|
1574
|
+
readonly check: IconNode;
|
|
1575
|
+
readonly clipboard: IconNode;
|
|
1576
|
+
readonly "clipboard-copy": IconNode;
|
|
1577
|
+
readonly "code-xml": IconNode;
|
|
1578
|
+
readonly copy: IconNode;
|
|
1579
|
+
readonly file: IconNode;
|
|
1580
|
+
readonly "file-code": IconNode;
|
|
1581
|
+
readonly "file-spreadsheet": IconNode;
|
|
1582
|
+
readonly "file-text": IconNode;
|
|
1583
|
+
readonly "image-plus": IconNode;
|
|
1584
|
+
readonly loader: IconNode;
|
|
1585
|
+
readonly "loader-circle": IconNode;
|
|
1586
|
+
readonly mic: IconNode;
|
|
1587
|
+
readonly paperclip: IconNode;
|
|
1588
|
+
readonly "refresh-cw": IconNode;
|
|
1589
|
+
readonly search: IconNode;
|
|
1590
|
+
readonly send: IconNode;
|
|
1591
|
+
readonly "shield-alert": IconNode;
|
|
1592
|
+
readonly "shield-check": IconNode;
|
|
1593
|
+
readonly "shield-x": IconNode;
|
|
1594
|
+
readonly square: IconNode;
|
|
1595
|
+
readonly "thumbs-down": IconNode;
|
|
1596
|
+
readonly "thumbs-up": IconNode;
|
|
1597
|
+
readonly upload: IconNode;
|
|
1598
|
+
readonly "volume-2": IconNode;
|
|
1599
|
+
readonly x: IconNode;
|
|
1600
|
+
readonly user: IconNode;
|
|
1601
|
+
readonly mail: IconNode;
|
|
1602
|
+
readonly phone: IconNode;
|
|
1603
|
+
readonly calendar: IconNode;
|
|
1604
|
+
readonly clock: IconNode;
|
|
1605
|
+
readonly building: IconNode;
|
|
1606
|
+
readonly "map-pin": IconNode;
|
|
1607
|
+
readonly lock: IconNode;
|
|
1608
|
+
readonly key: IconNode;
|
|
1609
|
+
readonly "credit-card": IconNode;
|
|
1610
|
+
readonly "at-sign": IconNode;
|
|
1611
|
+
readonly hash: IconNode;
|
|
1612
|
+
readonly globe: IconNode;
|
|
1613
|
+
readonly link: IconNode;
|
|
1614
|
+
readonly "circle-check": IconNode;
|
|
1615
|
+
readonly "circle-x": IconNode;
|
|
1616
|
+
readonly "triangle-alert": IconNode;
|
|
1617
|
+
readonly info: IconNode;
|
|
1618
|
+
readonly ban: IconNode;
|
|
1619
|
+
readonly shield: IconNode;
|
|
1620
|
+
readonly "arrow-left": IconNode;
|
|
1621
|
+
readonly "arrow-right": IconNode;
|
|
1622
|
+
readonly "external-link": IconNode;
|
|
1623
|
+
readonly ellipsis: IconNode;
|
|
1624
|
+
readonly "ellipsis-vertical": IconNode;
|
|
1625
|
+
readonly menu: IconNode;
|
|
1626
|
+
readonly house: IconNode;
|
|
1627
|
+
readonly plus: IconNode;
|
|
1628
|
+
readonly minus: IconNode;
|
|
1629
|
+
readonly pencil: IconNode;
|
|
1630
|
+
readonly trash: IconNode;
|
|
1631
|
+
readonly "trash-2": IconNode;
|
|
1632
|
+
readonly save: IconNode;
|
|
1633
|
+
readonly download: IconNode;
|
|
1634
|
+
readonly share: IconNode;
|
|
1635
|
+
readonly funnel: IconNode;
|
|
1636
|
+
readonly settings: IconNode;
|
|
1637
|
+
readonly "rotate-cw": IconNode;
|
|
1638
|
+
readonly maximize: IconNode;
|
|
1639
|
+
readonly minimize: IconNode;
|
|
1640
|
+
readonly "shopping-cart": IconNode;
|
|
1641
|
+
readonly "shopping-bag": IconNode;
|
|
1642
|
+
readonly package: IconNode;
|
|
1643
|
+
readonly truck: IconNode;
|
|
1644
|
+
readonly tag: IconNode;
|
|
1645
|
+
readonly gift: IconNode;
|
|
1646
|
+
readonly receipt: IconNode;
|
|
1647
|
+
readonly wallet: IconNode;
|
|
1648
|
+
readonly store: IconNode;
|
|
1649
|
+
readonly "dollar-sign": IconNode;
|
|
1650
|
+
readonly percent: IconNode;
|
|
1651
|
+
readonly play: IconNode;
|
|
1652
|
+
readonly pause: IconNode;
|
|
1653
|
+
readonly "volume-x": IconNode;
|
|
1654
|
+
readonly camera: IconNode;
|
|
1655
|
+
readonly image: IconNode;
|
|
1656
|
+
readonly film: IconNode;
|
|
1657
|
+
readonly headphones: IconNode;
|
|
1658
|
+
readonly "message-circle": IconNode;
|
|
1659
|
+
readonly "message-square": IconNode;
|
|
1660
|
+
readonly bell: IconNode;
|
|
1661
|
+
readonly heart: IconNode;
|
|
1662
|
+
readonly star: IconNode;
|
|
1663
|
+
readonly eye: IconNode;
|
|
1664
|
+
readonly "eye-off": IconNode;
|
|
1665
|
+
readonly bookmark: IconNode;
|
|
1666
|
+
readonly "calendar-days": IconNode;
|
|
1667
|
+
readonly history: IconNode;
|
|
1668
|
+
readonly timer: IconNode;
|
|
1669
|
+
readonly folder: IconNode;
|
|
1670
|
+
readonly "folder-open": IconNode;
|
|
1671
|
+
readonly files: IconNode;
|
|
1672
|
+
readonly sparkles: IconNode;
|
|
1673
|
+
readonly zap: IconNode;
|
|
1674
|
+
readonly sun: IconNode;
|
|
1675
|
+
readonly moon: IconNode;
|
|
1676
|
+
readonly flag: IconNode;
|
|
1677
|
+
readonly monitor: IconNode;
|
|
1678
|
+
readonly smartphone: IconNode;
|
|
1679
|
+
};
|
|
1680
|
+
/**
|
|
1681
|
+
* Names of lucide icons that ship with the widget. Names not in this
|
|
1682
|
+
* union return `null` from `renderLucideIcon` (with a console warning).
|
|
1683
|
+
*/
|
|
1684
|
+
type IconName = keyof typeof LUCIDE_ICONS;
|
|
1685
|
+
|
|
1425
1686
|
/**
|
|
1426
1687
|
* Text content part for multi-modal messages
|
|
1427
1688
|
*/
|
|
@@ -1480,6 +1741,446 @@ type AgentWidgetContextProviderContext = {
|
|
|
1480
1741
|
config: AgentWidgetConfig;
|
|
1481
1742
|
};
|
|
1482
1743
|
type AgentWidgetContextProvider = (context: AgentWidgetContextProviderContext) => Record<string, unknown> | void | Promise<Record<string, unknown> | void>;
|
|
1744
|
+
/** A single selectable item in the mention menu (host-provided). */
|
|
1745
|
+
type AgentWidgetContextMentionItem = {
|
|
1746
|
+
/** Stable key within its source. */
|
|
1747
|
+
id: string;
|
|
1748
|
+
/** Shown in the menu and on the chip (e.g. "App.tsx"). */
|
|
1749
|
+
label: string;
|
|
1750
|
+
/** Subtitle line in the menu. */
|
|
1751
|
+
description?: string;
|
|
1752
|
+
/** Lucide icon name. */
|
|
1753
|
+
iconName?: string;
|
|
1754
|
+
/**
|
|
1755
|
+
* Accent color for this item's inline token (`display: "inline"`), any CSS
|
|
1756
|
+
* color. Sets `--persona-mention-token-accent` on the token, tinting its pill
|
|
1757
|
+
* background + icon/label — the per-item/per-type color knob (Slack/Linear
|
|
1758
|
+
* style). Prefer setting the same color across a source's items for a "color
|
|
1759
|
+
* per type" look, or theme by `[data-mention-source]` in CSS instead. Ignored
|
|
1760
|
+
* in chip mode.
|
|
1761
|
+
*/
|
|
1762
|
+
color?: string;
|
|
1763
|
+
/** Group header override; defaults to the source's `label`. */
|
|
1764
|
+
group?: string;
|
|
1765
|
+
/** Optional recency/popularity hint the default matcher boosts on. */
|
|
1766
|
+
recencyScore?: number;
|
|
1767
|
+
/**
|
|
1768
|
+
* SKILLS / SLASH-COMMANDS. When set, this item is a COMMAND (a verb) rather
|
|
1769
|
+
* than a context mention (a noun), so selecting it dispatches a behavior
|
|
1770
|
+
* instead of adding a context chip. Absent for ordinary mentions.
|
|
1771
|
+
*
|
|
1772
|
+
* - `"prompt"`: a prompt macro. `resolve()` returns `insertText` (or
|
|
1773
|
+
* `llmAppend`) which is written into the composer (see `insertMode`);
|
|
1774
|
+
* `submitOnSelect` optionally sends it immediately. No chip.
|
|
1775
|
+
* - `"action"`: a client action. `action()` runs in the browser; no resolve,
|
|
1776
|
+
* no chip, no message sent (e.g. `/clear`, `/theme dark`).
|
|
1777
|
+
* - `"server"`: a server-invoked skill. Routed like a `resolveOn:"submit"`
|
|
1778
|
+
* mention whose `resolve().context` reaches the backend via request
|
|
1779
|
+
* `context.mentions.<sourceId>.<itemId>` (a flow/agent reads it).
|
|
1780
|
+
*/
|
|
1781
|
+
command?: "prompt" | "action" | "server";
|
|
1782
|
+
/**
|
|
1783
|
+
* `command:"action"` handler. Receives the parsed `args` (text after the
|
|
1784
|
+
* command name), plus a small `composer` capability + `config`/`messages`.
|
|
1785
|
+
* Short-circuits the mention flow (no chip, no send). Ignored otherwise.
|
|
1786
|
+
*/
|
|
1787
|
+
action?: (ctx: AgentWidgetContextMentionCommandContext) => void | Promise<void>;
|
|
1788
|
+
/**
|
|
1789
|
+
* `command:"prompt"` insertion mode. `"replace"` (default) swaps the whole
|
|
1790
|
+
* composer value for the resolved text; `"insert-at-caret"` replaces only the
|
|
1791
|
+
* `/token` span, keeping surrounding prose. Ignored otherwise.
|
|
1792
|
+
*/
|
|
1793
|
+
insertMode?: "replace" | "insert-at-caret";
|
|
1794
|
+
/**
|
|
1795
|
+
* When true, a `command:"prompt"` submits the composer immediately after
|
|
1796
|
+
* inserting its text (a one-shot macro). Ignored for other kinds.
|
|
1797
|
+
*/
|
|
1798
|
+
submitOnSelect?: boolean;
|
|
1799
|
+
/**
|
|
1800
|
+
* COMMANDS only. Ghost hint for a free-text argument (e.g. "order id" →
|
|
1801
|
+
* `/lookup ‹order id›` in the menu). Its presence switches the command to
|
|
1802
|
+
* INLINE COMPLETION (Slack-style): selecting it fills `/name ` into the
|
|
1803
|
+
* composer for inline arg entry instead of dispatching on select, and the
|
|
1804
|
+
* command is executed at SUBMIT with the typed args. `command:"server"` items
|
|
1805
|
+
* always use inline completion (their chip had no way to add an argument);
|
|
1806
|
+
* for `"prompt"`/`"action"` items this is opt-in. Ignored for non-commands.
|
|
1807
|
+
*/
|
|
1808
|
+
commandArgsPlaceholder?: string;
|
|
1809
|
+
};
|
|
1810
|
+
/**
|
|
1811
|
+
* Capability object handed to a `command:"action"` handler. The widget exposes
|
|
1812
|
+
* only composer-local operations; broader actions (clear the transcript, change
|
|
1813
|
+
* theme) are wired by the host via closures over its own controller.
|
|
1814
|
+
*/
|
|
1815
|
+
type AgentWidgetContextMentionComposerCapability = {
|
|
1816
|
+
/** Current composer text. */
|
|
1817
|
+
getValue: () => string;
|
|
1818
|
+
/** Replace composer text (fires `input`, moves caret to end, refocuses). */
|
|
1819
|
+
setValue: (value: string) => void;
|
|
1820
|
+
/** Submit the composer (same path as pressing send). */
|
|
1821
|
+
submit: () => void;
|
|
1822
|
+
};
|
|
1823
|
+
/** Context passed to a `command:"action"` handler. */
|
|
1824
|
+
type AgentWidgetContextMentionCommandContext = {
|
|
1825
|
+
/** Text typed after the command name (e.g. `staging` for `/deploy staging`). */
|
|
1826
|
+
args: string;
|
|
1827
|
+
config: AgentWidgetConfig;
|
|
1828
|
+
messages: AgentWidgetMessage[];
|
|
1829
|
+
composer: AgentWidgetContextMentionComposerCapability;
|
|
1830
|
+
};
|
|
1831
|
+
/** Reference stored on a sent message for transcript fidelity + chip rendering. */
|
|
1832
|
+
type AgentWidgetContextMentionRef = {
|
|
1833
|
+
sourceId: string;
|
|
1834
|
+
itemId: string;
|
|
1835
|
+
label: string;
|
|
1836
|
+
iconName?: string;
|
|
1837
|
+
/** Accent color for the inline token (see `AgentWidgetContextMentionItem.color`). */
|
|
1838
|
+
color?: string;
|
|
1839
|
+
};
|
|
1840
|
+
/**
|
|
1841
|
+
* One ordered segment of a sent message's prose, for inline mention rendering
|
|
1842
|
+
* (`contextMentions.display: "inline"`). Text runs and atomic mention tokens
|
|
1843
|
+
* interleave in document order so the sent bubble re-renders `@tokens` in place
|
|
1844
|
+
* and composer history can round-trip them. Display/transcript concern only —
|
|
1845
|
+
* the model still sees resolved bodies via `llmContent`/`contentParts`.
|
|
1846
|
+
*/
|
|
1847
|
+
type AgentWidgetContentSegment = {
|
|
1848
|
+
kind: "text";
|
|
1849
|
+
text: string;
|
|
1850
|
+
} | {
|
|
1851
|
+
kind: "mention";
|
|
1852
|
+
ref: AgentWidgetContextMentionRef;
|
|
1853
|
+
};
|
|
1854
|
+
/**
|
|
1855
|
+
* The payload a source returns from `resolve()` for one selected item.
|
|
1856
|
+
* Lead with `llmAppend` — it is the only channel guaranteed to reach the model
|
|
1857
|
+
* with no backend changes.
|
|
1858
|
+
*/
|
|
1859
|
+
type AgentWidgetContextMentionPayload = {
|
|
1860
|
+
/**
|
|
1861
|
+
* PRIMARY, model-visible channel. Appended to this user message's LLM content
|
|
1862
|
+
* so the model actually sees the context with no backend changes.
|
|
1863
|
+
*/
|
|
1864
|
+
llmAppend?: string;
|
|
1865
|
+
/**
|
|
1866
|
+
* `command:"prompt"` macros only. Text written into the COMPOSER on select
|
|
1867
|
+
* (see `AgentWidgetContextMentionItem.insertMode`) — distinct from the hidden
|
|
1868
|
+
* `llmAppend` context channel. Falls back to `llmAppend` when omitted.
|
|
1869
|
+
*/
|
|
1870
|
+
insertText?: string;
|
|
1871
|
+
/** Extra content parts (e.g. file text / image) via the multi-modal path. */
|
|
1872
|
+
contentParts?: ContentPart[];
|
|
1873
|
+
/**
|
|
1874
|
+
* OPT-IN structured channel. Merged into request `context` under
|
|
1875
|
+
* `mentions.<sourceId>.<itemId>` for flows/agents that read it. NOTE: ambient
|
|
1876
|
+
* `context` is NOT guaranteed to reach the model — use `llmAppend` if you need
|
|
1877
|
+
* the model to see it.
|
|
1878
|
+
*/
|
|
1879
|
+
context?: Record<string, unknown>;
|
|
1880
|
+
};
|
|
1881
|
+
/**
|
|
1882
|
+
* One resolved mention, handed to `contextMentions.llmFormat` to build the
|
|
1883
|
+
* model-visible block. `text` is the source's `llmAppend`; `ref`/`item` carry
|
|
1884
|
+
* the selection identity/metadata for a custom formatter (e.g. a source-specific
|
|
1885
|
+
* wrapper or a path from `item`).
|
|
1886
|
+
*/
|
|
1887
|
+
type AgentWidgetMentionLlmEntry = {
|
|
1888
|
+
/** The mention's display label (from `ref.label`). */
|
|
1889
|
+
label: string;
|
|
1890
|
+
/** The resolved model-visible body (the source's `llmAppend`). */
|
|
1891
|
+
text: string;
|
|
1892
|
+
ref: AgentWidgetContextMentionRef;
|
|
1893
|
+
item: AgentWidgetContextMentionItem;
|
|
1894
|
+
};
|
|
1895
|
+
type AgentWidgetContextMentionSearchContext = {
|
|
1896
|
+
messages: AgentWidgetMessage[];
|
|
1897
|
+
config: AgentWidgetConfig;
|
|
1898
|
+
/** Aborts when the next keystroke supersedes this in-flight search. */
|
|
1899
|
+
signal: AbortSignal;
|
|
1900
|
+
};
|
|
1901
|
+
type AgentWidgetContextMentionResolveContext = AgentWidgetContextMentionSearchContext & {
|
|
1902
|
+
/** Plain-text composer value at resolve time. */
|
|
1903
|
+
composerText: string;
|
|
1904
|
+
/**
|
|
1905
|
+
* For `command` items: the text typed after the command name (e.g.
|
|
1906
|
+
* `"123"` for `/lookup 123`). Empty string for ordinary mentions.
|
|
1907
|
+
*/
|
|
1908
|
+
args: string;
|
|
1909
|
+
};
|
|
1910
|
+
type AgentWidgetContextMentionSource = {
|
|
1911
|
+
id: string;
|
|
1912
|
+
/** Group header shown in the menu. */
|
|
1913
|
+
label: string;
|
|
1914
|
+
/**
|
|
1915
|
+
* Filter items for the current `@query` (empty query → recent/popular).
|
|
1916
|
+
* Implement server-side search for large/remote sets, or return all items and
|
|
1917
|
+
* let the widget rank them with `defaultMentionFilter`
|
|
1918
|
+
* (see `createStaticMentionSource` for the common case).
|
|
1919
|
+
*/
|
|
1920
|
+
search: (query: string, ctx: AgentWidgetContextMentionSearchContext) => AgentWidgetContextMentionItem[] | Promise<AgentWidgetContextMentionItem[]>;
|
|
1921
|
+
/**
|
|
1922
|
+
* Fetch the payload for dispatch. Called once when the user SELECTS the item
|
|
1923
|
+
* (eagerly, cached on the chip, abortable on removal) unless `resolveOn` is
|
|
1924
|
+
* `"submit"`. A throw/abort drops the mention via `onMentionResolveError`.
|
|
1925
|
+
*/
|
|
1926
|
+
resolve: (item: AgentWidgetContextMentionItem, ctx: AgentWidgetContextMentionResolveContext) => AgentWidgetContextMentionPayload | Promise<AgentWidgetContextMentionPayload>;
|
|
1927
|
+
/**
|
|
1928
|
+
* When to call `resolve()`:
|
|
1929
|
+
* - `"select"` (default): eager on pick; parallelizes the fetch with the user
|
|
1930
|
+
* finishing their sentence so submit stays instant.
|
|
1931
|
+
* - `"submit"`: defer to send time, for time-sensitive sources (e.g. current
|
|
1932
|
+
* page state that may change between select and send).
|
|
1933
|
+
* @default "select"
|
|
1934
|
+
*/
|
|
1935
|
+
resolveOn?: "select" | "submit";
|
|
1936
|
+
/**
|
|
1937
|
+
* COMMAND sources only. Resolve a `/name` (the first token of a command line)
|
|
1938
|
+
* to its menu item, for submit-time inline-command dispatch and the menu's
|
|
1939
|
+
* "typing args now" suppression. `createSlashCommandsSource` sets this; plain
|
|
1940
|
+
* `@`-mention sources leave it undefined.
|
|
1941
|
+
*/
|
|
1942
|
+
matchCommand?: (name: string) => AgentWidgetContextMentionItem | undefined;
|
|
1943
|
+
};
|
|
1944
|
+
/** Context passed to the optional `renderMentionMenu` override. */
|
|
1945
|
+
type AgentWidgetContextMentionMenuRenderContext = {
|
|
1946
|
+
/** Current trigger query ("" when freshly opened). */
|
|
1947
|
+
query: string;
|
|
1948
|
+
/** Grouped, ranked, capped results ready to paint. */
|
|
1949
|
+
groups: {
|
|
1950
|
+
source: AgentWidgetContextMentionSource;
|
|
1951
|
+
items: AgentWidgetContextMentionItem[];
|
|
1952
|
+
}[];
|
|
1953
|
+
/** Per-source async state for loading/empty/error rendering, keyed by source id. */
|
|
1954
|
+
status: Record<string, "loading" | "ready" | "empty" | "error">;
|
|
1955
|
+
/** Index into the flat keyboard-traversal order. */
|
|
1956
|
+
activeIndex: number;
|
|
1957
|
+
/** Commit a selection (strips `@query`, adds chip, resolves on select). */
|
|
1958
|
+
select: (item: AgentWidgetContextMentionItem) => void;
|
|
1959
|
+
/** Close the menu, keeping a literal `@`. */
|
|
1960
|
+
close: () => void;
|
|
1961
|
+
};
|
|
1962
|
+
/** Context passed to the optional `renderMentionItem` per-row override. */
|
|
1963
|
+
type AgentWidgetContextMentionItemRenderContext = {
|
|
1964
|
+
/** The item to render. */
|
|
1965
|
+
item: AgentWidgetContextMentionItem;
|
|
1966
|
+
/** The source this item came from (its group). */
|
|
1967
|
+
source: AgentWidgetContextMentionSource;
|
|
1968
|
+
/** Current trigger query, for highlighting matches. */
|
|
1969
|
+
query: string;
|
|
1970
|
+
/** True when this row is the keyboard-highlighted one at render time. */
|
|
1971
|
+
active: boolean;
|
|
1972
|
+
/** Position in the flat keyboard-traversal order. */
|
|
1973
|
+
index: number;
|
|
1974
|
+
};
|
|
1975
|
+
/** Context passed to the optional `renderMentionChip` override. */
|
|
1976
|
+
type AgentWidgetContextMentionChipRenderContext = {
|
|
1977
|
+
ref: AgentWidgetContextMentionRef;
|
|
1978
|
+
/** Resolve-on-select lifecycle for spinner→ready→error UI. */
|
|
1979
|
+
status: "resolving" | "ready" | "error";
|
|
1980
|
+
/**
|
|
1981
|
+
* The resolved payload, once available (select-resolved sources only). Use it
|
|
1982
|
+
* to preview already-fetched content on hover. Undefined while `status` is
|
|
1983
|
+
* `"resolving"`, on `"error"`, and for `resolveOn:"submit"` sources (which
|
|
1984
|
+
* resolve at send time, not while the chip sits in the composer — for those,
|
|
1985
|
+
* `ref.itemId` carries the source key you can re-read on demand, e.g. a CSS
|
|
1986
|
+
* selector for the smart-dom source).
|
|
1987
|
+
*/
|
|
1988
|
+
payload?: AgentWidgetContextMentionPayload;
|
|
1989
|
+
/** Remove the chip; aborts any in-flight resolve. */
|
|
1990
|
+
remove: () => void;
|
|
1991
|
+
};
|
|
1992
|
+
/**
|
|
1993
|
+
* Where a trigger char is allowed to open the menu:
|
|
1994
|
+
* - `"anywhere"` (default): after any whitespace or start (the `@` rule).
|
|
1995
|
+
* - `"line-start"`: only when the char before the trigger is a newline or the
|
|
1996
|
+
* start of input — the natural rule for `/` slash-commands.
|
|
1997
|
+
* - `"input-start"`: only at index 0 of the composer.
|
|
1998
|
+
*/
|
|
1999
|
+
type AgentWidgetMentionTriggerPosition = "anywhere" | "line-start" | "input-start";
|
|
2000
|
+
/**
|
|
2001
|
+
* A SECOND (or Nth) trigger channel sharing the same menu engine — e.g. `/` for
|
|
2002
|
+
* slash-commands alongside `@` for context. The legacy `trigger`/`sources`
|
|
2003
|
+
* fields form the implicit first channel; `triggers[]` adds more. At any caret
|
|
2004
|
+
* at most one channel is active, so all channels drive one menu/controller.
|
|
2005
|
+
*/
|
|
2006
|
+
type AgentWidgetMentionTriggerChannel = {
|
|
2007
|
+
/** Trigger character (e.g. "/"). */
|
|
2008
|
+
trigger: string;
|
|
2009
|
+
/** Sources for this channel (searched only when this trigger is active). */
|
|
2010
|
+
sources: AgentWidgetContextMentionSource[];
|
|
2011
|
+
/** Where the trigger may open. @default "anywhere" */
|
|
2012
|
+
triggerPosition?: AgentWidgetMentionTriggerPosition;
|
|
2013
|
+
/**
|
|
2014
|
+
* Let the query span spaces so a command can take ARGS (`/deploy staging`).
|
|
2015
|
+
* A newline still ends it. Pair with `triggerPosition: "line-start"` for
|
|
2016
|
+
* slash-commands. @default false
|
|
2017
|
+
*/
|
|
2018
|
+
allowSpaces?: boolean;
|
|
2019
|
+
/** Show a composer affordance button for this channel. @default false */
|
|
2020
|
+
showButton?: boolean;
|
|
2021
|
+
/** Icon for this channel's affordance button. */
|
|
2022
|
+
buttonIconName?: string;
|
|
2023
|
+
/** Tooltip / aria-label for this channel's affordance button. */
|
|
2024
|
+
buttonTooltipText?: string;
|
|
2025
|
+
/** Placeholder for this channel's picker search field. */
|
|
2026
|
+
searchPlaceholder?: string;
|
|
2027
|
+
};
|
|
2028
|
+
type AgentWidgetContextMentionConfig = {
|
|
2029
|
+
/** @default false */
|
|
2030
|
+
enabled?: boolean;
|
|
2031
|
+
/**
|
|
2032
|
+
* Show the visible composer affordance button (the discoverable entry point).
|
|
2033
|
+
* Strongly recommended; the bare `@` trigger alone is hard to discover for
|
|
2034
|
+
* non-technical users. @default true
|
|
2035
|
+
*/
|
|
2036
|
+
showButton?: boolean;
|
|
2037
|
+
/**
|
|
2038
|
+
* Icon for the affordance button (any registered Lucide name). Defaults to a
|
|
2039
|
+
* "+" signifier — the consumer-recognized "add context" affordance — rather
|
|
2040
|
+
* than an "@" glyph, which reads as power-user. Use `"at-sign"` on a
|
|
2041
|
+
* developer/power-user surface. @default "plus"
|
|
2042
|
+
*/
|
|
2043
|
+
buttonIconName?: string;
|
|
2044
|
+
/** Tooltip / aria-label for the affordance button. @default "Add context" */
|
|
2045
|
+
buttonTooltipText?: string;
|
|
2046
|
+
/**
|
|
2047
|
+
* Placeholder for the picker's search field, shown when the menu is opened
|
|
2048
|
+
* from the affordance button (a Cursor/Copilot-style picker that inserts no
|
|
2049
|
+
* trigger character). The typed-trigger path keeps its query in the textarea
|
|
2050
|
+
* and never shows this field. @default "Search context…"
|
|
2051
|
+
*/
|
|
2052
|
+
searchPlaceholder?: string;
|
|
2053
|
+
/** Trigger character. @default "@" */
|
|
2054
|
+
trigger?: string;
|
|
2055
|
+
/**
|
|
2056
|
+
* Where the primary `trigger` may open the menu. @default "anywhere"
|
|
2057
|
+
*/
|
|
2058
|
+
triggerPosition?: AgentWidgetMentionTriggerPosition;
|
|
2059
|
+
/**
|
|
2060
|
+
* ADDITIONAL trigger channels sharing this engine — e.g. a `/` slash-command
|
|
2061
|
+
* channel next to `@` context. Each channel has its own trigger char,
|
|
2062
|
+
* sources, and position rule. See `AgentWidgetMentionTriggerChannel`.
|
|
2063
|
+
*/
|
|
2064
|
+
triggers?: AgentWidgetMentionTriggerChannel[];
|
|
2065
|
+
/** Max mentions per message. @default 8 */
|
|
2066
|
+
maxMentions?: number;
|
|
2067
|
+
/** Max items shown per source group before "keep typing to narrow". @default 6 */
|
|
2068
|
+
maxItemsPerGroup?: number;
|
|
2069
|
+
/**
|
|
2070
|
+
* Debounce for ASYNC source search only (ms). Synchronous sources and the
|
|
2071
|
+
* menu's first paint are never debounced. @default 150
|
|
2072
|
+
*/
|
|
2073
|
+
searchDebounceMs?: number;
|
|
2074
|
+
/** Registered mention sources (search + resolve). */
|
|
2075
|
+
sources: AgentWidgetContextMentionSource[];
|
|
2076
|
+
/** Chip icon fallback when a source/item omits one. @default "at-sign" */
|
|
2077
|
+
chipIconName?: string;
|
|
2078
|
+
/**
|
|
2079
|
+
* How each resolved mention's `llmAppend` text is wrapped into a delimited
|
|
2080
|
+
* block before it is prepended to the model-visible message content. Blocks
|
|
2081
|
+
* are joined with a blank line and the typed prose follows last.
|
|
2082
|
+
*
|
|
2083
|
+
* - `"fenced"` (default): a fenced code block with the label in the info
|
|
2084
|
+
* string, e.g. selecting `App.tsx` emits:
|
|
2085
|
+
* ```text
|
|
2086
|
+
* ```App.tsx
|
|
2087
|
+
* <file body>
|
|
2088
|
+
* ```
|
|
2089
|
+
* ```
|
|
2090
|
+
* The fence auto-escalates (four+ backticks) when the body itself contains a
|
|
2091
|
+
* fence, so a body can never terminate its own wrapper.
|
|
2092
|
+
* - `"document"`: Anthropic's long-context document shape, e.g.:
|
|
2093
|
+
* ```text
|
|
2094
|
+
* <document index="1">
|
|
2095
|
+
* <source>App.tsx</source>
|
|
2096
|
+
* <document_content>
|
|
2097
|
+
* <file body>
|
|
2098
|
+
* </document_content>
|
|
2099
|
+
* </document>
|
|
2100
|
+
* ```
|
|
2101
|
+
* Prefer this for prose/document-shaped sources per Anthropic's long-context
|
|
2102
|
+
* guidance (indexed `<document>` blocks improve grounding and citation). A
|
|
2103
|
+
* body containing the literal `</document_content>` closing tag falls back to
|
|
2104
|
+
* the fenced block for that entry to avoid a broken XML boundary.
|
|
2105
|
+
* - function form: fully owns the block for one mention — its return string is
|
|
2106
|
+
* used verbatim (no extra wrapping), joined with the other blocks. `index` is
|
|
2107
|
+
* the 0-based position among the message's mention blocks.
|
|
2108
|
+
*
|
|
2109
|
+
* @default "fenced"
|
|
2110
|
+
*/
|
|
2111
|
+
llmFormat?: "fenced" | "document" | ((entry: AgentWidgetMentionLlmEntry, index: number) => string);
|
|
2112
|
+
/**
|
|
2113
|
+
* How `@` selections appear in the composer and sent user bubble.
|
|
2114
|
+
*
|
|
2115
|
+
* - `"chip"` (default): strip `@query` on select; show a compact pill in the
|
|
2116
|
+
* composer context row; `content` is prose-only.
|
|
2117
|
+
* - `"inline"`: insert an atomic styled token in the sentence (Slack/Linear/
|
|
2118
|
+
* Cursor style), backed by a contenteditable composer. Slash-command channels
|
|
2119
|
+
* (`triggers[]` with `/`) stay inline-text regardless — they already use the
|
|
2120
|
+
* `/name args` model, not chips. `renderMentionChip` is ignored for `@`
|
|
2121
|
+
* mentions in this mode.
|
|
2122
|
+
*
|
|
2123
|
+
* The resolved-context channel (`llmContent`/`contentParts`) is unchanged
|
|
2124
|
+
* across both modes — inline tokens are a display concern.
|
|
2125
|
+
*
|
|
2126
|
+
* @default "chip"
|
|
2127
|
+
*/
|
|
2128
|
+
display?: "chip" | "inline";
|
|
2129
|
+
/**
|
|
2130
|
+
* Fired when a pick is rejected: it duplicates an existing chip in chip display
|
|
2131
|
+
* (`"duplicate"` — inline display allows the same item as multiple tokens, so it
|
|
2132
|
+
* never rejects for this reason), hits `maxMentions` (`"limit"`), or (inline
|
|
2133
|
+
* display) the composer text changed between parse and commit so the token could
|
|
2134
|
+
* not be inserted (`"stale"`).
|
|
2135
|
+
*/
|
|
2136
|
+
onMentionRejected?: (item: AgentWidgetContextMentionItem, reason: "duplicate" | "limit" | "stale") => void;
|
|
2137
|
+
/**
|
|
2138
|
+
* A `resolve()` that throws/aborts: the mention is dropped and the message
|
|
2139
|
+
* still sends. Surface a non-blocking notice here if desired.
|
|
2140
|
+
*/
|
|
2141
|
+
onMentionResolveError?: (item: AgentWidgetContextMentionItem, error: unknown) => void;
|
|
2142
|
+
/**
|
|
2143
|
+
* MID-LEVEL render override for the autocomplete menu. The widget still owns
|
|
2144
|
+
* trigger detection, search, debounce/abort, keyboard nav, and positioning;
|
|
2145
|
+
* you only supply the menu markup and drive selection through `ctx`. Omit to
|
|
2146
|
+
* use the built-in grouped menu. @default built-in
|
|
2147
|
+
*/
|
|
2148
|
+
renderMentionMenu?: (ctx: AgentWidgetContextMentionMenuRenderContext) => HTMLElement;
|
|
2149
|
+
/**
|
|
2150
|
+
* NARROW render override for a single result row's INNER content, keeping the
|
|
2151
|
+
* built-in menu chrome (group headers, loading/empty/error, keyboard nav, the
|
|
2152
|
+
* "keep typing" hint). The widget keeps the `role="option"` wrapper and its
|
|
2153
|
+
* click/hover wiring; you return only the row's contents. For full menu
|
|
2154
|
+
* control use `renderMentionMenu` instead. Highlight is CSS-driven via the
|
|
2155
|
+
* wrapper's `[data-active]` attribute, so this is called once per render, not
|
|
2156
|
+
* on every arrow key. Ignored when `renderMentionMenu` is set. @default built-in
|
|
2157
|
+
*/
|
|
2158
|
+
renderMentionItem?: (ctx: AgentWidgetContextMentionItemRenderContext) => HTMLElement;
|
|
2159
|
+
/**
|
|
2160
|
+
* MID-LEVEL render override for a single context chip. Return your own pill
|
|
2161
|
+
* (must include an accessible remove control wired to `ctx.remove`); reflect
|
|
2162
|
+
* `ctx.status` for resolve-on-select. Omit to use the built-in compact pill.
|
|
2163
|
+
* @default built-in
|
|
2164
|
+
*/
|
|
2165
|
+
renderMentionChip?: (ctx: AgentWidgetContextMentionChipRenderContext) => HTMLElement;
|
|
2166
|
+
/**
|
|
2167
|
+
* INLINE display only (`display: "inline"`). Render override for a single inline
|
|
2168
|
+
* mention TOKEN — the atomic styled node that sits in the sentence, in both the
|
|
2169
|
+
* contenteditable composer and the read-only sent bubble. Return your own
|
|
2170
|
+
* element (e.g. a fully custom colored pill); the composer marks it
|
|
2171
|
+
* `contenteditable="false"` and stamps `data-mention-id` so it stays atomic.
|
|
2172
|
+
* Omit to use the built-in pill (icon + `@label`, tinted by
|
|
2173
|
+
* `--persona-mention-token-accent` / `ref.color`, themeable per source via the
|
|
2174
|
+
* `[data-mention-source]` attribute). Ignored in chip mode.
|
|
2175
|
+
* @default built-in
|
|
2176
|
+
*/
|
|
2177
|
+
renderMentionToken?: (ctx: AgentWidgetContextMentionTokenRenderContext) => HTMLElement;
|
|
2178
|
+
};
|
|
2179
|
+
/** Render context for `renderMentionToken`. `readonly` is true in the sent bubble. */
|
|
2180
|
+
type AgentWidgetContextMentionTokenRenderContext = {
|
|
2181
|
+
ref: AgentWidgetContextMentionRef;
|
|
2182
|
+
readonly: boolean;
|
|
2183
|
+
};
|
|
1483
2184
|
type AgentWidgetRequestPayloadMessage = {
|
|
1484
2185
|
role: AgentWidgetMessageRole;
|
|
1485
2186
|
content: MessageContent;
|
|
@@ -2032,7 +2733,13 @@ type AgentWidgetControllerEventMap = {
|
|
|
2032
2733
|
* new artifact content arrives or the host calls `showArtifacts()` on the widget handle.
|
|
2033
2734
|
*/
|
|
2034
2735
|
type AgentWidgetArtifactsLayoutConfig = {
|
|
2035
|
-
/**
|
|
2736
|
+
/**
|
|
2737
|
+
* Flex gap between chat column and artifact pane.
|
|
2738
|
+
* @default 0 (welded); detached uses the panel inset
|
|
2739
|
+
* @remarks In welded appearances (`panel` / `seamless`) a nonzero gap opens a
|
|
2740
|
+
* visible seam in the single card. It is honored geometrically (resize clamps
|
|
2741
|
+
* and the seam handle account for it) but is usually undesired.
|
|
2742
|
+
*/
|
|
2036
2743
|
splitGap?: string;
|
|
2037
2744
|
/** Artifact column width in split mode. @default 40% */
|
|
2038
2745
|
paneWidth?: string;
|
|
@@ -2063,16 +2770,39 @@ type AgentWidgetArtifactsLayoutConfig = {
|
|
|
2063
2770
|
/** Optional max artifact width cap while resizing (`px` only). Layout still bounds by chat min width. */
|
|
2064
2771
|
resizableMaxWidth?: string;
|
|
2065
2772
|
/**
|
|
2066
|
-
* Visual treatment for the artifact column in split
|
|
2067
|
-
* - `'panel'`:
|
|
2068
|
-
*
|
|
2773
|
+
* Visual treatment for the artifact column in a desktop split.
|
|
2774
|
+
* - `'panel'`: one welded card (border + radius wrap chat + pane) with a hairline
|
|
2775
|
+
* divider on the pane's chat-facing edge, zero gap (default).
|
|
2776
|
+
* - `'seamless'`: the same welded card with no internal divider or chrome, zero gap.
|
|
2777
|
+
* - `'detached'`: two separate elevated cards: gap from `--persona-panel-inset`,
|
|
2778
|
+
* all-side border and radius on each, and canvas background behind the split.
|
|
2779
|
+
* In an inline embed this also insets the split from the container edges on all
|
|
2780
|
+
* sides (the page canvas shows through), so the all-side margin no longer requires
|
|
2781
|
+
* `launcher.detachedPanel`.
|
|
2782
|
+
*
|
|
2783
|
+
* Default is `'panel'` unless `launcher.detachedPanel` is true, in which case an unset
|
|
2784
|
+
* `paneAppearance` resolves to `'detached'`. An explicit value always wins.
|
|
2069
2785
|
* @default 'panel'
|
|
2070
2786
|
*/
|
|
2071
|
-
paneAppearance?: "panel" | "seamless";
|
|
2787
|
+
paneAppearance?: "panel" | "seamless" | "detached";
|
|
2072
2788
|
/** Border radius on the artifact pane (CSS length). Works with any `paneAppearance`. */
|
|
2073
2789
|
paneBorderRadius?: string;
|
|
2074
2790
|
/** CSS `box-shadow` on the artifact pane. Set `"none"` to suppress the default shadow. */
|
|
2075
2791
|
paneShadow?: string;
|
|
2792
|
+
/**
|
|
2793
|
+
* CSS `box-shadow` for the chat column card in a detached split. Defaults to the same
|
|
2794
|
+
* elevation as the artifact pane; set to `"none"` to keep the chat flat while the pane stays raised.
|
|
2795
|
+
*/
|
|
2796
|
+
chatShadow?: string;
|
|
2797
|
+
/**
|
|
2798
|
+
* Chat column surface in a detached split. `"card"` (default) renders the chat as an inset card
|
|
2799
|
+
* matching the artifact pane; `"flush"` renders the chat flush with the container (no border, radius,
|
|
2800
|
+
* or shadow) and insets only the artifact pane, so the chat is flat background and the pane floats.
|
|
2801
|
+
* Only affects an inline-embedded detached split (the container-filling case); in floating, docked,
|
|
2802
|
+
* or sidebar modes it falls back to the card look.
|
|
2803
|
+
* @default 'card'
|
|
2804
|
+
*/
|
|
2805
|
+
chatSurface?: "card" | "flush";
|
|
2076
2806
|
/**
|
|
2077
2807
|
* Full `border` shorthand for the artifact `<aside>` (all sides). Overrides default pane borders.
|
|
2078
2808
|
* Example: `"1px solid #cccccc"`.
|
|
@@ -2084,14 +2814,12 @@ type AgentWidgetArtifactsLayoutConfig = {
|
|
|
2084
2814
|
*/
|
|
2085
2815
|
paneBorderLeft?: string;
|
|
2086
2816
|
/**
|
|
2087
|
-
*
|
|
2088
|
-
* top-right and bottom-right radii, and round the **artifact pane’s** top-right and bottom-right
|
|
2089
|
-
* to match `persona-rounded-2xl` (`--persona-radius-lg`) so the two columns read as one shell.
|
|
2817
|
+
* @deprecated No-op. Panel and seamless splits now weld into one card by default.
|
|
2090
2818
|
*/
|
|
2091
2819
|
unifiedSplitChrome?: boolean;
|
|
2092
2820
|
/**
|
|
2093
|
-
*
|
|
2094
|
-
* @default matches
|
|
2821
|
+
* Desktop welded split only: override the artifact pane's outer-right corner radius (CSS length).
|
|
2822
|
+
* @default matches the panel radius (`--persona-panel-radius`)
|
|
2095
2823
|
*/
|
|
2096
2824
|
unifiedSplitOuterRadius?: string;
|
|
2097
2825
|
/**
|
|
@@ -2111,6 +2839,10 @@ type AgentWidgetArtifactsLayoutConfig = {
|
|
|
2111
2839
|
* @default 'default'
|
|
2112
2840
|
*/
|
|
2113
2841
|
toolbarPreset?: "default" | "document";
|
|
2842
|
+
/** Visible title in the artifact toolbar. @default "Artifacts" */
|
|
2843
|
+
toolbarTitle?: string;
|
|
2844
|
+
/** Label for the artifact dismiss control. @default "Close" */
|
|
2845
|
+
closeButtonLabel?: string;
|
|
2114
2846
|
/**
|
|
2115
2847
|
* When `toolbarPreset` is `document`, show a visible "Copy" label next to the copy icon.
|
|
2116
2848
|
*/
|
|
@@ -2125,6 +2857,17 @@ type AgentWidgetArtifactsLayoutConfig = {
|
|
|
2125
2857
|
documentToolbarToggleActiveBackground?: string;
|
|
2126
2858
|
/** Active view/source toggle border color. Sets `--persona-artifact-doc-toggle-active-border`. */
|
|
2127
2859
|
documentToolbarToggleActiveBorderColor?: string;
|
|
2860
|
+
/** Show an expand/collapse toggle in the artifact toolbar (both presets). Expanded fills the widget with the pane and hides the chat column. Default: false. */
|
|
2861
|
+
showExpandToggle?: boolean;
|
|
2862
|
+
/** Show the copy control in the `default` toolbar preset (the `document` preset always shows it). Default: false. */
|
|
2863
|
+
showCopyButton?: boolean;
|
|
2864
|
+
/** Edge fade on the scrollable tab strip. true = both ends (dynamic). @default true */
|
|
2865
|
+
tabFade?: boolean | {
|
|
2866
|
+
start?: boolean;
|
|
2867
|
+
end?: boolean;
|
|
2868
|
+
};
|
|
2869
|
+
/** Tab fade width (CSS length). @default 24px */
|
|
2870
|
+
tabFadeSize?: string;
|
|
2128
2871
|
/**
|
|
2129
2872
|
* Invoked when the document toolbar Refresh control is used (before the pane re-renders).
|
|
2130
2873
|
* Use to replay `connectStream`, refetch, etc.
|
|
@@ -2148,20 +2891,349 @@ type AgentWidgetArtifactsLayoutConfig = {
|
|
|
2148
2891
|
jsonPayload: string;
|
|
2149
2892
|
}) => void | Promise<void>;
|
|
2150
2893
|
};
|
|
2894
|
+
type PersonaArtifactDisplayMode = "card" | "panel" | "inline";
|
|
2895
|
+
/** 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. */
|
|
2896
|
+
type PersonaArtifactActionContext = {
|
|
2897
|
+
artifactId: string | null;
|
|
2898
|
+
title: string;
|
|
2899
|
+
artifactType: string;
|
|
2900
|
+
markdown?: string;
|
|
2901
|
+
file?: PersonaArtifactFileMeta;
|
|
2902
|
+
/** Component artifacts: pretty-printed { component, props } JSON. */
|
|
2903
|
+
jsonPayload?: string;
|
|
2904
|
+
};
|
|
2905
|
+
/**
|
|
2906
|
+
* Context passed to a `features.artifacts.statusLabel` function on every
|
|
2907
|
+
* artifact streaming update, once per visible surface. Treat it as read-only:
|
|
2908
|
+
* the function should be pure and fast (it runs per streaming delta, per
|
|
2909
|
+
* surface).
|
|
2910
|
+
*/
|
|
2911
|
+
type PersonaArtifactStatusLabelContext = {
|
|
2912
|
+
artifactId: string;
|
|
2913
|
+
artifactType: "markdown" | "component";
|
|
2914
|
+
title?: string;
|
|
2915
|
+
/** The default subject, e.g. "document", "component", or a file type label like "HTML file". */
|
|
2916
|
+
typeLabel: string;
|
|
2917
|
+
file?: PersonaArtifactFileMeta;
|
|
2918
|
+
/** Accumulated streamed content length so far (0 for component artifacts). */
|
|
2919
|
+
chars: number;
|
|
2920
|
+
/** Accumulated line count so far (0 for component artifacts). */
|
|
2921
|
+
lines: number;
|
|
2922
|
+
/** Milliseconds since this artifact's first streaming update was seen. */
|
|
2923
|
+
elapsedMs: number;
|
|
2924
|
+
/** Lazy accessor for the accumulated markdown source (empty string for component artifacts). Call only if needed; parsing cost is opt-in. */
|
|
2925
|
+
content: () => string;
|
|
2926
|
+
/** Which surface is asking, so hosts can shorten for cramped spots. */
|
|
2927
|
+
surface: "card" | "inline-chrome" | "status-body";
|
|
2928
|
+
};
|
|
2929
|
+
/** A custom action button rendered in an artifact toolbar/card slot. */
|
|
2930
|
+
type PersonaArtifactCustomAction = {
|
|
2931
|
+
/** Stable id, used for DOM wiring and keyed re-renders. */
|
|
2932
|
+
id: string;
|
|
2933
|
+
/** Accessible label; also the visible text when showLabel is true. */
|
|
2934
|
+
label: string;
|
|
2935
|
+
/** Registry icon name, or a factory returning your own element (e.g. a brand SVG). The factory result is author-owned code, not sanitized wire data. */
|
|
2936
|
+
icon?: IconName | (() => HTMLElement | SVGElement);
|
|
2937
|
+
/** Render icon + text instead of icon-only. Default: false. */
|
|
2938
|
+
showLabel?: boolean;
|
|
2939
|
+
/** Per-artifact gate, evaluated on each render. Omitted = always visible. */
|
|
2940
|
+
visible?: (ctx: PersonaArtifactActionContext) => boolean;
|
|
2941
|
+
/** May be async; rejections are swallowed like built-in action errors. */
|
|
2942
|
+
onClick: (ctx: PersonaArtifactActionContext) => void | Promise<void>;
|
|
2943
|
+
};
|
|
2151
2944
|
type AgentWidgetArtifactsFeature = {
|
|
2152
2945
|
/** When true, Persona shows the artifact pane and handles artifact_* SSE events */
|
|
2153
2946
|
enabled?: boolean;
|
|
2154
2947
|
/** If set, artifact events for other types are ignored */
|
|
2155
2948
|
allowedTypes?: PersonaArtifactKind[];
|
|
2949
|
+
/**
|
|
2950
|
+
* Where artifact bodies render. A single mode applies to all artifacts;
|
|
2951
|
+
* the object form sets a default plus per-type overrides.
|
|
2952
|
+
* Defaults to "panel" (current behavior).
|
|
2953
|
+
*/
|
|
2954
|
+
display?: PersonaArtifactDisplayMode | {
|
|
2955
|
+
default?: PersonaArtifactDisplayMode;
|
|
2956
|
+
byType?: Partial<Record<PersonaArtifactKind, PersonaArtifactDisplayMode>>;
|
|
2957
|
+
};
|
|
2156
2958
|
/** Split / drawer dimensions and launcher widen behavior */
|
|
2157
2959
|
layout?: AgentWidgetArtifactsLayoutConfig;
|
|
2158
2960
|
/**
|
|
2159
|
-
*
|
|
2160
|
-
*
|
|
2961
|
+
* Controls inline preview of previewable file artifacts (HTML/SVG written by
|
|
2962
|
+
* a Claude Managed agent). When a markdown artifact carries `file` metadata,
|
|
2963
|
+
* the pane can render an isolated `<iframe srcdoc>` sandbox instead of a code
|
|
2964
|
+
* block.
|
|
2965
|
+
*/
|
|
2966
|
+
filePreview?: {
|
|
2967
|
+
/** Enable rendered preview for html/svg files. Defaults to enabled. Set false to force source view. */
|
|
2968
|
+
enabled?: boolean;
|
|
2969
|
+
/**
|
|
2970
|
+
* `sandbox` attribute for the preview iframe. Defaults to `"allow-scripts"`.
|
|
2971
|
+
* `allow-same-origin` is stripped (with a console warning) unless
|
|
2972
|
+
* `dangerouslyAllowSameOrigin` is set: the opaque origin is what isolates
|
|
2973
|
+
* the preview from the host page. Embedder-trusted config.
|
|
2974
|
+
*/
|
|
2975
|
+
iframeSandbox?: string;
|
|
2976
|
+
/**
|
|
2977
|
+
* Allows `allow-same-origin` to pass through `iframeSandbox`. Off by
|
|
2978
|
+
* default because it lets agent-written file content run with the host
|
|
2979
|
+
* page's origin (DOM, storage, credentialed requests). Only set this when
|
|
2980
|
+
* every previewed file source is fully trusted.
|
|
2981
|
+
*/
|
|
2982
|
+
dangerouslyAllowSameOrigin?: boolean;
|
|
2983
|
+
/**
|
|
2984
|
+
* Loading treatment for the preview iframe. Default on.
|
|
2985
|
+
*
|
|
2986
|
+
* A sandboxed `iframe srcdoc` (opaque origin, `allow-scripts` only) paints
|
|
2987
|
+
* blank until its content renders — seconds for artifacts that pull CDN
|
|
2988
|
+
* scripts (React/Babel). The default shows a themed "Loading preview…"
|
|
2989
|
+
* overlay over the iframe, dismissed the instant the content signals it has
|
|
2990
|
+
* painted (an injected `postMessage` reporter) or a hard timeout elapses.
|
|
2991
|
+
*
|
|
2992
|
+
* `false` disables the overlay and the injected ready signal entirely (the
|
|
2993
|
+
* srcdoc becomes the raw file source, the prior behavior). An object tunes
|
|
2994
|
+
* the timing; omitted / `true` uses all defaults.
|
|
2995
|
+
*/
|
|
2996
|
+
loading?: boolean | {
|
|
2997
|
+
/** Show the overlay only if the preview is not ready after this many ms. Default 200. */
|
|
2998
|
+
delayMs?: number;
|
|
2999
|
+
/** Once shown, keep the overlay visible at least this long (anti-flicker). Default 300. */
|
|
3000
|
+
minVisibleMs?: number;
|
|
3001
|
+
/** Give up waiting and reveal the iframe regardless after this many ms. Default 8000. */
|
|
3002
|
+
timeoutMs?: number;
|
|
3003
|
+
/**
|
|
3004
|
+
* Append the `postMessage` ready reporter to the srcdoc so the overlay
|
|
3005
|
+
* dismisses on first paint rather than the iframe `load` event (which
|
|
3006
|
+
* fires before post-DOMContentLoaded rendering like Babel compilation).
|
|
3007
|
+
* Default true. When false, the overlay dismisses on `load` + a double
|
|
3008
|
+
* `requestAnimationFrame`, or the timeout.
|
|
3009
|
+
*/
|
|
3010
|
+
injectReadySignal?: boolean;
|
|
3011
|
+
/**
|
|
3012
|
+
* Escalation text shown beside the spinner after `labelDelayMs`.
|
|
3013
|
+
* Default `"Starting preview..."`. `false` renders an icon-only
|
|
3014
|
+
* indicator forever (no text ever). A short work-naming label is
|
|
3015
|
+
* added only after a delay by design — icon-first, with text reserved
|
|
3016
|
+
* for genuinely slow loads (per Geist/Sandpack guidance; HIG warns
|
|
3017
|
+
* against the vague word "loading").
|
|
3018
|
+
*/
|
|
3019
|
+
label?: string | false;
|
|
3020
|
+
/**
|
|
3021
|
+
* Delay before the escalation label fades in, measured from when the
|
|
3022
|
+
* overlay actually becomes visible (i.e. after `delayMs`), not from
|
|
3023
|
+
* iframe creation. Default 2000.
|
|
3024
|
+
*/
|
|
3025
|
+
labelDelayMs?: number;
|
|
3026
|
+
/**
|
|
3027
|
+
* Full replacement for the default indicator (spinner + escalation
|
|
3028
|
+
* label). Called once when the overlay is built; return any element
|
|
3029
|
+
* (a brand mark, skeleton, custom animation) to own the indicator
|
|
3030
|
+
* content entirely (the escalation-label logic is then skipped), or
|
|
3031
|
+
* return `null` to fall back to the default. A thrown error also falls
|
|
3032
|
+
* back. Mirrors `renderInline` / `renderCard`'s null-falls-back
|
|
3033
|
+
* contract. The overlay backdrop, timing, and dismissal stay
|
|
3034
|
+
* widget-owned either way.
|
|
3035
|
+
*/
|
|
3036
|
+
renderIndicator?: (ctx: {
|
|
3037
|
+
artifactId: string;
|
|
3038
|
+
config: AgentWidgetConfig;
|
|
3039
|
+
}) => HTMLElement | null;
|
|
3040
|
+
};
|
|
3041
|
+
};
|
|
3042
|
+
/**
|
|
3043
|
+
* Custom action buttons for the artifact pane toolbar, rendered between the
|
|
3044
|
+
* refresh and expand/close controls in both toolbar presets. Re-read on live
|
|
3045
|
+
* config updates.
|
|
3046
|
+
*/
|
|
3047
|
+
toolbarActions?: PersonaArtifactCustomAction[];
|
|
3048
|
+
/**
|
|
3049
|
+
* Custom action buttons for the artifact reference card, rendered before the
|
|
3050
|
+
* Download button on complete artifacts. Clicks are delegated, so they
|
|
3051
|
+
* survive re-renders and page refresh.
|
|
3052
|
+
*/
|
|
3053
|
+
cardActions?: PersonaArtifactCustomAction[];
|
|
3054
|
+
/**
|
|
3055
|
+
* File chrome (title bar + toolbar) around inline preview blocks
|
|
3056
|
+
* (`display: "inline"`). Default when undefined: chrome on, with the built-in
|
|
3057
|
+
* Copy and Expand controls. Pass `false` to render the bare preview body
|
|
3058
|
+
* (frame → padded body, no chrome bar), or an object to toggle the built-in
|
|
3059
|
+
* controls individually.
|
|
3060
|
+
*
|
|
3061
|
+
* Note: default-on chrome adds a title bar and buttons to every existing
|
|
3062
|
+
* inline host on upgrade; set `inlineChrome: false` to opt out.
|
|
3063
|
+
*/
|
|
3064
|
+
inlineChrome?: boolean | {
|
|
3065
|
+
/** Show the built-in Copy button (complete artifacts only). Default true. */
|
|
3066
|
+
showCopy?: boolean;
|
|
3067
|
+
/** Show the built-in Expand button (opens the pane for this artifact). Default true. */
|
|
3068
|
+
showExpand?: boolean;
|
|
3069
|
+
/**
|
|
3070
|
+
* Show the built-in rendered/source view toggle (complete artifacts
|
|
3071
|
+
* only). Default true. The toggle is availability-gated: it appears only
|
|
3072
|
+
* for file-backed markdown artifacts that have a rendered alternative to
|
|
3073
|
+
* their source (previewable HTML/SVG, or markdown-kind files), and never
|
|
3074
|
+
* when `inlineBody.viewMode: "source"` forces a source-only body. Plain
|
|
3075
|
+
* markdown and component artifacts don't get it (the pane toggle covers
|
|
3076
|
+
* those).
|
|
3077
|
+
*/
|
|
3078
|
+
showViewToggle?: boolean;
|
|
3079
|
+
};
|
|
3080
|
+
/**
|
|
3081
|
+
* Custom action buttons for the inline chrome toolbar, rendered before the
|
|
3082
|
+
* built-in Copy/Expand controls on complete artifacts. Same shape as
|
|
3083
|
+
* `cardActions`; each action's `visible` gate is respected and clicks are
|
|
3084
|
+
* delegated, so they survive re-renders and page refresh.
|
|
3085
|
+
*/
|
|
3086
|
+
inlineActions?: PersonaArtifactCustomAction[];
|
|
3087
|
+
/**
|
|
3088
|
+
* Replace the artifact tab strip entirely (Seam A). Return an element mounted in
|
|
3089
|
+
* place of the built-in `.persona-artifact-list`; the pane still owns the toolbar,
|
|
3090
|
+
* preview body, iframe reuse, and lazy-render gate. Re-invoked when the records or
|
|
3091
|
+
* selection change. Custom bars own their own accessibility; use `createRovingTablist`
|
|
3092
|
+
* to keep keyboard/tablist behavior. When set, the built-in strip (scroll, fade,
|
|
3093
|
+
* tablist) is not rendered.
|
|
3094
|
+
*
|
|
3095
|
+
* Return either a fresh element per call, or the SAME element updated in place.
|
|
3096
|
+
* Returning a stable element preserves internal state across selection changes:
|
|
3097
|
+
* the pane skips remounting an unchanged node, so a roving tablist keeps keyboard
|
|
3098
|
+
* focus on the selected tab (a fresh element per call drops focus and breaks
|
|
3099
|
+
* Arrow-key nav). See the reference bars in `apps/web/src/artifact-demo.ts`.
|
|
3100
|
+
*/
|
|
3101
|
+
renderTabBar?: (ctx: {
|
|
3102
|
+
records: PersonaArtifactRecord[];
|
|
3103
|
+
selectedId: string | null;
|
|
3104
|
+
onSelect: (id: string) => void;
|
|
3105
|
+
}) => HTMLElement;
|
|
3106
|
+
/**
|
|
3107
|
+
* Body layout for inline artifact blocks (`display: "inline"`). Controls how
|
|
3108
|
+
* the block reserves height and behaves while a file/document artifact
|
|
3109
|
+
* streams, so the streaming source no longer grows an unbounded `<pre>` and
|
|
3110
|
+
* then snaps to the completed preview. Affects only the inline block; the
|
|
3111
|
+
* artifact pane is unchanged.
|
|
3112
|
+
*
|
|
3113
|
+
* Defaults (a behavior change from prior versions, which grew with content
|
|
3114
|
+
* during streaming): a fixed 320px streaming source window with tail-follow,
|
|
3115
|
+
* a top edge fade, and an animated streaming→complete swap. Pass
|
|
3116
|
+
* `height: "auto"` to restore the old grow-with-content streaming behavior.
|
|
3117
|
+
*/
|
|
3118
|
+
inlineBody?: {
|
|
3119
|
+
/** What the body shows while streaming. Default `"source"`. */
|
|
3120
|
+
streamingView?: "source" | "status";
|
|
3121
|
+
/**
|
|
3122
|
+
* How the completed body renders. `"rendered"` (default) keeps the current
|
|
3123
|
+
* behavior: file previews in a sandboxed iframe, markdown through the
|
|
3124
|
+
* markdown pipeline. `"source"` always shows the raw syntax-highlighted
|
|
3125
|
+
* source instead — for hosts where the artifact is input to the host system
|
|
3126
|
+
* (a code editor, a query runner) rather than something to preview. Unlike
|
|
3127
|
+
* `filePreview.enabled: false`, this also covers markdown-kind files and
|
|
3128
|
+
* plain markdown artifacts. Component artifacts always render through the
|
|
3129
|
+
* registry.
|
|
3130
|
+
*/
|
|
3131
|
+
viewMode?: "rendered" | "source";
|
|
3132
|
+
/**
|
|
3133
|
+
* Body height per state. A number reserves that many px for the whole body
|
|
3134
|
+
* region (border-box, padding included) with internal scroll — the
|
|
3135
|
+
* zero-layout-shift path; `"auto"` means content-sized. A
|
|
3136
|
+
* scalar applies to both the streaming and complete states; the object form
|
|
3137
|
+
* sets them independently. Default `320` for both states.
|
|
3138
|
+
*
|
|
3139
|
+
* Note: with `"auto"` on the complete state, non-iframe bodies (rendered
|
|
3140
|
+
* markdown, source view, component) are content-sized, but a file-preview
|
|
3141
|
+
* iframe cannot be content-sized without postMessage plumbing, so it falls
|
|
3142
|
+
* back to the CSS-var default (`--persona-artifact-inline-frame-height`,
|
|
3143
|
+
* 320px).
|
|
3144
|
+
*
|
|
3145
|
+
* Numeric heights are applied via the CSS var
|
|
3146
|
+
* `--persona-artifact-inline-body-height` on the block root. The older
|
|
3147
|
+
* `--persona-artifact-inline-frame-height` var still overrides the iframe
|
|
3148
|
+
* height when this one is unset, so themes pinned to it keep working.
|
|
3149
|
+
*/
|
|
3150
|
+
height?: number | "auto" | {
|
|
3151
|
+
streaming?: number | "auto";
|
|
3152
|
+
complete?: number | "auto";
|
|
3153
|
+
};
|
|
3154
|
+
/**
|
|
3155
|
+
* Tail-follow the newest streamed lines in a fixed-height source window: if
|
|
3156
|
+
* the viewport is already at the bottom, keep it pinned as content arrives;
|
|
3157
|
+
* if the reader scrolled up, don't fight them. Only meaningful for a numeric
|
|
3158
|
+
* streaming height. Default `true`.
|
|
3159
|
+
*
|
|
3160
|
+
* Precedence: ignored when `overflow: "clip"` (a clipped window shows the
|
|
3161
|
+
* top of the document and never scrolls, so there is no tail to follow).
|
|
3162
|
+
*/
|
|
3163
|
+
followOutput?: boolean;
|
|
3164
|
+
/**
|
|
3165
|
+
* How a fixed-height source window handles content taller than the window.
|
|
3166
|
+
*
|
|
3167
|
+
* - `"scroll"` (default) — the current behavior: an internally scrollable
|
|
3168
|
+
* window that tail-follows the newest streamed lines (see `followOutput`),
|
|
3169
|
+
* so the reader sees the growing tail of the document.
|
|
3170
|
+
* - `"clip"` — a fixed-height window that shows the TOP of the document,
|
|
3171
|
+
* `overflow: hidden` with no internal scroll and no tail-follow
|
|
3172
|
+
* (`followOutput` is ignored in this mode). When content overflows the
|
|
3173
|
+
* window a bottom edge fade signals there is more below (the top is always
|
|
3174
|
+
* visible, so a top fade never applies); an explicit `fadeMask` still wins
|
|
3175
|
+
* over this clip-mode default. When the inline chrome's Expand control is
|
|
3176
|
+
* enabled the whole body doubles as an expand hitbox (click / Enter / Space
|
|
3177
|
+
* opens the artifact in the pane), matching the industry inline-card
|
|
3178
|
+
* pattern; otherwise the clip is purely visual.
|
|
3179
|
+
*
|
|
3180
|
+
* Only meaningful for a numeric streaming/complete height. Default
|
|
3181
|
+
* `"scroll"`.
|
|
3182
|
+
*/
|
|
3183
|
+
overflow?: "scroll" | "clip";
|
|
3184
|
+
/**
|
|
3185
|
+
* Edge fade masks on the fixed-height streaming window (a top fade signals
|
|
3186
|
+
* clipped content above, a bottom fade signals clipped content below). Each
|
|
3187
|
+
* fade renders only when content is actually clipped on that edge, so with
|
|
3188
|
+
* tail-follow pinned at the bottom the bottom fade stays inert until the
|
|
3189
|
+
* reader scrolls up mid-stream. `true` = `{ top: true, bottom: true }`,
|
|
3190
|
+
* `false` = none. Default `{ top: true, bottom: true }`.
|
|
3191
|
+
*/
|
|
3192
|
+
fadeMask?: boolean | {
|
|
3193
|
+
top?: boolean;
|
|
3194
|
+
bottom?: boolean;
|
|
3195
|
+
};
|
|
3196
|
+
/**
|
|
3197
|
+
* Animate the streaming→complete body swap. `"auto"` uses the View
|
|
3198
|
+
* Transitions API when supported and `prefers-reduced-motion` is off;
|
|
3199
|
+
* `"none"` swaps instantly. Default `"auto"`.
|
|
3200
|
+
*/
|
|
3201
|
+
transition?: "auto" | "none";
|
|
3202
|
+
/**
|
|
3203
|
+
* What the block becomes once the artifact completes.
|
|
3204
|
+
*
|
|
3205
|
+
* - `"inline"` (default) — the streamed body stays inline forever, as
|
|
3206
|
+
* configured by the other `inlineBody` options.
|
|
3207
|
+
* - `"card"` — the block streams inline as configured, then collapses to the
|
|
3208
|
+
* compact artifact reference card once the artifact completes (the Copilot
|
|
3209
|
+
* "chiclet" / Claude side-panel handoff pattern), keeping the thread
|
|
3210
|
+
* scannable. The collapse plays as a short CSS height transition (skipped
|
|
3211
|
+
* under `prefers-reduced-motion`); it does not use the View Transitions
|
|
3212
|
+
* API, so `transition` does not affect it. After the collapse the card's
|
|
3213
|
+
* normal actions apply (click opens the artifact pane). `viewMode`, the
|
|
3214
|
+
* inline rendered/source view toggle, `inlineActions`, and inline copy are
|
|
3215
|
+
* streaming-phase-only in this mode and inert once the block is a card
|
|
3216
|
+
* (there is nothing to toggle or copy on a collapsed card). Blocks that are
|
|
3217
|
+
* already complete when they first render (page-refresh hydration) render
|
|
3218
|
+
* the card directly, with no flash of the inline body and no animation.
|
|
3219
|
+
*
|
|
3220
|
+
* Default `"inline"`.
|
|
3221
|
+
*/
|
|
3222
|
+
completeDisplay?: "inline" | "card";
|
|
3223
|
+
};
|
|
3224
|
+
/**
|
|
3225
|
+
* Called when an artifact action is triggered (open, download, expand).
|
|
3226
|
+
* Return `true` to intercept: the widget then does not change state.
|
|
3227
|
+
* For `expand`, `expanded` is the state the toggle is about to enter and
|
|
3228
|
+
* `artifactId` is the currently selected artifact (or `null` when none).
|
|
2161
3229
|
*/
|
|
2162
3230
|
onArtifactAction?: (action: {
|
|
2163
3231
|
type: 'open' | 'download';
|
|
2164
3232
|
artifactId: string;
|
|
3233
|
+
} | {
|
|
3234
|
+
type: 'expand';
|
|
3235
|
+
artifactId: string | null;
|
|
3236
|
+
expanded: boolean;
|
|
2165
3237
|
}) => boolean | void;
|
|
2166
3238
|
/**
|
|
2167
3239
|
* Custom renderer for artifact reference cards shown in the message thread.
|
|
@@ -2177,6 +3249,72 @@ type AgentWidgetArtifactsFeature = {
|
|
|
2177
3249
|
config: AgentWidgetConfig;
|
|
2178
3250
|
defaultRenderer: () => HTMLElement;
|
|
2179
3251
|
}) => HTMLElement | null;
|
|
3252
|
+
/**
|
|
3253
|
+
* Custom renderer for inline artifact blocks (display: "inline"), mirroring
|
|
3254
|
+
* `renderCard`. Return an element to replace the default inline preview,
|
|
3255
|
+
* or null to use the default.
|
|
3256
|
+
*/
|
|
3257
|
+
renderInline?: (context: {
|
|
3258
|
+
artifact: {
|
|
3259
|
+
artifactId: string;
|
|
3260
|
+
title: string;
|
|
3261
|
+
artifactType: string;
|
|
3262
|
+
status: string;
|
|
3263
|
+
};
|
|
3264
|
+
config: AgentWidgetConfig;
|
|
3265
|
+
defaultRenderer: () => HTMLElement;
|
|
3266
|
+
}) => HTMLElement | null;
|
|
3267
|
+
/**
|
|
3268
|
+
* Text shown while an artifact streams, in place of the default
|
|
3269
|
+
* `Generating <type>...` status. Applies to every streaming surface: the
|
|
3270
|
+
* reference card status line, the inline chrome meta label, and the inline
|
|
3271
|
+
* streaming status body (`inlineBody.streamingView: "status"`).
|
|
3272
|
+
*
|
|
3273
|
+
* - A plain string replaces the default label everywhere (localization or
|
|
3274
|
+
* brand voice).
|
|
3275
|
+
* - A function is called on every artifact update for each visible surface;
|
|
3276
|
+
* it must be pure and fast. Returning a string sets the animated label
|
|
3277
|
+
* only. Returning `{ label, detail }` splits the status into an animated
|
|
3278
|
+
* label (re-applied only when its text changes, so the loading animation
|
|
3279
|
+
* stays stable) and a plain un-animated detail span that may update freely
|
|
3280
|
+
* per delta (live counters).
|
|
3281
|
+
*
|
|
3282
|
+
* Default when unset: the current behavior, `Generating <type>...` with no
|
|
3283
|
+
* detail. If the function throws, the default label is used for that update
|
|
3284
|
+
* (a bad host callback must never break rendering). There is deliberately no
|
|
3285
|
+
* percent progress: streams do not announce total length, so counts and
|
|
3286
|
+
* elapsed time are the only truthful signals.
|
|
3287
|
+
*/
|
|
3288
|
+
statusLabel?: string | ((ctx: PersonaArtifactStatusLabelContext) => string | {
|
|
3289
|
+
label: string;
|
|
3290
|
+
detail?: string;
|
|
3291
|
+
});
|
|
3292
|
+
/**
|
|
3293
|
+
* Animation applied to the artifact card's "Generating …" status text while
|
|
3294
|
+
* the artifact streams. Character-by-character modes (`shimmer`,
|
|
3295
|
+
* `shimmer-color`, `rainbow`) wrap each character in a span with a staggered
|
|
3296
|
+
* `animation-delay`; `pulse` fades the whole status text; `none` disables the
|
|
3297
|
+
* animation. Honors `prefers-reduced-motion`.
|
|
3298
|
+
* @default "shimmer"
|
|
3299
|
+
*/
|
|
3300
|
+
loadingAnimation?: AgentWidgetToolCallLoadingAnimation;
|
|
3301
|
+
/**
|
|
3302
|
+
* Duration of one full animation cycle in milliseconds.
|
|
3303
|
+
* Applies to pulse, shimmer, shimmer-color, and rainbow modes.
|
|
3304
|
+
* @default 2000
|
|
3305
|
+
*/
|
|
3306
|
+
loadingAnimationDuration?: number;
|
|
3307
|
+
/**
|
|
3308
|
+
* Primary color for shimmer-color animation mode.
|
|
3309
|
+
* Defaults to the current text color.
|
|
3310
|
+
*/
|
|
3311
|
+
loadingAnimationColor?: string;
|
|
3312
|
+
/**
|
|
3313
|
+
* Secondary/end color for shimmer-color animation mode.
|
|
3314
|
+
* Creates a gradient sweep between `loadingAnimationColor` and this color.
|
|
3315
|
+
* @default "#3b82f6"
|
|
3316
|
+
*/
|
|
3317
|
+
loadingAnimationSecondaryColor?: string;
|
|
2180
3318
|
};
|
|
2181
3319
|
/**
|
|
2182
3320
|
* How the transcript scrolls while an assistant response streams in.
|
|
@@ -2304,6 +3442,13 @@ type AgentWidgetToolCallDisplayFeature = {
|
|
|
2304
3442
|
* @default false
|
|
2305
3443
|
*/
|
|
2306
3444
|
grouped?: boolean;
|
|
3445
|
+
/**
|
|
3446
|
+
* Controls how a grouped tool sequence is rendered.
|
|
3447
|
+
* - `"stack"`: show the group summary and each child tool row.
|
|
3448
|
+
* - `"summary"`: show one consolidated summary row only.
|
|
3449
|
+
* @default "stack"
|
|
3450
|
+
*/
|
|
3451
|
+
groupedMode?: "stack" | "summary";
|
|
2307
3452
|
/**
|
|
2308
3453
|
* When false, tool call bubbles show only the collapsed summary with no
|
|
2309
3454
|
* expand/collapse toggle. Users see tool awareness without full details.
|
|
@@ -2993,6 +4138,24 @@ type AgentWidgetLauncherConfig = {
|
|
|
2993
4138
|
* @default false
|
|
2994
4139
|
*/
|
|
2995
4140
|
sidebarMode?: boolean;
|
|
4141
|
+
/**
|
|
4142
|
+
* When true, the widget panel renders as a detached card inset within its region,
|
|
4143
|
+
* with rounded corners on all sides and elevation (shadow plus hairline border),
|
|
4144
|
+
* instead of sitting flush against the region edges.
|
|
4145
|
+
*
|
|
4146
|
+
* The gap around the card is themed via `theme.components.panel.inset`. The
|
|
4147
|
+
* background revealed behind it is themed via `theme.components.panel.canvasBackground`
|
|
4148
|
+
* in docked and inline embed modes. In sidebar mode the gap stays click-through, so the
|
|
4149
|
+
* host page shows through it the same way it does in floating mode, and canvasBackground
|
|
4150
|
+
* is a no-op there.
|
|
4151
|
+
*
|
|
4152
|
+
* Applies to sidebar, docked, and inline embed modes. Ignored in mobile fullscreen,
|
|
4153
|
+
* where chrome is already suppressed. Floating mode is unchanged, since it already
|
|
4154
|
+
* renders as a detached card.
|
|
4155
|
+
*
|
|
4156
|
+
* @default false
|
|
4157
|
+
*/
|
|
4158
|
+
detachedPanel?: boolean;
|
|
2996
4159
|
/**
|
|
2997
4160
|
* Width of the sidebar panel when sidebarMode is true.
|
|
2998
4161
|
* @default "420px"
|
|
@@ -5036,6 +6199,18 @@ type AgentWidgetConfig = {
|
|
|
5036
6199
|
}) => string;
|
|
5037
6200
|
plugins?: AgentWidgetPlugin[];
|
|
5038
6201
|
contextProviders?: AgentWidgetContextProvider[];
|
|
6202
|
+
/**
|
|
6203
|
+
* Context mentions: let users explicitly pull external context into a turn by
|
|
6204
|
+
* typing `@` or clicking a visible composer button, both opening one shared
|
|
6205
|
+
* searchable menu of host-provided sources. Selecting a mention adds a
|
|
6206
|
+
* removable pill chip; resolved content reaches the model via `llmAppend`
|
|
6207
|
+
* (default) or the opt-in structured `context` channel.
|
|
6208
|
+
*
|
|
6209
|
+
* Disabled by default. When enabled, the mention runtime is lazy-loaded from a
|
|
6210
|
+
* sibling chunk on first use, so sites that leave it off pay no bundle cost.
|
|
6211
|
+
* See `docs/context-mentions-plan.md`.
|
|
6212
|
+
*/
|
|
6213
|
+
contextMentions?: AgentWidgetContextMentionConfig;
|
|
5039
6214
|
requestMiddleware?: AgentWidgetRequestMiddleware;
|
|
5040
6215
|
actionParsers?: AgentWidgetActionParser[];
|
|
5041
6216
|
actionHandlers?: AgentWidgetActionHandler[];
|
|
@@ -5578,6 +6753,25 @@ type AgentWidgetMessage = {
|
|
|
5578
6753
|
* The `content` field contains the text-only representation for display.
|
|
5579
6754
|
*/
|
|
5580
6755
|
contentParts?: ContentPart[];
|
|
6756
|
+
/**
|
|
6757
|
+
* Context mentions attached to this (user) message, for transcript fidelity +
|
|
6758
|
+
* chip rendering in the sent bubble. Refs only — the resolved payloads are
|
|
6759
|
+
* merged into `llmContent`/`contentParts` (model-visible) at send time.
|
|
6760
|
+
*/
|
|
6761
|
+
contextMentions?: AgentWidgetContextMentionRef[];
|
|
6762
|
+
/**
|
|
6763
|
+
* Ordered prose + mention blocks for inline-mode rendering and composer history
|
|
6764
|
+
* recall (`contextMentions.display: "inline"`). Present only on inline-mode user
|
|
6765
|
+
* messages; when omitted the sent bubble falls back to the chip row derived from
|
|
6766
|
+
* `contextMentions`. Display/transcript concern only — not the model channel.
|
|
6767
|
+
*/
|
|
6768
|
+
contentSegments?: AgentWidgetContentSegment[];
|
|
6769
|
+
/**
|
|
6770
|
+
* Resolved opt-in structured mention context for this (user) message, merged
|
|
6771
|
+
* into the request `context` under `mentions.<sourceId>.<itemId>` by the
|
|
6772
|
+
* client. Internal: set at send time from each source's `resolve().context`.
|
|
6773
|
+
*/
|
|
6774
|
+
mentionContext?: Record<string, unknown>;
|
|
5581
6775
|
streaming?: boolean;
|
|
5582
6776
|
variant?: AgentWidgetMessageVariant;
|
|
5583
6777
|
sequence?: number;
|
|
@@ -5798,6 +6992,21 @@ type InjectComponentDirectiveOptions = {
|
|
|
5798
6992
|
*/
|
|
5799
6993
|
sequence?: number;
|
|
5800
6994
|
};
|
|
6995
|
+
/**
|
|
6996
|
+
* Optional file metadata attached to a markdown artifact that represents a
|
|
6997
|
+
* concrete file written by a Claude Managed agent (e.g. `/mnt/session/outputs/cat.html`).
|
|
6998
|
+
* Additive: the artifact content stays a fenced code block on the wire for
|
|
6999
|
+
* backward compatibility; new widgets use this to recover the raw source and
|
|
7000
|
+
* offer a preview. Mirrors the `file` field on the core `artifact_start` event.
|
|
7001
|
+
*/
|
|
7002
|
+
type PersonaArtifactFileMeta = {
|
|
7003
|
+
/** Full path of the written file (also used as the artifact title). */
|
|
7004
|
+
path: string;
|
|
7005
|
+
/** MIME type of the file (used for download and preview decisions). */
|
|
7006
|
+
mimeType: string;
|
|
7007
|
+
/** Fence language the content was encoded with (html/xml/md/text). */
|
|
7008
|
+
language?: string;
|
|
7009
|
+
};
|
|
5801
7010
|
type PersonaArtifactRecord = {
|
|
5802
7011
|
id: string;
|
|
5803
7012
|
artifactType: PersonaArtifactKind;
|
|
@@ -5806,6 +7015,8 @@ type PersonaArtifactRecord = {
|
|
|
5806
7015
|
markdown?: string;
|
|
5807
7016
|
component?: string;
|
|
5808
7017
|
props?: Record<string, unknown>;
|
|
7018
|
+
/** Present when this markdown artifact is a previewable file (see PersonaArtifactFileMeta). */
|
|
7019
|
+
file?: PersonaArtifactFileMeta;
|
|
5809
7020
|
};
|
|
5810
7021
|
/** Programmatic artifact upsert (controller / window API) */
|
|
5811
7022
|
type PersonaArtifactManualUpsert = {
|
|
@@ -5813,12 +7024,18 @@ type PersonaArtifactManualUpsert = {
|
|
|
5813
7024
|
artifactType: "markdown";
|
|
5814
7025
|
title?: string;
|
|
5815
7026
|
content: string;
|
|
7027
|
+
/** Optional file metadata for previewable file artifacts. */
|
|
7028
|
+
file?: PersonaArtifactFileMeta;
|
|
7029
|
+
/** Set false to update the registry/pane without a transcript block (pre-4.x behavior). */
|
|
7030
|
+
transcript?: boolean;
|
|
5816
7031
|
} | {
|
|
5817
7032
|
id?: string;
|
|
5818
7033
|
artifactType: "component";
|
|
5819
7034
|
title?: string;
|
|
5820
7035
|
component: string;
|
|
5821
7036
|
props?: Record<string, unknown>;
|
|
7037
|
+
/** Set false to update the registry/pane without a transcript block (pre-4.x behavior). */
|
|
7038
|
+
transcript?: boolean;
|
|
5822
7039
|
};
|
|
5823
7040
|
type AgentWidgetEvent = {
|
|
5824
7041
|
type: "message";
|
|
@@ -5853,6 +7070,8 @@ type AgentWidgetEvent = {
|
|
|
5853
7070
|
artifactType: PersonaArtifactKind;
|
|
5854
7071
|
title?: string;
|
|
5855
7072
|
component?: string;
|
|
7073
|
+
/** Present when this markdown artifact is a previewable file. */
|
|
7074
|
+
file?: PersonaArtifactFileMeta;
|
|
5856
7075
|
} | {
|
|
5857
7076
|
type: "artifact_delta";
|
|
5858
7077
|
id: string;
|