@robota-sdk/agent-tools 3.0.0-beta.8 → 3.0.0-beta.81
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/LICENSE +661 -21
- package/README.md +140 -31
- package/dist/browser/browser.d.ts +67 -0
- package/dist/browser/browser.d.ts.map +1 -0
- package/dist/browser/browser.js +2 -0
- package/dist/browser/browser.js.map +1 -0
- package/dist/node/index.cjs +3348 -1463
- package/dist/node/index.d.cts +984 -307
- package/dist/node/index.d.cts.map +1 -0
- package/dist/node/index.d.ts +984 -307
- package/dist/node/index.d.ts.map +1 -0
- package/dist/node/index.js +3286 -1419
- package/dist/node/index.js.map +1 -0
- package/package.json +52 -19
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @robota-sdk/agent-tools
|
|
2
2
|
|
|
3
|
-
Tool registry, tool creation infrastructure,
|
|
3
|
+
Tool registry, tool creation infrastructure, 9 built-in CLI tools, sandbox execution ports, and sandbox workspace manifests for the Robota SDK.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -18,56 +18,165 @@ Peer dependency: `@robota-sdk/agent-core`
|
|
|
18
18
|
import { createZodFunctionTool } from '@robota-sdk/agent-tools';
|
|
19
19
|
import { z } from 'zod';
|
|
20
20
|
|
|
21
|
-
const weatherTool = createZodFunctionTool(
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
const weatherTool = createZodFunctionTool(
|
|
22
|
+
'get_weather',
|
|
23
|
+
'Get current weather for a city',
|
|
24
|
+
z.object({
|
|
25
25
|
city: z.string().describe('City name'),
|
|
26
26
|
}),
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}),
|
|
30
|
-
});
|
|
27
|
+
async (args) => JSON.stringify({ city: args['city'], temperature: 22, condition: 'sunny' }),
|
|
28
|
+
);
|
|
31
29
|
```
|
|
32
30
|
|
|
33
31
|
### Use Built-in Tools
|
|
34
32
|
|
|
35
33
|
```typescript
|
|
36
|
-
import {
|
|
34
|
+
import {
|
|
35
|
+
createBashTool,
|
|
36
|
+
createReadTool,
|
|
37
|
+
createGlobTool,
|
|
38
|
+
createGrepTool,
|
|
39
|
+
} from '@robota-sdk/agent-tools';
|
|
37
40
|
import { Robota } from '@robota-sdk/agent-core';
|
|
41
|
+
import type { IAIProvider } from '@robota-sdk/agent-core';
|
|
42
|
+
|
|
43
|
+
declare const provider: IAIProvider;
|
|
44
|
+
|
|
45
|
+
// A file tool is built against an explicit containment root and refuses anything outside it
|
|
46
|
+
// (ARCH-010). There is no ready-made instance to import: one bound at import time can carry no root,
|
|
47
|
+
// and a file tool without a root has no boundary.
|
|
48
|
+
const cwd = process.cwd();
|
|
38
49
|
|
|
39
50
|
const agent = new Robota({
|
|
40
51
|
name: 'DevAgent',
|
|
41
52
|
aiProviders: [provider],
|
|
42
53
|
defaultModel: { provider: 'anthropic', model: 'claude-sonnet-4-6' },
|
|
43
|
-
tools: [
|
|
54
|
+
tools: [
|
|
55
|
+
createBashTool({ cwd }),
|
|
56
|
+
createReadTool({ cwd }),
|
|
57
|
+
createGlobTool({ cwd }),
|
|
58
|
+
createGrepTool({ cwd }),
|
|
59
|
+
],
|
|
60
|
+
});
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Built-in Tools
|
|
64
|
+
|
|
65
|
+
Every tool that touches the filesystem is a FACTORY taking the containment root it operates in
|
|
66
|
+
(`cwd`, required — ARCH-010). There is no ready-made instance to import: one bound at import time can
|
|
67
|
+
carry no root, and a file tool with no root has no boundary.
|
|
68
|
+
|
|
69
|
+
| Export | Tool Name | Description |
|
|
70
|
+
| --------------------- | --------------- | ----------------------------------------------------------------------------- |
|
|
71
|
+
| `createShellTool` | Shell | Execute host shell commands; OS-aware (POSIX `sh`/`bash`, Windows PowerShell) |
|
|
72
|
+
| `createBashTool` | Bash | Model-familiar alias of `Shell` — same OS-aware implementation |
|
|
73
|
+
| `createReadTool` | Read | Read file contents with line numbers (cat -n) |
|
|
74
|
+
| `createWriteTool` | Write | Write content to a file (creates parent dirs) |
|
|
75
|
+
| `createEditTool` | Edit | Replace a specific string in a file |
|
|
76
|
+
| `createGlobTool` | Glob | Find files matching a glob pattern (fast-glob) |
|
|
77
|
+
| `createGrepTool` | Grep | Search file contents with regex patterns |
|
|
78
|
+
| `createToolSearchTool` | ToolSearch | Load withheld (deferred) tool schemas by query or exact name; resident so the model can reach it |
|
|
79
|
+
| `webFetchTool` | WebFetch | Fetch URL content (HTML-to-text conversion) |
|
|
80
|
+
| `webSearchTool` | WebSearch | Web search via Brave Search API |
|
|
81
|
+
| `askUserQuestionTool` | AskUserQuestion | Model asks the user structured questions (options/multi-select/free text) |
|
|
82
|
+
|
|
83
|
+
The last three stay instances: they touch no filesystem, so there is no root to contain them by.
|
|
84
|
+
|
|
85
|
+
`AskUserQuestion` lets the model ask the user 1–4 structured questions mid-turn through the injected
|
|
86
|
+
ask port (CMD-004); each environment renders it its own way (Ink dialog, web modal, programmatic
|
|
87
|
+
pre-answer), and headless runs get a structured `unavailable` result instead of a hang or a guess.
|
|
88
|
+
|
|
89
|
+
`Shell` and `Bash` are two registered names for one OS-aware implementation: the shell is resolved per-OS and the tool description names the active OS/shell so the model writes the right syntax (e.g. macOS BSD vs Linux GNU utilities differ).
|
|
90
|
+
|
|
91
|
+
The sandbox-aware factories (`createBashTool`, `createReadTool`, `createWriteTool`, `createEditTool`) also accept an optional `sandboxClient`; without one they run against the host filesystem, contained by `cwd`.
|
|
92
|
+
|
|
93
|
+
## Sandbox Execution
|
|
94
|
+
|
|
95
|
+
`ISandboxClient` is the provider-neutral execution-plane port used by sandbox-aware built-in tools:
|
|
96
|
+
|
|
97
|
+
<!-- doc-example-skip: requires the optional e2b dependency -->
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
import { E2BSandboxClient, createBashTool, createReadTool } from '@robota-sdk/agent-tools';
|
|
101
|
+
import { Sandbox } from 'e2b';
|
|
102
|
+
|
|
103
|
+
const e2b = await Sandbox.create();
|
|
104
|
+
const sandboxClient = new E2BSandboxClient({ sandbox: e2b });
|
|
105
|
+
|
|
106
|
+
// `cwd` is required even with a sandbox client: it is the root inside the sandbox, and the host
|
|
107
|
+
// path guard still applies to any tool that falls through to the host filesystem.
|
|
108
|
+
const cwd = '/workspace';
|
|
109
|
+
const bashTool = createBashTool({ sandboxClient, cwd });
|
|
110
|
+
const readTool = createReadTool({ sandboxClient, cwd });
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
The package does not depend on E2B directly. `E2BSandboxClient` adapts an E2B-compatible object with `commands.run`, `files.read`, `files.write`, and optional `createSnapshot`, `pause`, `connect`, or factory methods supplied by the application. `snapshot()` returns a provider-owned resumable workspace reference; `restore(snapshotId)` hydrates the adapter from that reference. `InMemorySandboxClient` is available for deterministic tests and contract verification.
|
|
114
|
+
|
|
115
|
+
### Workspace Manifests
|
|
116
|
+
|
|
117
|
+
`IWorkspaceManifest` declares the fresh sandbox workspace before a session starts. Paths are workspace-relative and cannot escape the target root.
|
|
118
|
+
|
|
119
|
+
<!-- doc-example-skip: requires the optional e2b dependency -->
|
|
120
|
+
|
|
121
|
+
```typescript
|
|
122
|
+
import { applyWorkspaceManifest, E2BSandboxClient } from '@robota-sdk/agent-tools';
|
|
123
|
+
import { Sandbox } from 'e2b';
|
|
124
|
+
|
|
125
|
+
const sandbox = await Sandbox.create();
|
|
126
|
+
const sandboxClient = new E2BSandboxClient({ sandbox });
|
|
127
|
+
|
|
128
|
+
await applyWorkspaceManifest(sandboxClient, {
|
|
129
|
+
entries: {
|
|
130
|
+
'task.md': { type: 'file', content: 'Analyze this repository.\n' },
|
|
131
|
+
repo: { type: 'gitRepo', url: 'https://github.com/example/project.git', ref: 'main' },
|
|
132
|
+
output: { type: 'dir' },
|
|
133
|
+
},
|
|
44
134
|
});
|
|
45
135
|
```
|
|
46
136
|
|
|
47
|
-
|
|
137
|
+
The generic applicator writes inline/local files, creates directories, and clones Git repositories through `ISandboxClient`. Cloud storage mount entries are part of the contract, but they return `unsupported` until a provider-specific adapter implements native mounting.
|
|
138
|
+
|
|
139
|
+
## Edit and Write Safety
|
|
48
140
|
|
|
49
|
-
|
|
50
|
-
| --------------- | --------- | ------------------------------------ |
|
|
51
|
-
| `bashTool` | Bash | Execute shell commands |
|
|
52
|
-
| `readTool` | Read | Read file contents with line numbers |
|
|
53
|
-
| `writeTool` | Write | Write content to a file |
|
|
54
|
-
| `editTool` | Edit | Replace a specific string in a file |
|
|
55
|
-
| `globTool` | Glob | Find files matching a glob pattern |
|
|
56
|
-
| `grepTool` | Grep | Search file contents with regex |
|
|
57
|
-
| `webFetchTool` | WebFetch | Fetch URL content (HTML-to-text) |
|
|
58
|
-
| `webSearchTool` | WebSearch | Web search via Brave Search API |
|
|
141
|
+
Recent file tool updates keep write/edit behavior atomic and make Edit tool results easier for higher layers to display. Atomic replacements preserve existing target mode bits, so executable scripts remain executable after Write or Edit updates. The Edit tool returns line metadata for changed regions, allowing the CLI to render concise context hunks instead of dumping full files or opaque summaries.
|
|
59
142
|
|
|
60
143
|
## Tool Infrastructure
|
|
61
144
|
|
|
62
|
-
| Export
|
|
63
|
-
|
|
|
64
|
-
| `ToolRegistry`
|
|
65
|
-
| `FunctionTool`
|
|
66
|
-
| `createFunctionTool`
|
|
67
|
-
| `createZodFunctionTool`
|
|
68
|
-
| `
|
|
69
|
-
| `
|
|
145
|
+
| Export | Description |
|
|
146
|
+
| ------------------------ | ---------------------------------------------------------- |
|
|
147
|
+
| `ToolRegistry` | Central tool registration and schema lookup |
|
|
148
|
+
| `FunctionTool` | JS function tool with Zod schema validation |
|
|
149
|
+
| `createFunctionTool` | Factory for creating function tools |
|
|
150
|
+
| `createZodFunctionTool` | Factory with Zod validation and JSON Schema conversion |
|
|
151
|
+
| `IToolInvocationResult` | Result type for built-in CLI tool invocations |
|
|
152
|
+
| `ISandboxClient` | Provider-neutral sandbox execution port |
|
|
153
|
+
| `IWorkspaceManifest` | Declarative sandbox workspace setup contract |
|
|
154
|
+
| `applyWorkspaceManifest` | Generic manifest applicator for sandbox clients |
|
|
155
|
+
| `E2BSandboxClient` | Adapter for E2B-compatible sandbox instances and snapshots |
|
|
156
|
+
| `InMemorySandboxClient` | Deterministic sandbox client for tests |
|
|
157
|
+
|
|
158
|
+
## IToolInvocationResult Shape
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
interface IToolInvocationResult {
|
|
162
|
+
success: boolean;
|
|
163
|
+
output: string;
|
|
164
|
+
error?: string;
|
|
165
|
+
exitCode?: number;
|
|
166
|
+
startLine?: number; // Start line number of the edit in the original file (Edit tool only)
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
`IToolInvocationResult` is the inner result type used by built-in tools. It is serialized to JSON and placed inside the `IToolResult.data` field before being returned to the Robota execution loop.
|
|
171
|
+
|
|
172
|
+
## Dependencies
|
|
173
|
+
|
|
174
|
+
| Dependency | Kind | Purpose |
|
|
175
|
+
| ------------------------ | ---- | ------------------------------------------------------ |
|
|
176
|
+
| `@robota-sdk/agent-core` | Peer | Abstract tool base class, tool interfaces, event types |
|
|
177
|
+
| `fast-glob` | Prod | High-performance glob matching for the Glob tool |
|
|
178
|
+
| `zod` | Prod | Schema validation for function tool parameters |
|
|
70
179
|
|
|
71
180
|
## License
|
|
72
181
|
|
|
73
|
-
|
|
182
|
+
Robota is dual-licensed under the [GNU AGPL-3.0](../../LICENSE) or a [commercial license](../../COMMERCIAL.md). See [LICENSING.md](../../LICENSING.md).
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { FunctionTool, IToolSchema, TToolExecutor, TToolParameters, TUniversalValue } from "@robota-sdk/agent-core";
|
|
2
|
+
import { TypeOf, ZodType } from "zod";
|
|
3
|
+
//#region src/types/tool-result.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Result returned by a CLI tool invocation
|
|
6
|
+
*/
|
|
7
|
+
interface IToolInvocationResult {
|
|
8
|
+
success: boolean;
|
|
9
|
+
output: string;
|
|
10
|
+
error?: string;
|
|
11
|
+
exitCode?: number;
|
|
12
|
+
/** Start line number of the edit in the original file (Edit tool only) */
|
|
13
|
+
startLine?: number;
|
|
14
|
+
}
|
|
15
|
+
//#endregion
|
|
16
|
+
//#region src/implementations/function-tool.d.ts
|
|
17
|
+
/**
|
|
18
|
+
* Helper function to create a function tool from a simple function
|
|
19
|
+
*/
|
|
20
|
+
declare function createFunctionTool(name: string, description: string, parameters: IToolSchema['parameters'], fn: TToolExecutor): FunctionTool;
|
|
21
|
+
/**
|
|
22
|
+
* What a tool declares about itself beyond its callable shape (CLI-1990).
|
|
23
|
+
*
|
|
24
|
+
* Optional, and omission is a declaration too: a tool that says nothing is RESIDENT — its schema is
|
|
25
|
+
* sent on every request, which is what every tool in the tree does today.
|
|
26
|
+
*/
|
|
27
|
+
interface IFunctionToolResidencyOptions {
|
|
28
|
+
/**
|
|
29
|
+
* Withhold this tool's schema from the model until it is loaded by `ToolSearch` or forced by a
|
|
30
|
+
* `toolChoice`. Only honoured while the tool-search policy is engaged, so declaring it on a small
|
|
31
|
+
* tool set costs nothing.
|
|
32
|
+
*/
|
|
33
|
+
deferLoading?: boolean;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Helper function to create a function tool from Zod schema
|
|
37
|
+
*/
|
|
38
|
+
declare function createZodFunctionTool<S extends ZodType>(name: string, description: string, zodSchema: S, fn: TToolExecutor<TypeOf<S>>, residency?: IFunctionToolResidencyOptions): FunctionTool;
|
|
39
|
+
//#endregion
|
|
40
|
+
//#region src/implementations/function-tool/types.d.ts
|
|
41
|
+
/**
|
|
42
|
+
* Parameter type validation options
|
|
43
|
+
*/
|
|
44
|
+
interface IFunctionToolValidationOptions {
|
|
45
|
+
strict?: boolean;
|
|
46
|
+
allowUnknown?: boolean;
|
|
47
|
+
validateTypes?: boolean;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Tool execution metadata
|
|
51
|
+
*/
|
|
52
|
+
interface IFunctionToolExecutionMetadata {
|
|
53
|
+
executionTime: number;
|
|
54
|
+
toolName: string;
|
|
55
|
+
parameters: TToolParameters;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Tool result with metadata
|
|
59
|
+
*/
|
|
60
|
+
interface IFunctionToolResult {
|
|
61
|
+
success: boolean;
|
|
62
|
+
data: TUniversalValue;
|
|
63
|
+
metadata?: IFunctionToolExecutionMetadata;
|
|
64
|
+
}
|
|
65
|
+
//#endregion
|
|
66
|
+
export { type IFunctionToolExecutionMetadata, type IFunctionToolResult, type IFunctionToolValidationOptions, type IToolInvocationResult, createFunctionTool, createZodFunctionTool };
|
|
67
|
+
//# sourceMappingURL=browser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser.d.ts","names":[],"sources":["../../src/types/tool-result.ts","../../src/implementations/function-tool.ts","../../src/implementations/function-tool/types.ts"],"mappings":";;;;;;UAGiB;EACf;EACA;EACA;EACA;;EAEA;;;;;;;iBCKc,mBACd,cACA,qBACA,YAAY,2BACZ,IAAI,gBACH;;;;;;;UAgBc;;;;;;EAMf;;;;;iBAMc,sBAAsB,UAAU,SAC9C,cACA,qBACA,WAAW,GACX,IAAI,cAAc,OAAO,KACzB,YAAW,gCACV;;;;;;UC7Cc;EACf;EACA;EACA;;;;;UAMe;EACf;EACA;EACA,YAAY;;;;;UAMG;EACf;EACA,MAAM;EACN,WAAW"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{FunctionTool as e,ValidationError as t,zodToJsonSchema as n}from"@robota-sdk/agent-core";function r(t,n,r,i){return new e({name:t,description:n,parameters:r},i)}function i(r,i,a,o,s={}){return new e({name:r,description:i,parameters:n(a),...s.deferLoading!==void 0&&{deferLoading:s.deferLoading}},async(e,n)=>{let r=a.safeParse(e);if(!r.success)throw new t(`Zod validation failed: ${r.error}`);let i=await o(r.data,n);return typeof i==`string`?i:JSON.stringify(i)})}export{r as createFunctionTool,i as createZodFunctionTool};
|
|
2
|
+
//# sourceMappingURL=browser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser.js","names":[],"sources":["../../src/implementations/function-tool.ts"],"sourcesContent":["import { FunctionTool, ValidationError, zodToJsonSchema } from '@robota-sdk/agent-core';\n\nimport type { IToolExecutionContext, TToolExecutor, TToolParameters } from '@robota-sdk/agent-core';\nimport type { IToolSchema } from '@robota-sdk/agent-core';\nimport type { TUniversalValue } from '@robota-sdk/agent-core';\nimport type { TypeOf, ZodType } from 'zod';\n\n// The concrete `FunctionTool` class is owned by @robota-sdk/agent-core (DATA-005 SSOT).\n// These factories construct core's `FunctionTool`; agent-tools owns only the factories\n// and the Zod-flavored wrapper.\n\n/**\n * Helper function to create a function tool from a simple function\n */\nexport function createFunctionTool(\n name: string,\n description: string,\n parameters: IToolSchema['parameters'],\n fn: TToolExecutor,\n): FunctionTool {\n const schema: IToolSchema = {\n name,\n description,\n parameters,\n };\n\n return new FunctionTool(schema, fn);\n}\n\n/**\n * What a tool declares about itself beyond its callable shape (CLI-1990).\n *\n * Optional, and omission is a declaration too: a tool that says nothing is RESIDENT — its schema is\n * sent on every request, which is what every tool in the tree does today.\n */\nexport interface IFunctionToolResidencyOptions {\n /**\n * Withhold this tool's schema from the model until it is loaded by `ToolSearch` or forced by a\n * `toolChoice`. Only honoured while the tool-search policy is engaged, so declaring it on a small\n * tool set costs nothing.\n */\n deferLoading?: boolean;\n}\n\n/**\n * Helper function to create a function tool from Zod schema\n */\nexport function createZodFunctionTool<S extends ZodType>(\n name: string,\n description: string,\n zodSchema: S,\n fn: TToolExecutor<TypeOf<S>>,\n residency: IFunctionToolResidencyOptions = {},\n): FunctionTool {\n // Use comprehensive Zod to JSON schema conversion\n const parameters = zodToJsonSchema(zodSchema);\n\n const schema: IToolSchema = {\n name,\n description,\n parameters,\n // Spread rather than assigned: an absent marker must stay ABSENT, not become `undefined`, so a\n // resident tool's schema is byte-identical to what it was before residency existed.\n ...(residency.deferLoading !== undefined && { deferLoading: residency.deferLoading }),\n };\n\n // Wrap the function with validation and ensure proper parameter handling\n const wrappedFn: TToolExecutor = async (\n parameters: TToolParameters,\n context?: IToolExecutionContext,\n ): Promise<TUniversalValue> => {\n // Use Zod for runtime validation — the executor receives the PARSED, schema-typed value\n // (SDK-009): the runtime guarantee and the compile-time type now flow together.\n const parseResult = zodSchema.safeParse(parameters);\n if (!parseResult.success) {\n throw new ValidationError(`Zod validation failed: ${parseResult.error}`);\n }\n\n const result = await fn(parseResult.data as TypeOf<S>, context);\n // Ensure result is always a string for consistency with core package\n return typeof result === 'string' ? result : JSON.stringify(result);\n };\n\n return new FunctionTool(schema, wrappedFn);\n}\n\n// zodToJsonSchema function moved to Facade pattern schema-converter module\n"],"mappings":"gGAcA,SAAgB,EACd,EACA,EACA,EACA,EACc,CAOd,OAAO,IAAI,EAAa,CALtB,OACA,cACA,YAG2B,EAAG,CAAE,CACpC,CAoBA,SAAgB,EACd,EACA,EACA,EACA,EACA,EAA2C,CAAC,EAC9B,CA8Bd,OAAO,IAAI,EAAa,CAzBtB,OACA,cACA,WALiB,EAAgB,CAKxB,EAGT,GAAI,EAAU,eAAiB,IAAA,IAAa,CAAE,aAAc,EAAU,YAAa,CAoB7D,EAAQ,MAf9B,EACA,IAC6B,CAG7B,IAAM,EAAc,EAAU,UAAU,CAAU,EAClD,GAAI,CAAC,EAAY,QACf,MAAM,IAAI,EAAgB,0BAA0B,EAAY,OAAO,EAGzE,IAAM,EAAS,MAAM,EAAG,EAAY,KAAmB,CAAO,EAE9D,OAAO,OAAO,GAAW,SAAW,EAAS,KAAK,UAAU,CAAM,CACpE,CAEyC,CAC3C"}
|