@runtypelabs/persona 3.31.1 → 3.34.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 +17 -10
- package/dist/animations/glyph-cycle.d.cts +1 -1
- package/dist/animations/glyph-cycle.d.ts +1 -1
- package/dist/animations/{types-quh7NmYD.d.cts → types-CthJFfNx.d.cts} +7 -0
- package/dist/animations/{types-quh7NmYD.d.ts → types-CthJFfNx.d.ts} +7 -0
- package/dist/animations/wipe.d.cts +1 -1
- package/dist/animations/wipe.d.ts +1 -1
- package/dist/codegen.cjs +1 -1
- package/dist/codegen.js +1 -1
- package/dist/index.cjs +43 -43
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +320 -8
- package/dist/index.d.ts +320 -8
- package/dist/index.global.js +193 -192
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +43 -43
- package/dist/index.js.map +1 -1
- package/dist/launcher.global.js +117 -117
- package/dist/launcher.global.js.map +1 -1
- package/dist/smart-dom-reader.d.cts +110 -2
- package/dist/smart-dom-reader.d.ts +110 -2
- package/dist/theme-editor.cjs +30 -30
- package/dist/theme-editor.d.cts +124 -5
- package/dist/theme-editor.d.ts +124 -5
- package/dist/theme-editor.js +30 -30
- package/package.json +3 -3
- package/src/ask-user-question-tool.test.ts +148 -0
- package/src/ask-user-question-tool.ts +138 -0
- package/src/client.ts +43 -9
- package/src/codegen.test.ts +0 -14
- package/src/components/messages.ts +10 -0
- package/src/components/suggestions.ts +49 -6
- package/src/index-core.ts +15 -0
- package/src/runtime/host-layout.test.ts +206 -9
- package/src/runtime/host-layout.ts +121 -8
- package/src/runtime/init.test.ts +2 -2
- package/src/session.ts +188 -32
- package/src/session.webmcp.test.ts +48 -0
- package/src/suggest-replies-tool.test.ts +445 -0
- package/src/suggest-replies-tool.ts +152 -0
- package/src/theme-editor/index.ts +2 -0
- package/src/theme-editor/webmcp/index.ts +2 -0
- package/src/theme-editor/webmcp/types.ts +16 -3
- package/src/types.ts +108 -2
- package/src/ui.docked.test.ts +2 -2
- package/src/ui.suggest-replies.test.ts +237 -0
- package/src/ui.ts +57 -13
- package/src/utils/dock.test.ts +23 -1
- package/src/utils/dock.ts +2 -0
- package/src/voice/voice.test.ts +0 -51
- package/src/install-config.test.ts +0 -38
package/README.md
CHANGED
|
@@ -17,6 +17,8 @@ pnpm build
|
|
|
17
17
|
- `dist/index.js` (ESM), `dist/index.cjs` (CJS), and `dist/index.global.js` (IIFE) provide different module formats.
|
|
18
18
|
- `dist/widget.css` is the prefixed Tailwind bundle.
|
|
19
19
|
- `dist/install.global.js` is the automatic installer script for easy script tag installation.
|
|
20
|
+
- `dist/launcher.global.js` is the tiny critical launcher used by deferred script-tag installs before the full panel bundle loads.
|
|
21
|
+
- `dist/webmcp-polyfill.js` is the lazy WebMCP polyfill chunk used by the IIFE bundle only when `config.webmcp.enabled` is true and the page has no `document.modelContext`.
|
|
20
22
|
|
|
21
23
|
### Using with modules
|
|
22
24
|
|
|
@@ -92,33 +94,36 @@ const docked = initAgentWidget({
|
|
|
92
94
|
| --- | --- | --- |
|
|
93
95
|
| `target` | `string \| HTMLElement` | CSS selector or element where widget mounts. |
|
|
94
96
|
| `config` | `AgentWidgetConfig` | Widget configuration object (see the [Configuration Reference](./docs/CONFIGURATION-REFERENCE.md)). |
|
|
95
|
-
| `useShadowDom` | `boolean` | Use Shadow DOM for style isolation (default: `
|
|
97
|
+
| `useShadowDom` | `boolean` | Use Shadow DOM for style isolation (default: `false`). |
|
|
96
98
|
| `onChatReady` | `() => void` | Callback fired when the widget is initialized and its API is callable. |
|
|
97
99
|
| `onReady` | `() => void` | **Deprecated** alias of `onChatReady`; still works, removed in the next major. |
|
|
98
100
|
| `windowKey` | `string` | If provided, stores the controller on `window[windowKey]` for global access. Automatically cleaned up on `destroy()`. |
|
|
99
101
|
|
|
100
102
|
When `config.launcher.mountMode` is `'docked'`, `target` is treated as the page container that Persona should wrap. Use a concrete element such as `#workspace-main`; `body` and `html` are rejected.
|
|
101
103
|
|
|
104
|
+
**Height contract:** the docked shell sizes itself with `height: 100%`, so give it a definite height — usually `html, body { height: 100% }` or a fixed-height app-shell container around the target. If no ancestor provides one, the panel is clamped to `dock.maxHeight` (default `100dvh`; `resize`/`emerge` are also sticky-pinned — `push`/`overlay` get the cap only) so it stays viewport-sized and scrolls internally, and a console warning explains the fix. Override the cap with a CSS length or disable the guard with `dock.maxHeight: false`.
|
|
105
|
+
|
|
102
106
|
With **`dock.reveal: 'resize'`** (default), a **closed** dock uses a **`0px`** column. **`'emerge'`** uses the same **column width** animation (content reflows) but the chat panel stays **`dock.width`** wide and is **clipped** by the growing slot—like a normal-width widget emerging from the edge. **`'overlay'`** overlays with `transform`. **`'push'`** uses a sliding track (Shopify-style). The built-in launcher stays hidden in docked mode—open with **`controller.open()`** (or your own chrome).
|
|
103
107
|
|
|
104
108
|
**Rounded / card layout:** `initAgentWidget` inserts a flex **shell** as the **direct child** of your target’s **parent**, with your `target` in the content column and the dock beside it. Put border-radius, border, and `overflow: hidden` on that **parent** (or an ancestor that wraps only the shell) so the dock column sits inside the same visual card as your content.
|
|
105
109
|
|
|
106
|
-
**Inner push/overlay:** With `reveal: 'push'` or `'overlay'`, only the wrapped node moves. Use a **narrow `target`** (e.g. a main canvas div). For **`dock.side: 'left'`**, place a persistent rail **in flow** next to the stage (e.g. flex `[nav | stage]`) so the dock doesn’t open **under** the sidebar. For a **right** dock, you can instead use a **full-width** stage with an **absolute** left rail if you want the canvas to translate **behind** that rail.
|
|
110
|
+
**Inner push/overlay:** With `reveal: 'push'` or `'overlay'`, only the wrapped node moves. Use a **narrow `target`** (e.g. a main canvas div). For **`dock.side: 'left'`**, place a persistent rail **in flow** next to the stage (e.g. flex `[nav | stage]`) so the dock doesn’t open **under** the sidebar. For a **right** dock, you can instead use a **full-width** stage with an **absolute** left rail if you want the canvas to translate **behind** that rail. `position: fixed`/`sticky` content inside the target stays **viewport-anchored** (it is not pushed), so offset it while the dock is open if needed, e.g. `[data-persona-dock-open="true"] .my-fixed-bar { right: 420px; }`.
|
|
107
111
|
|
|
108
|
-
> **Security note:**
|
|
112
|
+
> **Security note:** Persona sanitizes rendered message HTML with DOMPurify by default (`sanitize: true`), including output returned from `postprocessMessage`, `markdownPostprocessor`, and `directivePostprocessor`. If your custom postprocessor intentionally returns tags or attributes outside the built-in allowlist, provide `sanitize: (html) => ...`; only set `sanitize: false` for fully trusted content.
|
|
109
113
|
|
|
110
114
|
### Documentation
|
|
111
115
|
|
|
112
116
|
The full reference lives in [`docs/`](./docs/) and the theming guide:
|
|
113
117
|
|
|
114
118
|
- [Programmatic Control & Events](./docs/PROGRAMMATIC-CONTROL.md) — controller API, message hooks and injection, enriched DOM context, WebMCP page tools, DOM and controller events, state loading
|
|
115
|
-
- [UI Features & Components](./docs/UI-COMPONENTS.md) — message actions and feedback, loading indicators,
|
|
116
|
-
- [Script Tag Installation & Framework Integration](./docs/INSTALLATION-FRAMEWORKS.md) — automatic installer, manual script tag setup, React, Next.js, Remix, Gatsby, and Astro guides
|
|
117
|
-
- [Configuration Reference](./docs/CONFIGURATION-REFERENCE.md) — every config option: core, client token mode, agent mode, UI & theme, launcher, layout, voice, tool calls, suggestion chips, state & storage
|
|
119
|
+
- [UI Features & Components](./docs/UI-COMPONENTS.md) — message actions and feedback, loading/idle indicators, approvals, built-in `ask_user_question` and `suggest_replies` tools, dropdown menus, button utilities, dynamic forms
|
|
120
|
+
- [Script Tag Installation & Framework Integration](./docs/INSTALLATION-FRAMEWORKS.md) — automatic installer, deferred launcher lifecycle hooks, manual script tag setup, React, Next.js, Remix, Gatsby, and Astro guides
|
|
121
|
+
- [Configuration Reference](./docs/CONFIGURATION-REFERENCE.md) — every config option: core, client token mode, agent mode, UI & theme, launcher/docking, layout, voice, WebMCP, tool calls, features, suggestion chips, state & storage
|
|
118
122
|
- [Stream Parser Configuration](./docs/STREAM-PARSERS.md) — JSON, XML, and plain-text stream parsers and custom parser factories
|
|
119
|
-
- [THEME-CONFIG.md](./THEME-CONFIG.md) — the complete theme and design-token reference
|
|
120
123
|
- [Message Injection](./docs/MESSAGE-INJECTION.md) — full injection and component-directive reference
|
|
121
124
|
- [Dynamic Forms](./docs/DYNAMIC-FORMS.md) — field schema, form styles, and recipes
|
|
125
|
+
- [Code Generator](./docs/CODE-GENERATOR.md) — `@runtypelabs/persona/codegen` options for CLI/server-side snippet generation
|
|
126
|
+
- [THEME-CONFIG.md](./THEME-CONFIG.md) — the complete theme and design-token reference
|
|
122
127
|
|
|
123
128
|
### Optional proxy server
|
|
124
129
|
|
|
@@ -196,7 +201,9 @@ Add `RUNTYPE_API_KEY` to your environment. The proxy constructs the Runtype payl
|
|
|
196
201
|
|
|
197
202
|
### Development notes
|
|
198
203
|
|
|
199
|
-
- The widget streams results using SSE and mirrors
|
|
200
|
-
- Tailwind
|
|
201
|
-
- Run `pnpm dev` from the repository root to boot the example proxy (`examples/
|
|
204
|
+
- The widget streams results using SSE and mirrors Runtype flow/agent events, including `step_await` local-tool pauses and `/resume` continuations.
|
|
205
|
+
- Tailwind classes are prefixed with `tvw-` and scoped to `[data-persona-root]`, so they won't collide with the host page.
|
|
206
|
+
- Run `pnpm dev` from the repository root to boot the example proxy (`examples/vercel-edge`) and the vanilla demo (`examples/embedded-app`).
|
|
202
207
|
- The proxy prefers port `43111` but automatically selects the next free port if needed.
|
|
208
|
+
- `features.askUserQuestion.expose` and `features.suggestReplies.expose` advertise built-in LOCAL client tools through `clientTools[]`; leave `expose` off if the flow already declares those tools server-side.
|
|
209
|
+
- `webmcp: { enabled: true }` snapshots page-registered tools on `document.modelContext`, sends them as `clientTools[]`, executes returned `webmcp:*` calls in the browser, and resumes the paused execution.
|
|
@@ -659,6 +659,13 @@ type AgentMessageMetadata = {
|
|
|
659
659
|
* paginated stepper. Persists alongside `askUserQuestionAnswers`.
|
|
660
660
|
*/
|
|
661
661
|
askUserQuestionIndex?: number;
|
|
662
|
+
/**
|
|
663
|
+
* Set to `true` once a `suggest_replies` tool call's fire-and-forget
|
|
664
|
+
* `/resume` has been accepted by the server. Persisted belt-and-suspenders
|
|
665
|
+
* mirror of the in-memory resolved-key dedupe, so hydration/re-emit paths
|
|
666
|
+
* never re-resume the call.
|
|
667
|
+
*/
|
|
668
|
+
suggestRepliesResolved?: boolean;
|
|
662
669
|
};
|
|
663
670
|
/**
|
|
664
671
|
* Context passed to plugin lifecycle hooks. Carries the live DOM references
|
|
@@ -659,6 +659,13 @@ type AgentMessageMetadata = {
|
|
|
659
659
|
* paginated stepper. Persists alongside `askUserQuestionAnswers`.
|
|
660
660
|
*/
|
|
661
661
|
askUserQuestionIndex?: number;
|
|
662
|
+
/**
|
|
663
|
+
* Set to `true` once a `suggest_replies` tool call's fire-and-forget
|
|
664
|
+
* `/resume` has been accepted by the server. Persisted belt-and-suspenders
|
|
665
|
+
* mirror of the in-memory resolved-key dedupe, so hydration/re-emit paths
|
|
666
|
+
* never re-resume the call.
|
|
667
|
+
*/
|
|
668
|
+
suggestRepliesResolved?: boolean;
|
|
662
669
|
};
|
|
663
670
|
/**
|
|
664
671
|
* Context passed to plugin lifecycle hooks. Carries the live DOM references
|
package/dist/codegen.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";var $=Object.defineProperty;var M=Object.getOwnPropertyDescriptor;var R=Object.getOwnPropertyNames;var v=Object.prototype.hasOwnProperty;var I=(e,r)=>{for(var n in r)$(e,n,{get:r[n],enumerable:!0})},W=(e,r,n,s)=>{if(r&&typeof r=="object"||typeof r=="function")for(let o of R(r))!v.call(e,o)&&o!==n&&$(e,o,{get:()=>r[o],enumerable:!(s=M(r,o))||s.enumerable});return e};var H=e=>W($({},"__esModule",{value:!0}),e);var B={};I(B,{generateCodeSnippet:()=>_});module.exports=H(B);var x="3.
|
|
1
|
+
"use strict";var $=Object.defineProperty;var M=Object.getOwnPropertyDescriptor;var R=Object.getOwnPropertyNames;var v=Object.prototype.hasOwnProperty;var I=(e,r)=>{for(var n in r)$(e,n,{get:r[n],enumerable:!0})},W=(e,r,n,s)=>{if(r&&typeof r=="object"||typeof r=="function")for(let o of R(r))!v.call(e,o)&&o!==n&&$(e,o,{get:()=>r[o],enumerable:!(s=M(r,o))||s.enumerable});return e};var H=e=>W($({},"__esModule",{value:!0}),e);var B={};I(B,{generateCodeSnippet:()=>_});module.exports=H(B);var x="3.34.0";var c=x;function u(e){if(e!==void 0)return typeof e=="string"?e:Array.isArray(e)?`[${e.map(r=>r.toString()).join(", ")}]`:e.toString()}function D(e){if(e)return{getHeaders:u(e.getHeaders),onFeedback:u(e.onFeedback),onCopy:u(e.onCopy),requestMiddleware:u(e.requestMiddleware),actionHandlers:u(e.actionHandlers),actionParsers:u(e.actionParsers),postprocessMessage:u(e.postprocessMessage),contextProviders:u(e.contextProviders),streamParser:u(e.streamParser)}}var A=`({ text, message }: any) => {
|
|
2
2
|
const jsonSource = (message as any).rawContent || text || message.content;
|
|
3
3
|
if (!jsonSource || typeof jsonSource !== 'string') return null;
|
|
4
4
|
let cleanJson = jsonSource
|
package/dist/codegen.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var S="3.
|
|
1
|
+
var S="3.34.0";var c=S;function u(e){if(e!==void 0)return typeof e=="string"?e:Array.isArray(e)?`[${e.map(r=>r.toString()).join(", ")}]`:e.toString()}function T(e){if(e)return{getHeaders:u(e.getHeaders),onFeedback:u(e.onFeedback),onCopy:u(e.onCopy),requestMiddleware:u(e.requestMiddleware),actionHandlers:u(e.actionHandlers),actionParsers:u(e.actionParsers),postprocessMessage:u(e.postprocessMessage),contextProviders:u(e.contextProviders),streamParser:u(e.streamParser)}}var x=`({ text, message }: any) => {
|
|
2
2
|
const jsonSource = (message as any).rawContent || text || message.content;
|
|
3
3
|
if (!jsonSource || typeof jsonSource !== 'string') return null;
|
|
4
4
|
let cleanJson = jsonSource
|