@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.
@@ -1,370 +1,1047 @@
1
- import { IToolRegistry, ITool, IToolSchema, TToolParameters, TUniversalValue, IFunctionTool, TToolExecutor, IEventService, IToolExecutionContext, IToolResult, IParameterValidationResult, IOpenAPIToolConfig } from '@robota-sdk/agent-core';
2
-
1
+ import { FunctionTool, IToolSchema, TToolExecutor, TToolParameters, TUniversalValue, ToolExecutionError } from "@robota-sdk/agent-core";
2
+ import { TypeOf, ZodType, z } from "zod";
3
+ import { IEgressDeps, IEgressPolicy } from "@robota-sdk/agent-core/node";
4
+ import fg from "fast-glob";
5
+ //#region src/types/tool-result.d.ts
3
6
  /**
4
7
  * Result returned by a CLI tool invocation
5
8
  */
6
- interface TToolResult {
7
- success: boolean;
8
- output: string;
9
- error?: string;
10
- exitCode?: number;
11
- }
12
-
13
- /**
14
- * Tool registry implementation
15
- * Manages tool registration, validation, and retrieval
16
- */
17
- declare class ToolRegistry implements IToolRegistry {
18
- private tools;
19
- /**
20
- * Register a tool
21
- */
22
- register(tool: ITool): void;
23
- /**
24
- * Unregister a tool
25
- */
26
- unregister(name: string): void;
27
- /**
28
- * Get tool by name
29
- */
30
- get(name: string): ITool | undefined;
31
- /**
32
- * Get all registered tools
33
- */
34
- getAll(): ITool[];
35
- /**
36
- * Get tool schemas
37
- */
38
- getSchemas(): IToolSchema[];
39
- /**
40
- * Check if tool exists
41
- */
42
- has(name: string): boolean;
43
- /**
44
- * Clear all tools
45
- */
46
- clear(): void;
47
- /**
48
- * Get tool names
49
- */
50
- getToolNames(): string[];
51
- /**
52
- * Get tools by pattern
53
- */
54
- getToolsByPattern(pattern: string | RegExp): ITool[];
55
- /**
56
- * Get tool count
57
- */
58
- size(): number;
59
- /**
60
- * Validate tool schema
61
- */
62
- private validateToolSchema;
63
- }
64
-
65
- /**
66
- * FunctionTool - Type definitions for Facade pattern implementation
67
- *
68
- * REASON: Complex Zod schema type compatibility requires separation of concerns
69
- * ALTERNATIVES_CONSIDERED:
70
- * 1. Fix all Zod undefined issues in single file (creates maintenance burden)
71
- * 2. Use any types strategically (reduces type safety)
72
- * 3. Remove Zod support entirely (breaks existing functionality)
73
- * 4. Create complex conditional types (adds cognitive overhead)
74
- * 5. Use type assertions everywhere (increases runtime risk)
75
- * NOTE: Tool functionality is now integrated into @robota-sdk/agent-tools package
76
- */
77
-
78
- /**
79
- * Zod schema compatibility types
80
- */
81
- interface IZodParseResult {
82
- success: boolean;
83
- data?: TToolParameters;
84
- error?: string | Error;
85
- }
86
- interface IZodSchemaDef {
87
- typeName?: string;
88
- innerType?: IZodSchema;
89
- valueType?: IZodSchema;
90
- checks?: Array<{
91
- kind: string;
92
- value?: TUniversalValue;
93
- }>;
94
- shape?: () => Record<string, IZodSchema>;
95
- type?: IZodSchema;
96
- values?: TUniversalValue[];
97
- description?: string;
98
- }
99
- interface IZodSchema {
100
- parse(value: TToolParameters): TToolParameters;
101
- safeParse(value: TToolParameters): IZodParseResult;
102
- _def?: IZodSchemaDef;
9
+ interface IToolInvocationResult {
10
+ success: boolean;
11
+ output: string;
12
+ error?: string;
13
+ exitCode?: number;
14
+ /** Start line number of the edit in the original file (Edit tool only) */
15
+ startLine?: number;
16
+ }
17
+ //#endregion
18
+ //#region src/sandbox/types.d.ts
19
+ interface ISandboxRunOptions {
20
+ timeoutMs?: number;
21
+ workingDirectory?: string;
22
+ }
23
+ interface ISandboxRunResult {
24
+ stdout: string;
25
+ stderr?: string;
26
+ exitCode: number;
27
+ }
28
+ interface IWorkspaceManifestFileEntry {
29
+ type: 'file';
30
+ content: string;
31
+ encoding?: 'utf8';
32
+ }
33
+ interface IWorkspaceManifestDirectoryEntry {
34
+ type: 'dir';
35
+ }
36
+ interface IWorkspaceManifestLocalFileEntry {
37
+ type: 'localFile';
38
+ src: string;
39
+ }
40
+ interface IWorkspaceManifestLocalDirectoryEntry {
41
+ type: 'localDir';
42
+ src: string;
43
+ }
44
+ interface IWorkspaceManifestGitRepositoryEntry {
45
+ type: 'gitRepo';
46
+ url: string;
47
+ ref?: string;
48
+ shallow?: boolean;
49
+ }
50
+ interface IWorkspaceManifestS3MountEntry {
51
+ type: 's3Mount';
52
+ bucket: string;
53
+ prefix?: string;
54
+ region: string;
55
+ }
56
+ interface IWorkspaceManifestGcsMountEntry {
57
+ type: 'gcsMount';
58
+ bucket: string;
59
+ prefix?: string;
60
+ }
61
+ interface IWorkspaceManifestR2MountEntry {
62
+ type: 'r2Mount';
63
+ bucket: string;
64
+ accountId: string;
65
+ prefix?: string;
66
+ }
67
+ interface IWorkspaceManifestAzureBlobMountEntry {
68
+ type: 'azureBlobMount';
69
+ container: string;
70
+ account: string;
71
+ prefix?: string;
72
+ }
73
+ type TWorkspaceManifestEntry = IWorkspaceManifestFileEntry | IWorkspaceManifestDirectoryEntry | IWorkspaceManifestLocalFileEntry | IWorkspaceManifestLocalDirectoryEntry | IWorkspaceManifestGitRepositoryEntry | IWorkspaceManifestS3MountEntry | IWorkspaceManifestGcsMountEntry | IWorkspaceManifestR2MountEntry | IWorkspaceManifestAzureBlobMountEntry;
74
+ interface IWorkspaceManifestPermissions {
75
+ read?: string[];
76
+ write?: string[];
77
+ }
78
+ interface IWorkspaceManifest {
79
+ entries: Record<string, TWorkspaceManifestEntry>;
80
+ environment?: Record<string, string>;
81
+ permissions?: IWorkspaceManifestPermissions;
82
+ }
83
+ interface IWorkspaceManifestApplyOptions {
84
+ targetRoot?: string;
85
+ hostRoot?: string;
86
+ }
87
+ type TWorkspaceManifestApplyStatus = 'applied' | 'unsupported';
88
+ interface IWorkspaceManifestAppliedEntry {
89
+ path: string;
90
+ type: TWorkspaceManifestEntry['type'];
91
+ status: TWorkspaceManifestApplyStatus;
92
+ message?: string;
93
+ }
94
+ interface IWorkspaceManifestApplyResult {
95
+ entries: IWorkspaceManifestAppliedEntry[];
103
96
  }
104
97
  /**
105
- * Parameter type validation options
98
+ * How a sandbox's filesystem relates to the host's (issue #3081).
99
+ *
100
+ * - `shared` — OS-level confinement of commands over the host filesystem (Seatbelt, bubblewrap).
101
+ * File tools stay on the host, bounded by the path guard and the permission rules.
102
+ * - `separate` — a remote or VM filesystem (E2B, in-memory). EVERY file tool must route through the
103
+ * sandbox, or a search would read one filesystem while an edit writes another.
106
104
  */
107
- interface IFunctionToolValidationOptions {
108
- strict?: boolean;
109
- allowUnknown?: boolean;
110
- validateTypes?: boolean;
105
+ type TSandboxFilesystem = 'shared' | 'separate';
106
+ /** A process to start: the executable, its arguments, and where it runs. */
107
+ interface ICommandInvocation {
108
+ readonly command: string;
109
+ readonly args: readonly string[];
110
+ readonly cwd: string;
111
+ /** Data handed to the process on descriptors 3, 4, …, each written whole and then closed. */
112
+ readonly inputDescriptors?: readonly Uint8Array[];
113
+ /** Runs once the process has exited; a returned note is appended to the command's output. */
114
+ readonly afterExit?: () => string | undefined;
111
115
  }
116
+ interface ISandboxClient {
117
+ /** Absent means `separate`: every client before this field existed had its own filesystem. */
118
+ readonly filesystem?: TSandboxFilesystem;
119
+ /**
120
+ * A `shared` client that confines a host process in place: the shell tool starts the returned
121
+ * invocation itself, so timeouts, cancellation, output limits and process-group kill stay the
122
+ * tool's. Returning the invocation unchanged runs the command unconfined.
123
+ */
124
+ wrapCommand?(invocation: ICommandInvocation, shellCommand: string): ICommandInvocation;
125
+ /**
126
+ * Whether this client confines `shellCommand` and its settings let a confined command run without
127
+ * a prompt. The permission gate still refuses or asks first for deny rules, ask rules and the
128
+ * never-auto set.
129
+ */
130
+ autoApproves?(shellCommand: string): boolean;
131
+ run(command: string, options?: ISandboxRunOptions): Promise<ISandboxRunResult>;
132
+ readFile(path: string): Promise<string>;
133
+ writeFile(path: string, content: string): Promise<void>;
134
+ applyManifest?(manifest: IWorkspaceManifest, options?: IWorkspaceManifestApplyOptions): Promise<IWorkspaceManifestApplyResult>;
135
+ /** Return a provider-owned resumable workspace reference. */
136
+ snapshot?(): Promise<string>;
137
+ /** Hydrate this client from a provider-owned workspace reference. */
138
+ restore?(snapshotId: string): Promise<void>;
139
+ }
140
+ interface ISandboxToolOptions {
141
+ sandboxClient?: ISandboxClient;
142
+ /** Abort a host file read between bounded chunks. */
143
+ signal?: AbortSignal;
144
+ /**
145
+ * The tool's working-directory root on the host (non-sandbox) path. REQUIRED — ARCH-010.
146
+ *
147
+ * For the tools that read and enumerate — `Read`/`Write`/`Edit` and, since SEC-007, `Glob`/`Grep` —
148
+ * this is a CONTAINMENT boundary: access outside it is refused, decided on canonical (symlink-
149
+ * resolved) paths. For `Shell`/`Bash` it is the DEFAULT working directory and deliberately not a
150
+ * boundary — a cwd guard on arbitrary command execution is undone by the first `cd` (see the
151
+ * shell-tool file header).
152
+ *
153
+ * It is required because it was optional: with no root the containment guard used to answer
154
+ * "allowed", so a construction site that simply forgot supplied an unsandboxed `Read`. The audit
155
+ * found three layers that had. Optional here means the boundary is a convention each caller may or
156
+ * may not follow, and a boundary nobody is obliged to supply is not a boundary. Callers that
157
+ * genuinely mean "this process's directory" now say `process.cwd()` where a reader can see it.
158
+ */
159
+ cwd: string;
160
+ }
161
+ //#endregion
162
+ //#region src/sandbox/e2b-sandbox-client.d.ts
163
+ interface IE2BCommandStartOptions {
164
+ timeoutMs?: number;
165
+ cwd?: string;
166
+ background?: false;
167
+ }
168
+ interface IE2BCommandResult {
169
+ stdout?: string;
170
+ stderr?: string;
171
+ exitCode?: number;
172
+ exit_code?: number;
173
+ }
174
+ interface IE2BCommands {
175
+ run(command: string, options?: IE2BCommandStartOptions): Promise<IE2BCommandResult>;
176
+ }
177
+ interface IE2BFiles {
178
+ read(path: string): Promise<string | Uint8Array>;
179
+ write(path: string, content: string): Promise<void>;
180
+ }
181
+ interface IE2BSnapshot {
182
+ snapshotId?: string;
183
+ id?: string;
184
+ }
185
+ interface IE2BSandboxAdapter {
186
+ sandboxId?: string;
187
+ commands: IE2BCommands;
188
+ files: IE2BFiles;
189
+ pause?(): Promise<boolean | string | void>;
190
+ connect?(): Promise<IE2BSandboxAdapter>;
191
+ createSnapshot?(): Promise<IE2BSnapshot>;
192
+ }
193
+ interface IE2BSandboxClientOptions {
194
+ sandbox: IE2BSandboxAdapter;
195
+ connectSandbox?: (sandboxId: string) => Promise<IE2BSandboxAdapter>;
196
+ createSandboxFromSnapshot?: (snapshotId: string) => Promise<IE2BSandboxAdapter>;
197
+ }
198
+ declare class E2BSandboxClient implements ISandboxClient {
199
+ private sandbox;
200
+ private readonly connectSandbox?;
201
+ private readonly createSandboxFromSnapshot?;
202
+ constructor(options: IE2BSandboxClientOptions);
203
+ run(command: string, options?: ISandboxRunOptions): Promise<ISandboxRunResult>;
204
+ readFile(path: string): Promise<string>;
205
+ writeFile(path: string, content: string): Promise<void>;
206
+ snapshot(): Promise<string>;
207
+ restore(snapshotId: string): Promise<void>;
208
+ }
209
+ //#endregion
210
+ //#region src/sandbox/in-memory-sandbox-client.d.ts
211
+ type TInMemorySandboxRunHandler = (command: string, options: ISandboxRunOptions | undefined, files: ReadonlyMap<string, string>) => Promise<ISandboxRunResult> | ISandboxRunResult;
212
+ interface IInMemorySandboxClientOptions {
213
+ files?: Record<string, string>;
214
+ runHandler?: TInMemorySandboxRunHandler;
215
+ }
216
+ declare class InMemorySandboxClient implements ISandboxClient {
217
+ private readonly files;
218
+ private readonly snapshots;
219
+ private readonly runHandler?;
220
+ private snapshotSequence;
221
+ constructor(options?: IInMemorySandboxClientOptions);
222
+ run(command: string, options?: ISandboxRunOptions): Promise<ISandboxRunResult>;
223
+ readFile(path: string): Promise<string>;
224
+ writeFile(path: string, content: string): Promise<void>;
225
+ snapshot(): Promise<string>;
226
+ restore(snapshotId: string): Promise<void>;
227
+ getFile(path: string): string | undefined;
228
+ }
229
+ //#endregion
230
+ //#region src/sandbox/containment.d.ts
231
+ type TExecutionContainment = 'host' | `sandbox-${TSandboxFilesystem}`;
232
+ declare function describeExecutionContainment(client: ISandboxClient | undefined): TExecutionContainment;
233
+ /** Whether file tools must read and write through the sandbox rather than the host filesystem. */
234
+ declare function routesFilesThroughSandbox(client: ISandboxClient | undefined): boolean;
235
+ //#endregion
236
+ //#region src/sandbox/workspace-manifest.d.ts
237
+ declare function applyWorkspaceManifest(sandboxClient: ISandboxClient, manifest: IWorkspaceManifest, options?: IWorkspaceManifestApplyOptions): Promise<IWorkspaceManifestApplyResult>;
238
+ declare function validateWorkspaceManifestPath(path: string): string;
239
+ //#endregion
240
+ //#region src/sandbox/os-sandbox-policy.d.ts
112
241
  /**
113
- * Schema conversion options
242
+ * What an OS-level sandbox lets a command touch, written once per backend (issue #3082).
243
+ *
244
+ * The same policy becomes bubblewrap arguments on Linux and a Seatbelt profile on macOS:
245
+ * - the whole filesystem is readable except the `denyRead` paths;
246
+ * - writes are allowed only inside the workspace, the temporary directories and `allowWrite`;
247
+ * - inside the workspace, the files that configure git, the agent, MCP servers and shells stay
248
+ * read-only, so a confined command cannot change what the next session trusts;
249
+ * - the network is either reachable or not. There is no per-domain allowlist: that needs a proxy
250
+ * process the OS cannot enforce, and a boundary here is only worth what the OS enforces.
114
251
  */
115
- interface ISchemaConversionOptions {
116
- includeDescription?: boolean;
117
- strictTypes?: boolean;
118
- allowAdditionalProperties?: boolean;
252
+ interface IOsSandboxPolicy {
253
+ /** The workspace root, real path. Writable. */
254
+ readonly root: string;
255
+ /** Temporary directories, real paths. Writable. */
256
+ readonly tempDirectories: readonly string[];
257
+ /** Further writable paths, absolute. */
258
+ readonly allowWrite: readonly string[];
259
+ /** Paths hidden from the command, absolute, with whether each is a directory. */
260
+ readonly denyRead: readonly {
261
+ readonly path: string;
262
+ readonly directory: boolean;
263
+ }[];
264
+ readonly network: boolean;
119
265
  }
120
266
  /**
121
- * Tool execution metadata
267
+ * Workspace entries a confined command must not write, relative to the root. `.git` is read-only
268
+ * as a whole: the files that make git run something (config, hooks, `commondir`, per-worktree
269
+ * config) are too many and too easy to add to for a list inside it to stay complete, so git
270
+ * commands that write run unconfined, through the ordinary permission path.
122
271
  */
123
- interface IFunctionToolExecutionMetadata {
124
- executionTime: number;
125
- toolName: string;
126
- parameters: TToolParameters;
272
+ declare function protectedWorkspaceEntries(): readonly string[];
273
+ interface IBubblewrapInput {
274
+ readonly policy: IOsSandboxPolicy;
275
+ /** Which of `protectedWorkspaceEntries()` and the writable worktree folders exist. */
276
+ readonly exists: (path: string) => boolean;
277
+ /** Entry names in a directory, for the worktrees whose `.git` file must stay put. */
278
+ readonly listDirectory: (path: string) => readonly string[];
279
+ readonly cwd: string;
280
+ readonly command: string;
281
+ readonly args: readonly string[];
282
+ /**
283
+ * The descriptor `bwrap --seccomp` reads the Unix-socket filter from. Required when the network
284
+ * is off: without it a daemon's socket is still reachable.
285
+ */
286
+ readonly seccompDescriptor?: number;
127
287
  }
288
+ /** The `bwrap` argument vector that runs `command args` under the policy. */
289
+ declare function bubblewrapArguments(input: IBubblewrapInput): string[];
128
290
  /**
129
- * Tool result with metadata
291
+ * The Seatbelt profile for `sandbox-exec -p`. Later rules win, so the order below is the policy:
292
+ * deny writes, allow the writable places, deny the protected entries again, reopen worktrees.
130
293
  */
131
- interface IFunctionToolResult {
132
- success: boolean;
133
- data: TUniversalValue;
134
- metadata?: IFunctionToolExecutionMetadata;
294
+ declare function seatbeltProfile(policy: IOsSandboxPolicy): string;
295
+ //#endregion
296
+ //#region src/sandbox/os-sandbox-client.d.ts
297
+ type TOsSandboxBackend = 'bubblewrap' | 'seatbelt';
298
+ interface IOsSandboxSettings {
299
+ /** Confine shell commands. */
300
+ readonly enabled: boolean;
301
+ /** A confined command runs without a prompt; deny and ask rules still apply first. */
302
+ readonly autoAllowBashIfSandboxed: boolean;
303
+ /** Commands (first word) that run unconfined and take the ordinary permission path. */
304
+ readonly excludedCommands: readonly string[];
305
+ /** Further writable paths: absolute, `~/`-relative, or relative to the workspace. */
306
+ readonly allowWrite: readonly string[];
307
+ /** Paths hidden from confined commands, written the same way. */
308
+ readonly denyRead: readonly string[];
309
+ /** Whether confined commands may reach the network. */
310
+ readonly network: boolean;
311
+ }
312
+ declare const DEFAULT_OS_SANDBOX_SETTINGS: IOsSandboxSettings;
313
+ /** What this machine can do, found once at startup. */
314
+ interface IOsSandboxAvailability {
315
+ readonly backend?: TOsSandboxBackend;
316
+ /** The backend's executable, when found and working. */
317
+ readonly executable?: string;
318
+ /** What to install or fix, when the platform has a backend but it cannot run. */
319
+ readonly missing: readonly string[];
320
+ /** Set when the platform has no backend at all. */
321
+ readonly unsupportedPlatform?: string;
322
+ }
323
+ interface IDetectOsSandboxOptions {
324
+ readonly platform?: NodeJS.Platform;
325
+ readonly arch?: string;
326
+ /** Test seam; production runs the probe with `spawnSync`. */
327
+ readonly probe?: (command: string, args: readonly string[]) => {
328
+ ok: boolean;
329
+ detail?: string;
330
+ };
135
331
  }
136
-
332
+ /** Find the platform's backend and check it can actually start a sandbox here. */
333
+ declare function detectOsSandbox(options?: IDetectOsSandboxOptions): IOsSandboxAvailability;
334
+ interface IOsSandboxClientOptions {
335
+ /** The workspace root. */
336
+ readonly root: string;
337
+ readonly availability: IOsSandboxAvailability;
338
+ readonly settings?: Partial<IOsSandboxSettings>;
339
+ readonly homeDirectory?: string;
340
+ }
341
+ interface IOsSandboxStatus {
342
+ readonly settings: IOsSandboxSettings;
343
+ readonly availability: IOsSandboxAvailability;
344
+ /** Settings ask for confinement and the backend can provide it. */
345
+ readonly active: boolean;
346
+ }
347
+ declare class OsSandboxClient implements ISandboxClient {
348
+ readonly filesystem: "shared";
349
+ private readonly root;
350
+ private readonly availability;
351
+ private readonly homeDirectory;
352
+ private current;
353
+ private inFlight;
354
+ private baseline;
355
+ /** Entries a clean-up could not restore, with the state they must return to. */
356
+ private readonly unresolved;
357
+ constructor(options: IOsSandboxClientOptions);
358
+ status(): IOsSandboxStatus;
359
+ /** Change the settings for the next command. */
360
+ configure(settings: Partial<IOsSandboxSettings>): void;
361
+ /** Whether `shellCommand` would run confined. */
362
+ confines(shellCommand: string): boolean;
363
+ autoApproves(shellCommand: string): boolean;
364
+ wrapCommand(invocation: ICommandInvocation, shellCommand: string): ICommandInvocation;
365
+ /**
366
+ * How each protected entry stands before a command: bubblewrap can mount an existing entry
367
+ * read-only, but not one that does not exist yet, and a symlink it mounts through to its target
368
+ * while the link itself stays replaceable. Read with `lstat`, so a dangling link is not "missing".
369
+ */
370
+ private protectedEntryStates;
371
+ /**
372
+ * Undo what the command did to protected entries it could reach: one it created where none
373
+ * existed is moved into `.robota/sandbox-quarantine`, and a symlink it replaced is restored. Moved,
374
+ * not deleted, so nothing the host wrote meanwhile is lost.
375
+ */
376
+ /** Whether a path's real location is under the read-only mounts: not the workspace, temp or `allowWrite`. */
377
+ private resolvesOutsideWritableWorkspace;
378
+ /**
379
+ * Never throws: this runs as the command's process closes, and an exception there would take the
380
+ * host down and leave the entry in place. The quarantine is outside the workspace, under the
381
+ * user's `~/.robota`, where the command cannot reach it; what cannot be moved there is removed.
382
+ */
383
+ private restoreProtectedEntries;
384
+ /**
385
+ * Where set-aside entries go: the workspace's own `.robota`, when it was a real directory before
386
+ * the command — then it was mounted read-only, so the command could not reach it, and a rename
387
+ * within one filesystem needs no permission inside the entry. Otherwise the user's `~/.robota`.
388
+ * Decided from the baseline: what is there now may be the command's own replacement.
389
+ */
390
+ private quarantineRoot;
391
+ private setAside;
392
+ /** The policy for the current settings, with every path made absolute and real. */
393
+ policy(): IOsSandboxPolicy;
394
+ run(command: string, options?: ISandboxRunOptions): Promise<ISandboxRunResult>;
395
+ readFile(path: string): Promise<string>;
396
+ writeFile(path: string, content: string): Promise<void>;
397
+ }
398
+ //#endregion
399
+ //#region src/retrieval/types.d.ts
137
400
  /**
138
- * Function tool implementation
139
- * Wraps a JavaScript function as a tool with schema validation
401
+ * SELFHOST-003: codebase-retrieval adapter contract (v1).
140
402
  *
141
- * Implements IFunctionTool without extending AbstractTool to avoid
142
- * circular runtime dependency (tools → agents → tools).
143
- */
144
- declare class FunctionTool implements IFunctionTool {
145
- readonly schema: IToolSchema;
146
- readonly fn: TToolExecutor;
147
- private eventService;
148
- constructor(schema: IToolSchema, fn: TToolExecutor);
149
- /**
150
- * Get tool name
151
- */
152
- getName(): string;
153
- /**
154
- * Set EventService for post-construction injection.
155
- * Accepts EventService as-is without transformation.
156
- * Caller is responsible for providing properly configured EventService.
157
- */
158
- setEventService(eventService: IEventService | undefined): void;
159
- /**
160
- * Execute the function tool
161
- */
162
- execute(parameters: TToolParameters, context?: IToolExecutionContext): Promise<IToolResult>;
163
- /**
164
- * Validate parameters (simple boolean result)
165
- */
166
- validate(parameters: TToolParameters): boolean;
167
- /**
168
- * Validate tool parameters with detailed result
169
- */
170
- validateParameters(parameters: TToolParameters): IParameterValidationResult;
171
- /**
172
- * Get tool description
173
- */
174
- getDescription(): string;
175
- /**
176
- * Get detailed validation errors
177
- */
178
- private getValidationErrors;
179
- /**
180
- * Validate individual parameter type
181
- */
182
- private validateParameterType;
183
- /**
184
- * Validate constructor inputs
185
- */
186
- private validateConstructorInputs;
403
+ * Mirrors the sandbox port precedent (`ISandboxClient` in `../sandbox/types.ts`): the port + types live
404
+ * in `agent-tools` and `createRetrievalTool({ adapter })` composes over the port. The neutral repo-map
405
+ * ranking adapter (`./repo-map-adapter.ts`) implements this port; the heavy source parser is injected as
406
+ * the duck-typed `IRetrievalSourceParser` (like `IE2BSandboxAdapter`), and the corpus is supplied from the
407
+ * surface — so NO heavy parser SDK and NO repo paths live in this package.
408
+ *
409
+ * v1 backend = repo-map graph-centrality ranking (no natural-language query). The embedding-vector
410
+ * backend (`query(nl_text) → top-k`) is a consciously deferred follow-up (P4) that may revise this port.
411
+ */
412
+ /** A symbol (definition) extracted from a source file by the injected parser. */
413
+ interface IRetrievalSymbol {
414
+ /** Repo-relative file the symbol is defined in. */
415
+ file: string;
416
+ /** Symbol name (function/class/const/…). */
417
+ name: string;
418
+ /** Neutral definition kind (e.g. `function`, `class`); opaque to the ranker. */
419
+ kind: string;
420
+ /** 1-based line of the definition. */
421
+ line: number;
422
+ }
423
+ /** One source file parsed into its definitions + the identifiers it references (graph edges). */
424
+ interface IRetrievalParsedFile {
425
+ /** Symbols defined in this file. */
426
+ definitions: IRetrievalSymbol[];
427
+ /** Identifiers this file references (edges toward other files' definitions). */
428
+ references: string[];
187
429
  }
188
430
  /**
189
- * Helper function to create a function tool from a simple function
431
+ * Duck-typed source-parser port (mirror `IE2BSandboxAdapter`): parse one file's source into its
432
+ * definitions + references. Injected so no heavy parser SDK becomes an `agent-tools` dependency.
190
433
  */
191
- declare function createFunctionTool(name: string, description: string, parameters: IToolSchema['parameters'], fn: TToolExecutor): FunctionTool;
434
+ interface IRetrievalSourceParser {
435
+ parse(file: string, content: string): IRetrievalParsedFile;
436
+ }
437
+ /** One corpus file (supplied from the surface — the package holds no repo paths). */
438
+ interface IRetrievalCorpusFile {
439
+ /** Repo-relative path. */
440
+ path: string;
441
+ /** File source. */
442
+ content: string;
443
+ }
192
444
  /**
193
- * Helper function to create a function tool from Zod schema
445
+ * A retrieval request: rank the corpus relative to the active files / mentioned identifiers within a
446
+ * token budget. There is NO natural-language query in v1 (repo-map ranking) — that is the deferred
447
+ * vector backend's shape.
448
+ */
449
+ interface IRetrievalRequest {
450
+ /** Repo-relative files currently in focus; their references seed the ranking (personalization). */
451
+ activeFiles?: string[];
452
+ /** Extra identifiers to bias the ranking toward. */
453
+ mentionedIdentifiers?: string[];
454
+ /** Maximum tokens the ranked result may consume. */
455
+ tokenBudget: number;
456
+ }
457
+ /** One ranked result entry (a relevant symbol), with its centrality score + token cost. */
458
+ interface IRetrievalRankedSymbol {
459
+ file: string;
460
+ name: string;
461
+ kind: string;
462
+ line: number;
463
+ /** Relevance score (higher = more central/relevant); ranker-defined, monotonic. */
464
+ score: number;
465
+ /** Estimated tokens this entry contributes to the budget. */
466
+ tokens: number;
467
+ }
468
+ /** The result of a retrieval: ranked entries whose total tokens ≤ the request budget. */
469
+ interface IRetrievalResult {
470
+ /** Ranked entries, most relevant first; `sum(tokens) ≤ request.tokenBudget`. */
471
+ symbols: IRetrievalRankedSymbol[];
472
+ /** Total tokens across `symbols` (≤ budget). */
473
+ totalTokens: number;
474
+ }
475
+ /** The retrieval adapter port (mirror `ISandboxClient`). `createRetrievalTool` composes over this. */
476
+ interface IRetrievalAdapter {
477
+ retrieve(request: IRetrievalRequest): Promise<IRetrievalResult>;
478
+ }
479
+ /** Tool options carrying the retrieval adapter (mirror `ISandboxToolOptions`). */
480
+ interface IRetrievalToolOptions {
481
+ adapter?: IRetrievalAdapter;
482
+ }
483
+ /**
484
+ * One indexed corpus file (SELFHOST-003 P2): its parsed definitions + references. This is the parsed
485
+ * form the ranker consumes, so a built index lets the adapter rank WITHOUT re-parsing the corpus on
486
+ * every `retrieve()`.
194
487
  */
195
- declare function createZodFunctionTool(name: string, description: string, zodSchema: IZodSchema, fn: TToolExecutor): FunctionTool;
196
-
488
+ interface IRepoMapIndexEntry {
489
+ /** Repo-relative path. */
490
+ path: string;
491
+ /** Symbols defined in this file. */
492
+ definitions: IRetrievalSymbol[];
493
+ /** Identifiers this file references. */
494
+ references: string[];
495
+ }
197
496
  /**
198
- * OpenAPI tool implementation
199
- * Executes API calls based on OpenAPI 3.0 specifications
497
+ * A built, serializable repo-map index (SELFHOST-003 P2): the whole corpus parsed once. Persist it
498
+ * (see `serializeRepoMapIndex`/`deserializeRepoMapIndex`) so retrieval is build-once, rank-many. The
499
+ * `version` guards forward-compatibility of the persisted form.
500
+ */
501
+ interface IRepoMapIndex {
502
+ /** Persisted-schema version. */
503
+ version: number;
504
+ /** One entry per corpus file, parsed. */
505
+ entries: IRepoMapIndexEntry[];
506
+ }
507
+ /**
508
+ * A set of corpus changes to apply incrementally to a built index (SELFHOST-003 P3): only the changed
509
+ * files are re-parsed; the rest of the index is reused unchanged.
510
+ */
511
+ interface IRepoMapIndexChanges {
512
+ /** Files added or modified — re-parsed and upserted into the index. */
513
+ upserted?: IRetrievalCorpusFile[];
514
+ /** Repo-relative paths removed — their entries are dropped from the index. */
515
+ removed?: string[];
516
+ }
517
+ //#endregion
518
+ //#region src/retrieval/repo-map-index.d.ts
519
+ /** Persisted-schema version — bump when `IRepoMapIndex`'s serialized shape changes incompatibly. */
520
+ declare const REPO_MAP_INDEX_VERSION = 1;
521
+ interface IBuildRepoMapIndexOptions {
522
+ /** Injected source parser (duck-typed; no heavy parser SDK becomes an `agent-tools` dependency). */
523
+ parser: IRetrievalSourceParser;
524
+ /** The corpus to index, supplied from the surface (no repo paths live in this package). */
525
+ corpus: IRetrievalCorpusFile[];
526
+ }
527
+ /** Parse the whole corpus once into a serializable repo-map index. */
528
+ declare function buildRepoMapIndex(options: IBuildRepoMapIndexOptions): IRepoMapIndex;
529
+ /**
530
+ * Apply corpus changes to a built index INCREMENTALLY (SELFHOST-003 P3): re-parse only the `upserted`
531
+ * files and drop `removed` paths, reusing every unchanged entry. Returns a new index (the input is not
532
+ * mutated). A file present in both `removed` and `upserted` is upserted (re-parse wins); a path repeated
533
+ * within `upserted` is de-duplicated last-wins, so the result always has one entry per path — matching a
534
+ * full rebuild (entry order does not affect ranking). Unchanged entries are REUSED BY REFERENCE; index
535
+ * entries are treated as immutable, so callers must not mutate an entry in place.
536
+ */
537
+ declare function updateRepoMapIndex(index: IRepoMapIndex, changes: IRepoMapIndexChanges, parser: IRetrievalSourceParser): IRepoMapIndex;
538
+ /** Serialize a built index to a neutral JSON string for persistence by the surface. */
539
+ declare function serializeRepoMapIndex(index: IRepoMapIndex): string;
540
+ /**
541
+ * Restore a built index from its serialized form. Throws on malformed JSON or an unsupported
542
+ * `version` — a stale/incompatible persisted index must be rebuilt, never silently mis-ranked.
543
+ */
544
+ declare function deserializeRepoMapIndex(serialized: string): IRepoMapIndex;
545
+ //#endregion
546
+ //#region src/retrieval/repo-map-adapter.d.ts
547
+ /**
548
+ * Construct from EITHER a prebuilt/persisted `index` (P2) OR a `parser` + `corpus` (parsed once at
549
+ * construction). At least one form must be supplied (else the constructor throws); if both are given,
550
+ * `index` takes precedence.
551
+ */
552
+ interface IRepoMapRetrievalAdapterOptions {
553
+ /** Injected source parser (duck-typed) — required when building from a corpus. */
554
+ parser?: IRetrievalSourceParser;
555
+ /** The corpus to index, supplied from the surface — required when building from a corpus. */
556
+ corpus?: IRetrievalCorpusFile[];
557
+ /** A prebuilt/persisted index (SELFHOST-003 P2) — rank over this without re-parsing. */
558
+ index?: IRepoMapIndex;
559
+ }
560
+ declare class RepoMapRetrievalAdapter implements IRetrievalAdapter {
561
+ private readonly index;
562
+ constructor(options: IRepoMapRetrievalAdapterOptions);
563
+ retrieve(request: IRetrievalRequest): Promise<IRetrievalResult>;
564
+ }
565
+ //#endregion
566
+ //#region src/retrieval/retrieval-tool.d.ts
567
+ declare function createRetrievalTool(options?: IRetrievalToolOptions): FunctionTool;
568
+ //#endregion
569
+ //#region src/computer-use/types.d.ts
570
+ /**
571
+ * SELFHOST-010: computer-use driver port + perceive→act contract (v1).
200
572
  *
201
- * Implements ITool without extending AbstractTool to avoid
202
- * circular runtime dependency (tools → agents → tools).
203
- */
204
- declare class OpenAPITool implements ITool {
205
- readonly schema: IToolSchema;
206
- private readonly apiSpec;
207
- private readonly operationId;
208
- private readonly baseURL;
209
- private readonly config;
210
- private eventService;
211
- constructor(config: IOpenAPIToolConfig);
212
- /**
213
- * Execute the OpenAPI tool
214
- */
215
- execute(parameters: TToolParameters, context?: IToolExecutionContext): Promise<IToolResult>;
216
- /**
217
- * Validate tool parameters
218
- */
219
- validate(parameters: TToolParameters): boolean;
220
- /**
221
- * Validate tool parameters with detailed result
222
- */
223
- validateParameters(parameters: TToolParameters): IParameterValidationResult;
224
- /**
225
- * Get tool name
226
- */
227
- getName(): string;
228
- /**
229
- * Set EventService for post-construction injection.
230
- */
231
- setEventService(eventService: IEventService | undefined): void;
232
- /**
233
- * Get tool description
234
- */
235
- getDescription(): string;
236
- /**
237
- * Execute the actual API call
238
- * @private
239
- */
240
- private executeAPICall;
241
- /**
242
- * Find the operation in the OpenAPI specification
243
- */
244
- private findOperation;
245
- /**
246
- * Build HTTP request configuration from OpenAPI operation and parameters
247
- */
248
- private buildRequestConfig;
249
- /**
250
- * Create tool schema from OpenAPI operation specification
251
- */
252
- private createSchemaFromOpenAPI;
253
- /**
254
- * Convert OpenAPI parameter to tool parameter schema
255
- */
256
- private convertOpenAPIParamToSchema;
257
- /**
258
- * Convert OpenAPI schema to parameter schema
259
- */
260
- private convertOpenAPISchemaToParameterSchema;
261
- /**
262
- * Map OpenAPI type to JSON schema type
263
- */
264
- private mapOpenAPIType;
265
- }
266
- /**
267
- * Factory function to create OpenAPI tools from specification
268
- */
269
- declare function createOpenAPITool(config: IOpenAPIToolConfig): OpenAPITool;
270
-
271
- /**
272
- * FunctionTool - Schema conversion utilities for Facade pattern
573
+ * Mirrors the sandbox port precedent (`ISandboxClient` in `../sandbox/types.ts`): the port + the typed
574
+ * action contract live in `agent-tools`, and the tool factory (`createComputerTool({ driver })`) composes
575
+ * over the port. A neutral `ScriptedComputerDriver` (test-support, under `./testing`) and a zero-dependency
576
+ * duck-typed `PageComputerDriver` reference adapter (`./page-computer-driver.ts`, mirror `E2BSandboxClient`)
577
+ * implement this port — so NO heavy browser SDK and NO concrete target (URL/host) live in this package; the
578
+ * surface supplies the concrete driver + target env.
273
579
  *
274
- * REASON: Complex Zod to JSON schema conversion requires isolated utility functions
275
- * ALTERNATIVES_CONSIDERED:
276
- * 1. Keep conversion logic in main class (violates single responsibility)
277
- * 2. Use third-party library (adds external dependency)
278
- * 3. Manual conversion each time (code duplication)
279
- * 4. Runtime type checking only (loses compile-time safety)
280
- * 5. Remove Zod support (breaks backward compatibility)
281
- * TODO: Consider caching conversion results for performance
580
+ * The contract is the OpenAI/Hermes perceive→act loop expressed once, neutrally: `screenshot()` perceives,
581
+ * and `act(action)` executes one typed mutating action and returns the resulting screenshot so the model
582
+ * re-perceives. The permission-bearing tool boundary splits in two (`ComputerView` perceives, `Computer`
583
+ * acts) but the typed action union stays WHOLE here in the driver contract.
282
584
  */
283
-
585
+ /** A perceived screenshot: encoded image bytes the surface produced. */
586
+ interface IComputerScreenshot {
587
+ /** Base64-encoded image bytes. */
588
+ data: string;
589
+ /** IANA media type of the encoded bytes (e.g. `image/png`). */
590
+ mediaType: string;
591
+ /** Optional pixel width of the captured surface. */
592
+ width?: number;
593
+ /** Optional pixel height of the captured surface. */
594
+ height?: number;
595
+ }
596
+ /** Mouse button for click/drag actions. */
597
+ type TComputerMouseButton = 'left' | 'right' | 'middle';
598
+ /** A screen coordinate (device-independent pixels from the top-left of the perceived surface). */
599
+ interface IComputerPoint {
600
+ x: number;
601
+ y: number;
602
+ }
603
+ /** Click at a coordinate. */
604
+ interface IComputerClickAction {
605
+ type: 'click';
606
+ x: number;
607
+ y: number;
608
+ button?: TComputerMouseButton;
609
+ }
610
+ /** Double-click at a coordinate. */
611
+ interface IComputerDoubleClickAction {
612
+ type: 'double_click';
613
+ x: number;
614
+ y: number;
615
+ button?: TComputerMouseButton;
616
+ }
617
+ /** Type literal text at the current focus. */
618
+ interface IComputerTypeAction {
619
+ type: 'type';
620
+ text: string;
621
+ }
622
+ /** Press a chord/sequence of keys (e.g. `['Control', 'a']`). */
623
+ interface IComputerKeypressAction {
624
+ type: 'keypress';
625
+ keys: string[];
626
+ }
627
+ /** Scroll at a coordinate by a wheel delta. */
628
+ interface IComputerScrollAction {
629
+ type: 'scroll';
630
+ x: number;
631
+ y: number;
632
+ deltaX: number;
633
+ deltaY: number;
634
+ }
635
+ /** Drag along a path of points (press at the first point, move through the rest, release at the last). */
636
+ interface IComputerDragAction {
637
+ type: 'drag';
638
+ path: IComputerPoint[];
639
+ button?: TComputerMouseButton;
640
+ }
641
+ /** Wait for the surface to settle. */
642
+ interface IComputerWaitAction {
643
+ type: 'wait';
644
+ /** Milliseconds to wait; the driver applies a sensible default when omitted. */
645
+ ms?: number;
646
+ }
647
+ /**
648
+ * Hand control to the human (halt-for-user). Executing this suspends the action loop and PAUSES perception
649
+ * (no screenshot is captured for its duration) so a secret the human types never enters the model context;
650
+ * control resumes only on an explicit resume signal (`endTakeover()`).
651
+ */
652
+ interface IComputerTakeoverAction {
653
+ type: 'takeover';
654
+ /** Optional human-readable reason surfaced to the user (e.g. `enter your password`). */
655
+ reason?: string;
656
+ }
657
+ /** The whole typed mutating-action union — stays WHOLE in the driver contract. */
658
+ type TComputerAction = IComputerClickAction | IComputerDoubleClickAction | IComputerTypeAction | IComputerKeypressAction | IComputerScrollAction | IComputerDragAction | IComputerWaitAction | IComputerTakeoverAction;
659
+ /** The discriminant literals of {@link TComputerAction}. */
660
+ type TComputerActionType = TComputerAction['type'];
284
661
  /**
285
- * Convert Zod schema to JSON Schema format with safe undefined handling
662
+ * The result of executing one action through the driver.
663
+ *
664
+ * For every non-takeover action the fresh post-action `screenshot` is present so the model re-perceives.
665
+ * While a takeover suspends the action loop, perception is paused: `screenshot` is ABSENT and
666
+ * `takeover` is `true`.
286
667
  */
287
- declare function zodToJsonSchema(schema: IZodSchema, options?: ISchemaConversionOptions): IToolSchema['parameters'];
288
-
668
+ interface IComputerActionResult {
669
+ /** Fresh screenshot AFTER the action; absent while a takeover pauses perception. */
670
+ screenshot?: IComputerScreenshot;
671
+ /** True while a human takeover suspends the action loop (perception is paused for its duration). */
672
+ takeover?: boolean;
673
+ }
289
674
  /**
290
- * BashTool — execute shell commands via child_process.spawn
675
+ * The computer-use driver port (mirror `ISandboxClient`). `createComputerTool` composes over this.
291
676
  *
292
- * Returns TToolResult JSON string. Non-zero exit is returned as success:true
293
- * with exitCode set, matching Claude Code behaviour (the command ran, it just
294
- * exited non-zero — the LLM can decide what to do with that information).
677
+ * `screenshot()` perceives (returns `undefined` while a takeover pauses perception). `act(action)` executes
678
+ * one typed mutating action and returns the resulting screenshot. `beginTakeover()`/`endTakeover()` are the
679
+ * optional halt-for-user hooks the surface implements (surface the real window, block/resume perception).
680
+ */
681
+ interface IComputerDriver {
682
+ /** Perceive the current surface; `undefined` while a takeover pauses perception. */
683
+ screenshot(): Promise<IComputerScreenshot | undefined>;
684
+ /** Execute one typed mutating action and return its result (a fresh screenshot, unless paused). */
685
+ act(action: TComputerAction): Promise<IComputerActionResult>;
686
+ /** Optional: begin a human takeover (surface the real window, pause perception). */
687
+ beginTakeover?(reason?: string): Promise<void>;
688
+ /** Optional: end a human takeover and resume the action loop + perception. */
689
+ endTakeover?(): Promise<void>;
690
+ }
691
+ /** Tool options carrying the computer-use driver (mirror `ISandboxToolOptions`). */
692
+ interface IComputerToolOptions {
693
+ driver?: IComputerDriver;
694
+ }
695
+ /**
696
+ * Duck-typed browser-page port for the zero-dep `PageComputerDriver` reference adapter (mirror
697
+ * `IE2BSandboxAdapter`). It is a STRUCTURAL description of a browser-page-shaped object (Playwright/CDP
698
+ * page); the surface passes the real page. Declaring it here keeps `agent-tools` free of any browser SDK
699
+ * import — the neutrality invariant (TC-06).
295
700
  */
701
+ interface IBrowserPageMouseAdapter {
702
+ click(x: number, y: number, options?: {
703
+ button?: TComputerMouseButton;
704
+ clickCount?: number;
705
+ }): Promise<void>;
706
+ move(x: number, y: number): Promise<void>;
707
+ down(options?: {
708
+ button?: TComputerMouseButton;
709
+ }): Promise<void>;
710
+ up(options?: {
711
+ button?: TComputerMouseButton;
712
+ }): Promise<void>;
713
+ wheel(deltaX: number, deltaY: number): Promise<void>;
714
+ }
715
+ interface IBrowserPageKeyboardAdapter {
716
+ type(text: string): Promise<void>;
717
+ press(key: string): Promise<void>;
718
+ }
719
+ interface IBrowserPageAdapter {
720
+ /** Capture the page as encoded image bytes. */
721
+ screenshot(options?: {
722
+ type?: string;
723
+ }): Promise<Uint8Array | string>;
724
+ mouse: IBrowserPageMouseAdapter;
725
+ keyboard: IBrowserPageKeyboardAdapter;
726
+ /** Optional wait; the driver falls back to a timer when the page does not expose one. */
727
+ waitForTimeout?(ms: number): Promise<void>;
728
+ }
729
+ //#endregion
730
+ //#region src/computer-use/computer-tool.d.ts
731
+ /** The tool-boundary result shape returned (as JSON) by both `ComputerView` and `Computer`. */
732
+ interface IComputerToolResult {
733
+ success: boolean;
734
+ /** Fresh screenshot after the perceive/act; absent while a takeover pauses perception. */
735
+ screenshot?: IComputerScreenshot;
736
+ /** True when a human takeover suspends the action loop (perception paused). */
737
+ takeover?: boolean;
738
+ /** Error message when the tool could not run (no driver, or an invalid action). */
739
+ error?: string;
740
+ }
741
+ /** Build the `ComputerView` perceive tool over the injected driver. */
742
+ declare function createComputerViewTool(options?: IComputerToolOptions): FunctionTool;
743
+ /** Build the `Computer` act tool over the injected driver. */
744
+ declare function createComputerActTool(options?: IComputerToolOptions): FunctionTool;
296
745
  /**
297
- * BashTool instance — register with Robota agent tools registry.
746
+ * Create BOTH computer-use tools — `ComputerView` (perceive) and `Computer` (act) — over one injected
747
+ * driver. Mirrors `create*Tool(options)`; returns the pair so the assembly layer can spread them into the
748
+ * default set adapter-gated (see `createDefaultTools`).
298
749
  */
299
- declare const bashTool: FunctionTool;
300
-
750
+ declare function createComputerTool(options?: IComputerToolOptions): FunctionTool[];
751
+ //#endregion
752
+ //#region src/computer-use/page-computer-driver.d.ts
753
+ interface IPageComputerDriverOptions {
754
+ /** The real browser page (duck-typed; the surface supplies it). */
755
+ page: IBrowserPageAdapter;
756
+ /** Media type of the captured bytes (default `image/png`). */
757
+ mediaType?: string;
758
+ /** Default wait when a `wait` action omits `ms` (default 500ms). */
759
+ defaultWaitMs?: number;
760
+ }
761
+ declare class PageComputerDriver implements IComputerDriver {
762
+ private readonly page;
763
+ private readonly mediaType;
764
+ private readonly defaultWaitMs;
765
+ private suspended;
766
+ constructor(options: IPageComputerDriverOptions);
767
+ private capture;
768
+ private wait;
769
+ screenshot(): Promise<IComputerScreenshot | undefined>;
770
+ act(action: TComputerAction): Promise<IComputerActionResult>;
771
+ /** Move the pointer along a multi-point path with the button held (mouse down → moves → up). */
772
+ private performDrag;
773
+ beginTakeover(_reason?: string): Promise<void>;
774
+ endTakeover(): Promise<void>;
775
+ }
776
+ //#endregion
777
+ //#region src/implementations/function-tool.d.ts
301
778
  /**
302
- * ReadTool — read a file and return its contents with line numbers (cat -n style).
779
+ * Helper function to create a function tool from a simple function
780
+ */
781
+ declare function createFunctionTool(name: string, description: string, parameters: IToolSchema['parameters'], fn: TToolExecutor): FunctionTool;
782
+ /**
783
+ * What a tool declares about itself beyond its callable shape (CLI-1990).
303
784
  *
304
- * Supports offset/limit for partial reads. Detects binary files and refuses to
305
- * return their raw bytes. Default limit is 2000 lines.
785
+ * Optional, and omission is a declaration too: a tool that says nothing is RESIDENT — its schema is
786
+ * sent on every request, which is what every tool in the tree does today.
306
787
  */
788
+ interface IFunctionToolResidencyOptions {
789
+ /**
790
+ * Withhold this tool's schema from the model until it is loaded by `ToolSearch` or forced by a
791
+ * `toolChoice`. Only honoured while the tool-search policy is engaged, so declaring it on a small
792
+ * tool set costs nothing.
793
+ */
794
+ deferLoading?: boolean;
795
+ }
307
796
  /**
308
- * ReadTool instance — register with Robota agent tools registry.
797
+ * Helper function to create a function tool from Zod schema
309
798
  */
310
- declare const readTool: FunctionTool;
311
-
799
+ declare function createZodFunctionTool<S extends ZodType>(name: string, description: string, zodSchema: S, fn: TToolExecutor<TypeOf<S>>, residency?: IFunctionToolResidencyOptions): FunctionTool;
800
+ //#endregion
801
+ //#region src/implementations/function-tool/types.d.ts
312
802
  /**
313
- * WriteTool — write content to a file, auto-creating parent directories.
803
+ * Parameter type validation options
314
804
  */
805
+ interface IFunctionToolValidationOptions {
806
+ strict?: boolean;
807
+ allowUnknown?: boolean;
808
+ validateTypes?: boolean;
809
+ }
315
810
  /**
316
- * WriteTool instance — register with Robota agent tools registry.
811
+ * Tool execution metadata
317
812
  */
318
- declare const writeTool: FunctionTool;
319
-
813
+ interface IFunctionToolExecutionMetadata {
814
+ executionTime: number;
815
+ toolName: string;
816
+ parameters: TToolParameters;
817
+ }
320
818
  /**
321
- * EditTool — perform string-replace edits on a file.
819
+ * Tool result with metadata
820
+ */
821
+ interface IFunctionToolResult {
822
+ success: boolean;
823
+ data: TUniversalValue;
824
+ metadata?: IFunctionToolExecutionMetadata;
825
+ }
826
+ //#endregion
827
+ //#region src/builtins/tool-options.d.ts
828
+ /** Options every builtin tool factory accepts: override the model-facing description. */
829
+ interface IBuiltinToolDescriptionOptions {
830
+ /** Replaces the default model-facing description verbatim when provided. */
831
+ description?: string;
832
+ }
833
+ /**
834
+ * Options for a builtin that touches the host filesystem WITHOUT a sandbox seam (SEC-007).
322
835
  *
323
- * By default, requires the oldString to appear exactly once in the file
324
- * (ensuring surgical edits). Pass replaceAll:true to replace all occurrences.
836
+ * `Glob` and `Grep` enumerate; they have no provider-sandbox mode to route through, so a containment
837
+ * root is the only boundary they can have. Splitting this out of {@link ISandboxBuiltinToolOptions}
838
+ * keeps them from advertising a `sandboxClient` they would silently ignore.
325
839
  */
840
+ interface IContainedBuiltinToolOptions extends IBuiltinToolDescriptionOptions {
841
+ /**
842
+ * The directory the tool's filesystem access is confined to. REQUIRED — ARCH-010. An out-of-root
843
+ * search root is refused, no entry whose CANONICAL path escapes the root is enumerated, and relative
844
+ * paths the model supplies resolve against this root rather than `process.cwd()`.
845
+ *
846
+ * Required rather than optional because the guard used to be fail-open when it was absent, so
847
+ * omitting it produced an unbounded enumerator rather than an error.
848
+ */
849
+ cwd: string;
850
+ }
851
+ /** Options for builtin factories that also operate on the sandbox/host filesystem. */
852
+ interface ISandboxBuiltinToolOptions extends ISandboxToolOptions, IBuiltinToolDescriptionOptions {}
853
+ //#endregion
854
+ //#region src/builtins/shell-tool.d.ts
855
+ /** Options for the shell tool factories (sandbox + description seam + routing-hint derivation). */
856
+ interface IShellToolOptions extends ISandboxBuiltinToolOptions {
857
+ /** Host-selected executable; absence uses the neutral platform/SHELL default. */
858
+ shellExecutable?: string;
859
+ /**
860
+ * Registered names of the sibling tools available in this assembly (NEUT-002). When provided,
861
+ * the default description's dedicated-tool routing hints are restricted to this set; when
862
+ * omitted, the full default hint set is used. Ignored when `description` overrides the text.
863
+ */
864
+ availableTools?: readonly string[];
865
+ }
326
866
  /**
327
- * EditTool instance — register with Robota agent tools registry.
867
+ * Create a `Shell` tool instance — register with the Robota agent tools registry.
868
+ * The description is resolved at creation time for the host's active shell.
328
869
  */
329
- declare const editTool: FunctionTool;
330
-
870
+ declare function createShellTool(options: IShellToolOptions): FunctionTool;
331
871
  /**
332
- * GlobTool — fast file pattern search using fast-glob.
333
- *
334
- * Excludes node_modules and .git by default.
335
- * Results are sorted by modification time (most recently modified first).
872
+ * Create a `Bash` tool instance — the model-familiar alias of the same OS-aware shell tool.
336
873
  */
874
+ declare function createBashTool(options: IShellToolOptions): FunctionTool;
875
+ //#endregion
876
+ //#region src/builtins/read-tool.d.ts
877
+ /** A budget refusal is a hard failure so a workflow cannot treat it as file content. */
878
+ declare class ReadByteLimitError extends ToolExecutionError {
879
+ readonly boundary: 'input' | 'output';
880
+ constructor(boundary: 'input' | 'output');
881
+ }
882
+ /** Abort is a hard failure; the workflow must not accept a partial read. */
883
+ declare class ReadCancelledError extends ToolExecutionError {
884
+ constructor();
885
+ }
337
886
  /**
338
- * GlobTool instance — register with Robota agent tools registry.
887
+ * Create a ReadTool instance — register with Robota agent tools registry.
339
888
  */
340
- declare const globTool: FunctionTool;
341
-
889
+ declare function createReadTool(options: ISandboxBuiltinToolOptions): FunctionTool;
890
+ //#endregion
891
+ //#region src/builtins/write-tool.d.ts
342
892
  /**
343
- * GrepTool — recursive regex content search.
344
- *
345
- * Supports two output modes:
346
- * - files_with_matches (default): return only file paths that contain a match
347
- * - content: return matching lines with optional context lines
893
+ * Create a WriteTool instance — register with Robota agent tools registry.
348
894
  */
895
+ declare function createWriteTool(options: ISandboxBuiltinToolOptions): FunctionTool;
896
+ //#endregion
897
+ //#region src/builtins/edit-tool.d.ts
349
898
  /**
350
- * GrepTool instance — register with Robota agent tools registry.
899
+ * Create an EditTool instance — register with Robota agent tools registry.
351
900
  */
352
- declare const grepTool: FunctionTool;
353
-
901
+ declare function createEditTool(options: ISandboxBuiltinToolOptions): FunctionTool;
902
+ //#endregion
903
+ //#region src/builtins/glob-tool.d.ts
354
904
  /**
355
- * WebFetchTool — fetch a URL and return its content as text.
356
- *
357
- * HTML is stripped to plain text for readability. Uses Node.js native fetch.
358
- * Output is capped at 30K chars (same as other tools).
905
+ * Create a GlobTool instance — register with Robota agent tools registry.
906
+ */
907
+ declare function createGlobTool(options: IContainedBuiltinToolOptions): FunctionTool;
908
+ //#endregion
909
+ //#region src/builtins/grep-tool.d.ts
910
+ /** A grep isolation failure is a hard tool failure, distinct from ordinary no-match/invalid-input results. */
911
+ declare class GrepIsolationError extends ToolExecutionError {
912
+ readonly reason: 'timeout' | 'cancelled' | 'limit' | 'failed';
913
+ constructor(reason: 'timeout' | 'cancelled' | 'limit' | 'failed');
914
+ }
915
+ /** Options for the grep tool factory: containment root + description seam + shell-tool reference. */
916
+ interface IGrepToolOptions extends IContainedBuiltinToolOptions {
917
+ /** Cancels the isolated regex search and waits for its worker to exit. */
918
+ signal?: AbortSignal;
919
+ /**
920
+ * Registered name of the shell tool the default description references (default: `Shell`).
921
+ * Ignored when `description` overrides the text.
922
+ */
923
+ shellToolName?: string;
924
+ }
925
+ /**
926
+ * Create a GrepTool instance — register with Robota agent tools registry.
927
+ */
928
+ declare function createGrepTool(options: IGrepToolOptions): FunctionTool;
929
+ //#endregion
930
+ //#region src/builtins/web-fetch-tool.d.ts
931
+ /** #2026: the egress policy this tool fetches under, and the deps a test injects (fetch, DNS lookup). */
932
+ interface IWebFetchEgressOptions {
933
+ policy?: IEgressPolicy;
934
+ deps?: IEgressDeps;
935
+ }
936
+ interface IWebFetchToolOptions extends IBuiltinToolDescriptionOptions {
937
+ egress?: IWebFetchEgressOptions;
938
+ }
939
+ /**
940
+ * Create a WebFetchTool instance — register with Robota agent tools registry.
941
+ */
942
+ declare function createWebFetchTool(options?: IWebFetchToolOptions): FunctionTool;
943
+ /**
944
+ * WebFetchTool instance — register with Robota agent tools registry.
359
945
  */
360
946
  declare const webFetchTool: FunctionTool;
361
-
947
+ //#endregion
948
+ //#region src/builtins/web-search-provider.d.ts
362
949
  /**
363
- * WebSearchTool — search the web and return results.
950
+ * NEUT-008: web-search provider port.
364
951
  *
365
- * Uses Brave Search API when BRAVE_API_KEY is set.
366
- * Returns an error with setup instructions otherwise.
952
+ * Mirrors the retrieval/computer-use port precedent (`IRetrievalAdapter`, `IComputerDriver`):
953
+ * the duck-typed port lives in `agent-tools` and `createWebSearchTool({ provider })` composes
954
+ * over it. The vendor-specific default adapter (`./brave-search-provider.ts`) implements this
955
+ * port and is the only place a vendor endpoint may live — the TOOL layer holds no vendor
956
+ * literals.
957
+ */
958
+ /** One web search result entry (the tool serializes these verbatim for the model). */
959
+ interface IWebSearchResultItem {
960
+ title: string;
961
+ url: string;
962
+ snippet: string;
963
+ }
964
+ /** A search request: the query plus the maximum number of results the caller wants. */
965
+ interface IWebSearchQuery {
966
+ query: string;
967
+ /** Requested maximum result count; a provider may cap it lower (vendor API limits). */
968
+ limit: number;
969
+ }
970
+ /**
971
+ * The web-search provider port. Implementations resolve their own credentials/endpoint and
972
+ * THROW on failure (missing configuration, HTTP error, network error) — the tool layer converts
973
+ * the thrown message into a structured `IToolInvocationResult` error.
974
+ */
975
+ interface IWebSearchProvider {
976
+ search(request: IWebSearchQuery, signal?: AbortSignal): Promise<IWebSearchResultItem[]>;
977
+ }
978
+ /** Options for `createWebSearchTool`: inject a provider (default: the Brave Search adapter). */
979
+ interface IWebSearchToolProviderOptions {
980
+ provider?: IWebSearchProvider;
981
+ }
982
+ //#endregion
983
+ //#region src/builtins/web-search-tool.d.ts
984
+ /** Options for the web-search tool factory: description seam + provider port injection. */
985
+ interface IWebSearchToolOptions extends IBuiltinToolDescriptionOptions, IWebSearchToolProviderOptions {}
986
+ /**
987
+ * Create a WebSearchTool instance — register with Robota agent tools registry.
988
+ */
989
+ declare function createWebSearchTool(options?: IWebSearchToolOptions): FunctionTool;
990
+ /**
991
+ * WebSearchTool instance — register with Robota agent tools registry.
367
992
  */
368
993
  declare const webSearchTool: FunctionTool;
369
-
370
- export { FunctionTool, type IFunctionToolExecutionMetadata, type IFunctionToolResult, type IFunctionToolValidationOptions, type ISchemaConversionOptions, type IZodParseResult, type IZodSchema, type IZodSchemaDef, OpenAPITool, type TToolResult, ToolRegistry, bashTool, createFunctionTool, createOpenAPITool, createZodFunctionTool, editTool, globTool, grepTool, readTool, webFetchTool, webSearchTool, writeTool, zodToJsonSchema };
994
+ //#endregion
995
+ //#region src/builtins/brave-search-provider.d.ts
996
+ /**
997
+ * Create the Brave Search provider. Throws from `search()` when `BRAVE_API_KEY` is not set or
998
+ * the API responds with an error — the tool layer surfaces the message as a structured result.
999
+ */
1000
+ declare function createBraveSearchProvider(): IWebSearchProvider;
1001
+ //#endregion
1002
+ //#region src/builtins/ask-user-question-tool.d.ts
1003
+ /**
1004
+ * Create an `AskUserQuestion` tool instance — register with the Robota agent tools registry.
1005
+ */
1006
+ declare function createAskUserQuestionTool(options?: IBuiltinToolDescriptionOptions): FunctionTool;
1007
+ /** `AskUserQuestion` tool instance — register with the Robota agent tools registry. */
1008
+ declare const askUserQuestionTool: FunctionTool;
1009
+ //#endregion
1010
+ //#region src/builtins/tool-search-tool.d.ts
1011
+ /**
1012
+ * The registered name — agent-core's own constant, re-exported under this package's name so the
1013
+ * execution layer's unknown-tool remedy and this tool can never name two different things.
1014
+ */
1015
+ declare const TOOL_SEARCH_NAME = "ToolSearch";
1016
+ /** What the model gets back: what is now callable, and what could not be consulted. */
1017
+ interface IToolSearchOutput {
1018
+ loaded: Array<{
1019
+ name: string;
1020
+ description: string;
1021
+ }>;
1022
+ unavailableSources: string[];
1023
+ }
1024
+ /**
1025
+ * Create a `ToolSearch` tool instance — register it RESIDENT with the agent's tool registry.
1026
+ *
1027
+ * It must never itself be deferred: a search tool the model cannot see is a catalog with no way in,
1028
+ * which is the state the vendor's own "at least one tool must stay resident" invariant forbids.
1029
+ */
1030
+ declare function createToolSearchTool(options?: IBuiltinToolDescriptionOptions): FunctionTool;
1031
+ /** `ToolSearch` tool instance — register with the Robota agent tools registry. */
1032
+ declare const toolSearchTool: FunctionTool;
1033
+ //#endregion
1034
+ //#region src/builtins/tool-search-matching.d.ts
1035
+ /** Both vendors default a tool search to five results; so does this one. */
1036
+ declare const DEFAULT_TOOL_SEARCH_LIMIT = 5;
1037
+ /**
1038
+ * The tools a query selects, best match first and capped at `limit`.
1039
+ *
1040
+ * Ordering is total and deterministic: rank first, then name, so two tools that matched the same way
1041
+ * never trade places between calls. An empty query string matches nothing rather than everything —
1042
+ * "search for nothing" is a question with an empty answer, not a request for the whole catalog.
1043
+ */
1044
+ declare function matchDeferredTools(schemas: readonly IToolSchema[], query: string, limit: number): IToolSchema[];
1045
+ //#endregion
1046
+ export { DEFAULT_OS_SANDBOX_SETTINGS, DEFAULT_TOOL_SEARCH_LIMIT, E2BSandboxClient, GrepIsolationError, type IBrowserPageAdapter, type IBrowserPageKeyboardAdapter, type IBrowserPageMouseAdapter, type IBubblewrapInput, type IBuildRepoMapIndexOptions, type IBuiltinToolDescriptionOptions, type ICommandInvocation, type IComputerActionResult, type IComputerClickAction, type IComputerDoubleClickAction, type IComputerDragAction, type IComputerDriver, type IComputerKeypressAction, type IComputerPoint, type IComputerScreenshot, type IComputerScrollAction, type IComputerTakeoverAction, type IComputerToolOptions, type IComputerToolResult, type IComputerTypeAction, type IComputerWaitAction, type IContainedBuiltinToolOptions, type IDetectOsSandboxOptions, type IE2BSandboxAdapter, type IE2BSandboxClientOptions, type IFunctionToolExecutionMetadata, type IFunctionToolResidencyOptions, type IFunctionToolResult, type IFunctionToolValidationOptions, type IGrepToolOptions, type IInMemorySandboxClientOptions, type IOsSandboxAvailability, type IOsSandboxClientOptions, type IOsSandboxPolicy, type IOsSandboxSettings, type IOsSandboxStatus, type IPageComputerDriverOptions, type IRepoMapIndex, type IRepoMapIndexChanges, type IRepoMapIndexEntry, type IRepoMapRetrievalAdapterOptions, type IRetrievalAdapter, type IRetrievalCorpusFile, type IRetrievalParsedFile, type IRetrievalRankedSymbol, type IRetrievalRequest, type IRetrievalResult, type IRetrievalSourceParser, type IRetrievalSymbol, type IRetrievalToolOptions, type ISandboxBuiltinToolOptions, type ISandboxClient, type ISandboxRunOptions, type ISandboxRunResult, type ISandboxToolOptions, type IShellToolOptions, type IToolInvocationResult, type IToolSearchOutput, type IWebFetchToolOptions, type IWebSearchProvider, type IWebSearchQuery, type IWebSearchResultItem, type IWebSearchToolOptions, type IWebSearchToolProviderOptions, type IWorkspaceManifest, type IWorkspaceManifestAppliedEntry, type IWorkspaceManifestApplyOptions, type IWorkspaceManifestApplyResult, type IWorkspaceManifestAzureBlobMountEntry, type IWorkspaceManifestDirectoryEntry, type IWorkspaceManifestFileEntry, type IWorkspaceManifestGcsMountEntry, type IWorkspaceManifestGitRepositoryEntry, type IWorkspaceManifestLocalDirectoryEntry, type IWorkspaceManifestLocalFileEntry, type IWorkspaceManifestPermissions, type IWorkspaceManifestR2MountEntry, type IWorkspaceManifestS3MountEntry, InMemorySandboxClient, OsSandboxClient, PageComputerDriver, REPO_MAP_INDEX_VERSION, ReadByteLimitError, ReadCancelledError, RepoMapRetrievalAdapter, type TComputerAction, type TComputerActionType, type TComputerMouseButton, type TExecutionContainment, type TInMemorySandboxRunHandler, TOOL_SEARCH_NAME, type TOsSandboxBackend, type TSandboxFilesystem, type TWorkspaceManifestApplyStatus, type TWorkspaceManifestEntry, applyWorkspaceManifest, askUserQuestionTool, bubblewrapArguments, buildRepoMapIndex, createAskUserQuestionTool, createBashTool, createBraveSearchProvider, createComputerActTool, createComputerTool, createComputerViewTool, createEditTool, createFunctionTool, createGlobTool, createGrepTool, createReadTool, createRetrievalTool, createShellTool, createToolSearchTool, createWebFetchTool, createWebSearchTool, createWriteTool, createZodFunctionTool, describeExecutionContainment, deserializeRepoMapIndex, detectOsSandbox, matchDeferredTools, protectedWorkspaceEntries, routesFilesThroughSandbox, seatbeltProfile, serializeRepoMapIndex, toolSearchTool, updateRepoMapIndex, validateWorkspaceManifestPath, webFetchTool, webSearchTool };
1047
+ //# sourceMappingURL=index.d.ts.map