@runtypelabs/persona 4.32.0 → 4.32.1
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/dist/activity-ui.cjs +1 -1
- package/dist/activity-ui.js +1 -1
- package/dist/{chunk-BrptyKSq.js → chunk-B3l7TOOv.js} +1 -1
- package/dist/{chunk-CkE90FtA.js → chunk-B4ecQzeK.js} +1 -1
- package/dist/{chunk-BWCo3rCm.js → chunk-B_H0l3u2.js} +1 -1
- package/dist/{chunk-MdlQetfC.js → chunk-BbXc58OA.js} +1 -1
- package/dist/chunk-BkOYJ11B.js +1 -0
- package/dist/{chunk-DE0cSmku.js → chunk-BpjtKnGI.js} +1 -1
- package/dist/{chunk-CzZBmTLd.js → chunk-C9uOhfk5.js} +1 -1
- package/dist/{chunk-CHAwCqpk.js → chunk-CdpVP6LZ.js} +1 -1
- package/dist/{chunk-DZg9bFK6.js → chunk-CumoXK3u.js} +1 -1
- package/dist/{chunk-FEzOcZof.js → chunk-DM-OJt5q.js} +1 -1
- package/dist/{chunk-Cb7qy0c7.js → chunk-DNdeIFJ6.js} +1 -1
- package/dist/{chunk-VaT6xry9.js → chunk-DTGvDx8o.js} +1 -1
- package/dist/{chunk-ezlpsYGk.js → chunk-DVZ8ri1z.js} +1 -1
- package/dist/{chunk-DhedQnek.js → chunk-DgZZqy14.js} +1 -1
- package/dist/{chunk-C2IbR39s.js → chunk-UWMfWW2a.js} +1 -1
- package/dist/client-dispatch.js +1 -1
- package/dist/client-history.js +1 -1
- package/dist/codegen.cjs +1 -1
- package/dist/codegen.js +1 -1
- package/dist/index.cjs +3 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.global.js +1 -1
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/launcher.global.js +1 -1
- package/dist/launcher.global.js.map +1 -1
- package/dist/theme-editor-preview.cjs +3 -3
- package/dist/theme-editor-preview.js +3 -3
- package/dist/theme-editor.cjs +1 -1
- package/dist/theme-editor.js +1 -1
- package/dist/theme-reference.cjs +1 -1
- package/dist/theme-reference.js +1 -1
- package/dist/voice-runtime.cjs +1 -1
- package/dist/voice-runtime.js +1 -1
- package/dist/widget.css +1 -1
- package/package.json +1 -1
- package/src/styles/widget.css +12 -0
- package/src/utils/brand.test.ts +50 -0
- package/src/utils/brand.ts +6 -2
- package/src/utils/tokens.ts +2 -1
- package/src/utils/tool-activity-summary.test.ts +8 -0
- package/src/utils/tool-activity-summary.ts +2 -1
- package/dist/chunk-DDAwu89-.js +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@runtypelabs/persona",
|
|
3
|
-
"version": "4.32.
|
|
3
|
+
"version": "4.32.1",
|
|
4
4
|
"description": "Themeable, pluggable streaming agent widget for websites, in plain JS with support for voice input and reasoning / tool output.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
package/src/styles/widget.css
CHANGED
|
@@ -6993,6 +6993,18 @@
|
|
|
6993
6993
|
.persona-turn-activity-body .persona-tool-bubble.persona-activity-row {
|
|
6994
6994
|
--persona-activity-height: var(--persona-components-toolBubble-rowHeight, var(--persona-components-activity-rowHeight, 28px));
|
|
6995
6995
|
}
|
|
6996
|
+
[data-persona-defaults="v5"] [data-persona-tool-group-stack] .persona-tool-bubble.persona-activity-row {
|
|
6997
|
+
--persona-activity-height: var(--persona-components-toolBubble-rowHeight, var(--persona-components-activity-rowHeight, 24px));
|
|
6998
|
+
}
|
|
6999
|
+
[data-persona-defaults="v5"] [data-persona-tool-group-stack] .persona-activity-header:not(.persona-theme-padding) {
|
|
7000
|
+
padding-block: 2px;
|
|
7001
|
+
line-height: max(18px, calc(var(--persona-activity-label-size) * 1.35));
|
|
7002
|
+
}
|
|
7003
|
+
@media (any-pointer: coarse) {
|
|
7004
|
+
[data-persona-defaults="v5"] [data-persona-tool-group-stack] .persona-tool-bubble.persona-activity-row {
|
|
7005
|
+
--persona-activity-height: var(--persona-components-toolBubble-rowHeight, var(--persona-components-activity-rowHeight, 44px));
|
|
7006
|
+
}
|
|
7007
|
+
}
|
|
6996
7008
|
.persona-turn-activity-body .persona-reasoning-bubble.persona-activity-row {
|
|
6997
7009
|
--persona-activity-height: var(--persona-components-reasoningBubble-rowHeight, var(--persona-components-activity-rowHeight, 28px));
|
|
6998
7010
|
}
|
package/src/utils/brand.test.ts
CHANGED
|
@@ -73,6 +73,56 @@ describe('brand derivation', () => {
|
|
|
73
73
|
expect(theme.components?.panel?.modes?.floating?.border).toContain('var(--persona-border)');
|
|
74
74
|
expect(theme.components?.panel?.shadow).toBe(theme.palette?.shadows?.xl);
|
|
75
75
|
});
|
|
76
|
+
describe.each(['light', 'dark'] as const)('%s message presentation', (colorScheme) => {
|
|
77
|
+
const elevations = [
|
|
78
|
+
['flat', 'none'],
|
|
79
|
+
['subtle', '0 2px 8px rgba(0, 0, 0, 0.08)'],
|
|
80
|
+
['raised', '0 12px 32px rgba(0, 0, 0, 0.18)'],
|
|
81
|
+
] as const;
|
|
82
|
+
it.each(elevations)('keeps V5 prose plain with %s elevation at every density', (elevation, shadow) => {
|
|
83
|
+
for (const density of ['compact', 'comfortable', 'spacious'] as const) {
|
|
84
|
+
const config = { colorScheme, future: { v5Defaults: true }, brand: { elevation, density } };
|
|
85
|
+
const vars = getCssVariables(getActiveTheme(config));
|
|
86
|
+
expect(vars['--persona-message-assistant-shadow']).toBe('none');
|
|
87
|
+
expect(vars['--persona-message-assistant-border']).toBe('transparent');
|
|
88
|
+
expect(vars['--persona-message-assistant-padding']).toBe('0px');
|
|
89
|
+
// These existing surfaces still follow elevation; this is not a global
|
|
90
|
+
// rule that every default of `none` must opt out of brand styling.
|
|
91
|
+
expect(vars['--persona-message-user-shadow']).toBe(shadow);
|
|
92
|
+
expect(getActiveTheme(config).components.introCard?.shadow).toBe(shadow);
|
|
93
|
+
const v4 = getCssVariables(getActiveTheme({ ...config, future: { v5Defaults: false } }));
|
|
94
|
+
expect(v4['--persona-message-assistant-shadow']).toBe(shadow);
|
|
95
|
+
expect(v4['--persona-message-assistant-border']).not.toBe('transparent');
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
it.each(elevations)('lets custom padded bubbles follow %s elevation', (elevation, shadow) => {
|
|
99
|
+
for (const [density, padding] of [['compact', '8px'], ['comfortable', '12px'], ['spacious', '16px']] as const) {
|
|
100
|
+
const theme = { components: { message: { assistant: {
|
|
101
|
+
background: 'semantic.colors.container', padding, borderRadius: '12px',
|
|
102
|
+
border: 'semantic.colors.border', borderWidth: '1px', shadow: 'palette.shadows.sm',
|
|
103
|
+
} } } };
|
|
104
|
+
// Shared overrides and dark-only overrides both remain authoritative.
|
|
105
|
+
for (const overrides of colorScheme === 'dark' ? [{ theme }, { darkTheme: theme }] : [{ theme }]) {
|
|
106
|
+
const vars = getCssVariables(getActiveTheme({
|
|
107
|
+
colorScheme, future: { v5Defaults: true }, brand: { elevation, density }, ...overrides,
|
|
108
|
+
}));
|
|
109
|
+
expect(vars['--persona-message-assistant-shadow']).toBe(shadow);
|
|
110
|
+
expect(vars['--persona-message-assistant-padding']).toBe(padding);
|
|
111
|
+
expect(vars['--persona-message-assistant-border']).not.toBe('transparent');
|
|
112
|
+
expect(vars['--persona-message-assistant-border-width']).toBe('1px');
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
it('preserves explicit assistant shadows and borders over brand elevation', () => {
|
|
117
|
+
const vars = getCssVariables(getActiveTheme({
|
|
118
|
+
colorScheme, future: { v5Defaults: true }, brand: { elevation: 'raised' },
|
|
119
|
+
theme: { components: { message: { assistant: { shadow: '0 1px 2px red', border: '#123456' } } } },
|
|
120
|
+
...(colorScheme === 'dark' ? { darkTheme: { components: { message: { assistant: { shadow: 'none', border: '#abcdef' } } } } } : {}),
|
|
121
|
+
}));
|
|
122
|
+
expect(vars['--persona-message-assistant-shadow']).toBe(colorScheme === 'dark' ? 'none' : '0 1px 2px red');
|
|
123
|
+
expect(vars['--persona-message-assistant-border']).toBe(colorScheme === 'dark' ? '#abcdef' : '#123456');
|
|
124
|
+
});
|
|
125
|
+
});
|
|
76
126
|
it.each([false, true])('keeps neutral-derived surfaces and elevation coherent (%s)', (v5Defaults) => {
|
|
77
127
|
const theme = getActiveTheme({ future: { v5Defaults }, brand: { neutral: '#161b22', radius: 'none', elevation: 'flat' } });
|
|
78
128
|
const vars = getCssVariables(theme);
|
package/src/utils/brand.ts
CHANGED
|
@@ -111,8 +111,12 @@ export const deriveBrandTheme = (brand?: BrandConfig, scheme: 'light' | 'dark' =
|
|
|
111
111
|
const shadow = flat ? 'none' : brand.elevation === 'subtle' ? '0 2px 8px rgba(0, 0, 0, 0.08)' : '0 12px 32px rgba(0, 0, 0, 0.18)';
|
|
112
112
|
const border = flat ? '1px solid var(--persona-border)' : '1px solid color-mix(in srgb, var(--persona-border) 65%, transparent)';
|
|
113
113
|
theme.palette = { ...theme.palette, shadows: { sm: shadow, md: shadow, lg: shadow, xl: shadow, '2xl': shadow } };
|
|
114
|
-
const shadows = (node: Record<string, unknown
|
|
114
|
+
const shadows = (node: Record<string, unknown>, path = ''): Record<string, unknown> => {
|
|
115
115
|
const overlay: Record<string, unknown> = {};
|
|
116
|
+
// V5 assistant defaults are unpadded prose, not a surface to elevate.
|
|
117
|
+
// Explicit theme tokens still win; custom bubbles can opt into the brand
|
|
118
|
+
// shadow scale with `palette.shadows.sm` alongside their padding/background.
|
|
119
|
+
if (v5Defaults && path === 'message.assistant') return overlay;
|
|
116
120
|
for (const [key, value] of Object.entries(node)) {
|
|
117
121
|
if (key.toLowerCase().endsWith('shadow')) {
|
|
118
122
|
overlay[key] = shadow;
|
|
@@ -120,7 +124,7 @@ export const deriveBrandTheme = (brand?: BrandConfig, scheme: 'light' | 'dark' =
|
|
|
120
124
|
if (borderKey in node) overlay[borderKey] = typeof node[borderKey] === 'string' && (node[borderKey] as string).includes('solid') ? border : flat ? 'semantic.colors.border' : 'color-mix(in srgb, var(--persona-border) 65%, transparent)';
|
|
121
125
|
}
|
|
122
126
|
else if (value && typeof value === 'object') {
|
|
123
|
-
const child = shadows(value as Record<string, unknown
|
|
127
|
+
const child = shadows(value as Record<string, unknown>, path ? `${path}.${key}` : key);
|
|
124
128
|
if (Object.keys(child).length) overlay[key] = child;
|
|
125
129
|
}
|
|
126
130
|
}
|
package/src/utils/tokens.ts
CHANGED
|
@@ -603,7 +603,8 @@ export const DEFAULT_COMPONENTS_V5: ComponentTokens = {
|
|
|
603
603
|
},
|
|
604
604
|
launcher: CIRCLE_LAUNCHER_TOKENS,
|
|
605
605
|
activity: {
|
|
606
|
-
|
|
606
|
+
// CSS owns contextual parent, nested, and coarse-pointer row heights.
|
|
607
|
+
labelSize: "13px", iconSize: "16px", indent: "0px",
|
|
607
608
|
transcriptGap: "0px", responseGap: "12px",
|
|
608
609
|
groupIndent: "16px", groupGap: "2px", groupPadding: "2px 0",
|
|
609
610
|
bodyPadding: "4px 0", bodyFontWeight: "400", sectionGap: "8px", bodySurface: "transparent",
|
|
@@ -6,6 +6,7 @@ const tool = (name: string, extra: Partial<AgentWidgetToolCall> = {}): AgentWidg
|
|
|
6
6
|
|
|
7
7
|
describe("semantic tool activity", () => {
|
|
8
8
|
it.each([
|
|
9
|
+
["search_docs", "Searched docs"], ["read_file", "Read a file"],
|
|
9
10
|
["web_search", "Searched the web"], ["web_search_preview", "Searched the web"], ["WebSearch", "Searched the web"],
|
|
10
11
|
["web_fetch", "Read a web page"], ["WebFetch", "Read a web page"],
|
|
11
12
|
["file_search", "Searched files"], ["search_files", "Searched files"], ["Glob", "Searched files"],
|
|
@@ -22,6 +23,12 @@ describe("semantic tool activity", () => {
|
|
|
22
23
|
["sql_db_query", "Queried the database"], ["search_gmail", "Searched email"],
|
|
23
24
|
])("maps exact alias %s", (name, label) => expect(toolActivityLabel(tool(name))).toBe(label));
|
|
24
25
|
|
|
26
|
+
it("summarizes documentation searches and file reads without a custom hook", () => {
|
|
27
|
+
expect(summarizeToolActivity([tool("search_docs"), tool("read_file")])).toBe("Searched docs, read files");
|
|
28
|
+
expect(summarizeToolActivity([tool("search_docs", { status: "running" }), tool("read_file", { status: "pending" })])).toBe("Searching docs, reading files");
|
|
29
|
+
expect(toolActivityLabel(tool("read_file", { status: "running" }))).toBe("Reading a file");
|
|
30
|
+
});
|
|
31
|
+
|
|
25
32
|
it.each(["search_events", "search_nodes", "read_graph", "open_nodes", "read", "search", "git_commit", "my_web_search", "web_search_custom"])("keeps ambiguous %s generic", name => {
|
|
26
33
|
expect(toolActivityLabel(tool(name))).toMatch(/^Used /);
|
|
27
34
|
});
|
|
@@ -127,6 +134,7 @@ describe("semantic tool activity", () => {
|
|
|
127
134
|
});
|
|
128
135
|
|
|
129
136
|
it.each([
|
|
137
|
+
["search_docs", "search"], ["read_file", "file-text"],
|
|
130
138
|
["web_search", "globe"], ["Read", "file-text"], ["edit_file", "pencil"], ["Bash", "terminal"],
|
|
131
139
|
["sql_db_query", "database"], ["search_events", "wrench"], ["my_web_search", "wrench"],
|
|
132
140
|
])("maps the completed icon for %s without guessing", (name, icon) => expect(toolActivityIcon(tool(name))).toBe(icon));
|
|
@@ -3,10 +3,11 @@ import type { AgentWidgetConfig, AgentWidgetToolCall } from "../types";
|
|
|
3
3
|
// Exact documented names only. Ambiguous names such as search_events or
|
|
4
4
|
// search_nodes need provider metadata, which tool messages do not carry.
|
|
5
5
|
const categories = [
|
|
6
|
+
["search_docs", "Searching docs", "Searched docs", "search"],
|
|
6
7
|
["web_search|web_search_preview|WebSearch", "Searching the web", "Searched the web", "globe"],
|
|
7
8
|
["web_fetch|WebFetch", "Reading web pages", "Read web pages", "globe", "single"],
|
|
8
9
|
["file_search|search_files|Glob", "Searching files", "Searched files", "search"],
|
|
9
|
-
["read_text_file|read_multiple_files|Read", "Reading files", "Read files", "file-text", "single"],
|
|
10
|
+
["read_file|read_text_file|read_multiple_files|Read", "Reading files", "Read files", "file-text", "single"],
|
|
10
11
|
["write_file|edit_file|apply_patch|Write|Edit|NotebookEdit", "Editing files", "Edited files", "pencil", "single"],
|
|
11
12
|
["list_directory|list_directory_with_sizes|directory_tree", "Browsing files", "Browsed files", "folder"],
|
|
12
13
|
["Grep", "Searching code", "Searched code", "search"],
|
package/dist/chunk-DDAwu89-.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const e=`4.32.0`;export{e as t};
|