@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 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`). Slash commands: `/status`, `/tools`, `/raw <tool> <json>`, `/quit`.
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
- - `repl.js` + `llmClient.js` — the REPL driver.
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-bridge.test.cjs` covers the wire protocol.
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).