@runtypelabs/persona 4.13.0 → 4.15.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 +4 -4
- package/dist/animations/glyph-cycle.d.cts +1 -1
- package/dist/animations/glyph-cycle.d.ts +1 -1
- package/dist/animations/{types-DveIaNx6.d.cts → types-BpWGm7_6.d.cts} +17 -0
- package/dist/animations/{types-DveIaNx6.d.ts → types-BpWGm7_6.d.ts} +17 -0
- package/dist/animations/wipe.d.cts +1 -1
- package/dist/animations/wipe.d.ts +1 -1
- package/dist/chunk-QJ4LV2KW.js +1 -0
- package/dist/codegen.cjs +12 -11
- package/dist/codegen.js +14 -13
- package/dist/{context-mentions-ONG7A7M6.js → context-mentions-BTSTIBFC.js} +1 -1
- package/dist/context-mentions.cjs +11 -8
- package/dist/context-mentions.d.cts +339 -22
- package/dist/context-mentions.d.ts +339 -22
- package/dist/context-mentions.js +11 -8
- package/dist/index.cjs +68 -67
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +483 -48
- package/dist/index.d.ts +483 -48
- package/dist/index.global.js +61 -58
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +70 -69
- package/dist/index.js.map +1 -1
- package/dist/launcher.global.js +5 -2
- package/dist/launcher.global.js.map +1 -1
- package/dist/smart-dom-reader.d.cts +339 -22
- package/dist/smart-dom-reader.d.ts +339 -22
- package/dist/theme-editor-preview.cjs +67 -67
- package/dist/theme-editor-preview.d.cts +355 -23
- package/dist/theme-editor-preview.d.ts +355 -23
- package/dist/theme-editor-preview.js +75 -75
- package/dist/theme-editor.cjs +10 -10
- package/dist/theme-editor.d.cts +376 -24
- package/dist/theme-editor.d.ts +376 -24
- package/dist/theme-editor.js +10 -10
- package/dist/theme-reference.cjs +1 -1
- package/dist/theme-reference.d.cts +38 -0
- package/dist/theme-reference.d.ts +38 -0
- package/dist/theme-reference.js +1 -1
- package/dist/widget.css +1 -1
- package/package.json +1 -1
- package/src/artifacts-session.test.ts +106 -0
- package/src/ask-user-question-tool.ts +10 -7
- package/src/client.test.ts +2 -2
- package/src/client.ts +4 -1
- package/src/components/artifact-card.ts +13 -2
- package/src/components/artifact-inline.ts +11 -2
- package/src/components/artifact-preview.ts +1 -1
- package/src/components/composer-builder.test.ts +2 -0
- package/src/components/composer-builder.ts +1 -1
- package/src/components/composer-parts.test.ts +105 -4
- package/src/components/composer-parts.ts +54 -16
- package/src/components/message-bubble.test.ts +7 -1
- package/src/components/message-bubble.ts +11 -8
- package/src/components/messages.ts +5 -2
- package/src/components/panel.ts +31 -5
- package/src/components/pill-composer-builder.test.ts +18 -0
- package/src/components/suggestions.test.ts +233 -0
- package/src/components/suggestions.ts +463 -81
- package/src/components/widget-view.ts +4 -0
- package/src/defaults.ts +5 -3
- package/src/generated/runtype-openapi-contract.ts +17 -0
- package/src/index-core.ts +52 -2
- package/src/launcher-global.ts +1 -1
- package/src/plugins/types.ts +71 -3
- package/src/presets.ts +3 -3
- package/src/session.ts +55 -12
- package/src/styles/widget-styles.test.ts +162 -0
- package/src/styles/widget.css +440 -1
- package/src/suggest-replies-tool.test.ts +233 -2
- package/src/suggest-replies-tool.ts +115 -39
- package/src/theme-editor/index.ts +5 -0
- package/src/theme-editor/presets.test.ts +43 -0
- package/src/theme-editor/presets.ts +101 -87
- package/src/theme-editor/preview-utils.test.ts +34 -0
- package/src/theme-editor/preview-utils.ts +77 -2
- package/src/theme-editor/sections.test.ts +72 -7
- package/src/theme-editor/sections.ts +113 -13
- package/src/theme-editor/state-preferences.test.ts +15 -0
- package/src/theme-editor/state.ts +46 -0
- package/src/theme-editor/types.ts +15 -1
- package/src/theme-editor/webmcp/tools.test.ts +13 -0
- package/src/theme-editor/webmcp/tools.ts +5 -0
- package/src/theme-reference.ts +9 -2
- package/src/types/theme.ts +32 -0
- package/src/types.ts +291 -25
- package/src/ui.artifact-pane-gating.test.ts +5 -5
- package/src/ui.config-preferences.test.ts +166 -0
- package/src/ui.detached-panel.test.ts +1 -1
- package/src/ui.suggest-replies.test.ts +1066 -1
- package/src/ui.ts +311 -45
- package/src/ui.typing-indicator.test.ts +135 -0
- package/src/utils/artifact-display.test.ts +180 -16
- package/src/utils/artifact-display.ts +155 -14
- package/src/utils/artifact-file.test.ts +1 -1
- package/src/utils/code-generators.test.ts +40 -0
- package/src/utils/code-generators.ts +22 -0
- package/src/utils/config-merge.test.ts +84 -0
- package/src/utils/config-merge.ts +6 -1
- package/src/utils/feature-preferences.test.ts +326 -0
- package/src/utils/feature-preferences.ts +498 -0
- package/src/utils/icons.test.ts +26 -0
- package/src/utils/icons.ts +8 -0
- package/src/utils/theme.test.ts +171 -0
- package/src/utils/tokens.ts +71 -7
- package/dist/chunk-MMUPR2JW.js +0 -1
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { ThemeEditorState } from "./state";
|
|
3
|
+
|
|
4
|
+
describe("ThemeEditorState preference reset", () => {
|
|
5
|
+
it("unsets a path and prunes empty parent objects", () => {
|
|
6
|
+
const state = new ThemeEditorState(undefined, {}, { mergeDefaults: false });
|
|
7
|
+
state.set("features.artifacts.display.files", "inline");
|
|
8
|
+
expect(state.get("features.artifacts.display.files")).toBe("inline");
|
|
9
|
+
|
|
10
|
+
state.unset("features.artifacts.display.files");
|
|
11
|
+
|
|
12
|
+
expect(state.get("features.artifacts.display.files")).toBeUndefined();
|
|
13
|
+
expect(state.getConfig()).not.toHaveProperty("features");
|
|
14
|
+
});
|
|
15
|
+
});
|
|
@@ -32,6 +32,30 @@ function setByPath(obj: unknown, path: string, value: unknown): unknown {
|
|
|
32
32
|
};
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
function unsetByPath(obj: unknown, path: string): unknown {
|
|
36
|
+
const parts = path.split('.');
|
|
37
|
+
if (parts.length === 1) {
|
|
38
|
+
const result = { ...(obj as Record<string, unknown>) };
|
|
39
|
+
delete result[parts[0]];
|
|
40
|
+
return result;
|
|
41
|
+
}
|
|
42
|
+
const [first, ...rest] = parts;
|
|
43
|
+
const current = obj as Record<string, unknown>;
|
|
44
|
+
const child = unsetByPath(current?.[first] ?? {}, rest.join('.'));
|
|
45
|
+
const result = { ...current };
|
|
46
|
+
if (
|
|
47
|
+
typeof child === 'object' &&
|
|
48
|
+
child !== null &&
|
|
49
|
+
!Array.isArray(child) &&
|
|
50
|
+
Object.keys(child as Record<string, unknown>).length === 0
|
|
51
|
+
) {
|
|
52
|
+
delete result[first];
|
|
53
|
+
} else {
|
|
54
|
+
result[first] = child;
|
|
55
|
+
}
|
|
56
|
+
return result;
|
|
57
|
+
}
|
|
58
|
+
|
|
35
59
|
// ─── ThemeEditorState ───────────────────────────────────────────
|
|
36
60
|
|
|
37
61
|
export class ThemeEditorState {
|
|
@@ -111,6 +135,28 @@ export class ThemeEditorState {
|
|
|
111
135
|
this.notifyListeners();
|
|
112
136
|
}
|
|
113
137
|
|
|
138
|
+
/** Delete a dot-path and prune empty parents so sparse preferences inherit. */
|
|
139
|
+
unset(path: string): void {
|
|
140
|
+
if (path.startsWith('theme.')) {
|
|
141
|
+
const themePath = path.replace('theme.', '');
|
|
142
|
+
this.theme = unsetByPath(this.theme, themePath) as PersonaTheme;
|
|
143
|
+
this.syncThemeIntoConfig();
|
|
144
|
+
} else if (path.startsWith('darkTheme.')) {
|
|
145
|
+
const themePath = path.replace('darkTheme.', '');
|
|
146
|
+
this.config = {
|
|
147
|
+
...this.config,
|
|
148
|
+
darkTheme: unsetByPath(
|
|
149
|
+
this.config.darkTheme ?? {},
|
|
150
|
+
themePath
|
|
151
|
+
) as AgentWidgetConfig['darkTheme'],
|
|
152
|
+
};
|
|
153
|
+
} else {
|
|
154
|
+
this.config = unsetByPath(this.config, path) as AgentWidgetConfig;
|
|
155
|
+
}
|
|
156
|
+
this.recordHistory();
|
|
157
|
+
this.notifyListeners();
|
|
158
|
+
}
|
|
159
|
+
|
|
114
160
|
/** Batch-set multiple paths at once */
|
|
115
161
|
setBatch(updates: Record<string, unknown>): void {
|
|
116
162
|
let themeChanged = false;
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
/** Field definition types for the declarative configurator system (headless: no DOM) */
|
|
2
2
|
|
|
3
3
|
import type { DeepPartial, PersonaTheme } from '../types/theme';
|
|
4
|
-
import type {
|
|
4
|
+
import type {
|
|
5
|
+
AgentWidgetConfig,
|
|
6
|
+
WidgetPreferenceCapabilities,
|
|
7
|
+
WidgetPreferenceSlice,
|
|
8
|
+
} from '../types';
|
|
5
9
|
|
|
6
10
|
// ─── Field System ────────────────────────────────────────────────
|
|
7
11
|
|
|
@@ -101,6 +105,12 @@ export interface FieldDef {
|
|
|
101
105
|
formatValue?: (value: unknown) => unknown;
|
|
102
106
|
/** Convert control input back into the stored value shape */
|
|
103
107
|
parseValue?: (value: unknown) => unknown;
|
|
108
|
+
/** Capability required for hosts to render this field. */
|
|
109
|
+
requiresCapability?: keyof WidgetPreferenceCapabilities;
|
|
110
|
+
/** The host may offer an inherit/reset action which deletes this path. */
|
|
111
|
+
unsettable?: boolean;
|
|
112
|
+
/** Label for the inherit/reset action. Default: "Use default". */
|
|
113
|
+
unsetLabel?: string;
|
|
104
114
|
}
|
|
105
115
|
|
|
106
116
|
export interface SectionDef {
|
|
@@ -112,6 +122,8 @@ export interface SectionDef {
|
|
|
112
122
|
collapsed?: boolean;
|
|
113
123
|
/** Preset buttons for this section */
|
|
114
124
|
presets?: SectionPreset[];
|
|
125
|
+
/** Capability required for hosts to render this section. */
|
|
126
|
+
requiresCapability?: keyof WidgetPreferenceCapabilities;
|
|
115
127
|
}
|
|
116
128
|
|
|
117
129
|
export interface SectionPreset {
|
|
@@ -149,6 +161,8 @@ export interface ThemeEditorPreset {
|
|
|
149
161
|
toolCall?: AgentWidgetToolCallConfig;
|
|
150
162
|
/** Tool call styling for dark mode (falls back to toolCall if not set) */
|
|
151
163
|
darkToolCall?: AgentWidgetToolCallConfig;
|
|
164
|
+
/** Sparse, persistable widget behavior layered separately from theme tokens. */
|
|
165
|
+
behavior?: WidgetPreferenceSlice;
|
|
152
166
|
preview: {
|
|
153
167
|
primary: string;
|
|
154
168
|
surface: string;
|
|
@@ -123,6 +123,19 @@ describe('createThemeEditorTools', () => {
|
|
|
123
123
|
);
|
|
124
124
|
});
|
|
125
125
|
|
|
126
|
+
it('apply_preset installs both Persona default slots with automatic scheme selection', async () => {
|
|
127
|
+
const out = await call(tools.get('apply_preset')!, { presetId: 'persona-default' });
|
|
128
|
+
|
|
129
|
+
expect(out.applied.appliedPreset.id).toBe('persona-default');
|
|
130
|
+
expect(state.get('colorScheme')).toBe('auto');
|
|
131
|
+
expect(state.get('theme.components.artifact.pane.background')).toBe(
|
|
132
|
+
'semantic.colors.container'
|
|
133
|
+
);
|
|
134
|
+
expect(state.get('darkTheme.semantic.colors.surface')).toBe(
|
|
135
|
+
'palette.colors.gray.800'
|
|
136
|
+
);
|
|
137
|
+
});
|
|
138
|
+
|
|
126
139
|
it('configure_widget writes config paths', async () => {
|
|
127
140
|
await call(tools.get('configure_widget')!, {
|
|
128
141
|
launcherPosition: 'bottom-left',
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
import { createTheme } from '../../utils/theme';
|
|
13
|
+
import { applyFeaturePreferences } from '../../utils/feature-preferences';
|
|
13
14
|
import type { AgentWidgetConfig } from '../../types';
|
|
14
15
|
import type { PersonaTheme } from '../../types/theme';
|
|
15
16
|
import { generateColorScale, SHADE_KEYS } from '../color-utils';
|
|
@@ -469,8 +470,12 @@ export function createThemeEditorTools(
|
|
|
469
470
|
const config: AgentWidgetConfig = { ...state.getConfig() };
|
|
470
471
|
if (preset.darkTheme) {
|
|
471
472
|
config.darkTheme = createTheme(preset.darkTheme, { validate: false }) as PersonaTheme;
|
|
473
|
+
config.colorScheme = 'auto';
|
|
472
474
|
}
|
|
473
475
|
if (preset.toolCall) config.toolCall = preset.toolCall;
|
|
476
|
+
if (preset.behavior) {
|
|
477
|
+
config.features = applyFeaturePreferences(config.features, [preset.behavior]);
|
|
478
|
+
}
|
|
474
479
|
state.setFullConfig(config, theme);
|
|
475
480
|
const warnings = quickContrastWarnings(state, ['body', 'assistant-message'], 'light');
|
|
476
481
|
return result({ appliedPreset: { id: preset.id, name: preset.name } }, warnings);
|
package/src/theme-reference.ts
CHANGED
|
@@ -142,7 +142,8 @@ export const THEME_TOKEN_DOCS = {
|
|
|
142
142
|
'Floating scroll-to-bottom affordance shared by transcript and event stream: background, foreground, border, size, borderRadius, shadow, padding, gap, fontSize, iconSize.',
|
|
143
143
|
toolBubble: 'shadow: tool call row box-shadow.',
|
|
144
144
|
reasoningBubble: 'shadow: reasoning/thinking row box-shadow.',
|
|
145
|
-
composer:
|
|
145
|
+
composer:
|
|
146
|
+
'Message input form: shadow (box-shadow), padding (form inset), gap (textarea row to actions row), fontSize and lineHeight (textarea type).',
|
|
146
147
|
artifact:
|
|
147
148
|
'toolbar (icon styling, copy menu), tab (background, active states), pane (background, toolbarBackground).',
|
|
148
149
|
},
|
|
@@ -245,8 +246,14 @@ export const THEME_TOKEN_DOCS = {
|
|
|
245
246
|
properties:
|
|
246
247
|
'enabled, provider ("browser" | "runtype"), browserFallback, voice, rate, pitch.',
|
|
247
248
|
},
|
|
249
|
+
suggestions: {
|
|
250
|
+
description:
|
|
251
|
+
'Rich starter and follow-up suggestion surfaces. Strings remain valid item shorthand.',
|
|
252
|
+
properties:
|
|
253
|
+
'starters.items, starters.variant ("card" | "chip" | "list"), starters.placement ("auto" | "welcome" | "composer"), starters.behavior ("send" | "fill"), starters.overflow ("scroll" | "wrap"), starters.maxItems, followUps.enabled, followUps.expose, followUps.variant, followUps.placement ("auto" | "after-message" | "composer"), followUps.behavior, followUps.overflow ("scroll" | "wrap"), followUps.maxItems.',
|
|
254
|
+
},
|
|
248
255
|
suggestionChips:
|
|
249
|
-
'string[]
|
|
256
|
+
'Deprecated string[] shorthand for starter prompts. Prefer suggestions.starters.items.',
|
|
250
257
|
messageActions: {
|
|
251
258
|
description: 'Message action buttons (copy, upvote, downvote).',
|
|
252
259
|
properties:
|
package/src/types/theme.ts
CHANGED
|
@@ -365,6 +365,14 @@ export interface ReasoningBubbleTokens {
|
|
|
365
365
|
export interface ComposerChromeTokens {
|
|
366
366
|
/** Box-shadow on the composer form (raw CSS, e.g. `none`). */
|
|
367
367
|
shadow: string;
|
|
368
|
+
/** Inner padding of the composer form (raw CSS shorthand). @default "0.75rem 1rem" */
|
|
369
|
+
padding?: string;
|
|
370
|
+
/** Gap between the textarea row and the actions row. @default "0.5rem" */
|
|
371
|
+
gap?: string;
|
|
372
|
+
/** Composer textarea font-size. @default "0.875rem" */
|
|
373
|
+
fontSize?: string;
|
|
374
|
+
/** Composer textarea line-height. @default "1.25rem" */
|
|
375
|
+
lineHeight?: string;
|
|
368
376
|
}
|
|
369
377
|
|
|
370
378
|
/** Artifact toolbar chrome. */
|
|
@@ -524,6 +532,28 @@ export interface ScrollToBottomTokens extends ComponentTokenSet {
|
|
|
524
532
|
iconSize?: string;
|
|
525
533
|
}
|
|
526
534
|
|
|
535
|
+
/** Visual tokens shared by one suggestion presentation variant. */
|
|
536
|
+
export interface SuggestionVariantTokens extends ComponentTokenSet {
|
|
537
|
+
gap?: string;
|
|
538
|
+
minHeight?: string;
|
|
539
|
+
fontSize?: string;
|
|
540
|
+
lineHeight?: string;
|
|
541
|
+
iconSize?: string;
|
|
542
|
+
hoverBackground?: TokenReference<'color'>;
|
|
543
|
+
hoverForeground?: TokenReference<'color'>;
|
|
544
|
+
hoverBorder?: TokenReference<'color'>;
|
|
545
|
+
pressedBackground?: TokenReference<'color'>;
|
|
546
|
+
focusRing?: TokenReference<'color'>;
|
|
547
|
+
disabledOpacity?: string;
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
/** Starter and follow-up suggestion chrome. */
|
|
551
|
+
export interface SuggestionTokens {
|
|
552
|
+
chip: SuggestionVariantTokens;
|
|
553
|
+
card: SuggestionVariantTokens;
|
|
554
|
+
list: SuggestionVariantTokens;
|
|
555
|
+
}
|
|
556
|
+
|
|
527
557
|
/** Toggle group chrome (used by createToggleGroup). */
|
|
528
558
|
export interface ToggleGroupTokens {
|
|
529
559
|
/** Gap between toggle buttons. Default: 0 (connected). */
|
|
@@ -555,6 +585,8 @@ export interface ComponentTokens {
|
|
|
555
585
|
labelButton?: LabelButtonTokens;
|
|
556
586
|
/** Scroll-to-bottom indicator styling tokens. */
|
|
557
587
|
scrollToBottom?: ScrollToBottomTokens;
|
|
588
|
+
/** Starter prompt and follow-up suggestion styling tokens. */
|
|
589
|
+
suggestion?: SuggestionTokens;
|
|
558
590
|
/** Toggle group styling tokens. */
|
|
559
591
|
toggleGroup?: ToggleGroupTokens;
|
|
560
592
|
/** Artifact toolbar, tab strip, and pane chrome. */
|
package/src/types.ts
CHANGED
|
@@ -685,6 +685,15 @@ export type AgentToolsConfig = {
|
|
|
685
685
|
/** Artifact kinds for the Persona sidebar and dispatch payload */
|
|
686
686
|
export type PersonaArtifactKind = "markdown" | "component";
|
|
687
687
|
|
|
688
|
+
export type PersonaArtifactPresentation = {
|
|
689
|
+
/**
|
|
690
|
+
* Producer hint for where this artifact renders (content-disposition
|
|
691
|
+
* model). Beats configured defaults; loses to explicit `files`/`byKind`
|
|
692
|
+
* rules. Persona never infers it; the producer or host supplies it.
|
|
693
|
+
*/
|
|
694
|
+
preferredMode?: PersonaArtifactDisplayModeInput;
|
|
695
|
+
};
|
|
696
|
+
|
|
688
697
|
/**
|
|
689
698
|
* Agent configuration for agent execution mode.
|
|
690
699
|
* When provided in the widget config, enables agent loop execution instead of flow dispatch.
|
|
@@ -1375,10 +1384,60 @@ export type AgentWidgetArtifactsLayoutConfig = {
|
|
|
1375
1384
|
}) => void | Promise<void>;
|
|
1376
1385
|
};
|
|
1377
1386
|
|
|
1387
|
+
/**
|
|
1388
|
+
* Where the artifact body renders by default. Every mode shows the compact
|
|
1389
|
+
* reference in the transcript; the mode names where the body goes:
|
|
1390
|
+
* nowhere yet (`collapsed`), the side panel (`panel`), or the conversation
|
|
1391
|
+
* itself (`inline`).
|
|
1392
|
+
*/
|
|
1378
1393
|
export type PersonaArtifactDisplayMode =
|
|
1379
|
-
| "
|
|
1380
|
-
| "panel"
|
|
1381
|
-
| "inline"; //
|
|
1394
|
+
| "collapsed" // body renders nowhere until the user selects the reference; pane opens on click
|
|
1395
|
+
| "panel" // body renders in the side panel, which auto-opens on artifact_start (default behavior)
|
|
1396
|
+
| "inline"; // body renders directly in the transcript; no pane involvement
|
|
1397
|
+
|
|
1398
|
+
/**
|
|
1399
|
+
* Accepted wherever a display mode is written. `"card"` is a deprecated
|
|
1400
|
+
* alias of `"collapsed"` (the old name described the reference card, which
|
|
1401
|
+
* every mode shows, instead of where the body renders). Resolution and
|
|
1402
|
+
* parsing always canonicalize to `"collapsed"`.
|
|
1403
|
+
*/
|
|
1404
|
+
export type PersonaArtifactDisplayModeInput =
|
|
1405
|
+
| PersonaArtifactDisplayMode
|
|
1406
|
+
| "card";
|
|
1407
|
+
|
|
1408
|
+
/**
|
|
1409
|
+
* Display rules for file-backed artifacts. `byMediaType` keys are exact MIME
|
|
1410
|
+
* types (`"text/html"`) or major-type wildcards (`"image/*"`), matched
|
|
1411
|
+
* case-insensitively without parameters; exact beats wildcard.
|
|
1412
|
+
*/
|
|
1413
|
+
export type PersonaArtifactFilesDisplayRules = {
|
|
1414
|
+
default?: PersonaArtifactDisplayModeInput;
|
|
1415
|
+
byMediaType?: Record<string, PersonaArtifactDisplayModeInput>;
|
|
1416
|
+
};
|
|
1417
|
+
|
|
1418
|
+
/**
|
|
1419
|
+
* Scoped artifact display rules. Matching resolves from the most specific
|
|
1420
|
+
* selector to `default`; see `resolveArtifactDisplay`.
|
|
1421
|
+
*
|
|
1422
|
+
* Across preference layers, one merge rule applies everywhere: a string value
|
|
1423
|
+
* replaces the whole subtree it names; an object refines it per key. So
|
|
1424
|
+
* `files: "inline"` overrides every lower-layer file rule, while
|
|
1425
|
+
* `files: { default: "inline" }` keeps lower-layer MIME exceptions.
|
|
1426
|
+
*/
|
|
1427
|
+
export type PersonaArtifactDisplayRules = {
|
|
1428
|
+
default?: PersonaArtifactDisplayModeInput;
|
|
1429
|
+
byKind?: Partial<
|
|
1430
|
+
Record<PersonaArtifactKind, PersonaArtifactDisplayModeInput>
|
|
1431
|
+
>;
|
|
1432
|
+
/**
|
|
1433
|
+
* @deprecated Use `byKind`. When both are present, `byKind` wins.
|
|
1434
|
+
*/
|
|
1435
|
+
byType?: Partial<
|
|
1436
|
+
Record<PersonaArtifactKind, PersonaArtifactDisplayModeInput>
|
|
1437
|
+
>;
|
|
1438
|
+
/** Rules for any artifact carrying file metadata. */
|
|
1439
|
+
files?: PersonaArtifactDisplayModeInput | PersonaArtifactFilesDisplayRules;
|
|
1440
|
+
};
|
|
1382
1441
|
|
|
1383
1442
|
/** 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. */
|
|
1384
1443
|
export type PersonaArtifactActionContext = {
|
|
@@ -1439,15 +1498,12 @@ export type AgentWidgetArtifactsFeature = {
|
|
|
1439
1498
|
allowedTypes?: PersonaArtifactKind[];
|
|
1440
1499
|
/**
|
|
1441
1500
|
* Where artifact bodies render. A single mode applies to all artifacts;
|
|
1442
|
-
* the object form sets a default plus
|
|
1501
|
+
* the object form sets a default plus scoped overrides.
|
|
1443
1502
|
* Defaults to "panel" (current behavior).
|
|
1444
1503
|
*/
|
|
1445
1504
|
display?:
|
|
1446
|
-
|
|
|
1447
|
-
|
|
|
1448
|
-
default?: PersonaArtifactDisplayMode;
|
|
1449
|
-
byType?: Partial<Record<PersonaArtifactKind, PersonaArtifactDisplayMode>>;
|
|
1450
|
-
};
|
|
1505
|
+
| PersonaArtifactDisplayModeInput
|
|
1506
|
+
| PersonaArtifactDisplayRules;
|
|
1451
1507
|
/** Split / drawer dimensions and launcher widen behavior */
|
|
1452
1508
|
layout?: AgentWidgetArtifactsLayoutConfig;
|
|
1453
1509
|
/**
|
|
@@ -2201,20 +2257,85 @@ export type AgentWidgetFeatureFlags = {
|
|
|
2201
2257
|
*/
|
|
2202
2258
|
askUserQuestion?: AgentWidgetAskUserQuestionFeature;
|
|
2203
2259
|
/**
|
|
2204
|
-
* Built-in `suggest_replies`
|
|
2205
|
-
*
|
|
2206
|
-
*
|
|
2207
|
-
*
|
|
2260
|
+
* Built-in `suggest_replies` follow-ups. When the assistant invokes the
|
|
2261
|
+
* tool, the widget shows the suggestions using `suggestions.followUps` and
|
|
2262
|
+
* immediately resumes the execution: fire-and-forget, no user input awaited.
|
|
2263
|
+
*
|
|
2264
|
+
* @deprecated Both keys moved to `suggestions.followUps`: use
|
|
2265
|
+
* `suggestions.followUps.enabled` and `suggestions.followUps.expose`. This
|
|
2266
|
+
* alias keeps working per key, with `suggestions.followUps` winning.
|
|
2208
2267
|
*/
|
|
2209
2268
|
suggestReplies?: AgentWidgetSuggestRepliesFeature;
|
|
2210
2269
|
};
|
|
2211
2270
|
|
|
2271
|
+
export type WidgetPreferenceCapabilities = {
|
|
2272
|
+
artifacts?: boolean;
|
|
2273
|
+
tools?: boolean;
|
|
2274
|
+
reasoning?: boolean;
|
|
2275
|
+
};
|
|
2276
|
+
|
|
2277
|
+
/**
|
|
2278
|
+
* Persistable artifact-layout choices. The full layout config deliberately is
|
|
2279
|
+
* not exposed because it also contains callbacks and embedder-owned chrome.
|
|
2280
|
+
*/
|
|
2281
|
+
export type WidgetArtifactLayoutPreference = Pick<
|
|
2282
|
+
AgentWidgetArtifactsLayoutConfig,
|
|
2283
|
+
| "paneWidth"
|
|
2284
|
+
| "paneMaxWidth"
|
|
2285
|
+
| "paneMinWidth"
|
|
2286
|
+
| "expandLauncherPanelWhenOpen"
|
|
2287
|
+
| "expandedPanelWidth"
|
|
2288
|
+
| "resizable"
|
|
2289
|
+
| "resizableMinWidth"
|
|
2290
|
+
| "resizableMaxWidth"
|
|
2291
|
+
>;
|
|
2292
|
+
|
|
2293
|
+
/**
|
|
2294
|
+
* Curated, JSON-serializable display preferences in native `features` shape.
|
|
2295
|
+
*
|
|
2296
|
+
* Absence means inherit the next preference layer and ultimately Persona's
|
|
2297
|
+
* current default. Persist only explicit choices; resetting a choice deletes
|
|
2298
|
+
* its key.
|
|
2299
|
+
*
|
|
2300
|
+
* Capability facts (`artifacts.enabled`, `allowedTypes`), trusted iframe
|
|
2301
|
+
* security, callbacks, actions, renderers, labels, and theme styling are
|
|
2302
|
+
* intentionally excluded because they remain embedder/code-owned.
|
|
2303
|
+
*/
|
|
2304
|
+
export type WidgetPreferenceSlice = {
|
|
2305
|
+
showToolCalls?: boolean;
|
|
2306
|
+
showReasoning?: boolean;
|
|
2307
|
+
toolCallDisplay?: Pick<
|
|
2308
|
+
AgentWidgetToolCallDisplayFeature,
|
|
2309
|
+
| "collapsedMode"
|
|
2310
|
+
| "expandable"
|
|
2311
|
+
| "grouped"
|
|
2312
|
+
| "groupedMode"
|
|
2313
|
+
| "loadingAnimation"
|
|
2314
|
+
>;
|
|
2315
|
+
reasoningDisplay?: Pick<
|
|
2316
|
+
AgentWidgetReasoningDisplayFeature,
|
|
2317
|
+
"expandable" | "activePreview"
|
|
2318
|
+
>;
|
|
2319
|
+
artifacts?: {
|
|
2320
|
+
/**
|
|
2321
|
+
* String and object forms are both persistable and mean different things
|
|
2322
|
+
* when layers merge: a string replaces every lower-layer display rule; an
|
|
2323
|
+
* object refines lower layers per selector key (same rule applies to
|
|
2324
|
+
* `display.files`).
|
|
2325
|
+
*/
|
|
2326
|
+
display?: PersonaArtifactDisplayModeInput | PersonaArtifactDisplayRules;
|
|
2327
|
+
filePreview?: { enabled?: boolean };
|
|
2328
|
+
layout?: WidgetArtifactLayoutPreference;
|
|
2329
|
+
};
|
|
2330
|
+
};
|
|
2331
|
+
|
|
2212
2332
|
/**
|
|
2213
|
-
* Feature config for the built-in `suggest_replies`
|
|
2214
|
-
*
|
|
2215
|
-
*
|
|
2216
|
-
*
|
|
2217
|
-
*
|
|
2333
|
+
* Feature config for the built-in `suggest_replies` follow-ups.
|
|
2334
|
+
*
|
|
2335
|
+
* @deprecated Both keys moved to `suggestions.followUps`
|
|
2336
|
+
* (`suggestions.followUps.enabled` / `suggestions.followUps.expose`), which
|
|
2337
|
+
* also owns presentation, placement, and send/fill behavior. Resolution is
|
|
2338
|
+
* per key with `suggestions.followUps` winning; removal waits for 5.0.
|
|
2218
2339
|
*/
|
|
2219
2340
|
export type AgentWidgetSuggestRepliesFeature = {
|
|
2220
2341
|
/**
|
|
@@ -2222,14 +2343,18 @@ export type AgentWidgetSuggestRepliesFeature = {
|
|
|
2222
2343
|
* renders as a regular tool bubble and is NOT auto-resumed: only set this
|
|
2223
2344
|
* with no server-side `suggest_replies` declaration, or the execution
|
|
2224
2345
|
* parks awaiting a resume that never comes.
|
|
2346
|
+
* @deprecated Use `suggestions.followUps.enabled`.
|
|
2225
2347
|
*/
|
|
2226
2348
|
enabled?: boolean;
|
|
2227
2349
|
/**
|
|
2228
2350
|
* Advertise the built-in `suggest_replies` tool to the agent on every
|
|
2229
2351
|
* dispatch via `clientTools[]`: no server-side `runtimeTools` declaration
|
|
2230
|
-
* needed. Defaults to `false
|
|
2231
|
-
*
|
|
2232
|
-
*
|
|
2352
|
+
* needed. Defaults to `false`. Declare the tool in one place: the API
|
|
2353
|
+
* dedupes a double declaration by name with `clientTools[]` winning, so the
|
|
2354
|
+
* model still sees exactly one tool, but the widget's description and schema
|
|
2355
|
+
* win and the effective tool type becomes `local` (the execution pauses and
|
|
2356
|
+
* the widget auto-resumes it). Ignored when `enabled` is `false`.
|
|
2357
|
+
* @deprecated Use `suggestions.followUps.expose`.
|
|
2233
2358
|
*/
|
|
2234
2359
|
expose?: boolean;
|
|
2235
2360
|
};
|
|
@@ -2304,10 +2429,13 @@ export type AgentWidgetAskUserQuestionFeature = {
|
|
|
2304
2429
|
* matching {@link AskUserQuestionPayload}; when the model calls it, the
|
|
2305
2430
|
* existing answer-pill sheet renders and the answer resumes the execution.
|
|
2306
2431
|
*
|
|
2307
|
-
* Defaults to `false
|
|
2308
|
-
*
|
|
2309
|
-
*
|
|
2310
|
-
*
|
|
2432
|
+
* Defaults to `false`. Declare the tool in one place: the API dedupes a
|
|
2433
|
+
* double declaration by name with `clientTools[]` winning, so the model
|
|
2434
|
+
* still sees exactly one tool, but the widget's description and schema win
|
|
2435
|
+
* and the effective tool type becomes `local` (the execution pauses and the
|
|
2436
|
+
* widget resumes it with the user's answer). Ignored when `enabled` is
|
|
2437
|
+
* `false`: never offer the agent a question tool the widget can't render an
|
|
2438
|
+
* answer UI for.
|
|
2311
2439
|
*/
|
|
2312
2440
|
expose?: boolean;
|
|
2313
2441
|
/** Slide-in animation duration in ms. Defaults to 180. */
|
|
@@ -2796,6 +2924,10 @@ export type AgentWidgetSendButtonConfig = {
|
|
|
2796
2924
|
paddingY?: string;
|
|
2797
2925
|
iconText?: string;
|
|
2798
2926
|
iconName?: string;
|
|
2927
|
+
/** Icon glyph box in icon mode, e.g. "20px". Defaults to half of `size`. */
|
|
2928
|
+
iconSize?: string;
|
|
2929
|
+
/** Stroke width for the icon glyph, in viewBox units. Default 2. */
|
|
2930
|
+
iconStrokeWidth?: number;
|
|
2799
2931
|
useIcon?: boolean;
|
|
2800
2932
|
tooltipText?: string;
|
|
2801
2933
|
showTooltip?: boolean;
|
|
@@ -3611,6 +3743,123 @@ export type AgentWidgetSuggestionChipsConfig = {
|
|
|
3611
3743
|
paddingY?: string;
|
|
3612
3744
|
};
|
|
3613
3745
|
|
|
3746
|
+
/** A suggested next action shown to the user. Strings remain supported as shorthand. */
|
|
3747
|
+
export type AgentWidgetSuggestion =
|
|
3748
|
+
| string
|
|
3749
|
+
| {
|
|
3750
|
+
/** Stable analytics / DOM identity. Falls back to the prompt or label. */
|
|
3751
|
+
id?: string;
|
|
3752
|
+
/** Concise visible action label. */
|
|
3753
|
+
label: string;
|
|
3754
|
+
/** Text placed in the composer or sent. Defaults to `label`. */
|
|
3755
|
+
prompt?: string;
|
|
3756
|
+
/** Optional supporting copy, most useful with the `card` variant. */
|
|
3757
|
+
description?: string;
|
|
3758
|
+
/** Optional icon from Persona's bundled Lucide registry. */
|
|
3759
|
+
icon?: IconName;
|
|
3760
|
+
/**
|
|
3761
|
+
* CSS color for this item's glyph. Tints the icon only: label, border,
|
|
3762
|
+
* and background stay neutral. Ignored without an `icon`.
|
|
3763
|
+
*/
|
|
3764
|
+
iconColor?: string;
|
|
3765
|
+
/** Override the surface's click behavior for this item. */
|
|
3766
|
+
behavior?: AgentWidgetSuggestionBehavior;
|
|
3767
|
+
/** Visually promote one high-confidence action. */
|
|
3768
|
+
emphasis?: "default" | "primary";
|
|
3769
|
+
};
|
|
3770
|
+
|
|
3771
|
+
export type AgentWidgetSuggestionBehavior = "send" | "fill";
|
|
3772
|
+
export type AgentWidgetSuggestionVariant = "chip" | "card" | "list";
|
|
3773
|
+
export type AgentWidgetSuggestionSurface = "starter" | "followUp";
|
|
3774
|
+
/**
|
|
3775
|
+
* Who produced the rendered suggestions: static config, the agent's
|
|
3776
|
+
* `suggest_replies` tool, or `controller.setFollowUpSuggestions`.
|
|
3777
|
+
*/
|
|
3778
|
+
export type AgentWidgetSuggestionSource = "config" | "agent" | "host";
|
|
3779
|
+
|
|
3780
|
+
/**
|
|
3781
|
+
* A suggestion after Persona has normalized shorthand strings and resolved the
|
|
3782
|
+
* effective click behavior. Plugin hooks receive this stable shape.
|
|
3783
|
+
*/
|
|
3784
|
+
export type AgentWidgetResolvedSuggestion = {
|
|
3785
|
+
id: string;
|
|
3786
|
+
label: string;
|
|
3787
|
+
prompt: string;
|
|
3788
|
+
description?: string;
|
|
3789
|
+
icon?: IconName;
|
|
3790
|
+
/** CSS color for the glyph only; never the label, border, or background. */
|
|
3791
|
+
iconColor?: string;
|
|
3792
|
+
behavior: AgentWidgetSuggestionBehavior;
|
|
3793
|
+
emphasis: "default" | "primary";
|
|
3794
|
+
};
|
|
3795
|
+
|
|
3796
|
+
/** Presentation keys shared by every suggestion surface. */
|
|
3797
|
+
export type AgentWidgetSuggestionSurfaceConfig = {
|
|
3798
|
+
/** Item density. Defaults to `card` for starters and `chip` for follow-ups. */
|
|
3799
|
+
variant?: AgentWidgetSuggestionVariant;
|
|
3800
|
+
/** Default click behavior, overridable per item. Defaults to `send`. */
|
|
3801
|
+
behavior?: AgentWidgetSuggestionBehavior;
|
|
3802
|
+
/**
|
|
3803
|
+
* Layout for items past the surface width. Defaults to `wrap` for starters
|
|
3804
|
+
* and `scroll` for follow-ups. Applies to the `chip` variant only; the
|
|
3805
|
+
* `card` and `list` layouts manage their own stacking.
|
|
3806
|
+
*/
|
|
3807
|
+
overflow?: "scroll" | "wrap";
|
|
3808
|
+
/** Maximum visible items. Defaults to 4. */
|
|
3809
|
+
maxItems?: number;
|
|
3810
|
+
};
|
|
3811
|
+
|
|
3812
|
+
export type AgentWidgetStarterSuggestionsConfig =
|
|
3813
|
+
AgentWidgetSuggestionSurfaceConfig & {
|
|
3814
|
+
/** Suggestions shown before the first user message. */
|
|
3815
|
+
items?: AgentWidgetSuggestion[];
|
|
3816
|
+
/**
|
|
3817
|
+
* `auto` uses the welcome surface when the welcome card renders and the
|
|
3818
|
+
* composer otherwise. Explicit values are literal: `welcome` renders
|
|
3819
|
+
* nothing when the welcome card is hidden. Defaults to `auto`.
|
|
3820
|
+
*/
|
|
3821
|
+
placement?: "auto" | "welcome" | "composer";
|
|
3822
|
+
};
|
|
3823
|
+
|
|
3824
|
+
export type AgentWidgetFollowUpSuggestionsConfig =
|
|
3825
|
+
AgentWidgetSuggestionSurfaceConfig & {
|
|
3826
|
+
/**
|
|
3827
|
+
* Enable the built-in `suggest_replies` follow-ups. Defaults to true. When
|
|
3828
|
+
* false, `suggest_replies` renders as a regular tool bubble and is NOT
|
|
3829
|
+
* auto-resumed: only set this with no server-side `suggest_replies`
|
|
3830
|
+
* declaration, or the execution parks awaiting a resume that never comes.
|
|
3831
|
+
*/
|
|
3832
|
+
enabled?: boolean;
|
|
3833
|
+
/**
|
|
3834
|
+
* Advertise the built-in `suggest_replies` tool to the agent on every
|
|
3835
|
+
* dispatch via `clientTools[]`: no server-side `runtimeTools` declaration
|
|
3836
|
+
* needed. Defaults to `false`. Declare the tool in one place: the API
|
|
3837
|
+
* dedupes a double declaration by name with `clientTools[]` winning, so
|
|
3838
|
+
* the model still sees exactly one tool, but the widget's description and
|
|
3839
|
+
* schema win and the effective tool type becomes `local` (the execution
|
|
3840
|
+
* pauses and the widget auto-resumes it). Ignored when `enabled` is
|
|
3841
|
+
* `false`.
|
|
3842
|
+
*/
|
|
3843
|
+
expose?: boolean;
|
|
3844
|
+
/**
|
|
3845
|
+
* `auto` places follow-ups after the transcript in regular panels and above
|
|
3846
|
+
* the composer in composer-bar mode. Defaults to `auto`.
|
|
3847
|
+
*/
|
|
3848
|
+
placement?: "auto" | "after-message" | "composer";
|
|
3849
|
+
// No `items`: follow-up items are contextual and come from the agent's
|
|
3850
|
+
// `suggest_replies` tool or `controller.setFollowUpSuggestions`, not static
|
|
3851
|
+
// config. Static lists are `starters`.
|
|
3852
|
+
};
|
|
3853
|
+
|
|
3854
|
+
/**
|
|
3855
|
+
* Structured suggestions configuration. The legacy `suggestionChips` and
|
|
3856
|
+
* `suggestionChipsConfig` fields remain supported for backwards compatibility.
|
|
3857
|
+
*/
|
|
3858
|
+
export type AgentWidgetSuggestionsConfig = {
|
|
3859
|
+
starters?: AgentWidgetStarterSuggestionsConfig;
|
|
3860
|
+
followUps?: AgentWidgetFollowUpSuggestionsConfig;
|
|
3861
|
+
};
|
|
3862
|
+
|
|
3614
3863
|
/**
|
|
3615
3864
|
* Interface for pluggable stream parsers that extract text from streaming responses.
|
|
3616
3865
|
* Parsers handle incremental parsing to extract text values from structured formats (JSON, XML, etc.).
|
|
@@ -4902,6 +5151,15 @@ export type AgentWidgetConfig = {
|
|
|
4902
5151
|
*/
|
|
4903
5152
|
colorScheme?: 'auto' | 'light' | 'dark';
|
|
4904
5153
|
features?: AgentWidgetFeatureFlags;
|
|
5154
|
+
/**
|
|
5155
|
+
* Per-instance display overrides, applied over `features` through the
|
|
5156
|
+
* preference allowlist (security/capability keys cannot pass). String
|
|
5157
|
+
* `display` values replace the base rule subtree; objects refine it per
|
|
5158
|
+
* key. Each `controller.update({ preferences })` replaces the previous
|
|
5159
|
+
* slice wholesale (dropped keys revert to the base `features`); an
|
|
5160
|
+
* explicit-undefined patch clears it entirely.
|
|
5161
|
+
*/
|
|
5162
|
+
preferences?: WidgetPreferenceSlice;
|
|
4905
5163
|
/**
|
|
4906
5164
|
* When true, focus the chat input after the panel opens and the open animation completes.
|
|
4907
5165
|
* Applies to launcher mode (user click, controller.open(), autoExpand) and inline mode (on init).
|
|
@@ -4922,7 +5180,11 @@ export type AgentWidgetConfig = {
|
|
|
4922
5180
|
* with `initialArtifacts`.
|
|
4923
5181
|
*/
|
|
4924
5182
|
initialSelectedArtifactId?: string | null;
|
|
5183
|
+
/** Rich starter and follow-up suggestion surfaces. */
|
|
5184
|
+
suggestions?: AgentWidgetSuggestionsConfig;
|
|
5185
|
+
/** @deprecated Prefer `suggestions.starters.items`. */
|
|
4925
5186
|
suggestionChips?: string[];
|
|
5187
|
+
/** @deprecated Prefer semantic tokens under `theme.components.suggestion`. */
|
|
4926
5188
|
suggestionChipsConfig?: AgentWidgetSuggestionChipsConfig;
|
|
4927
5189
|
debug?: boolean;
|
|
4928
5190
|
formEndpoint?: string;
|
|
@@ -5864,6 +6126,8 @@ export type PersonaArtifactRecord = {
|
|
|
5864
6126
|
props?: Record<string, unknown>;
|
|
5865
6127
|
/** Present when this markdown artifact is a previewable file (see PersonaArtifactFileMeta). */
|
|
5866
6128
|
file?: PersonaArtifactFileMeta;
|
|
6129
|
+
/** Optional presentation metadata such as the producer's display-mode hint. */
|
|
6130
|
+
presentation?: PersonaArtifactPresentation;
|
|
5867
6131
|
};
|
|
5868
6132
|
|
|
5869
6133
|
/** Programmatic artifact upsert (controller / window API) */
|
|
@@ -5875,6 +6139,7 @@ export type PersonaArtifactManualUpsert =
|
|
|
5875
6139
|
content: string;
|
|
5876
6140
|
/** Optional file metadata for previewable file artifacts. */
|
|
5877
6141
|
file?: PersonaArtifactFileMeta;
|
|
6142
|
+
presentation?: PersonaArtifactPresentation;
|
|
5878
6143
|
/** Set false to update the registry/pane without a transcript block (pre-4.x behavior). */
|
|
5879
6144
|
transcript?: boolean;
|
|
5880
6145
|
}
|
|
@@ -5884,6 +6149,7 @@ export type PersonaArtifactManualUpsert =
|
|
|
5884
6149
|
title?: string;
|
|
5885
6150
|
component: string;
|
|
5886
6151
|
props?: Record<string, unknown>;
|
|
6152
|
+
presentation?: PersonaArtifactPresentation;
|
|
5887
6153
|
/** Set false to update the registry/pane without a transcript block (pre-4.x behavior). */
|
|
5888
6154
|
transcript?: boolean;
|
|
5889
6155
|
};
|