@robota-sdk/agent-tool-defaults 3.0.0-beta.82 → 3.0.0-beta.84
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 +164 -0
- package/README.md +80 -0
- package/dist/node/index.cjs +1 -1
- package/dist/node/index.js +1 -1
- package/dist/node/index.js.map +1 -1
- package/package.json +11 -5
- package/src/__tests__/create-default-tools.test.ts +29 -4
- package/src/create-default-tools.ts +8 -4
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# @robota-sdk/agent-tool-defaults
|
|
2
|
+
|
|
3
|
+
## 3.0.0-beta.84
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- c7f213c: `createDefaultTools` returned the same `WebFetch`/`WebSearch` tool instances on every call — the
|
|
8
|
+
two module-level singletons `@robota-sdk/agent-tools` exports — unlike every other tool in the set,
|
|
9
|
+
which was already built fresh per call. Two sessions built from separate `createDefaultTools({cwd})`
|
|
10
|
+
calls that were open at the same time shared those two tools without meaning to, which a resource
|
|
11
|
+
guard keyed by object identity (as `@robota-sdk/agent-roundtable-robota`'s does) rejected as reused
|
|
12
|
+
even though nothing about either tool needs to be shared across sessions. `WebFetch`/`WebSearch` are
|
|
13
|
+
now built per call, the same way `Glob`/`Grep` already were.
|
|
14
|
+
- Updated dependencies [9f46375]
|
|
15
|
+
- Updated dependencies [9c6a8db]
|
|
16
|
+
- Updated dependencies [9c6a8db]
|
|
17
|
+
- @robota-sdk/agent-core@3.0.0-beta.84
|
|
18
|
+
- @robota-sdk/agent-tools@3.0.0-beta.84
|
|
19
|
+
|
|
20
|
+
## 3.0.0-beta.83
|
|
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
|
+
- Updated dependencies [0368058]
|
|
48
|
+
- @robota-sdk/agent-core@3.0.0-beta.83
|
|
49
|
+
- @robota-sdk/agent-tools@3.0.0-beta.83
|
|
50
|
+
|
|
51
|
+
## 3.0.0-beta.82
|
|
52
|
+
|
|
53
|
+
### Patch Changes
|
|
54
|
+
|
|
55
|
+
- Updated dependencies [c7f9203]
|
|
56
|
+
- @robota-sdk/agent-core@3.0.0-beta.82
|
|
57
|
+
- @robota-sdk/agent-tools@3.0.0-beta.82
|
|
58
|
+
|
|
59
|
+
## 3.0.0-beta.81
|
|
60
|
+
|
|
61
|
+
### Patch Changes
|
|
62
|
+
|
|
63
|
+
- Updated dependencies [3038eb7]
|
|
64
|
+
- Updated dependencies [02b7452]
|
|
65
|
+
- Updated dependencies [ec5e477]
|
|
66
|
+
- @robota-sdk/agent-core@3.0.0-beta.81
|
|
67
|
+
- @robota-sdk/agent-tools@3.0.0-beta.81
|
|
68
|
+
|
|
69
|
+
## 3.0.0-beta.80
|
|
70
|
+
|
|
71
|
+
### Minor Changes
|
|
72
|
+
|
|
73
|
+
- 267af5f: The execution containment seam states where tools run.
|
|
74
|
+
|
|
75
|
+
- **`ISandboxClient.filesystem`** (`'shared' | 'separate'`, absent means `separate`).
|
|
76
|
+
- With a **separate** filesystem (E2B, in-memory), every file tool goes through the sandbox, and
|
|
77
|
+
`Glob`/`Grep`, which can only read the host, are withheld. Previously a remote sandbox still
|
|
78
|
+
offered host-reading search tools beside sandbox-writing edit tools.
|
|
79
|
+
- With a **shared** filesystem (OS-level confinement over the host's files), file tools stay on
|
|
80
|
+
the host under the path guard, and only commands go through the sandbox.
|
|
81
|
+
- **`describeExecutionContainment` / `routesFilesThroughSandbox`** name the containment (`host`,
|
|
82
|
+
`sandbox-shared`, `sandbox-separate`) instead of inferring it from an absent value.
|
|
83
|
+
- **`robota doctor` reports `execution.containment`.** Robota composes no sandbox today, so the
|
|
84
|
+
doctor says shell commands run unconfined on the host and the permission rules are the only
|
|
85
|
+
boundary. The CLI composition and the doctor read the same value.
|
|
86
|
+
- **The `Agent` and `BackgroundProcess` tools no longer fall back to `process.cwd()`** when they
|
|
87
|
+
were built without an execution root. They report an assembly error instead, as the file tools
|
|
88
|
+
already did (ARCH-010).
|
|
89
|
+
|
|
90
|
+
- 7b85767: ARCH-035 — the default tool set becomes a composition leaf.
|
|
91
|
+
|
|
92
|
+
**New package: `@robota-sdk/agent-tool-defaults`.** It owns `createDefaultTools` and
|
|
93
|
+
`ICreateDefaultToolsOptions`, including the adapter gating that adds `CodebaseRetrieval` when a
|
|
94
|
+
`retrievalAdapter` is supplied and the Computer tools when a `computerDriver` is.
|
|
95
|
+
|
|
96
|
+
**Breaking for `@robota-sdk/agent-framework`:** `createDefaultTools` and `ICreateDefaultToolsOptions`
|
|
97
|
+
are no longer exported from it. Import them from `@robota-sdk/agent-tool-defaults`. The packages are
|
|
98
|
+
pre-release and this repo keeps no compatibility shims, so they are moved rather than deprecated.
|
|
99
|
+
|
|
100
|
+
**Also breaking:** the internal `createSession` assembly factory is now `async`. This does NOT affect
|
|
101
|
+
`IAgentRuntime.createSession`, which stays synchronous — it does not call that factory, and a
|
|
102
|
+
verification scenario now asserts that explicitly, because propagating async through it would break
|
|
103
|
+
every consumer that builds a session without supplying `defaultTools`.
|
|
104
|
+
|
|
105
|
+
**Zero-config behaviour is unchanged**, deliberately. `createQuery` and the headless runtime have no
|
|
106
|
+
`defaultTools` seam, so a session built without one still receives the built-in tool tier —
|
|
107
|
+
`agent-framework` reaches the new leaf through a dynamic `import()`. An earlier revision of this work
|
|
108
|
+
proposed deleting the tier outright and was rejected on measurement: two published surfaces cannot
|
|
109
|
+
express the alternative, and the failure mode was a silently toolless agent behind a green typecheck.
|
|
110
|
+
|
|
111
|
+
**Why the move matters.** `agent-subagent-runner` legitimately depends on `agent-framework`, so while
|
|
112
|
+
the aggregator sat on that barrel a neutral runner could compose the product's tool surface with only
|
|
113
|
+
a scan in the way. It has no manifest edge to the new leaf, so that import does not resolve there at
|
|
114
|
+
all — the guarantee is carried by the type system now, mirroring what `@robota-sdk/agent-provider-defaults`
|
|
115
|
+
already does on the provider axis.
|
|
116
|
+
|
|
117
|
+
`@robota-sdk/pack-coding` is a patch: it consumes the leaf instead of rebuilding the same list by
|
|
118
|
+
hand. Its contributed tool surface is unchanged — verified from the published tarballs.
|
|
119
|
+
|
|
120
|
+
### Patch Changes
|
|
121
|
+
|
|
122
|
+
- 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).
|
|
123
|
+
- Updated dependencies [7b6234c]
|
|
124
|
+
- Updated dependencies [4eea54b]
|
|
125
|
+
- Updated dependencies [2345c0b]
|
|
126
|
+
- Updated dependencies [118fe0e]
|
|
127
|
+
- Updated dependencies [240777e]
|
|
128
|
+
- Updated dependencies [718bdf5]
|
|
129
|
+
- Updated dependencies [1698be4]
|
|
130
|
+
- Updated dependencies [d4189b9]
|
|
131
|
+
- Updated dependencies [9edae52]
|
|
132
|
+
- Updated dependencies [4078a72]
|
|
133
|
+
- Updated dependencies [4c73a0b]
|
|
134
|
+
- Updated dependencies [267af5f]
|
|
135
|
+
- Updated dependencies [196a900]
|
|
136
|
+
- Updated dependencies [f336838]
|
|
137
|
+
- Updated dependencies [34e50f0]
|
|
138
|
+
- Updated dependencies [722e88a]
|
|
139
|
+
- Updated dependencies [d23c848]
|
|
140
|
+
- Updated dependencies [807d161]
|
|
141
|
+
- Updated dependencies [fec722f]
|
|
142
|
+
- Updated dependencies [2d3b2c0]
|
|
143
|
+
- Updated dependencies [4772067]
|
|
144
|
+
- Updated dependencies [9fbab1b]
|
|
145
|
+
- Updated dependencies [a009f5b]
|
|
146
|
+
- Updated dependencies [61db70f]
|
|
147
|
+
- Updated dependencies [db80aba]
|
|
148
|
+
- Updated dependencies [4f3c075]
|
|
149
|
+
- Updated dependencies [475e085]
|
|
150
|
+
- Updated dependencies [e477440]
|
|
151
|
+
- Updated dependencies [9dcb5da]
|
|
152
|
+
- Updated dependencies [a95ca85]
|
|
153
|
+
- Updated dependencies [b6d14ce]
|
|
154
|
+
- Updated dependencies [0382a51]
|
|
155
|
+
- Updated dependencies [93d061d]
|
|
156
|
+
- Updated dependencies [39554a1]
|
|
157
|
+
- Updated dependencies [d28430a]
|
|
158
|
+
- Updated dependencies [07b627f]
|
|
159
|
+
- Updated dependencies [d0de5b2]
|
|
160
|
+
- Updated dependencies [833afe1]
|
|
161
|
+
- Updated dependencies [d6b9404]
|
|
162
|
+
- Updated dependencies [9814afc]
|
|
163
|
+
- @robota-sdk/agent-core@3.0.0-beta.80
|
|
164
|
+
- @robota-sdk/agent-tools@3.0.0-beta.80
|
package/README.md
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# @robota-sdk/agent-tool-defaults
|
|
2
|
+
|
|
3
|
+
The Robota SDK's built-in default tool set. `createDefaultTools()` builds the tools a Robota session
|
|
4
|
+
gets when its composition root supplies no tool list of its own, using the tool factories from
|
|
5
|
+
`@robota-sdk/agent-tools`. It implements no tool itself. File tools that run on the host are
|
|
6
|
+
contained by the `cwd` you pass; with a `sandboxClient` that has its own filesystem, file paths go to
|
|
7
|
+
the sandbox and `cwd` does not confine them. Adapter-gated tools appear only when you supply their
|
|
8
|
+
adapter. Import it at a composition root (the place that assembles an agent), not from library code.
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install @robota-sdk/agent-tool-defaults @robota-sdk/agent-core
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Usage
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
import { Robota } from '@robota-sdk/agent-core';
|
|
20
|
+
import type { IAIProvider } from '@robota-sdk/agent-core';
|
|
21
|
+
import { createDefaultTools } from '@robota-sdk/agent-tool-defaults';
|
|
22
|
+
|
|
23
|
+
declare const provider: IAIProvider;
|
|
24
|
+
|
|
25
|
+
const agent = new Robota({
|
|
26
|
+
name: 'DevAgent',
|
|
27
|
+
aiProviders: [provider],
|
|
28
|
+
defaultModel: { provider: 'anthropic', model: 'claude-sonnet-4-6' },
|
|
29
|
+
tools: createDefaultTools({ cwd: process.cwd() }),
|
|
30
|
+
});
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
`createDefaultTools()` is synchronous and performs no I/O, and the same options always produce the
|
|
34
|
+
same set of tools. Most tools are built fresh on each call; `WebFetch` and `WebSearch` are shared
|
|
35
|
+
instances.
|
|
36
|
+
|
|
37
|
+
## Tools
|
|
38
|
+
|
|
39
|
+
| Tool | Included when |
|
|
40
|
+
| -------------------------- | --------------------------------------------------------------- |
|
|
41
|
+
| `Shell`, `Bash` | Always |
|
|
42
|
+
| `Read`, `Write`, `Edit` | Always |
|
|
43
|
+
| `Glob`, `Grep` | Unless a `sandboxClient` with a separate filesystem is supplied |
|
|
44
|
+
| `WebFetch`, `WebSearch` | Always |
|
|
45
|
+
| `AskUserQuestion` | Always |
|
|
46
|
+
| `CodebaseRetrieval` | `retrievalAdapter` is supplied |
|
|
47
|
+
| `ComputerView`, `Computer` | `computerDriver` is supplied |
|
|
48
|
+
|
|
49
|
+
With a `sandboxClient`, `Shell` and `Bash` run commands through the sandbox. When the sandbox has
|
|
50
|
+
its own filesystem (the default for a client that does not declare `filesystem: 'shared'`), `Read`,
|
|
51
|
+
`Write` and `Edit` also go through it, and `Glob` / `Grep` are left out because they have no
|
|
52
|
+
sandbox path. File paths are then passed to the sandbox as given, and `cwd` does not confine them.
|
|
53
|
+
When the sandbox shares the host filesystem, file tools stay on the host, contained by `cwd`.
|
|
54
|
+
|
|
55
|
+
## Options
|
|
56
|
+
|
|
57
|
+
`createDefaultTools(options: ICreateDefaultToolsOptions): FunctionTool[]`
|
|
58
|
+
|
|
59
|
+
| Option | Type | Description |
|
|
60
|
+
| ------------------ | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
61
|
+
| `cwd` | `string` | Required. The root that host file tools are contained by (not file tools routed to a separate-filesystem sandbox), and the default working directory for `Shell` / `Bash`. |
|
|
62
|
+
| `sandboxClient` | `ISandboxClient` | Runs commands (and, on a separate filesystem, file tools) in a sandbox. |
|
|
63
|
+
| `shellExecutable` | `string` | Host-selected executable for `Shell` and `Bash`. |
|
|
64
|
+
| `retrievalAdapter` | `IRetrievalAdapter` | Adds the `CodebaseRetrieval` tool. |
|
|
65
|
+
| `computerDriver` | `IComputerDriver` | Adds the `ComputerView` and `Computer` tools. There is no host fallback. |
|
|
66
|
+
|
|
67
|
+
`ISandboxClient`, `IRetrievalAdapter` and `IComputerDriver` are exported by
|
|
68
|
+
`@robota-sdk/agent-tools`.
|
|
69
|
+
|
|
70
|
+
## Related packages
|
|
71
|
+
|
|
72
|
+
- [`@robota-sdk/agent-tools`](../agent-tools/README.md): the tool factories, the tool registry and
|
|
73
|
+
the sandbox clients.
|
|
74
|
+
- [`@robota-sdk/agent-core`](../agent-core/README.md): the `Robota` agent and the tool contract.
|
|
75
|
+
|
|
76
|
+
See [docs/SPEC.md](docs/SPEC.md) for the package contract.
|
|
77
|
+
|
|
78
|
+
## License
|
|
79
|
+
|
|
80
|
+
Robota is dual-licensed under the [GNU AGPL-3.0](../../LICENSE) or a [commercial license](../../COMMERCIAL.md). See [LICENSING.md](../../LICENSING.md).
|
package/dist/node/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("@robota-sdk/agent-tools");function t(t){let n=(0,e.routesFilesThroughSandbox)(t.sandboxClient),{sandboxClient:r,...i}=t,a=n?t:i;return[(0,e.createShellTool)(t),(0,e.createBashTool)(t),(0,e.createReadTool)(a),(0,e.createWriteTool)(a),(0,e.createEditTool)(a),...n?[]:[(0,e.createGlobTool)(t),(0,e.createGrepTool)(t)],e.
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("@robota-sdk/agent-tools");function t(t){let n=(0,e.routesFilesThroughSandbox)(t.sandboxClient),{sandboxClient:r,...i}=t,a=n?t:i;return[(0,e.createShellTool)(t),(0,e.createBashTool)(t),(0,e.createReadTool)(a),(0,e.createWriteTool)(a),(0,e.createEditTool)(a),...n?[]:[(0,e.createGlobTool)(t),(0,e.createGrepTool)(t)],(0,e.createWebFetchTool)(),(0,e.createWebSearchTool)(),(0,e.createAskUserQuestionTool)(),...t.retrievalAdapter?[(0,e.createRetrievalTool)({adapter:t.retrievalAdapter})]:[],...t.computerDriver?(0,e.createComputerTool)({driver:t.computerDriver}):[]]}exports.createDefaultTools=t;
|
package/dist/node/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{createAskUserQuestionTool as e,createBashTool as t,createComputerTool as n,createEditTool as r,createGlobTool as i,createGrepTool as a,createReadTool as o,createRetrievalTool as s,createShellTool as c,
|
|
1
|
+
import{createAskUserQuestionTool as e,createBashTool as t,createComputerTool as n,createEditTool as r,createGlobTool as i,createGrepTool as a,createReadTool as o,createRetrievalTool as s,createShellTool as c,createWebFetchTool as l,createWebSearchTool as u,createWriteTool as d,routesFilesThroughSandbox as f}from"@robota-sdk/agent-tools";function p(p){let m=f(p.sandboxClient),{sandboxClient:h,...g}=p,_=m?p:g;return[c(p),t(p),o(_),d(_),r(_),...m?[]:[i(p),a(p)],l(),u(),e(),...p.retrievalAdapter?[s({adapter:p.retrievalAdapter})]:[],...p.computerDriver?n({driver:p.computerDriver}):[]]}export{p as createDefaultTools};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/node/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/create-default-tools.ts"],"sourcesContent":["/**\n * The DEFAULT TOOL SET — a composition leaf.\n *\n * ARCH-035 moved this out of `@robota-sdk/agent-framework`. It is a defaults aggregator, and\n * `.agents/project-structure.md` classifies that family as a composition leaf \"imported only at\n * composition roots (entry-point-only)\" — not something a mid-layer assembly library owns, publishes\n * and self-consumes.\n *\n * The move is what carries the guarantee. `agent-subagent-runner` may depend on `agent-framework`\n * (it needs `createSubagentSession` and friends) but has no manifest edge to THIS package, so\n * `import { createDefaultTools } from '@robota-sdk/agent-tool-defaults'` does not resolve there at\n * all. A neutral runner composing the product's tool surface is now a compile error rather than a\n * scan finding — the same shape ARCH-021 achieved on the provider axis with\n * `@robota-sdk/agent-builtin-providers`.\n *\n * `DEFAULT_TOOL_DESCRIPTIONS` deliberately did NOT come along: its only consumer builds the system\n * prompt synchronously, and dragging it here would force either a static edge back into this leaf or\n * a second async hop through prompt building. It stays beside its consumer in `agent-framework`.\n */\nimport {\n createAskUserQuestionTool,\n createShellTool,\n createBashTool,\n createReadTool,\n createWriteTool,\n createEditTool,\n createRetrievalTool,\n createComputerTool,\n createGlobTool,\n createGrepTool,\n
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/create-default-tools.ts"],"sourcesContent":["/**\n * The DEFAULT TOOL SET — a composition leaf.\n *\n * ARCH-035 moved this out of `@robota-sdk/agent-framework`. It is a defaults aggregator, and\n * `.agents/project-structure.md` classifies that family as a composition leaf \"imported only at\n * composition roots (entry-point-only)\" — not something a mid-layer assembly library owns, publishes\n * and self-consumes.\n *\n * The move is what carries the guarantee. `agent-subagent-runner` may depend on `agent-framework`\n * (it needs `createSubagentSession` and friends) but has no manifest edge to THIS package, so\n * `import { createDefaultTools } from '@robota-sdk/agent-tool-defaults'` does not resolve there at\n * all. A neutral runner composing the product's tool surface is now a compile error rather than a\n * scan finding — the same shape ARCH-021 achieved on the provider axis with\n * `@robota-sdk/agent-builtin-providers`.\n *\n * `DEFAULT_TOOL_DESCRIPTIONS` deliberately did NOT come along: its only consumer builds the system\n * prompt synchronously, and dragging it here would force either a static edge back into this leaf or\n * a second async hop through prompt building. It stays beside its consumer in `agent-framework`.\n */\nimport {\n createAskUserQuestionTool,\n createShellTool,\n createBashTool,\n createReadTool,\n createWriteTool,\n createEditTool,\n createRetrievalTool,\n createComputerTool,\n createGlobTool,\n createGrepTool,\n createWebFetchTool,\n createWebSearchTool,\n routesFilesThroughSandbox,\n} from '@robota-sdk/agent-tools';\n\nimport type { FunctionTool } from '@robota-sdk/agent-core';\nimport type { ISandboxClient, IRetrievalAdapter, IComputerDriver } from '@robota-sdk/agent-tools';\n\n/**\n * Create the default set of CLI tools.\n * Returns the standard tools.\n */\nexport interface ICreateDefaultToolsOptions {\n sandboxClient?: ISandboxClient;\n /** Host-selected executable for Shell and Bash. */\n shellExecutable?: string;\n /**\n * The execution root every file tool is contained by. REQUIRED — ARCH-010.\n *\n * It was optional, and `child-process-subagent-worker.ts` called this factory with no argument at\n * all: `cwd` was `undefined`, the path guard was fail-open, and the subagent's `Read` returned\n * `/etc/hostname`. Requiring it means a construction site that forgets does not compile, which is\n * the only way a containment root stays a contract rather than a convention.\n */\n cwd: string;\n /** SELFHOST-003: when present, adds the adapter-gated `CodebaseRetrieval` tool (absent otherwise). */\n retrievalAdapter?: IRetrievalAdapter;\n /**\n * SELFHOST-010: when present, adds the adapter-gated `ComputerView` + `Computer` tools. Unlike the\n * shell tool's host `spawn` fallback, computer-use has NO host fallback — with no driver the tools are\n * simply ABSENT (there is no safe library-side \"local\" screen to fall back to).\n */\n computerDriver?: IComputerDriver;\n}\n\n/**\n * ARCH-035: returns `FunctionTool[]`, which is what every factory below actually returns.\n *\n * An earlier revision cast each one to `IToolWithEventService` because session assembly consumes that\n * interface. The cast was lossy in the direction that mattered: `ICapabilityPack.tools` is\n * `readonly FunctionTool[]`, so a pack CONSUMING this set could not assign it without a second cast\n * back — one erasure creating the need for another. `FunctionTool` satisfies `IToolWithEventService`,\n * so session assembly is unaffected and no cast is needed at either end.\n */\nexport function createDefaultTools(options: ICreateDefaultToolsOptions): FunctionTool[] {\n // Issue #3081: the sandbox's filesystem relation decides where file tools read and write. On a\n // SEPARATE filesystem every file tool goes through the sandbox — and `Glob`/`Grep`, which have no\n // sandbox path, are withheld, so a search can never read the host while an edit writes the\n // sandbox. On a SHARED filesystem (commands confined over the host's) file tools stay on the host\n // under the path guard, and only commands run through the sandbox.\n const separate = routesFilesThroughSandbox(options.sandboxClient);\n const { sandboxClient: _commandsOnly, ...hostFileOptions } = options;\n const fileOptions = separate ? options : hostFileOptions;\n return [\n createShellTool(options),\n createBashTool(options),\n createReadTool(fileOptions),\n createWriteTool(fileOptions),\n createEditTool(fileOptions),\n // SEC-007: built per call, NOT the module-level singletons. A singleton is context-free by\n // construction, so registering one meant `Glob`/`Grep` could enumerate outside the session's\n // working directory while `Read`/`Write`/`Edit` were contained.\n ...(separate ? [] : [createGlobTool(options), createGrepTool(options)]),\n // MUST 4: also built per call, for the same reason — `webFetchTool`/`webSearchTool` are\n // module-level singletons in `agent-tools`, so two concurrently open sessions built from this\n // set (e.g. two `sessionParticipant`s) shared them and tripped `resource-reused` even though\n // nothing about a WebFetch/WebSearch tool actually needs to be shared across sessions.\n createWebFetchTool(),\n createWebSearchTool(),\n createAskUserQuestionTool(),\n // Retrieval is adapter-gated: absent when no adapter is supplied (there is no host fallback).\n ...(options.retrievalAdapter\n ? [createRetrievalTool({ adapter: options.retrievalAdapter })]\n : []),\n // Computer-use is adapter-gated on the driver: absent when no driver is supplied. There is NO host\n // fallback (unlike the shell tool's host spawn) — no library-side \"local\" screen exists.\n ...(options.computerDriver ? createComputerTool({ driver: options.computerDriver }) : []),\n ];\n}\n"],"mappings":"mVA0EA,SAAgB,EAAmB,EAAqD,CAMtF,IAAM,EAAW,EAA0B,EAAQ,aAAa,EAC1D,CAAE,cAAe,EAAe,GAAG,GAAoB,EACvD,EAAc,EAAW,EAAU,EACzC,MAAO,CACL,EAAgB,CAAO,EACvB,EAAe,CAAO,EACtB,EAAe,CAAW,EAC1B,EAAgB,CAAW,EAC3B,EAAe,CAAW,EAI1B,GAAI,EAAW,CAAC,EAAI,CAAC,EAAe,CAAO,EAAG,EAAe,CAAO,CAAC,EAKrE,EAAmB,EACnB,EAAoB,EACpB,EAA0B,EAE1B,GAAI,EAAQ,iBACR,CAAC,EAAoB,CAAE,QAAS,EAAQ,gBAAiB,CAAC,CAAC,EAC3D,CAAC,EAGL,GAAI,EAAQ,eAAiB,EAAmB,CAAE,OAAQ,EAAQ,cAAe,CAAC,EAAI,CAAC,CACzF,CACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@robota-sdk/agent-tool-defaults",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.84",
|
|
4
4
|
"description": "The SDK's built-in default tool set (createDefaultTools) as a composition leaf over agent-tools",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
@@ -31,11 +31,16 @@
|
|
|
31
31
|
"default": "./dist/node/index.cjs"
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
|
-
}
|
|
34
|
+
},
|
|
35
|
+
"./package.json": "./package.json"
|
|
36
|
+
},
|
|
37
|
+
"engines": {
|
|
38
|
+
"node": ">=22.12.0"
|
|
35
39
|
},
|
|
36
40
|
"files": [
|
|
37
41
|
"dist",
|
|
38
|
-
"src"
|
|
42
|
+
"src",
|
|
43
|
+
"CHANGELOG.md"
|
|
39
44
|
],
|
|
40
45
|
"devDependencies": {
|
|
41
46
|
"@types/node": "^22.19.21",
|
|
@@ -49,9 +54,10 @@
|
|
|
49
54
|
"url": "https://github.com/woojubb/robota.git",
|
|
50
55
|
"directory": "packages/agent-tool-defaults"
|
|
51
56
|
},
|
|
57
|
+
"homepage": "https://docs.robota.io/en/packages/agent-tool-defaults/",
|
|
52
58
|
"dependencies": {
|
|
53
|
-
"@robota-sdk/agent-
|
|
54
|
-
"@robota-sdk/agent-
|
|
59
|
+
"@robota-sdk/agent-tools": "3.0.0-beta.84",
|
|
60
|
+
"@robota-sdk/agent-core": "3.0.0-beta.84"
|
|
55
61
|
},
|
|
56
62
|
"volta": {
|
|
57
63
|
"extends": "../../package.json"
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
import { mkdtempSync, rmSync } from 'node:fs';
|
|
2
|
+
import { tmpdir } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
|
|
1
5
|
import { InMemorySandboxClient } from '@robota-sdk/agent-tools';
|
|
2
|
-
import { describe, expect, it } from 'vitest';
|
|
6
|
+
import { afterAll, describe, expect, it } from 'vitest';
|
|
3
7
|
|
|
4
8
|
import { createDefaultTools } from '../create-default-tools.js';
|
|
5
9
|
|
|
@@ -9,8 +13,12 @@ import type { IRetrievalAdapter, IComputerDriver } from '@robota-sdk/agent-tools
|
|
|
9
13
|
* ARCH-010 made `cwd` a required field of `ICreateDefaultToolsOptions`. The cases that assert the tool
|
|
10
14
|
* LIST never execute a tool and so never reach a path guard; this root is named once, here, so that
|
|
11
15
|
* inertness is visible rather than implied. The containment cases below choose their own roots.
|
|
16
|
+
* Every root sits, unmade, inside one private per-run directory rather than at a fixed name under
|
|
17
|
+
* /tmp that another local user could create first.
|
|
12
18
|
*/
|
|
13
|
-
const
|
|
19
|
+
const PRIVATE_BASE = mkdtempSync(join(tmpdir(), 'robota-create-tools-'));
|
|
20
|
+
afterAll(() => rmSync(PRIVATE_BASE, { recursive: true, force: true }));
|
|
21
|
+
const ASSEMBLY_ROOT = join(PRIVATE_BASE, 'create-tools-assembly-root');
|
|
14
22
|
|
|
15
23
|
describe('createDefaultTools', () => {
|
|
16
24
|
it('assembles all default local tools and describes web tools as local tools', () => {
|
|
@@ -51,11 +59,11 @@ describe('createDefaultTools', () => {
|
|
|
51
59
|
// asserted is that the assembly produces a CONTAINED tool, not merely that a factory can accept a
|
|
52
60
|
// `cwd` nobody passes.
|
|
53
61
|
it('SEC-007: Glob and Grep are bound to the assembly cwd, not context-free singletons', async () => {
|
|
54
|
-
const contained = createDefaultTools({ cwd: '
|
|
62
|
+
const contained = createDefaultTools({ cwd: join(PRIVATE_BASE, 'sec007-assembly-scope') });
|
|
55
63
|
// ARCH-010 — this used to be `createDefaultTools()` with no root at all, which is no longer
|
|
56
64
|
// constructible. A SECOND root serves the same purpose and states it better: one shared singleton
|
|
57
65
|
// could not carry two different roots either way.
|
|
58
|
-
const otherRoot = createDefaultTools({ cwd: '
|
|
66
|
+
const otherRoot = createDefaultTools({ cwd: join(PRIVATE_BASE, 'sec007-other-scope') });
|
|
59
67
|
|
|
60
68
|
for (const name of ['Glob', 'Grep']) {
|
|
61
69
|
const tool = contained.find((candidate) => candidate.getName() === name);
|
|
@@ -81,6 +89,23 @@ describe('createDefaultTools', () => {
|
|
|
81
89
|
}
|
|
82
90
|
});
|
|
83
91
|
|
|
92
|
+
// MUST 4: `WebFetch`/`WebSearch` used to be the module-level singletons `webFetchTool` /
|
|
93
|
+
// `webSearchTool` from `@robota-sdk/agent-tools` — the SAME object on every call. Two
|
|
94
|
+
// concurrently open sessions each built from `createDefaultTools({cwd})` then shared them and
|
|
95
|
+
// tripped a resource guard's `resource-reused` even though nothing about either tool needs
|
|
96
|
+
// sharing across sessions. A fresh instance per call is the fix, mirroring Glob/Grep (SEC-007).
|
|
97
|
+
it('MUST 4: WebFetch and WebSearch are fresh instances per call, not context-free singletons', () => {
|
|
98
|
+
const first = createDefaultTools({ cwd: ASSEMBLY_ROOT });
|
|
99
|
+
const second = createDefaultTools({ cwd: ASSEMBLY_ROOT });
|
|
100
|
+
for (const name of ['WebFetch', 'WebSearch']) {
|
|
101
|
+
const a = first.find((tool) => tool.getName() === name);
|
|
102
|
+
const b = second.find((tool) => tool.getName() === name);
|
|
103
|
+
expect(a, `${name} must be part of the default set`).toBeDefined();
|
|
104
|
+
expect(b).toBeDefined();
|
|
105
|
+
expect(a).not.toBe(b);
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
|
|
84
109
|
// SELFHOST-003 TC-03: the retrieval adapter is threaded through assembly and the tool is
|
|
85
110
|
// adapter-gated — absent with no adapter, present (and only then) when an adapter is supplied.
|
|
86
111
|
it('TC-03: CodebaseRetrieval joins the default set only when a retrieval adapter is supplied', () => {
|
|
@@ -28,8 +28,8 @@ import {
|
|
|
28
28
|
createComputerTool,
|
|
29
29
|
createGlobTool,
|
|
30
30
|
createGrepTool,
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
createWebFetchTool,
|
|
32
|
+
createWebSearchTool,
|
|
33
33
|
routesFilesThroughSandbox,
|
|
34
34
|
} from '@robota-sdk/agent-tools';
|
|
35
35
|
|
|
@@ -91,8 +91,12 @@ export function createDefaultTools(options: ICreateDefaultToolsOptions): Functio
|
|
|
91
91
|
// construction, so registering one meant `Glob`/`Grep` could enumerate outside the session's
|
|
92
92
|
// working directory while `Read`/`Write`/`Edit` were contained.
|
|
93
93
|
...(separate ? [] : [createGlobTool(options), createGrepTool(options)]),
|
|
94
|
-
webFetchTool
|
|
95
|
-
|
|
94
|
+
// MUST 4: also built per call, for the same reason — `webFetchTool`/`webSearchTool` are
|
|
95
|
+
// module-level singletons in `agent-tools`, so two concurrently open sessions built from this
|
|
96
|
+
// set (e.g. two `sessionParticipant`s) shared them and tripped `resource-reused` even though
|
|
97
|
+
// nothing about a WebFetch/WebSearch tool actually needs to be shared across sessions.
|
|
98
|
+
createWebFetchTool(),
|
|
99
|
+
createWebSearchTool(),
|
|
96
100
|
createAskUserQuestionTool(),
|
|
97
101
|
// Retrieval is adapter-gated: absent when no adapter is supplied (there is no host fallback).
|
|
98
102
|
...(options.retrievalAdapter
|