@runtypelabs/persona-proxy 3.33.0 → 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 +21 -3
- package/dist/index.cjs +91 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +20 -1
- package/dist/index.d.ts +20 -1
- package/dist/index.js +90 -0
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/flows/index.ts +1 -0
- package/src/flows/webmcp-paint.ts +107 -0
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
## Vanilla Agent Proxy
|
|
2
2
|
|
|
3
|
-
Proxy server library for `@runtypelabs/persona` widget. Handles flow configuration
|
|
3
|
+
Proxy server library for `@runtypelabs/persona` widget. Handles flow configuration, CORS, feedback collection, WebMCP/client-tool forwarding, `/resume` continuations, and secure forwarding to Runtype.
|
|
4
4
|
|
|
5
5
|
### Installation
|
|
6
6
|
|
|
@@ -10,7 +10,7 @@ npm install @runtypelabs/persona-proxy
|
|
|
10
10
|
|
|
11
11
|
### Usage
|
|
12
12
|
|
|
13
|
-
The proxy server handles flow configuration and forwards requests to Runtype. You can configure
|
|
13
|
+
The proxy server handles flow configuration and forwards requests to Runtype. It mounts both the dispatch endpoint (default `/api/chat/dispatch`) and a matching child resume endpoint (`/api/chat/dispatch/resume`) so browser-executed LOCAL tools such as WebMCP page tools, `ask_user_question`, and `suggest_replies` can resume a paused execution. You can configure dispatch in three ways:
|
|
14
14
|
|
|
15
15
|
**Option 1: Use default flow (recommended for getting started)**
|
|
16
16
|
|
|
@@ -88,10 +88,28 @@ export default createVercelHandler({
|
|
|
88
88
|
| `allowedOrigins` | `string[]` | CORS allowed origins |
|
|
89
89
|
| `flowId` | `string` | Runtype flow ID to use |
|
|
90
90
|
| `flowConfig` | `RuntypeFlowConfig` | Custom flow configuration |
|
|
91
|
+
| `feedbackPath` | `string` | Message-feedback endpoint path. Default: `/api/feedback`. |
|
|
92
|
+
| `onFeedback` | `(feedback) => Promise<void> \| void` | Optional handler for upvote/downvote payloads. |
|
|
93
|
+
| `previewOriginPattern` | `RegExp \| false` | Additional dynamic preview-origin allowlist (defaults to `https://*.vercel.app`; disable with `false`). |
|
|
94
|
+
|
|
95
|
+
### WebMCP and built-in client tools
|
|
96
|
+
|
|
97
|
+
For flow-dispatch requests, the proxy preserves `clientTools[]` from the widget payload and forwards them upstream so Runtype can register browser-local tools for that turn. Tool results are sent by the widget to `${path}/resume`, and the proxy forwards that body to the upstream `/resume` endpoint using the same API key. Agent-mode payloads are forwarded as-is and also retain `clientTools[]`.
|
|
98
|
+
|
|
99
|
+
### CORS behavior
|
|
100
|
+
|
|
101
|
+
- If `allowedOrigins` is omitted or empty, the proxy reflects the request origin (or `*`).
|
|
102
|
+
- If `allowedOrigins` is set, exact matches are allowed.
|
|
103
|
+
- `NODE_ENV=development` reflects local dev origins even when they are not in `allowedOrigins`; an unset `NODE_ENV` is treated as production.
|
|
104
|
+
- Vercel preview deployments (`VERCEL_ENV=preview`) and origins matching `previewOriginPattern` are reflected so per-branch preview URLs work without enumerating them.
|
|
105
|
+
|
|
106
|
+
### Feedback endpoint
|
|
107
|
+
|
|
108
|
+
`messageActions` feedback can POST to `feedbackPath` (default `/api/feedback`). The built-in handler validates `type` (`upvote`/`downvote`) and `messageId`, adds a timestamp, logs in development, and then calls `onFeedback` if provided.
|
|
91
109
|
|
|
92
110
|
### Environment Setup
|
|
93
111
|
|
|
94
|
-
Add `RUNTYPE_API_KEY` to your environment. The proxy constructs the Runtype payload (including flow configuration) and streams the response back to the client.
|
|
112
|
+
Add `RUNTYPE_API_KEY` to your environment. The proxy constructs the Runtype payload (including flow configuration/client tools) and streams the response back to the client.
|
|
95
113
|
|
|
96
114
|
### Building
|
|
97
115
|
|
package/dist/index.cjs
CHANGED
|
@@ -31,6 +31,7 @@ __export(index_exports, {
|
|
|
31
31
|
THEME_ASSISTANT_FLOW: () => THEME_ASSISTANT_FLOW,
|
|
32
32
|
WEBMCP_CALENDAR_FLOW: () => WEBMCP_CALENDAR_FLOW,
|
|
33
33
|
WEBMCP_DOCKED_FLOW: () => WEBMCP_DOCKED_FLOW,
|
|
34
|
+
WEBMCP_PAINT_FLOW: () => WEBMCP_PAINT_FLOW,
|
|
34
35
|
WEBMCP_SLIDES_FLOW: () => WEBMCP_SLIDES_FLOW,
|
|
35
36
|
WEBMCP_STOREFRONT_FLOW: () => WEBMCP_STOREFRONT_FLOW,
|
|
36
37
|
createChatProxyApp: () => createChatProxyApp,
|
|
@@ -776,6 +777,95 @@ Keep options concrete and visual, never generic ("Option A"). Do NOT use it for
|
|
|
776
777
|
]
|
|
777
778
|
};
|
|
778
779
|
|
|
780
|
+
// src/flows/webmcp-paint.ts
|
|
781
|
+
var WEBMCP_PAINT_FLOW = {
|
|
782
|
+
name: "WebMCP Paint Flow",
|
|
783
|
+
description: "Paint Pal \u2014 paints in an embedded jspaint via page-provided WebMCP tools (clientTools[]), with a snapshot-and-look visual loop",
|
|
784
|
+
steps: [
|
|
785
|
+
{
|
|
786
|
+
id: "webmcp_paint_prompt",
|
|
787
|
+
name: "WebMCP Paint Prompt",
|
|
788
|
+
type: "prompt",
|
|
789
|
+
enabled: true,
|
|
790
|
+
config: {
|
|
791
|
+
model: "gemini-3.5-flash",
|
|
792
|
+
reasoning: false,
|
|
793
|
+
responseFormat: "markdown",
|
|
794
|
+
outputVariable: "prompt_result",
|
|
795
|
+
userPrompt: "{{user_message}}",
|
|
796
|
+
systemPrompt: `You are Paint Pal, an assistant that paints inside a real MS Paint (jspaint) running on this page. Your tools click the same toolbox, draw the same strokes, and land on the same undo stack the user's mouse would \u2014 the user watches every stroke animate live.
|
|
797
|
+
|
|
798
|
+
Voice: playful and brief. A sentence or two around the actions you take; never narrate every tool call.
|
|
799
|
+
|
|
800
|
+
## The canvas
|
|
801
|
+
|
|
802
|
+
A {{paint_context}} block rides along with every message: canvas width/height in pixels, the selected tool, and the current colors. The origin is the TOP-LEFT corner; x grows right, y grows down. Never guess the canvas size \u2014 read it from the context. Keep drawings comfortably inside the canvas with a ~20px margin.
|
|
803
|
+
|
|
804
|
+
## How to paint well
|
|
805
|
+
|
|
806
|
+
- Plan like a painter: large background regions first (sky, ground, sea), then big shapes, then details and outlines last. Paint covers what's under it.
|
|
807
|
+
- Prefer shape tools over freehand for geometry: select line/rectangle/ellipse and pass exactly 2 points (endpoints or opposite corners) to draw_stroke. Use pencil/brush freehand strokes for organic curves, and pass dense-enough points (every ~10-20px) so curves look smooth.
|
|
808
|
+
- flood_fill fills a contiguous region with a color \u2014 fill large areas instead of scribbling them in. Fill only works as expected on closed regions; draw the outline first.
|
|
809
|
+
- draw_stroke and flood_fill accept an optional tool and color in the same call \u2014 use those riders instead of separate select_tool / set_colors calls.
|
|
810
|
+
- Budget yourself: a typical drawing should take roughly 5-15 tool calls. If you catch yourself queueing dozens of strokes, simplify the plan.
|
|
811
|
+
|
|
812
|
+
## Look at your work (important)
|
|
813
|
+
|
|
814
|
+
After finishing a drawing \u2014 or whenever you are unsure how something came out \u2014 call get_canvas_snapshot and LOOK at the image it returns. If something is off (a floating roof, a fill that leaked, a lopsided circle), fix it: undo if needed, then redraw. One check-and-fix pass is usually enough; don't loop endlessly chasing perfection. Also use the snapshot when the user asks what's on the canvas or draws something for you to react to or guess.
|
|
815
|
+
|
|
816
|
+
## Game modes
|
|
817
|
+
|
|
818
|
+
The page advertises three games. Play along enthusiastically when the user picks one (or invents a variant).
|
|
819
|
+
|
|
820
|
+
### Pictionary (the user draws, you guess)
|
|
821
|
+
|
|
822
|
+
1. When the user proposes Pictionary, invite them to draw on the canvas and say "done" (suggest they pick something fun; do NOT draw anything yourself). Tip them to draw BIG with the brush \u2014 thin 1px pencil lines are genuinely hard for you to see in the snapshot.
|
|
823
|
+
2. When they say done, call get_canvas_snapshot and LOOK. Make your best guess; if unsure, give up to 3 ranked guesses with a word of reasoning ("the long ears say rabbit, but it could be a donkey").
|
|
824
|
+
3. React to the reveal like a good game-night opponent \u2014 gracious in defeat, smug in victory, always brief.
|
|
825
|
+
4. Offer the reverse round: you draw, they guess. When drawing, do NOT announce the subject \u2014 draw it, then ask for their guess.
|
|
826
|
+
|
|
827
|
+
### Paint-along tutorial (you teach, the user copies)
|
|
828
|
+
|
|
829
|
+
When the user asks to learn to draw something step by step:
|
|
830
|
+
|
|
831
|
+
1. Plan 3-5 simple steps (e.g. cat: head circle -> ears -> face -> whiskers -> body). Keep each step to 1-3 strokes.
|
|
832
|
+
2. Demonstrate on the LEFT HALF of the canvas only \u2014 the right half belongs to the user's copy. Say what you did in a few words.
|
|
833
|
+
3. After each step, if an **ask_user_question** tool is available, use it to pause: ask whether they're ready, with options like "Done \u2014 check my work", "Show me again", and "Skip ahead". Without the tool, just ask in prose.
|
|
834
|
+
4. When they say done, call get_canvas_snapshot, compare their right-half attempt to your left-half demo, and give one sentence of warm, specific feedback ("your ears are great \u2014 try making the whiskers longer") before the next step.
|
|
835
|
+
5. At the end, congratulate them and offer render_replay_gif so they can keep the whole lesson as an animated replay.
|
|
836
|
+
|
|
837
|
+
### Speedrun (a masterpiece against the clock)
|
|
838
|
+
|
|
839
|
+
When the user calls for a speedrun ("the Mona Lisa in 20 strokes"):
|
|
840
|
+
|
|
841
|
+
1. Honor the stroke budget strictly \u2014 count every draw_stroke and flood_fill against it. Default to 20 if unspecified.
|
|
842
|
+
2. Go bold and confident: large fills first, then the fewest, most evocative strokes. NO mid-run snapshot-and-fix loops \u2014 a speedrun is one take. (One snapshot at the very end is allowed, for the post-run commentary.)
|
|
843
|
+
3. When the budget is spent, call render_replay_gif so the user gets the animated replay \u2014 that GIF is the trophy. Tell them to hit Save in the window that opens.
|
|
844
|
+
4. Sign off with one line of artist's-statement bravado about what you made.
|
|
845
|
+
|
|
846
|
+
## Etiquette
|
|
847
|
+
|
|
848
|
+
- Everything you draw lands on the paint app's undo stack; the user can reverse you with Ctrl+Z. Don't be precious.
|
|
849
|
+
- clear_canvas asks the user for confirmation \u2014 if they decline, accept it and move on.
|
|
850
|
+
- After drawing, confirm briefly what you made \u2014 the user watched it happen, so don't re-describe every shape.
|
|
851
|
+
- If a tool reports an error, relay it plainly and suggest the fix.
|
|
852
|
+
- Never mention JSON, tool schemas, coordinates, or the WebMCP mechanism unless the user asks.
|
|
853
|
+
|
|
854
|
+
## Acting vs. claiming (critical)
|
|
855
|
+
|
|
856
|
+
- You can only change the canvas by calling a tool. Text alone draws nothing.
|
|
857
|
+
- Never say you drew anything unless a tool call you made IN THIS TURN returned a success result. If you have not called the tool yet, call it now instead of replying.
|
|
858
|
+
- If the user sends a bare confirmation ("do it", "yes", "go ahead") and your last reply proposed a drawing you did NOT execute, execute it now with tools.
|
|
859
|
+
|
|
860
|
+
## Live canvas state
|
|
861
|
+
|
|
862
|
+
{{paint_context}}`,
|
|
863
|
+
previousMessages: "{{messages}}"
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
]
|
|
867
|
+
};
|
|
868
|
+
|
|
779
869
|
// src/flows/webmcp-docked.ts
|
|
780
870
|
var WEBMCP_DOCKED_FLOW = {
|
|
781
871
|
name: "WebMCP Docked Dashboard Flow",
|
|
@@ -1376,6 +1466,7 @@ var index_default = createChatProxyApp;
|
|
|
1376
1466
|
THEME_ASSISTANT_FLOW,
|
|
1377
1467
|
WEBMCP_CALENDAR_FLOW,
|
|
1378
1468
|
WEBMCP_DOCKED_FLOW,
|
|
1469
|
+
WEBMCP_PAINT_FLOW,
|
|
1379
1470
|
WEBMCP_SLIDES_FLOW,
|
|
1380
1471
|
WEBMCP_STOREFRONT_FLOW,
|
|
1381
1472
|
createChatProxyApp,
|