@runtypelabs/persona 4.1.0 → 4.2.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/codegen.cjs +1 -1
- package/dist/codegen.js +1 -1
- package/dist/index.cjs +53 -53
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +15 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.global.js +41 -41
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +51 -51
- package/dist/index.js.map +1 -1
- package/dist/launcher.global.js +1 -1
- package/dist/launcher.global.js.map +1 -1
- package/dist/smart-dom-reader.d.cts +15 -0
- package/dist/smart-dom-reader.d.ts +15 -0
- package/dist/theme-editor-preview.cjs +46 -46
- package/dist/theme-editor-preview.d.cts +15 -0
- package/dist/theme-editor-preview.d.ts +15 -0
- package/dist/theme-editor-preview.js +46 -46
- package/dist/theme-editor.cjs +1 -1
- package/dist/theme-editor.d.cts +15 -0
- package/dist/theme-editor.d.ts +15 -0
- package/dist/theme-editor.js +1 -1
- package/dist/theme-reference.cjs +1 -1
- package/dist/theme-reference.js +1 -1
- package/dist/widget.css +224 -0
- package/package.json +1 -1
- package/src/client.test.ts +128 -0
- package/src/client.ts +25 -0
- package/src/components/approval-actions.test.ts +309 -0
- package/src/components/approval-actions.ts +461 -0
- package/src/styles/widget.css +224 -0
- package/src/theme-reference.ts +2 -2
- package/src/types.ts +15 -0
- package/src/ui.ts +19 -3
- package/src/utils/tokens.ts +15 -12
package/src/theme-reference.ts
CHANGED
|
@@ -227,9 +227,9 @@ export const THEME_TOKEN_DOCS = {
|
|
|
227
227
|
},
|
|
228
228
|
approval: {
|
|
229
229
|
description:
|
|
230
|
-
'Tool approval
|
|
230
|
+
'Tool approval card styling and behavior. Neutral surface card; the primary action anchors to the brand --persona-primary token. Set to false to disable. Set enableAlwaysAllow: true to add the split "Always allow / Allow once" control (needs a backend to persist the policy via onDecision\'s remember).',
|
|
231
231
|
properties:
|
|
232
|
-
'backgroundColor, borderColor, titleColor, descriptionColor, reasonColor, reasonLabel, approveButtonColor, approveButtonTextColor, denyButtonColor, denyButtonTextColor, parameterBackgroundColor, parameterTextColor,
|
|
232
|
+
'enableAlwaysAllow, detailsDisplay ("collapsed" | "expanded" | "hidden"), showDetailsLabel, hideDetailsLabel, backgroundColor, borderColor, titleColor, descriptionColor, reasonColor, reasonLabel, approveButtonColor, approveButtonTextColor, denyButtonColor, denyButtonTextColor, parameterBackgroundColor, parameterTextColor, approveLabel, denyLabel, formatDescription. (title no longer renders in the default card; use formatDescription to customize the summary.)',
|
|
233
233
|
},
|
|
234
234
|
copy: {
|
|
235
235
|
description: 'Widget text content.',
|
package/src/types.ts
CHANGED
|
@@ -2296,6 +2296,21 @@ export type AgentWidgetApprovalConfig = {
|
|
|
2296
2296
|
showDetailsLabel?: string;
|
|
2297
2297
|
/** Label for the toggle that hides the technical details */
|
|
2298
2298
|
hideDetailsLabel?: string;
|
|
2299
|
+
/**
|
|
2300
|
+
* Offer an "Always allow" affordance in the default approval bubble.
|
|
2301
|
+
*
|
|
2302
|
+
* Default `false`. When `false`, the bubble shows a single "Allow" (allow
|
|
2303
|
+
* once) plus "Deny". When `true`, the primary action becomes a split control:
|
|
2304
|
+
* "Always allow" (resolves with `{ remember: true }`) with a dropdown for
|
|
2305
|
+
* "Allow once", plus "Deny", and keyboard shortcuts (Enter = Always allow,
|
|
2306
|
+
* Cmd/Ctrl+Enter = Allow once, Esc = Deny).
|
|
2307
|
+
*
|
|
2308
|
+
* Keep this off unless your backend actually persists the don't-ask-again
|
|
2309
|
+
* policy: "Always allow" only resolves the *current* approval — honoring it
|
|
2310
|
+
* for *future* calls is up to your `onDecision` handler (which receives
|
|
2311
|
+
* `options.remember`). Showing it without that wiring would mislead users.
|
|
2312
|
+
*/
|
|
2313
|
+
enableAlwaysAllow?: boolean;
|
|
2299
2314
|
/**
|
|
2300
2315
|
* Build the user-facing summary line for an approval request. Overrides the
|
|
2301
2316
|
* default "The assistant wants to use “Tool name”." copy. Return a falsy
|
package/src/ui.ts
CHANGED
|
@@ -99,6 +99,7 @@ import {
|
|
|
99
99
|
} from "./suggest-replies-tool";
|
|
100
100
|
import { formatElapsedMs } from "./utils/formatting";
|
|
101
101
|
import { approvalDetailsExpansionState, createApprovalBubble, updateApprovalDetailsUI } from "./components/approval-bubble";
|
|
102
|
+
import { createBuiltInApprovalPlugin } from "./components/approval-actions";
|
|
102
103
|
import { createSuggestions } from "./components/suggestions";
|
|
103
104
|
import { EventStreamBuffer } from "./utils/event-stream-buffer";
|
|
104
105
|
import { EventStreamStore } from "./utils/event-stream-store";
|
|
@@ -542,7 +543,13 @@ export const createAgentExperience = (
|
|
|
542
543
|
|
|
543
544
|
// Get plugins for this instance
|
|
544
545
|
const plugins = pluginRegistry.getForInstance(config.plugins);
|
|
545
|
-
|
|
546
|
+
|
|
547
|
+
// The built-in approval renderer, shaped as a plugin. Resolved as a FALLBACK
|
|
548
|
+
// (not pushed into `plugins`) so a user `renderApproval` plugin always wins
|
|
549
|
+
// and a later config-update plugin push can't reorder ahead of it.
|
|
550
|
+
const { plugin: builtInApprovalPlugin, teardown: teardownBuiltInApprovals } =
|
|
551
|
+
createBuiltInApprovalPlugin();
|
|
552
|
+
|
|
546
553
|
// Register components from config
|
|
547
554
|
if (config.components) {
|
|
548
555
|
componentRegistry.registerAll(config.components);
|
|
@@ -2743,6 +2750,11 @@ export const createAgentExperience = (
|
|
|
2743
2750
|
}
|
|
2744
2751
|
});
|
|
2745
2752
|
|
|
2753
|
+
// Release this widget's pending built-in approval listeners + "Allow once"
|
|
2754
|
+
// popovers if it's destroyed while an approval is still open. Scoped to this
|
|
2755
|
+
// instance's state, so other widgets on the page are unaffected.
|
|
2756
|
+
destroyCallbacks.push(teardownBuiltInApprovals);
|
|
2757
|
+
|
|
2746
2758
|
// Activate the stream-animation plugin for this widget instance. Plugins
|
|
2747
2759
|
// with `styles` inject their CSS into the widget root once; plugins with
|
|
2748
2760
|
// `onAttach` (e.g., glyph-cycle's MutationObserver for real glyph tick
|
|
@@ -3418,7 +3430,10 @@ export const createAgentExperience = (
|
|
|
3418
3430
|
// interactivity), and idiomorph imports nodes via `document.importNode`,
|
|
3419
3431
|
// which strips them. So we build the live element, append a stub during
|
|
3420
3432
|
// morph, and inject the live element afterward.
|
|
3421
|
-
|
|
3433
|
+
// The built-in approval renderer is always available (as a fallback plugin),
|
|
3434
|
+
// so every approval flows through the stub-and-hydrate path whenever
|
|
3435
|
+
// approvals are enabled — a user `renderApproval` plugin just overrides it.
|
|
3436
|
+
const hasApprovalPlugin = config.approval !== false;
|
|
3422
3437
|
type ApprovalPluginHydrate = {
|
|
3423
3438
|
messageId: string;
|
|
3424
3439
|
fingerprint: string;
|
|
@@ -3638,7 +3653,8 @@ export const createAgentExperience = (
|
|
|
3638
3653
|
// any accordion listeners survive idiomorph's `importNode`. Gate the
|
|
3639
3654
|
// rebuild on fingerprint so interactive state (e.g. a collapsed
|
|
3640
3655
|
// accordion) is preserved while the approval stays pending.
|
|
3641
|
-
const approvalPlugin =
|
|
3656
|
+
const approvalPlugin =
|
|
3657
|
+
plugins.find((p) => typeof p.renderApproval === "function") ?? builtInApprovalPlugin;
|
|
3642
3658
|
const lastFp = lastApprovalBubbleFingerprint.get(message.id);
|
|
3643
3659
|
const needsRebuild = lastFp !== fingerprint;
|
|
3644
3660
|
let liveBubble: HTMLElement | null = null;
|
package/src/utils/tokens.ts
CHANGED
|
@@ -384,22 +384,25 @@ export const DEFAULT_COMPONENTS: ComponentTokens = {
|
|
|
384
384
|
icon: 'palette.colors.success.500',
|
|
385
385
|
},
|
|
386
386
|
},
|
|
387
|
+
// Neutral surface card (components/approval-actions.ts). The primary action
|
|
388
|
+
// anchors to the brand primary; deny is a neutral tinted button. Consumers who
|
|
389
|
+
// themed these (or set config.approval.* color overrides) still win.
|
|
387
390
|
approval: {
|
|
388
391
|
requested: {
|
|
389
|
-
background: '
|
|
390
|
-
border: '
|
|
392
|
+
background: 'semantic.colors.surface',
|
|
393
|
+
border: 'semantic.colors.border',
|
|
391
394
|
text: 'palette.colors.gray.900',
|
|
392
|
-
shadow: '0
|
|
395
|
+
shadow: '0 1px 2px 0 rgba(11, 11, 11, 0.06), 0 2px 8px 0 rgba(11, 11, 11, 0.04)',
|
|
393
396
|
},
|
|
394
397
|
approve: {
|
|
395
|
-
background: '
|
|
396
|
-
foreground: '
|
|
398
|
+
background: 'semantic.colors.primary',
|
|
399
|
+
foreground: 'semantic.colors.textInverse',
|
|
397
400
|
borderRadius: 'palette.radius.md',
|
|
398
401
|
padding: 'semantic.spacing.sm',
|
|
399
402
|
},
|
|
400
403
|
deny: {
|
|
401
|
-
background: '
|
|
402
|
-
foreground: '
|
|
404
|
+
background: 'semantic.colors.container',
|
|
405
|
+
foreground: 'semantic.colors.text',
|
|
403
406
|
borderRadius: 'palette.radius.md',
|
|
404
407
|
padding: 'semantic.spacing.sm',
|
|
405
408
|
},
|
|
@@ -681,12 +684,12 @@ export function themeToCssVariables(theme: PersonaTheme): Record<string, string>
|
|
|
681
684
|
cssVars['--persona-voice-processing-icon'] = cssVars['--persona-components-voice-processing-icon'] ?? cssVars['--persona-palette-colors-primary-500'];
|
|
682
685
|
cssVars['--persona-voice-speaking-icon'] = cssVars['--persona-components-voice-speaking-icon'] ?? cssVars['--persona-palette-colors-success-500'];
|
|
683
686
|
|
|
684
|
-
cssVars['--persona-approval-bg'] = cssVars['--persona-components-approval-requested-background'] ?? cssVars['--persona-
|
|
685
|
-
cssVars['--persona-approval-border'] = cssVars['--persona-components-approval-requested-border'] ?? cssVars['--persona-
|
|
687
|
+
cssVars['--persona-approval-bg'] = cssVars['--persona-components-approval-requested-background'] ?? cssVars['--persona-surface'];
|
|
688
|
+
cssVars['--persona-approval-border'] = cssVars['--persona-components-approval-requested-border'] ?? cssVars['--persona-border'];
|
|
686
689
|
cssVars['--persona-approval-text'] = cssVars['--persona-components-approval-requested-text'] ?? cssVars['--persona-palette-colors-gray-900'];
|
|
687
|
-
cssVars['--persona-approval-shadow'] = cssVars['--persona-components-approval-requested-shadow'] ?? '0
|
|
688
|
-
cssVars['--persona-approval-approve-bg'] = cssVars['--persona-components-approval-approve-background'] ?? cssVars['--persona-
|
|
689
|
-
cssVars['--persona-approval-deny-bg'] = cssVars['--persona-components-approval-deny-background'] ?? cssVars['--persona-
|
|
690
|
+
cssVars['--persona-approval-shadow'] = cssVars['--persona-components-approval-requested-shadow'] ?? '0 1px 2px 0 rgba(11, 11, 11, 0.06), 0 2px 8px 0 rgba(11, 11, 11, 0.04)';
|
|
691
|
+
cssVars['--persona-approval-approve-bg'] = cssVars['--persona-components-approval-approve-background'] ?? cssVars['--persona-button-primary-bg'];
|
|
692
|
+
cssVars['--persona-approval-deny-bg'] = cssVars['--persona-components-approval-deny-background'] ?? cssVars['--persona-container'];
|
|
690
693
|
|
|
691
694
|
cssVars['--persona-attachment-image-bg'] = cssVars['--persona-components-attachment-image-background'] ?? cssVars['--persona-palette-colors-gray-100'];
|
|
692
695
|
cssVars['--persona-attachment-image-border'] = cssVars['--persona-components-attachment-image-border'] ?? cssVars['--persona-palette-colors-gray-200'];
|