@robota-sdk/agent-cli 3.0.0-beta.93 → 3.0.0-beta.95

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.
Files changed (33) hide show
  1. package/CHANGELOG.md +221 -0
  2. package/README.md +7 -1
  3. package/dist/node/bin.js +16 -16
  4. package/dist/node/cli-core-DJIgDK0t.js +2920 -0
  5. package/dist/node/desktop-host.js +1 -1
  6. package/dist/node/headless.js +1 -1
  7. package/dist/node/host.d.ts +1 -1
  8. package/dist/node/host.js +1 -1
  9. package/dist/node/index.d.ts +2 -1
  10. package/dist/node/index.d.ts.map +1 -1
  11. package/dist/node/index.js +2 -2
  12. package/dist/node/{node-DDxqAmr9.js → node-BBey07fn.js} +7 -7
  13. package/dist/node/node-BBey07fn.js.map +1 -0
  14. package/dist/node/{node-CVEUtnXS.js → node-BOLpvRke.js} +2 -2
  15. package/dist/node/{node-CVEUtnXS.js.map → node-BOLpvRke.js.map} +1 -1
  16. package/dist/node/{node-DAf6oQNY.js → node-Bxcf0vqP.js} +6 -6
  17. package/dist/node/{node-DXIaHonc.js → node-CV7kyP4U.js} +1 -1
  18. package/dist/node/{node-BrAmtuTw.js → node-Dr_K99X7.js} +5 -5
  19. package/dist/node/{node-BrAmtuTw.js.map → node-Dr_K99X7.js.map} +1 -1
  20. package/dist/node/{node-1Kk9kvit.js → node-DsYjDBKf.js} +4 -4
  21. package/dist/node/{product-host-DqZRpcAh.d.ts → product-host-BACfuTu4.d.ts} +40 -11
  22. package/dist/node/product-host-BACfuTu4.d.ts.map +1 -0
  23. package/dist/node/product-host-BwV-X6oS.js +2954 -0
  24. package/dist/node/product-host-BwV-X6oS.js.map +1 -0
  25. package/dist/web/assets/index-DB915Rm-.js +314 -0
  26. package/dist/web/index.html +1 -1
  27. package/package.json +43 -37
  28. package/dist/node/cli-core-DutvpRdJ.js +0 -2921
  29. package/dist/node/node-DDxqAmr9.js.map +0 -1
  30. package/dist/node/product-host-DqZRpcAh.d.ts.map +0 -1
  31. package/dist/node/product-host-zZ2TTtQk.js +0 -2955
  32. package/dist/node/product-host-zZ2TTtQk.js.map +0 -1
  33. package/dist/web/assets/index-BQP0NBgG.js +0 -309
package/CHANGELOG.md CHANGED
@@ -1,5 +1,226 @@
1
1
  # @robota-sdk/agent-cli
2
2
 
3
+ ## 3.0.0-beta.95
4
+ ### Minor Changes
5
+
6
+ - c967c57: `robota acp` runs the agent as an Agent Client Protocol (v1) agent over stdio, so an editor that launches it (Zed, JetBrains and other ACP clients) can create a session, send prompts, see streamed replies and tool calls, approve or reject permission requests, and cancel a turn. Workspace trust, permission rules and the sandbox behave as in the terminal: the editor answers prompts and widens nothing. A folder that is not trusted yet is refused at `session/new` with the `trust` command to run, a working directory other than the one the agent was started in and any editor-supplied MCP servers or extra roots are refused, and a prompt that starts with `/` runs that command.
7
+
8
+ New package `@robota-sdk/agent-transport-acp` provides `createAcpTransport`, the ACP `ITransportAdapter` the command uses.
9
+
10
+ `@robota-sdk/agent-transport/node` gains `attachStdioCarrier`, the process-input bridge and close observation a stdio protocol carrier shares. `agent-transport-mcp` now uses it for its stdio carrier; its behavior is unchanged.
11
+ - 04a6de4: **Reasoning text a provider streams now reaches the editor as an ACP `agent_thought_chunk`, through a new `thinking_delta` session event.**
12
+
13
+ `IChatOptions.onThinkingDelta`, `IRunOptions.onThinkingDelta` and `IResumeExecutionOptions.onThinkingDelta`
14
+ (typed `TThinkingDeltaCallback`) carry reasoning text from a provider through the run, and the session
15
+ options (`ISessionOptions.onThinkingDelta`, `ICreateSessionOptions.onThinkingDelta`) hand it to the
16
+ session's owner. `InteractiveSession` emits it as `thinking_delta(delta)`, beside `text_delta`. The
17
+ text is never part of the reply: it is not appended to the conversation, not streamed through
18
+ `onTextDelta`, and the core adds no record of its own for it (no text-delta log entry, no
19
+ `provider_stream_raw_delta`); a provider's own native payload capture and response metadata keep
20
+ what the provider sent, as before. A reasoning delta counts as provider activity for the idle
21
+ timeout whether or not anyone listens to it, so a model that is only thinking is not cut off. The
22
+ existing `thinking(isThinking)` event is unchanged and remains the busy indicator. Where a provider
23
+ sends no reasoning text, nothing is emitted and nothing new is switched on.
24
+
25
+ `@robota-sdk/agent-interface-session` is a major change because a new session event name makes an
26
+ exhaustive map over the event names stop compiling until it classifies the event.
27
+
28
+ `@robota-sdk/agent-transport-acp` sends each non-empty `thinking_delta` to the editor as an
29
+ `agent_thought_chunk`, in order with the message chunks, so `robota acp` shows the model's reasoning
30
+ in the editor. A turn that streamed only thoughts still shows its result text, because only reply
31
+ text marks a turn as streamed. The WebSocket wire, the HTTP stream, headless stream-json, `query()`
32
+ and the terminal UI do not carry the new event in this change (`@robota-sdk/agent-transport` and
33
+ `@robota-sdk/agent-ui-terminal` classify it as non-surface). A forked skill and an in-process subagent
34
+ pass their reply text up but not their reasoning.
35
+
36
+ Two providers already receive reasoning text and now report it. `@robota-sdk/agent-provider-openai`
37
+ passes `response.reasoning_summary_text.delta` events of a streamed Responses call to
38
+ `onThinkingDelta`; the API sends them only when the provider profile asks for a reasoning summary, and
39
+ no request option changed; a summary streamed in several parts, and the summary of a later reasoning
40
+ item, each start on a new paragraph (`\n\n`) so the parts do not run together.
41
+ `@robota-sdk/agent-provider-openai-compatible` reports the text of Gemma's thought channel, which the
42
+ provider already removed from the reply, as it streams across chunk boundaries, with each later
43
+ channel of one reply on a new paragraph; the reply text is unchanged. No other provider reports
44
+ reasoning, and Anthropic thinking is not enabled. A model fallback chain still moves to the next model when only reasoning had streamed.
45
+
46
+ The scripted test provider (`@robota-sdk/agent-core/testing`) accepts an optional `thinking` string on
47
+ a turn and delivers it through `onThinkingDelta` before the turn's text; the scripted session harness
48
+ collects `thinking_delta` and now keeps a scripted tool-call turn's `usage`, which it used to drop.
49
+
50
+ ### Patch Changes
51
+
52
+ - 09e7e21: **An MCP server's form-mode elicitation during a tool call becomes a Robota ask prompt.**
53
+
54
+ `@robota-sdk/agent-mcp` opens a session with `elicitation: true` to declare form-mode elicitation and
55
+ answer it: a request the server raises while a tool call is in flight (a server→client
56
+ `elicitation/create` on the legacy era, an `input_required` round on 2026-07-28) is put to a person
57
+ through that call's ask port (`IMCPToolCallOptions.ask`, which the discovered tool fills from
58
+ `IToolExecutionContext.ask`) as one question titled with the configured server id and carrying the
59
+ server's message as one bounded line, with Respond and Decline, then one question per field
60
+ (choices, multi-select, yes/no, or free text validated against the field and re-asked once). The
61
+ answer continues the same call; the re-sent `tools/call` that carries it is the protocol's
62
+ continuation, not a replay, and a prompt is withdrawn when its call ends (an abort, or the call's
63
+ own timeout) — when the last in-flight call to that server ends, if there are several, since a
64
+ request names none of them. A request outside an in-flight call, or during a call that has no ask port, is
65
+ declined; a dismissal, a failing port or a second rejected answer cancels; a field named like a
66
+ credential is shown unmasked with a warning. URL mode is not offered. Without the opt-in nothing
67
+ changes: no capability is declared and an `input_required` result still closes the carrier. An
68
+ embedded request of another kind (sampling, roots) or more rounds than the client allows closes the
69
+ carrier as `input_required` does; an embedded elicitation the client refuses on its face (URL mode,
70
+ a malformed form) fails the call and leaves the carrier open.
71
+
72
+ `@robota-sdk/agent-cli` turns the opt-in on for the interactive terminal and the serve host driven by
73
+ the desktop app or the web GUI, which show the prompt, and leaves it off for print mode and for the
74
+ two serve-runtime hosts with no prompt surface, `mcp serve` and the ACP editor agent.
75
+
76
+ `@robota-sdk/agent-ui-web` renders an ask with `maxSelect` above 1 as a multi-select: options toggle
77
+ (click or 1–9), Submit answers with the ticked values once `minSelect` is met, and a toggle beyond
78
+ `maxSelect` is ignored, as in the terminal.
79
+ - 60f3965: **`robota mcp serve --ask-client` puts a caller's permission and ask prompts to the calling MCP client through elicitation instead of failing them.**
80
+
81
+ `@robota-sdk/agent-transport-mcp`: `createMcpTransport`, `createMcpHttpHost`,
82
+ `createMcpRemoteHttpHost` and `createAgentMcpServer` take `askClient`. Off by default, every prompt
83
+ is a tool error as before. On, and when the client declared form-mode elicitation, a permission or
84
+ ask prompt raised by that client's own call is put to it: a permission offers allow once or deny
85
+ only, never a remembered grant; an ask becomes a form (choice, multiple choice, free text); a masked
86
+ ask is never sent; deny, decline, cancel, a client error or an answer naming nothing offered keeps
87
+ today's outcome. stdio asks during the call. The HTTP hosts keep no session state, so they ask only
88
+ a client on the 2026-07-28 revision, through input-required rounds whose `requestState` is a
89
+ single-use random token naming one parked call; a 2025-era HTTP client keeps the tool error.
90
+ A call listens for prompts only while its own work drives the session, so a submission waiting
91
+ in the queue never holds another caller's prompt that it cannot answer.
92
+ Breaking for hand-written sessions: `IMcpTransportSession` now also requires `ISessionEvents`
93
+ (`on`/`off`), `ISessionPromptResolution` (`resolvePermission`/`resolveAsk`) and
94
+ `ISessionDriverAttribution` (`getActiveDriverId`), which `InteractiveSession` and the published
95
+ test double already implement.
96
+
97
+ `@robota-sdk/agent-interface-session` / `@robota-sdk/agent-session` / `@robota-sdk/agent-framework`:
98
+ `ISessionRuntimeTools.invokeRuntimeTool` (and `Session.invokeRuntimeTool`) accept
99
+ `options.permissionInteraction` and `options.driverId`. A direct call still denies a decision that
100
+ would need a person, and finds no one to ask a question, unless its caller passes
101
+ `permissionInteraction: 'interactive'`; then it asks the session's permission handler and its
102
+ tools get the session's ask port. `InteractiveSession` makes `driverId` the active driver while
103
+ the direct call runs, so a prompt the call raises carries it as `requesterDriverId`. With
104
+ `askClient` on, an MCP call runs under its own `mcp:<n>` driver id; a submission made that way is
105
+ attributed to it rather than to the owner.
106
+
107
+ `@robota-sdk/agent-transport`: exports `permissionSummaryArgument`, the argument a person recognises
108
+ a tool call by (`filePath` for the built-in file tools), for every transport that puts a permission
109
+ request to a person in its own wire form.
110
+
111
+ `@robota-sdk/agent-cli`: `mcp serve --ask-client` turns this on for whichever carrier the run serves.
112
+ - 26baaa9: **`@robota-sdk/agent-mcp` opens every MCP session through one `@modelcontextprotocol/client` 2.x client, for both protocol eras.**
113
+
114
+ Legacy negotiation stays the default; `protocolVersion: '2026-07-28'` pins the same client to the
115
+ modern era and never falls back to the legacy handshake. The hand-written stateless framing is gone,
116
+ and so is the package's dependency on the `@modelcontextprotocol/sdk` 1.x runtime: the client and its
117
+ schema package (`@modelcontextprotocol/client`, `@modelcontextprotocol/core`) are now the package's
118
+ dependencies, and the 1.x SDK remains only as a test dependency for legacy-era fixture servers. The
119
+ guarantees are unchanged and still tested: an unsupported result (`input_required`, an unknown result
120
+ type) closes the carrier and is never replayed (no client input is offered, so the SDK's automatic
121
+ input round stays off), and the receive bound, redirect refusal, pinned sockets, authenticated retry,
122
+ trace propagation and stdio authority live in the package's own transport and fetch wrappers as before.
123
+
124
+ Two behaviors change on the pinned 2026-07-28 era, both following the official client:
125
+
126
+ - A result that omits `resultType` is refused (`invalid-tool-result` for a tool call) instead of being
127
+ treated as complete. The tolerance served peers that predate the discriminator, which legacy
128
+ negotiation serves.
129
+ - An invalid freshness hint on `server/discover` (`ttlMs` negative or fractional, `cacheScope` unknown)
130
+ is read as the safest value (`ttlMs` 0, `cacheScope` private) instead of rejecting the server. List
131
+ pages and resource reads with an invalid hint are still refused.
132
+ - An `input_required` result that carries neither `inputRequests` nor `requestState` is refused as
133
+ `invalid-tool-result` rather than reported as `input_required`; either way the carrier closes and
134
+ nothing is replayed.
135
+
136
+ Against a real 2026-07-28 host the pinned path now also sends the body-derived request headers the
137
+ revision requires (`Mcp-Method`, `Mcp-Name`), which the hand-written framing did not; a headers helper
138
+ may no longer set either, as it already could not set the other headers the transport owns. A pinned
139
+ server that answers the discovery probe with a non-protocol HTTP error (a 404 page) is reported as a
140
+ failed startup carrying that status, not as a server lacking the revision. On the legacy era
141
+ `structuredContent` is still checked against the tool's declared `outputSchema`: the schema the latest
142
+ discovery saw travels with each call, since the SDK's own source for it is the aggregating `listTools`
143
+ cache that per-page discovery never fills.
144
+
145
+ `@robota-sdk/agent-cli` adds `@modelcontextprotocol/client` and `@modelcontextprotocol/core` to its
146
+ external `dependencies`, and with them `@modelcontextprotocol/server` and `@modelcontextprotocol/node`,
147
+ which its bundled MCP serve path already imported but the bundle inlined: with `core` external, the
148
+ server must resolve the one `core` it pins. It keeps the 1.x SDK, which
149
+ `@robota-sdk/agent-transport-mcp`'s stdio server still uses, and its import-boundary test now names
150
+ every `@modelcontextprotocol` package.
151
+ - b4c2572: **`@robota-sdk/agent-transport-mcp` serves stdio from `@modelcontextprotocol/server` 2.x, and the 1.x `@modelcontextprotocol/sdk` leaves the repository's runtime dependencies.**
152
+
153
+ The stdio server (`createAgentMcpServer`, `createMcpTransport`) now builds on the same v2 server
154
+ package the HTTP hosts already use, through its `/stdio` carrier; the catalog is validated with the
155
+ SDK's own `Tool` validator, so the HTTP hosts no longer re-serialize it at the SDK boundary. Client-
156
+ visible behavior is unchanged: the same tools, submission extension, admission, turn correlation and
157
+ error results, negotiated through the legacy `initialize` handshake as before. `createAgentMcpServer`
158
+ returns the v2 `Server` type; a consumer wiring its own carrier imports `StdioServerTransport` from
159
+ `@modelcontextprotocol/server/stdio`. The stdio connection is stateful, so the server can send
160
+ server-to-client requests such as `elicitInput` to a client that declares the capability (tested).
161
+ Two carrier details follow the v2 stdio transport: a single frame over 10 MiB now fails the stdio
162
+ carrier instead of being buffered without bound (the HTTP carriers already cap a body at 1 MiB), and
163
+ a line that is not JSON is skipped instead of failing the carrier. A malformed `tools/call` request
164
+ or result is answered with the SDK's invalid-params error, and an invalid catalog entry is reported
165
+ as `Invalid MCP tool: <path>: <reason>` instead of the 1.x validator's own text.
166
+
167
+ `@robota-sdk/agent-cli` drops `@modelcontextprotocol/sdk` from its external `dependencies`; nothing
168
+ in its bundle imports it any more. The 1.x SDK remains only as a test dependency of
169
+ `@robota-sdk/agent-mcp`, for its legacy-era fixture host.
170
+ - 115e104: **A command's caller can cancel what a skill command starts, including while the skill is prepared.**
171
+
172
+ `ISessionCommands.executeCommand` takes an optional trailing `{ signal }`. For a skill command it
173
+ reaches the turn the skill submits or the fork it runs, and the work before them: a cancel stops the
174
+ skill's activation before or after its shell expressions (once they start, all of them run to the
175
+ end), refuses a turn not yet started and interrupts one that is, and stops a fork. A command cancelled this way
176
+ rejects with the signal's reason whichever step the cancel reached, and a cancelled fork is not
177
+ recorded as an error. Before, a cancel that landed before the skill submitted its turn found nothing
178
+ for `abort()` to stop, and the turn then ran; a fork skill run as a command ignored the cancel. A
179
+ command that starts neither a turn nor a fork ignores the signal; every existing call keeps its shape.
180
+
181
+ A fork skill now receives the signal of whatever runs it, so a fork the model starts inside a turn
182
+ stops when that turn is aborted instead of running on.
183
+
184
+ `robota acp` hands each `/command` prompt's signal to the command, so `session/cancel` stops a skill
185
+ command's turn or fork even when it lands before the turn has started.
186
+
187
+ ## 3.0.0-beta.94
188
+ ### Minor Changes
189
+
190
+ - e706b43: Live telemetry can name its spans with the OpenTelemetry GenAI semantic conventions. Set
191
+ `PRODUCT_TELEMETRY_SEMCONV` to `gen_ai` to export `invoke_agent`, `chat {model}` (client) and
192
+ `execute_tool {tool}` spans with `gen_ai.*` attributes, keeping Robota-only facts as `agent.*`; or to
193
+ `gen_ai/dup` to emit both attribute sets while dashboards move. The default, `agent`, exports exactly
194
+ the spans it did before. An unknown value, or the setting while neither traces nor metrics are exported,
195
+ refuses startup. Console traces under a GenAI mode print the same projected spans.
196
+
197
+ The live prompt trace now carries each tool body's name (the session's tool-body observation includes it
198
+ and the framework's live projection passes a label-safe name through); it reaches spans only under a
199
+ GenAI mode and is never written to session history.
200
+ - ccff111: Live telemetry can name its metrics with the OpenTelemetry GenAI semantic conventions. With
201
+ `PRODUCT_TELEMETRY_SEMCONV` set to `gen_ai`, the metrics export the `gen_ai.client.inference.*`
202
+ duration, token-usage and per-call token histograms, `gen_ai.execute_tool.duration` and
203
+ `gen_ai.invoke_agent.*` duration and call counts, and drop only `agent.provider.input_tokens` and
204
+ `agent.provider.output_tokens`, which the GenAI usage counters replace exactly. `gen_ai/dup` exports
205
+ every `agent.*` metric and the GenAI ones. The default, `agent`, exports exactly the metrics it did
206
+ before. Provider- and tool-derived GenAI metrics are exported only when no such child was omitted, and
207
+ usage that was not received is recorded as 0 under the `unknown` modality, as the conventions specify.
208
+ The GenAI metrics carry the requested model as those conventions require, and their inference points
209
+ also take the `agent.provider.id` and `agent.model.id` labels under the same
210
+ `PRODUCT_TELEMETRY_METRIC_ATTRIBUTES` opt-ins as the `agent.*` metrics (the model only in `gen_ai/dup`),
211
+ so a provider split of token totals survives the dropped counters. `PRODUCT_TELEMETRY_SEMCONV` now applies to
212
+ traces and metrics, and is refused only when neither is exported over otlp or console. Console metrics
213
+ print the same projection.
214
+
215
+ `@robota-sdk/agent-telemetry-otel` adds `projectLivePromptMetricSamples`, which maps a live prompt trace
216
+ batch onto those GenAI metrics as plain, SDK-free samples with the recommended bucket boundaries, so
217
+ every host names and measures the same facts the same way. Its inference samples keep the label-safe
218
+ `agent.provider.id`, and `agent.model.id` in `gen_ai/dup`, as the provider span does.
219
+
220
+ ### Patch Changes
221
+
222
+ - The E2B hosted executor passes `--` before the mode when it sets private permissions on restored conversation files and their directory, so the commands also run on BSD/macOS `chmod`.
223
+
3
224
  ## 3.0.0-beta.93
4
225
  ### Minor Changes
5
226
 
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- **Language:** [English](README.md) | [한국어](docs/README-KO.md)
1
+ **Language:** [English](README.md) | [Korean](docs/README-KO.md)
2
2
 
3
3
  # @robota-sdk/agent-cli
4
4
 
@@ -336,6 +336,12 @@ A client that submits with `receivePrompts: true` answers the permission and ask
336
336
  raises; without it, a question no other client answers is denied, so choose the permission mode and
337
337
  rules the server runs under.
338
338
 
339
+ `robota acp` serves the agent to an editor (Zed, JetBrains and other
340
+ [Agent Client Protocol](https://agentclientprotocol.com/) clients) over stdio. Configure the editor to
341
+ run `robota acp` with the project folder as its working directory. Workspace trust, permissions and
342
+ the sandbox apply as in the terminal, and the editor asks you to approve each tool call the terminal
343
+ would. See [Editors](../../content/guide/cli.md#editors-agent-client-protocol).
344
+
339
345
  ### Reach other sessions and your other devices
340
346
 
341
347
  `/peers` lists the other live `robota` sessions on this machine, and `/peers send <session-id>