@robota-sdk/agent-tools 3.0.0-beta.81 → 3.0.0-beta.83
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 +559 -0
- package/dist/node/index.cjs +45 -45
- package/dist/node/index.d.cts +7 -1
- package/dist/node/index.d.cts.map +1 -1
- package/dist/node/index.d.ts +7 -1
- package/dist/node/index.d.ts.map +1 -1
- package/dist/node/index.js +46 -46
- package/dist/node/index.js.map +1 -1
- package/package.json +11 -6
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,559 @@
|
|
|
1
|
+
# @robota-sdk/agent-tools
|
|
2
|
+
|
|
3
|
+
## 3.0.0-beta.83
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 0368058: A running child-process subagent follows a `/sandbox` change made in its parent session. Before, it
|
|
8
|
+
kept the settings it started with until it ended, so a long-running `auto`-mode subagent went on
|
|
9
|
+
auto-approving confined commands after the user turned auto-allow off.
|
|
10
|
+
|
|
11
|
+
- `agent-tools` (minor): `OsSandboxClient.watchSettings(watcher)` reports each `configure`, until
|
|
12
|
+
its returned function is called.
|
|
13
|
+
- `agent-subagent-runner` (minor): the runner factory takes `watchParentSandboxSettings`, and
|
|
14
|
+
forwards each change to every running child as a `sandbox_settings` message. It watches before
|
|
15
|
+
reading the start payload, so no change is lost while a child starts, and stops when the child
|
|
16
|
+
exits or fails to start. A composed sandbox may define `applyParentSettings`. The worker applies
|
|
17
|
+
each change through it. On settings it cannot take, it aborts the run, lets a running command
|
|
18
|
+
finish, and ends the run with that error.
|
|
19
|
+
- `agent-cli` (patch): robota watches its live sandbox, and a child applies each change to the
|
|
20
|
+
instance its tools and approval read.
|
|
21
|
+
|
|
22
|
+
### Patch Changes
|
|
23
|
+
|
|
24
|
+
- 57280bf: Every published package now declares `"engines": { "node": ">=22.12.0" }`. Before, 27 of the 38
|
|
25
|
+
packages declared no floor (`agent-core`, `agent-tools` and every provider among them),
|
|
26
|
+
`agent-session` and `agent-file-authority` declared `>=20.19.0`, and the other nine declared
|
|
27
|
+
`>=22.0.0`, so a consumer on Node 20 saw at most a warning from a transitive dependency.
|
|
28
|
+
|
|
29
|
+
Why 22.12: `agent-cli` and `agent-ui-terminal` need Node 22 through `ink` 7, and the CommonJS entries
|
|
30
|
+
of `agent-tools` and its dependents, `agent-transport`/`node` and its dependents, and
|
|
31
|
+
`agent-ui-terminal` `require()` ESM-only dependencies (`p-limit`, `jose`, `chalk`), which Node 22
|
|
32
|
+
supports unflagged only from 22.12. `engines` is advisory unless the consumer enables `engine-strict`.
|
|
33
|
+
|
|
34
|
+
No code changes: `tsdown` now reads `node22.12.0` as its build target from the field.
|
|
35
|
+
|
|
36
|
+
- 18c0d5c: Every published package now exports `./package.json`, so `require('<package>/package.json')` and
|
|
37
|
+
`import('<package>/package.json', { with: { type: 'json' } })` work instead of failing with
|
|
38
|
+
`ERR_PACKAGE_PATH_NOT_EXPORTED`, and each tarball now ships the package's `CHANGELOG.md`.
|
|
39
|
+
- Updated dependencies [e689c8e]
|
|
40
|
+
- Updated dependencies [be0e53c]
|
|
41
|
+
- Updated dependencies [8bd5fac]
|
|
42
|
+
- Updated dependencies [57280bf]
|
|
43
|
+
- Updated dependencies [5033dd9]
|
|
44
|
+
- Updated dependencies [18c0d5c]
|
|
45
|
+
- Updated dependencies [dbd888d]
|
|
46
|
+
- Updated dependencies [1887e54]
|
|
47
|
+
- @robota-sdk/agent-core@3.0.0-beta.83
|
|
48
|
+
- @robota-sdk/agent-process@3.0.0-beta.83
|
|
49
|
+
|
|
50
|
+
## 3.0.0-beta.82
|
|
51
|
+
|
|
52
|
+
### Patch Changes
|
|
53
|
+
|
|
54
|
+
- Updated dependencies [c7f9203]
|
|
55
|
+
- @robota-sdk/agent-core@3.0.0-beta.82
|
|
56
|
+
- @robota-sdk/agent-process@3.0.0-beta.82
|
|
57
|
+
|
|
58
|
+
## 3.0.0-beta.81
|
|
59
|
+
|
|
60
|
+
### Minor Changes
|
|
61
|
+
|
|
62
|
+
- 3038eb7: A message from another session is instant messaging: text from an untrusted third party that
|
|
63
|
+
carries no authority. What the model does with it is decided by the session's ordinary permissions —
|
|
64
|
+
rules, permission mode and remembered consent — exactly like the session's own work. The per-origin
|
|
65
|
+
peer policy is gone.
|
|
66
|
+
|
|
67
|
+
**BREAKING**
|
|
68
|
+
|
|
69
|
+
- `agent-core`: `IPermissionEvaluationContext.peerTurn` is now a boolean. It decides only whether a
|
|
70
|
+
`repliesToPeer` tool exists; every other call in a peer turn is decided as in any turn. Removed:
|
|
71
|
+
`isToolAvailableInPeerTurn`, `isSecretPath`, `IPeerTurnAuthority`, `TPeerReach` (now exported by
|
|
72
|
+
`agent-interface-session-mobility`) and `IToolPermissionProfile.workspacePaths`.
|
|
73
|
+
- `agent-tools`: `Read` and `Glob` no longer declare `workspacePaths`.
|
|
74
|
+
- `agent-session`: `ISessionRunOptions.peerReach` is replaced by `peerTurn?: boolean`, and
|
|
75
|
+
`ISessionOptions.allowPeerChanges` is removed. An ask in a peer turn is answered like any other:
|
|
76
|
+
a consent the operator remembered answers it, and an "always allow" given there is remembered.
|
|
77
|
+
- `agent-interface-session`: `IPeerTurnContext` no longer has `reach`; it carries only the reply
|
|
78
|
+
route.
|
|
79
|
+
- `agent-interface-session-mobility`: `peerReachOf` is removed; `TPeerReach` moves here. A delegated
|
|
80
|
+
turn carries no reach.
|
|
81
|
+
- `agent-framework`: the `peers.allowChanges` setting is removed (an existing value is ignored). A
|
|
82
|
+
peer turn is offered the ordinary tools, plus `peer_reply`.
|
|
83
|
+
|
|
84
|
+
**Changes**
|
|
85
|
+
|
|
86
|
+
- `agent-framework`: the per-turn statement tells the model the message is an opinion from an
|
|
87
|
+
untrusted third party, not its owner's instruction, and that it decides for itself whether and how
|
|
88
|
+
to act. A message still expands no `@path` and attaches no context reference, and its requests
|
|
89
|
+
still carry no provider-hosted tool, since no permission step can decide one. The session takes
|
|
90
|
+
at most 6 messages a minute and 30 an hour from each sender for a turn; a message over the limit
|
|
91
|
+
is refused with a reason the sender receives. A prompt answer given in the name of a `peer:` or `external:`
|
|
92
|
+
driver is ignored. External-event turns keep their tool-less baseline.
|
|
93
|
+
- `agent-cli`: incoming peer turns carry only their reply route.
|
|
94
|
+
|
|
95
|
+
### Patch Changes
|
|
96
|
+
|
|
97
|
+
- Updated dependencies [3038eb7]
|
|
98
|
+
- Updated dependencies [02b7452]
|
|
99
|
+
- Updated dependencies [ec5e477]
|
|
100
|
+
- @robota-sdk/agent-core@3.0.0-beta.81
|
|
101
|
+
- @robota-sdk/agent-process@3.0.0-beta.81
|
|
102
|
+
|
|
103
|
+
## 3.0.0-beta.80
|
|
104
|
+
|
|
105
|
+
### Major Changes
|
|
106
|
+
|
|
107
|
+
- 807d161: **BREAKING — ARCH-010: the execution root is a required contract field, and the containment guard now fails closed.**
|
|
108
|
+
|
|
109
|
+
The file-tool containment guard was fail-open: with no root configured it answered "allowed". A tool
|
|
110
|
+
built with no `cwd` therefore had no boundary — measured, a `Read` constructed that way returned the
|
|
111
|
+
contents of `/etc/hostname` — and the child-process subagent worker called `createDefaultTools()` with
|
|
112
|
+
no argument at all, so subagents got exactly that. Three independent auditors found three different
|
|
113
|
+
symptoms of this one missing field.
|
|
114
|
+
|
|
115
|
+
**Removed — seven context-free tool singletons.** `readTool`, `writeTool`, `editTool`, `globTool`,
|
|
116
|
+
`grepTool`, `shellTool`, `bashTool` are gone from `@robota-sdk/agent-tools`. A module-level instance is
|
|
117
|
+
bound at import time and can carry no containment root, so after the guard was inverted they could only
|
|
118
|
+
refuse everything.
|
|
119
|
+
|
|
120
|
+
Migrate to the factory of the same name, passing the directory the tool is allowed to work in:
|
|
121
|
+
|
|
122
|
+
```ts
|
|
123
|
+
// before
|
|
124
|
+
import { readTool, globTool } from '@robota-sdk/agent-tools';
|
|
125
|
+
const tools = [readTool, globTool];
|
|
126
|
+
|
|
127
|
+
// after
|
|
128
|
+
import { createReadTool, createGlobTool } from '@robota-sdk/agent-tools';
|
|
129
|
+
const cwd = process.cwd(); // or the workspace this agent is scoped to
|
|
130
|
+
const tools = [createReadTool({ cwd }), createGlobTool({ cwd })];
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
`webFetchTool`, `webSearchTool` and `askUserQuestionTool` are unchanged — they touch no filesystem, so
|
|
134
|
+
there is no root to contain them by.
|
|
135
|
+
|
|
136
|
+
**`cwd` is now REQUIRED** on `ISandboxToolOptions`, `IContainedBuiltinToolOptions` (and everything
|
|
137
|
+
extending them), `ICreateDefaultToolsOptions`, `ISessionOptions` and `ISubagentOptions`. The `= {}`
|
|
138
|
+
default parameter was removed from every builtin factory — that default was the mechanism by which
|
|
139
|
+
"forgot the root" was legal. `new Session({...})` without `cwd` no longer compiles, and also throws at
|
|
140
|
+
construction, because a required field is only required to a TypeScript caller.
|
|
141
|
+
|
|
142
|
+
**`Session` no longer reads `process.cwd()`.** It uses the root it was given, and `getCwd()` exposes it
|
|
143
|
+
so a fork or subagent asks the session instead of re-deriving a root that can disagree with it.
|
|
144
|
+
|
|
145
|
+
**Behavioural change even for callers that already passed a root**: a tool that somehow reaches the
|
|
146
|
+
guard with no root now REFUSES with an explicit error ("no containment root is configured … this is an
|
|
147
|
+
assembly bug, not a path problem") instead of allowing the access.
|
|
148
|
+
|
|
149
|
+
### Minor Changes
|
|
150
|
+
|
|
151
|
+
- 267af5f: The execution containment seam states where tools run.
|
|
152
|
+
|
|
153
|
+
- **`ISandboxClient.filesystem`** (`'shared' | 'separate'`, absent means `separate`).
|
|
154
|
+
- With a **separate** filesystem (E2B, in-memory), every file tool goes through the sandbox, and
|
|
155
|
+
`Glob`/`Grep`, which can only read the host, are withheld. Previously a remote sandbox still
|
|
156
|
+
offered host-reading search tools beside sandbox-writing edit tools.
|
|
157
|
+
- With a **shared** filesystem (OS-level confinement over the host's files), file tools stay on
|
|
158
|
+
the host under the path guard, and only commands go through the sandbox.
|
|
159
|
+
- **`describeExecutionContainment` / `routesFilesThroughSandbox`** name the containment (`host`,
|
|
160
|
+
`sandbox-shared`, `sandbox-separate`) instead of inferring it from an absent value.
|
|
161
|
+
- **`robota doctor` reports `execution.containment`.** Robota composes no sandbox today, so the
|
|
162
|
+
doctor says shell commands run unconfined on the host and the permission rules are the only
|
|
163
|
+
boundary. The CLI composition and the doctor read the same value.
|
|
164
|
+
- **The `Agent` and `BackgroundProcess` tools no longer fall back to `process.cwd()`** when they
|
|
165
|
+
were built without an execution root. They report an assembly error instead, as the file tools
|
|
166
|
+
already did (ARCH-010).
|
|
167
|
+
|
|
168
|
+
- 722e88a: Shell commands can run in an OS-level sandbox: bubblewrap on Linux and WSL2, Seatbelt on macOS.
|
|
169
|
+
|
|
170
|
+
- **Confinement:** covers the command and every process it starts.
|
|
171
|
+
- Writes are limited to the working directory, the temporary directories and
|
|
172
|
+
`sandbox.filesystem.allowWrite`.
|
|
173
|
+
- Agent, git-hook, MCP and shell configuration inside the workspace stays read-only.
|
|
174
|
+
- `sandbox.filesystem.denyRead` hides paths from the command.
|
|
175
|
+
- The network is on or off (`sandbox.network.enabled`).
|
|
176
|
+
- **Modes:** `/sandbox` switches between `auto-allow`, `regular` and `off` for the next command and
|
|
177
|
+
saves the choice.
|
|
178
|
+
- In `auto-allow` (`sandbox.autoAllowBashIfSandboxed`), a confined command runs without a prompt
|
|
179
|
+
in `default` and `acceptEdits`.
|
|
180
|
+
- Deny rules, ask rules, critical removals and plan mode still apply first.
|
|
181
|
+
- **Exclusions:** `sandbox.excludedCommands` run unconfined, through the ordinary permission path.
|
|
182
|
+
- **When the sandbox cannot run:** a missing or unusable backend is reported at startup, in
|
|
183
|
+
`robota doctor` and in `/sandbox`, and commands then run unconfined.
|
|
184
|
+
`sandbox.failIfUnavailable` refuses to start instead.
|
|
185
|
+
- **New contracts:**
|
|
186
|
+
- `OsSandboxClient`, `detectOsSandbox`, `bubblewrapArguments`, `seatbeltProfile`.
|
|
187
|
+
- `ISandboxClient.wrapCommand` and `autoApproves`.
|
|
188
|
+
- `IPermissionEvaluationContext.sandboxAutoApproved`.
|
|
189
|
+
- The `commandSandbox` session option.
|
|
190
|
+
- The `sandbox` settings key and the `sandbox` command host adapter.
|
|
191
|
+
|
|
192
|
+
### Patch Changes
|
|
193
|
+
|
|
194
|
+
- 2345c0b: `Glob` and `Grep` now bound file collection to a fixed candidate ceiling before materializing more
|
|
195
|
+
matches, instead of enumerating and `stat`-ing an entire search tree before any `limit`/`headLimit`
|
|
196
|
+
had a chance to apply. `Glob` streams `fast-glob` matches instead of resolving its full-match
|
|
197
|
+
promise form, and `Grep`'s directory walk stops once it has visited the ceiling's worth of entries.
|
|
198
|
+
Both tools state the truncation explicitly in their output when the ceiling is hit — `Glob`'s result
|
|
199
|
+
ordering (by modification time) then applies only to the candidates collected before the ceiling,
|
|
200
|
+
not to the full match set.
|
|
201
|
+
- 118fe0e: Bound Edit file input before materializing content, including when file size metadata is stale, and reject a replaceAll whose output would exceed the same ceiling before writing.
|
|
202
|
+
- 240777e: Bound Grep file reads before materializing content, including when file size metadata is stale or a file grows during a search.
|
|
203
|
+
- 718bdf5: Run builtin Grep regex matching in preemptible isolation with bounded input, output, and execution time.
|
|
204
|
+
- 61db70f: Bound host Read input and formatted output bytes before a workflow can materialize an oversized file or result. Oversized reads now fail the tool call instead of returning content.
|
|
205
|
+
- db80aba: CLI-042: parallelize the Grep built-in tool's per-file content scan with bounded
|
|
206
|
+
concurrency (`p-limit(50)`), following the glob-tool precedent. Results are still
|
|
207
|
+
collected in file-enumeration order, so output is byte-identical to the previous
|
|
208
|
+
sequential implementation (verified against a pre-change golden on a 1,201-file
|
|
209
|
+
corpus); `headLimit` truncation and binary/unreadable-file skipping are unchanged.
|
|
210
|
+
- 4f3c075: Assemble complete, verified package generations before switching build output; preserve the previous generation on build failure and pack only verified regular-file images. Include copied CLI web assets in affected-build ordering and artifact transfer. Preserve the CLI version in managed build paths. Public runtime contracts remain compatible (patch).
|
|
211
|
+
- b6d14ce: Make the universal JSON-schema subset able to express an object, so a nested `z.object()` keeps its
|
|
212
|
+
properties and required fields instead of reaching the model as `{ "type": "object" }`. Tools and
|
|
213
|
+
structured-output schemas with one level of nesting are now advertised in full and enforced on the
|
|
214
|
+
tool-input path; `z.union` / `z.discriminatedUnion` / `z.literal` are supported and map to `anyOf`
|
|
215
|
+
and single-value enums; `.nullable()` keeps its null branch; and Zod's `strip`, `strict` and
|
|
216
|
+
`passthrough` modes stop collapsing into two `additionalProperties` emissions. Fixes the shipped
|
|
217
|
+
`Computer` and `AskUserQuestion` built-ins, whose action and question fields were being dropped
|
|
218
|
+
entirely.
|
|
219
|
+
|
|
220
|
+
`agent-core` is **minor**, not patch: `IObjectParameterSchema` is a new export, and
|
|
221
|
+
`IParameterSchema.type` became optional (a union node carries `anyOf` instead of a type), which is a
|
|
222
|
+
consumer-visible type change — two call sites in this repo needed editing to keep compiling.
|
|
223
|
+
`additionalProperties` also widened to `boolean | IParameterSchema`, and `required` and `anyOf` are
|
|
224
|
+
new members. The provider packages are **patch**: each adapts to the widened subset without changing
|
|
225
|
+
its own public surface.
|
|
226
|
+
|
|
227
|
+
- 07b627f: A local peer can now be answered, and what its turn may do depends on where it runs.
|
|
228
|
+
|
|
229
|
+
- `agent-core`: the permission evaluator takes a peer turn's authority as one more input
|
|
230
|
+
(`IPermissionEvaluationContext.peerTurn`), decided after the deny list and ceiling and before
|
|
231
|
+
bypass and allow rules. A peer on another host uses no tool. A peer on the same host may use an
|
|
232
|
+
inspect-class tool that declares `workspacePaths`, only when every named location resolves inside
|
|
233
|
+
the workspace and is not a credential (`isSecretPath`); write and execute tools are refused unless
|
|
234
|
+
enabled, and then every use asks. A tool declaring `repliesToPeer` exists only in a peer turn and
|
|
235
|
+
asks once the turn used another tool. New: `isToolAvailableInPeerTurn`, `TPeerReach`,
|
|
236
|
+
`IPeerTurnAuthority`. `IRunOptions.withholdHostedTools` leaves a provider's hosted tools out of a
|
|
237
|
+
run's requests (`nativeWebTools` with `false` withholds a hosted tool for one call).
|
|
238
|
+
- `agent-tools`: `Read` and `Glob` declare the arguments that say where they look. `Grep` does not:
|
|
239
|
+
it reads files it was never named, so a peer turn does not get it.
|
|
240
|
+
- `agent-session`: `ISessionRunOptions.peerReach` makes a run a peer turn for the permission policy;
|
|
241
|
+
every ask in it needs a fresh approval, and its requests carry no provider-hosted tool. `ISessionOptions.allowPeerChanges` enables write and execute
|
|
242
|
+
tools for same-host peer turns.
|
|
243
|
+
- `agent-interface-session`: `ISubmitOptions.peer` (`IPeerTurnContext`) carries a peer turn's reach,
|
|
244
|
+
the message it answers and the session a reply goes to.
|
|
245
|
+
- `agent-interface-session-mobility`: `IPeerMessage.inReplyTo` threads a conversation;
|
|
246
|
+
`peerReachOf(admission)` maps admission to a reach.
|
|
247
|
+
- `agent-framework`: a peer turn is offered what its origin allows, and a new `peer_reply` tool
|
|
248
|
+
answers the peer that sent the message, threaded to it. The setting `peers.allowChanges` enables
|
|
249
|
+
write and execute tools for same-host peer turns.
|
|
250
|
+
- `agent-ui-terminal`: a permission prompt in a peer turn names the requesting peer.
|
|
251
|
+
- `agent-cli`: incoming peer turns carry their reach and reply route; a conversation is limited in
|
|
252
|
+
depth and in how often this session answers it, and a reply over a limit is not sent and the
|
|
253
|
+
operator is told.
|
|
254
|
+
- `agent-provider-anthropic`, `agent-provider-openai-compatible` (Qwen): a request whose
|
|
255
|
+
`nativeWebTools` sets a hosted tool to `false` is sent without it.
|
|
256
|
+
|
|
257
|
+
- 833afe1: Remove the remaining polynomial-ReDoS backtracking (SEC-003, CodeQL `js/polynomial-redos`) and stop the DTLS fingerprint binding to SDP free text.
|
|
258
|
+
|
|
259
|
+
**`extractDtlsFingerprint` (agent-remote-pairing) — remote-reachable, pre-authentication.** Unlike the rest of this class, the SDP it parses arrives over the signaling relay, which the pairing design treats as untrusted, and it is parsed _before_ the channel-binding confirmation — on the browser peer, before `setRemoteDescription` too. Unanchored, `a=fingerprint:\S+\s+…` restarted from every offset in a non-space run: 5.0 s on a 400 KB SDP. It is now anchored to the start of an SDP line (`/^…/m`), which is linear and also stops the extractor from returning a value smuggled into another line's free text (`s=`, `i=`, an unrelated attribute) — text no DTLS stack reads, and which a relay controls. **Behaviour change:** a mid-line `a=fingerprint:` is no longer recognised. Every SDP a WebRTC stack emits puts the attribute at the start of its own line, so no real SDP is affected. A session-level line can still shadow a media-level one; that residual is recorded in the SEC-003 backlog.
|
|
260
|
+
|
|
261
|
+
**Trailing-run trims (agent-framework, agent-cli, agent-tools).** `replace(/-+$/, '')`-shaped regexes have no start anchor, so the engine retried the run from every offset inside it and each retry rescanned to the end — 3.0 s at 100 K characters, ~50 s at 400 K. The memory topic sanitiser, the provider profile-name sanitiser, the model-command tool-name projection, the npm registry URL builder, the git-worktree path-segment sanitiser and the sandbox-root normaliser now use linear index scans (`trimEdgeChars` / `trimTrailingChars` in agent-framework, local helpers elsewhere), proven equivalent to the regexes they replace over every string of the relevant alphabet up to 12 characters.
|
|
262
|
+
|
|
263
|
+
**Whitespace-ambiguity parsers (agent-framework).** The skill and agent-definition frontmatter list splitters used `/\s*,\s*/`, whose whitespace run overlapped nothing after it on a failed comma — 12.6 s on a 200 K run. They now split on `','`; the padding was already removed by the `.trim()` that follows, so the parsed lists are unchanged. The `.git` `gitdir:` pointer and the task-file open-item matcher used `\s*(.+)$` / `\s+(.+)$`, where `\s` and `.` both match a space; the capture is now pinned to start non-space, which accepts exactly the same inputs (verified exhaustively) and removes 14.5 s and 15.4 s worst cases.
|
|
264
|
+
|
|
265
|
+
**`WebFetch` HTML-to-text (agent-tools) — carried no CodeQL alert.** Found by sweeping for the same shapes rather than the flagged lines, and the only quadratic here whose input is a live response body from an arbitrary URL. `<[^>]+>`, `<script[\s\S]*?</script>` and `<style…>` each restarted from every opener that had no terminator: 12.6 s on 200 KB of `<`, and the 5 MB the fetch allows would have taken hours. All three are now single-pass scans, verified character-for-character identical to the regexes over ~800 K generated inputs.
|
|
266
|
+
|
|
267
|
+
Apart from the `extractDtlsFingerprint` anchoring noted above, no behaviour changes: every fix accepts the same inputs and produces the same values, and each ships an equivalence test pinning that.
|
|
268
|
+
|
|
269
|
+
- Updated dependencies [7b6234c]
|
|
270
|
+
- Updated dependencies [4eea54b]
|
|
271
|
+
- Updated dependencies [1698be4]
|
|
272
|
+
- Updated dependencies [d4189b9]
|
|
273
|
+
- Updated dependencies [9edae52]
|
|
274
|
+
- Updated dependencies [4078a72]
|
|
275
|
+
- Updated dependencies [4c73a0b]
|
|
276
|
+
- Updated dependencies [196a900]
|
|
277
|
+
- Updated dependencies [f336838]
|
|
278
|
+
- Updated dependencies [34e50f0]
|
|
279
|
+
- Updated dependencies [722e88a]
|
|
280
|
+
- Updated dependencies [d23c848]
|
|
281
|
+
- Updated dependencies [fec722f]
|
|
282
|
+
- Updated dependencies [2d3b2c0]
|
|
283
|
+
- Updated dependencies [4772067]
|
|
284
|
+
- Updated dependencies [9fbab1b]
|
|
285
|
+
- Updated dependencies [a009f5b]
|
|
286
|
+
- Updated dependencies [4f3c075]
|
|
287
|
+
- Updated dependencies [475e085]
|
|
288
|
+
- Updated dependencies [e477440]
|
|
289
|
+
- Updated dependencies [9dcb5da]
|
|
290
|
+
- Updated dependencies [a95ca85]
|
|
291
|
+
- Updated dependencies [b6d14ce]
|
|
292
|
+
- Updated dependencies [0382a51]
|
|
293
|
+
- Updated dependencies [93d061d]
|
|
294
|
+
- Updated dependencies [39554a1]
|
|
295
|
+
- Updated dependencies [d28430a]
|
|
296
|
+
- Updated dependencies [07b627f]
|
|
297
|
+
- Updated dependencies [d0de5b2]
|
|
298
|
+
- Updated dependencies [d6b9404]
|
|
299
|
+
- Updated dependencies [9814afc]
|
|
300
|
+
- @robota-sdk/agent-core@3.0.0-beta.80
|
|
301
|
+
- @robota-sdk/agent-process@3.0.0-beta.80
|
|
302
|
+
|
|
303
|
+
## 3.0.0-beta.79
|
|
304
|
+
|
|
305
|
+
### Patch Changes
|
|
306
|
+
|
|
307
|
+
- @robota-sdk/agent-core@3.0.0-beta.79
|
|
308
|
+
|
|
309
|
+
## 3.0.0-beta.78
|
|
310
|
+
|
|
311
|
+
### Patch Changes
|
|
312
|
+
|
|
313
|
+
- Updated dependencies [6f308d1]
|
|
314
|
+
- @robota-sdk/agent-core@3.0.0-beta.78
|
|
315
|
+
|
|
316
|
+
## 3.0.0-beta.77
|
|
317
|
+
|
|
318
|
+
### Patch Changes
|
|
319
|
+
|
|
320
|
+
- Updated dependencies
|
|
321
|
+
- @robota-sdk/agent-core@3.0.0-beta.77
|
|
322
|
+
- @robota-sdk/agent-process@3.0.0-beta.77
|
|
323
|
+
|
|
324
|
+
## 3.0.0-beta.76
|
|
325
|
+
|
|
326
|
+
### Patch Changes
|
|
327
|
+
|
|
328
|
+
- Updated dependencies
|
|
329
|
+
- Updated dependencies
|
|
330
|
+
- Updated dependencies
|
|
331
|
+
- Updated dependencies [576af62]
|
|
332
|
+
- @robota-sdk/agent-core@3.0.0-beta.76
|
|
333
|
+
|
|
334
|
+
## 3.0.0-beta.75
|
|
335
|
+
|
|
336
|
+
### Patch Changes
|
|
337
|
+
|
|
338
|
+
- Updated dependencies
|
|
339
|
+
- @robota-sdk/agent-core@3.0.0-beta.75
|
|
340
|
+
|
|
341
|
+
## 3.0.0-beta.74
|
|
342
|
+
|
|
343
|
+
### Patch Changes
|
|
344
|
+
|
|
345
|
+
- @robota-sdk/agent-core@3.0.0-beta.74
|
|
346
|
+
|
|
347
|
+
## 3.0.0-beta.73
|
|
348
|
+
|
|
349
|
+
### Patch Changes
|
|
350
|
+
|
|
351
|
+
- @robota-sdk/agent-core@3.0.0-beta.73
|
|
352
|
+
|
|
353
|
+
## 3.0.0-beta.72
|
|
354
|
+
|
|
355
|
+
### Patch Changes
|
|
356
|
+
|
|
357
|
+
- @robota-sdk/agent-core@3.0.0-beta.72
|
|
358
|
+
|
|
359
|
+
## 3.0.0-beta.71
|
|
360
|
+
|
|
361
|
+
### Patch Changes
|
|
362
|
+
|
|
363
|
+
- fix(context): unify token estimation to single SSOT — status bar and /context list now use the same serialized JSON estimate
|
|
364
|
+
- Updated dependencies
|
|
365
|
+
- @robota-sdk/agent-core@3.0.0-beta.71
|
|
366
|
+
|
|
367
|
+
## 3.0.0-beta.70
|
|
368
|
+
|
|
369
|
+
### Patch Changes
|
|
370
|
+
|
|
371
|
+
- @robota-sdk/agent-core@3.0.0-beta.70
|
|
372
|
+
|
|
373
|
+
## 3.0.0-beta.69
|
|
374
|
+
|
|
375
|
+
### Patch Changes
|
|
376
|
+
|
|
377
|
+
- @robota-sdk/agent-core@3.0.0-beta.69
|
|
378
|
+
|
|
379
|
+
## 3.0.0-beta.68
|
|
380
|
+
|
|
381
|
+
### Patch Changes
|
|
382
|
+
|
|
383
|
+
- @robota-sdk/agent-core@3.0.0-beta.68
|
|
384
|
+
|
|
385
|
+
## 3.0.0-beta.67
|
|
386
|
+
|
|
387
|
+
### Patch Changes
|
|
388
|
+
|
|
389
|
+
- @robota-sdk/agent-core@3.0.0-beta.67
|
|
390
|
+
|
|
391
|
+
## 3.0.0-beta.66
|
|
392
|
+
|
|
393
|
+
### Patch Changes
|
|
394
|
+
|
|
395
|
+
- @robota-sdk/agent-core@3.0.0-beta.66
|
|
396
|
+
|
|
397
|
+
## 3.0.0-beta.65
|
|
398
|
+
|
|
399
|
+
### Patch Changes
|
|
400
|
+
|
|
401
|
+
- @robota-sdk/agent-core@3.0.0-beta.65
|
|
402
|
+
|
|
403
|
+
## 3.0.0-beta.64
|
|
404
|
+
|
|
405
|
+
### Patch Changes
|
|
406
|
+
|
|
407
|
+
- @robota-sdk/agent-core@3.0.0-beta.64
|
|
408
|
+
|
|
409
|
+
## 3.0.0-beta.63
|
|
410
|
+
|
|
411
|
+
### Patch Changes
|
|
412
|
+
|
|
413
|
+
- @robota-sdk/agent-core@3.0.0-beta.63
|
|
414
|
+
|
|
415
|
+
## 3.0.0-beta.62
|
|
416
|
+
|
|
417
|
+
### Patch Changes
|
|
418
|
+
|
|
419
|
+
- Updated dependencies
|
|
420
|
+
- @robota-sdk/agent-core@3.0.0-beta.62
|
|
421
|
+
|
|
422
|
+
## 3.0.0-beta.61
|
|
423
|
+
|
|
424
|
+
### Minor Changes
|
|
425
|
+
|
|
426
|
+
- e243fb0: Add provider-neutral sandbox execution ports, E2B-compatible sandbox adapter, and SDK sandbox injection for Bash and core file tools.
|
|
427
|
+
- 18fcc5b: Add provider-neutral sandbox snapshot hydration for interactive sessions. Snapshot-capable sandbox clients now persist `sandboxSnapshotId` on shutdown and restore it before saved message replay on non-fork resume, while the E2B structural adapter supports both `createSnapshot()`-style checkpoints and pause/resume sandbox references.
|
|
428
|
+
- 3bde012: Add provider-neutral sandbox workspace manifests and wire `InteractiveSession` to apply them before session creation.
|
|
429
|
+
|
|
430
|
+
### Patch Changes
|
|
431
|
+
|
|
432
|
+
- d97bdf2: Add provider-owned model catalog metadata, route `/model` suggestions through the active provider, and make `cli:dev` resolve the CLI workspace dependency closure through source export conditions.
|
|
433
|
+
- Updated dependencies [1c0d44c]
|
|
434
|
+
- Updated dependencies [36eb7a9]
|
|
435
|
+
- Updated dependencies [d97bdf2]
|
|
436
|
+
- @robota-sdk/agent-core@3.0.0-beta.61
|
|
437
|
+
|
|
438
|
+
## 3.0.0-beta.60
|
|
439
|
+
|
|
440
|
+
### Patch Changes
|
|
441
|
+
|
|
442
|
+
- Updated dependencies [7439391]
|
|
443
|
+
- @robota-sdk/agent-core@3.0.0-beta.60
|
|
444
|
+
|
|
445
|
+
## 3.0.0-beta.59
|
|
446
|
+
|
|
447
|
+
### Patch Changes
|
|
448
|
+
|
|
449
|
+
- 95721ff: Preserve existing target mode bits during atomic Write and Edit file replacements.
|
|
450
|
+
- @robota-sdk/agent-core@3.0.0-beta.59
|
|
451
|
+
|
|
452
|
+
## 3.0.0-beta.58
|
|
453
|
+
|
|
454
|
+
### Patch Changes
|
|
455
|
+
|
|
456
|
+
- Updated dependencies
|
|
457
|
+
- @robota-sdk/agent-core@3.0.0-beta.58
|
|
458
|
+
|
|
459
|
+
## 3.0.0-beta.57
|
|
460
|
+
|
|
461
|
+
### Patch Changes
|
|
462
|
+
|
|
463
|
+
- 822a78b: Add self-hosting verification planning and atomic UTF-8 writes for built-in file mutation tools.
|
|
464
|
+
- Updated dependencies [16c3b6f]
|
|
465
|
+
- Updated dependencies [f61e2cb]
|
|
466
|
+
- @robota-sdk/agent-core@3.0.0-beta.57
|
|
467
|
+
|
|
468
|
+
## 3.0.0-beta.56
|
|
469
|
+
|
|
470
|
+
### Patch Changes
|
|
471
|
+
|
|
472
|
+
- Updated dependencies
|
|
473
|
+
- @robota-sdk/agent-core@3.0.0-beta.56
|
|
474
|
+
|
|
475
|
+
## 3.0.0-beta.55
|
|
476
|
+
|
|
477
|
+
### Patch Changes
|
|
478
|
+
|
|
479
|
+
- 38a72bf: fix: resolve ESLint tsconfig parsing errors and improve pnpm CI reliability
|
|
480
|
+
- Add tsconfig.eslint.json to all packages for per-package ESLint runs
|
|
481
|
+
- Migrate typecheck from pnpm -r exec tsc to per-package typecheck scripts
|
|
482
|
+
- Add --if-present to all recursive pnpm run scripts
|
|
483
|
+
- Fix React type imports, dynamic imports in tests, Express.Multer types
|
|
484
|
+
|
|
485
|
+
- Updated dependencies [38a72bf]
|
|
486
|
+
- @robota-sdk/agent-core@3.0.0-beta.55
|
|
487
|
+
|
|
488
|
+
## 3.0.0-beta.54
|
|
489
|
+
|
|
490
|
+
### Patch Changes
|
|
491
|
+
|
|
492
|
+
- Updated dependencies
|
|
493
|
+
- @robota-sdk/agent-core@3.0.0-beta.54
|
|
494
|
+
|
|
495
|
+
## 3.0.0-beta.53
|
|
496
|
+
|
|
497
|
+
### Patch Changes
|
|
498
|
+
|
|
499
|
+
- refactor: monolith decomposition — all agent-\* files under 300 lines
|
|
500
|
+
- Updated dependencies
|
|
501
|
+
- Updated dependencies
|
|
502
|
+
- @robota-sdk/agent-core@3.0.0-beta.53
|
|
503
|
+
|
|
504
|
+
## 3.0.0-beta.52
|
|
505
|
+
|
|
506
|
+
### Patch Changes
|
|
507
|
+
|
|
508
|
+
- @robota-sdk/agent-core@3.0.0-beta.52
|
|
509
|
+
|
|
510
|
+
## 3.0.0-beta.51
|
|
511
|
+
|
|
512
|
+
### Patch Changes
|
|
513
|
+
|
|
514
|
+
- @robota-sdk/agent-core@3.0.0-beta.51
|
|
515
|
+
|
|
516
|
+
## 3.0.0-beta.50
|
|
517
|
+
|
|
518
|
+
### Patch Changes
|
|
519
|
+
|
|
520
|
+
- fix: reinsert repository/homepage/bugs in correct field order
|
|
521
|
+
- @robota-sdk/agent-core@3.0.0-beta.50
|
|
522
|
+
|
|
523
|
+
## 3.0.0-beta.49
|
|
524
|
+
|
|
525
|
+
### Patch Changes
|
|
526
|
+
|
|
527
|
+
- fix: add repository, homepage, bugs metadata to all publishable packages
|
|
528
|
+
- @robota-sdk/agent-core@3.0.0-beta.49
|
|
529
|
+
|
|
530
|
+
## 3.0.0-beta.48
|
|
531
|
+
|
|
532
|
+
### Patch Changes
|
|
533
|
+
|
|
534
|
+
- @robota-sdk/agent-core@3.0.0-beta.48
|
|
535
|
+
|
|
536
|
+
## 3.0.0-beta.47
|
|
537
|
+
|
|
538
|
+
### Patch Changes
|
|
539
|
+
|
|
540
|
+
- @robota-sdk/agent-core@3.0.0-beta.47
|
|
541
|
+
|
|
542
|
+
## 3.0.0-beta.46
|
|
543
|
+
|
|
544
|
+
### Patch Changes
|
|
545
|
+
|
|
546
|
+
- @robota-sdk/agent-core@3.0.0-beta.46
|
|
547
|
+
|
|
548
|
+
## 3.0.0-beta.45
|
|
549
|
+
|
|
550
|
+
### Patch Changes
|
|
551
|
+
|
|
552
|
+
- @robota-sdk/agent-core@3.0.0-beta.45
|
|
553
|
+
|
|
554
|
+
## 3.0.0-beta.44
|
|
555
|
+
|
|
556
|
+
### Patch Changes
|
|
557
|
+
|
|
558
|
+
- Updated dependencies
|
|
559
|
+
- @robota-sdk/agent-core@3.0.0-beta.44
|
package/dist/node/index.cjs
CHANGED
|
@@ -615,6 +615,7 @@ var OsSandboxClient = class {
|
|
|
615
615
|
baseline = [];
|
|
616
616
|
/** Entries a clean-up could not restore, with the state they must return to. */
|
|
617
617
|
unresolved = /* @__PURE__ */ new Map();
|
|
618
|
+
watchers = /* @__PURE__ */ new Set();
|
|
618
619
|
constructor(options) {
|
|
619
620
|
this.root = realPathOrSelf(options.root);
|
|
620
621
|
this.availability = options.availability;
|
|
@@ -631,12 +632,23 @@ var OsSandboxClient = class {
|
|
|
631
632
|
active: this.current.enabled && this.availability.executable !== void 0
|
|
632
633
|
};
|
|
633
634
|
}
|
|
634
|
-
/** Change the settings for the next command. */
|
|
635
|
+
/** Change the settings for the next command, and tell whoever watches them. */
|
|
635
636
|
configure(settings) {
|
|
636
637
|
this.current = {
|
|
637
638
|
...this.current,
|
|
638
639
|
...settings
|
|
639
640
|
};
|
|
641
|
+
for (const watcher of this.watchers) watcher(this.current);
|
|
642
|
+
}
|
|
643
|
+
/**
|
|
644
|
+
* Be told the settings after each change, for as long as the returned function is not called. A
|
|
645
|
+
* copy of this sandbox in another process (a subagent's) follows the user's change this way.
|
|
646
|
+
*/
|
|
647
|
+
watchSettings(watcher) {
|
|
648
|
+
this.watchers.add(watcher);
|
|
649
|
+
return () => {
|
|
650
|
+
this.watchers.delete(watcher);
|
|
651
|
+
};
|
|
640
652
|
}
|
|
641
653
|
/** Whether `shellCommand` would run confined. */
|
|
642
654
|
confines(shellCommand) {
|
|
@@ -1942,60 +1954,48 @@ async function readFileTool(args, options) {
|
|
|
1942
1954
|
}
|
|
1943
1955
|
const pathError = checkPathWithinCwd(filePath, options.cwd);
|
|
1944
1956
|
if (pathError !== void 0) return pathError;
|
|
1945
|
-
|
|
1957
|
+
const failure = (error) => JSON.stringify({
|
|
1958
|
+
success: false,
|
|
1959
|
+
output: "",
|
|
1960
|
+
error
|
|
1961
|
+
});
|
|
1962
|
+
let handle;
|
|
1946
1963
|
try {
|
|
1947
|
-
|
|
1964
|
+
handle = await (0, node_fs_promises.open)(filePath, node_fs.constants.O_RDONLY | node_fs.constants.O_NONBLOCK, 384);
|
|
1948
1965
|
} catch (err) {
|
|
1949
|
-
const
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
};
|
|
1954
|
-
return JSON.stringify(result);
|
|
1955
|
-
}
|
|
1956
|
-
if (!fileStats.isFile()) {
|
|
1957
|
-
const result = {
|
|
1958
|
-
success: false,
|
|
1959
|
-
output: "",
|
|
1960
|
-
error: `Path is not a file: ${filePath}`
|
|
1961
|
-
};
|
|
1962
|
-
return JSON.stringify(result);
|
|
1966
|
+
const found = await (0, node_fs_promises.stat)(filePath).catch(() => void 0);
|
|
1967
|
+
if (found === void 0) return failure(`File not found: ${filePath}`);
|
|
1968
|
+
if (!found.isFile()) return failure(`Path is not a file: ${filePath}`);
|
|
1969
|
+
return failure(err instanceof Error ? err.message : String(err));
|
|
1963
1970
|
}
|
|
1964
1971
|
let buffer = Buffer.alloc(0);
|
|
1965
1972
|
let binaryFile = false;
|
|
1966
1973
|
try {
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
break;
|
|
1981
|
-
}
|
|
1982
|
-
binaryCheckedBytes += binaryCheckLength;
|
|
1983
|
-
bytes += bytesRead;
|
|
1984
|
-
if (bytes > MAX_READ_BYTES) throw new ReadByteLimitError("input");
|
|
1985
|
-
chunks.push(Buffer.from(chunk.subarray(0, bytesRead)));
|
|
1974
|
+
if (!(await handle.stat()).isFile()) return failure(`Path is not a file: ${filePath}`);
|
|
1975
|
+
const chunks = [];
|
|
1976
|
+
const chunk = Buffer.allocUnsafe(READ_CHUNK_BYTES$2);
|
|
1977
|
+
let bytes = 0;
|
|
1978
|
+
let binaryCheckedBytes = 0;
|
|
1979
|
+
while (bytes <= MAX_READ_BYTES) {
|
|
1980
|
+
if (options.signal?.aborted) throw new ReadCancelledError();
|
|
1981
|
+
const { bytesRead } = await handle.read(chunk, 0, Math.min(chunk.length, 4194305 - bytes), null);
|
|
1982
|
+
if (bytesRead === 0) break;
|
|
1983
|
+
const binaryCheckLength = Math.min(bytesRead, 8192 - binaryCheckedBytes);
|
|
1984
|
+
if (binaryCheckLength > 0 && isBinary(chunk.subarray(0, binaryCheckLength))) {
|
|
1985
|
+
binaryFile = true;
|
|
1986
|
+
break;
|
|
1986
1987
|
}
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1988
|
+
binaryCheckedBytes += binaryCheckLength;
|
|
1989
|
+
bytes += bytesRead;
|
|
1990
|
+
if (bytes > MAX_READ_BYTES) throw new ReadByteLimitError("input");
|
|
1991
|
+
chunks.push(Buffer.from(chunk.subarray(0, bytesRead)));
|
|
1990
1992
|
}
|
|
1993
|
+
if (!binaryFile) buffer = Buffer.concat(chunks, bytes);
|
|
1991
1994
|
} catch (err) {
|
|
1992
1995
|
if (err instanceof ReadByteLimitError || err instanceof ReadCancelledError) throw err;
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
error: err instanceof Error ? err.message : String(err)
|
|
1997
|
-
};
|
|
1998
|
-
return JSON.stringify(result);
|
|
1996
|
+
return failure(err instanceof Error ? err.message : String(err));
|
|
1997
|
+
} finally {
|
|
1998
|
+
await handle.close();
|
|
1999
1999
|
}
|
|
2000
2000
|
if (options.signal?.aborted) throw new ReadCancelledError();
|
|
2001
2001
|
if (binaryFile) {
|