@theprototype/agent 1.48.0 → 1.50.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 +54 -5
- package/catalog.json +1224 -0
- package/package.json +3 -2
- package/src/browserEngine.js +12 -0
- package/src/catalog.js +114 -0
- package/src/chat.js +303 -0
- package/src/llmClient.js +81 -9
- package/src/mcpServer.js +62 -9
- package/src/repl.js +243 -27
package/README.md
CHANGED
|
@@ -45,7 +45,7 @@ generation when the host has a mesh provider ready. Each tool's JSON schema is p
|
|
|
45
45
|
unchanged. When the host's set changes (a provider comes online, a role changes) the client is
|
|
46
46
|
told (`tools/list_changed`).
|
|
47
47
|
|
|
48
|
-
Beside them, four of the bridge's own:
|
|
48
|
+
Beside them, four of the bridge's own (plus the chat tools below):
|
|
49
49
|
|
|
50
50
|
| tool | what it does |
|
|
51
51
|
|---|---|
|
|
@@ -56,6 +56,48 @@ Beside them, four of the bridge's own:
|
|
|
56
56
|
|
|
57
57
|
Scene tools answer "not in the session yet" until the host lets the agent in.
|
|
58
58
|
|
|
59
|
+
## Talk to it from the app
|
|
60
|
+
|
|
61
|
+
People in the session can type to the agent in the app's **AI assistant** window (pick it in the
|
|
62
|
+
target list: "Claude · agent via MCP"). An MCP host only acts while its model runs, so the agent
|
|
63
|
+
has to be *listening*. Tell it once in the terminal:
|
|
64
|
+
|
|
65
|
+
> listen to my theprototype session
|
|
66
|
+
|
|
67
|
+
and it loops: `wait_for_message` → builds with the scene tools → `reply` → `wait_for_message`.
|
|
68
|
+
Its badge in the window says **listening**, **working** or **away**. The terminal stays a full
|
|
69
|
+
second window onto the same conversation: what you type there shows in the app "via terminal".
|
|
70
|
+
|
|
71
|
+
| tool | what it does |
|
|
72
|
+
|---|---|
|
|
73
|
+
| `wait_for_message` | blocks until someone types to the agent (`timeoutS`, default 240, at most 600); `null` = nobody wrote, wait again. The message has `from`, `name`, `role`, `text`, `chatId`, and its images |
|
|
74
|
+
| `reply` | streams into the window: each call adds a paragraph, `final: true` finishes it. `prompt` = the user's own words typed in the terminal, shown "via terminal" |
|
|
75
|
+
| `ask` | buttons in the window; the click comes back through `wait_for_message` with `answers` |
|
|
76
|
+
| `get_thread` | page back through a chat (`chatId`, `before`, `limit`) |
|
|
77
|
+
|
|
78
|
+
- **Roles.** Every message carries the sender's role as the agent's page knows it. A viewer may ask,
|
|
79
|
+
but while a viewer's request runs every edit is refused, and a viewer's images are dropped.
|
|
80
|
+
- **Stop.** The window's Stop marks the request cancelled: every later tool call returns
|
|
81
|
+
`cancelled` until the next message.
|
|
82
|
+
- **Images.** Each image arrives as an MCP image block (the model sees it) and as a private temp
|
|
83
|
+
file (`0600`, removed when the bridge exits) whose path is in the message — for a skill that wants
|
|
84
|
+
a file as its reference. The app downscales them and strips EXIF/GPS before they are sent.
|
|
85
|
+
- **Chats.** Every message carries its `chatId`. The first message in a chat the agent has not seen
|
|
86
|
+
this session carries `history` (its newest 20 messages) and a `summary`; `get_thread` pages back.
|
|
87
|
+
A host or admin can mute the agent (nothing is delivered) or remove it from **Users**.
|
|
88
|
+
- **`import_model`** (when the app offers it): pass `path` for a local `.glb` (≤ 25 MB, a
|
|
89
|
+
self-contained binary glTF); the bridge reads it and sends the bytes.
|
|
90
|
+
- **`import_file`** (when the app offers it): pass `path` for a local PNG / WebP (≤ 16 MB), JSON
|
|
91
|
+
(≤ 2 MB) or `.tpanim` clip, and optionally `spec_path` for the generator's input (a Pixling spec).
|
|
92
|
+
The bridge reads both, checks the type from the bytes and the size before sending anything, and
|
|
93
|
+
splits a big file into `chunk` calls itself. The file lands in Explorer ▸ Generated for everyone
|
|
94
|
+
(`knight_walk.png` + `knight_walk.pixling.json`); an image is also placed as a card in the scene
|
|
95
|
+
(`filter: "nearest"` for pixel art, `frame` for one frame of a sheet, `facing` to face the viewer).
|
|
96
|
+
Viewers' agents are refused. Works the same in `repl`.
|
|
97
|
+
|
|
98
|
+
With `repl` the bridge owns the model loop, so app messages go straight in as user turns — no
|
|
99
|
+
terminal needed after launch; replies stream (SSE) and terminal lines show "via terminal".
|
|
100
|
+
|
|
59
101
|
## How it joins
|
|
60
102
|
|
|
61
103
|
The agent opens your link in a headless browser: it **is** the app, as a peer. So it signals
|
|
@@ -82,7 +124,10 @@ npx @theprototype/agent smoke <link> # a scripted create / move / delete, no
|
|
|
82
124
|
```
|
|
83
125
|
|
|
84
126
|
`repl` drives the scene from your own OpenAI-compatible endpoint (or `AGENT_API_URL`,
|
|
85
|
-
`AGENT_API_KEY`, `AGENT_MODEL`)
|
|
127
|
+
`AGENT_API_KEY`, `AGENT_MODEL`), and answers what people type in the app's AI assistant window
|
|
128
|
+
(images go to the model as `image_url` parts; a text-only model is retried without them).
|
|
129
|
+
Slash commands: `/status`, `/tools`, `/raw <tool> <json>`, `/quit`. With stdin closed (a script,
|
|
130
|
+
a service) it keeps answering the app until Ctrl+C / SIGTERM.
|
|
86
131
|
|
|
87
132
|
### The wire engine
|
|
88
133
|
|
|
@@ -125,14 +170,18 @@ deployment (`https://preview-1-45.theprototype.pages.dev/#F0FD3`), a local dev s
|
|
|
125
170
|
tools, list refresh, the not-yet-in-the-session gate, graceful shutdown.
|
|
126
171
|
- `wireEngine.js` + `peerBridge.js` + `turn.js` + `messages.js` + `registry.js` + `tools.js` —
|
|
127
172
|
the wire engine: the approval dance, the minimal handshake, TURN, the goodbye.
|
|
128
|
-
- `
|
|
173
|
+
- `chat.js` — the chat tools, the image temp files, `import_model`'s / `import_file`'s local paths (chunking).
|
|
174
|
+
- `repl.js` + `llmClient.js` — the REPL driver (terminal + app messages, one transcript, SSE).
|
|
129
175
|
|
|
130
176
|
## Tests
|
|
131
177
|
|
|
132
178
|
```
|
|
133
|
-
npm test # link parsing, tool mapping + the MCP server over a fake engine, the wire engine (no network)
|
|
179
|
+
npm test # link parsing, tool mapping + the MCP server over a fake engine, chat, REPL vs a stub endpoint, the wire engine (no network)
|
|
134
180
|
```
|
|
135
181
|
|
|
136
182
|
End to end (in the app repo, against a dev server): `tests/e2e/agent-mcp.test.cjs` — a real MCP
|
|
137
183
|
stdio client spawns this bridge, a Playwright host page approves it, and the agent's edits land
|
|
138
|
-
in the host's scene; `tests/e2e/agent-
|
|
184
|
+
in the host's scene; `tests/e2e/agent-chat.test.cjs` — the chat loop (wait → exec → reply, roles,
|
|
185
|
+
Stop, images, history, mute) and REPL mode against a stub endpoint; `tests/e2e/agent-bridge.test.cjs`
|
|
186
|
+
covers the wire protocol. `TP_AGENT_INIT_SCRIPT=<file>` adds an init script to the agent page
|
|
187
|
+
(a test / diagnostic seam).
|