@robota-sdk/agent-cli 3.0.0-beta.94 → 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.
- package/CHANGELOG.md +184 -0
- package/README.md +6 -0
- package/dist/node/bin.js +16 -16
- package/dist/node/cli-core-DJIgDK0t.js +2920 -0
- package/dist/node/desktop-host.js +1 -1
- package/dist/node/headless.js +1 -1
- package/dist/node/host.d.ts +1 -1
- package/dist/node/host.js +1 -1
- package/dist/node/index.d.ts +2 -1
- package/dist/node/index.d.ts.map +1 -1
- package/dist/node/index.js +2 -2
- package/dist/node/{node-DDxqAmr9.js → node-BBey07fn.js} +7 -7
- package/dist/node/node-BBey07fn.js.map +1 -0
- package/dist/node/{node-BX6uQ1k-.js → node-BOLpvRke.js} +2 -2
- package/dist/node/{node-BX6uQ1k-.js.map → node-BOLpvRke.js.map} +1 -1
- package/dist/node/{node-DAf6oQNY.js → node-Bxcf0vqP.js} +6 -6
- package/dist/node/{node-BgVHmmdi.js → node-CV7kyP4U.js} +1 -1
- package/dist/node/{node-CtG-zp83.js → node-Dr_K99X7.js} +2 -2
- package/dist/node/{node-CtG-zp83.js.map → node-Dr_K99X7.js.map} +1 -1
- package/dist/node/{node-IYfzRFGU.js → node-DsYjDBKf.js} +1 -1
- package/dist/node/{product-host-DqZRpcAh.d.ts → product-host-BACfuTu4.d.ts} +40 -11
- package/dist/node/product-host-BACfuTu4.d.ts.map +1 -0
- package/dist/node/product-host-BwV-X6oS.js +2954 -0
- package/dist/node/product-host-BwV-X6oS.js.map +1 -0
- package/dist/web/assets/index-DB915Rm-.js +314 -0
- package/dist/web/index.html +1 -1
- package/package.json +43 -38
- package/dist/node/cli-core-Davokkgi.js +0 -2921
- package/dist/node/node-DDxqAmr9.js.map +0 -1
- package/dist/node/product-host-CBylXlR9.js +0 -2955
- package/dist/node/product-host-CBylXlR9.js.map +0 -1
- package/dist/node/product-host-DqZRpcAh.d.ts.map +0 -1
- package/dist/web/assets/index-BQP0NBgG.js +0 -309
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,189 @@
|
|
|
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
|
+
|
|
3
187
|
## 3.0.0-beta.94
|
|
4
188
|
### Minor Changes
|
|
5
189
|
|
package/README.md
CHANGED
|
@@ -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>
|