@robota-sdk/agent-tools 3.0.0-beta.79 → 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/README.md +39 -15
- package/dist/browser/browser.d.ts +14 -97
- package/dist/browser/browser.d.ts.map +1 -1
- package/dist/browser/browser.js +1 -1
- package/dist/browser/browser.js.map +1 -1
- package/dist/node/index.cjs +2356 -517
- package/dist/node/index.d.cts +1047 -0
- package/dist/node/index.d.cts.map +1 -0
- package/dist/node/index.d.ts +768 -131
- package/dist/node/index.d.ts.map +1 -1
- package/dist/node/index.js +2326 -510
- package/dist/node/index.js.map +1 -1
- package/package.json +33 -16
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
|
|
|
@@ -31,41 +31,64 @@ const weatherTool = createZodFunctionTool(
|
|
|
31
31
|
### Use Built-in Tools
|
|
32
32
|
|
|
33
33
|
```typescript
|
|
34
|
-
import {
|
|
34
|
+
import {
|
|
35
|
+
createBashTool,
|
|
36
|
+
createReadTool,
|
|
37
|
+
createGlobTool,
|
|
38
|
+
createGrepTool,
|
|
39
|
+
} from '@robota-sdk/agent-tools';
|
|
35
40
|
import { Robota } from '@robota-sdk/agent-core';
|
|
36
41
|
import type { IAIProvider } from '@robota-sdk/agent-core';
|
|
37
42
|
|
|
38
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();
|
|
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
|
+
],
|
|
44
60
|
});
|
|
45
61
|
```
|
|
46
62
|
|
|
47
63
|
## Built-in Tools
|
|
48
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
|
+
|
|
49
69
|
| Export | Tool Name | Description |
|
|
50
70
|
| --------------------- | --------------- | ----------------------------------------------------------------------------- |
|
|
51
|
-
| `
|
|
52
|
-
| `
|
|
53
|
-
| `
|
|
54
|
-
| `
|
|
55
|
-
| `
|
|
56
|
-
| `
|
|
57
|
-
| `
|
|
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 |
|
|
58
79
|
| `webFetchTool` | WebFetch | Fetch URL content (HTML-to-text conversion) |
|
|
59
80
|
| `webSearchTool` | WebSearch | Web search via Brave Search API |
|
|
60
81
|
| `askUserQuestionTool` | AskUserQuestion | Model asks the user structured questions (options/multi-select/free text) |
|
|
61
82
|
|
|
83
|
+
The last three stay instances: they touch no filesystem, so there is no root to contain them by.
|
|
84
|
+
|
|
62
85
|
`AskUserQuestion` lets the model ask the user 1–4 structured questions mid-turn through the injected
|
|
63
86
|
ask port (CMD-004); each environment renders it its own way (Ink dialog, web modal, programmatic
|
|
64
87
|
pre-answer), and headless runs get a structured `unavailable` result instead of a hang or a guess.
|
|
65
88
|
|
|
66
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).
|
|
67
90
|
|
|
68
|
-
|
|
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`.
|
|
69
92
|
|
|
70
93
|
## Sandbox Execution
|
|
71
94
|
|
|
@@ -80,8 +103,11 @@ import { Sandbox } from 'e2b';
|
|
|
80
103
|
const e2b = await Sandbox.create();
|
|
81
104
|
const sandboxClient = new E2BSandboxClient({ sandbox: e2b });
|
|
82
105
|
|
|
83
|
-
|
|
84
|
-
|
|
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 });
|
|
85
111
|
```
|
|
86
112
|
|
|
87
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.
|
|
@@ -122,8 +148,6 @@ Recent file tool updates keep write/edit behavior atomic and make Edit tool resu
|
|
|
122
148
|
| `FunctionTool` | JS function tool with Zod schema validation |
|
|
123
149
|
| `createFunctionTool` | Factory for creating function tools |
|
|
124
150
|
| `createZodFunctionTool` | Factory with Zod validation and JSON Schema conversion |
|
|
125
|
-
| `OpenAPITool` | Tool generated from OpenAPI specification |
|
|
126
|
-
| `createOpenAPITool` | Factory for creating OpenAPI tools |
|
|
127
151
|
| `IToolInvocationResult` | Result type for built-in CLI tool invocations |
|
|
128
152
|
| `ISandboxClient` | Provider-neutral sandbox execution port |
|
|
129
153
|
| `IWorkspaceManifest` | Declarative sandbox workspace setup contract |
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { FunctionTool, IToolSchema, TToolExecutor, TToolParameters, TUniversalValue } from "@robota-sdk/agent-core";
|
|
2
2
|
import { TypeOf, ZodType } from "zod";
|
|
3
|
-
|
|
4
3
|
//#region src/types/tool-result.d.ts
|
|
5
4
|
/**
|
|
6
5
|
* Result returned by a CLI tool invocation
|
|
@@ -14,111 +13,29 @@ interface IToolInvocationResult {
|
|
|
14
13
|
startLine?: number;
|
|
15
14
|
}
|
|
16
15
|
//#endregion
|
|
17
|
-
//#region src/
|
|
16
|
+
//#region src/implementations/function-tool.d.ts
|
|
18
17
|
/**
|
|
19
|
-
*
|
|
20
|
-
* Manages tool registration, validation, and retrieval
|
|
18
|
+
* Helper function to create a function tool from a simple function
|
|
21
19
|
*/
|
|
22
|
-
declare
|
|
23
|
-
private tools;
|
|
24
|
-
/**
|
|
25
|
-
* Register a tool
|
|
26
|
-
*/
|
|
27
|
-
register(tool: ITool): void;
|
|
28
|
-
/**
|
|
29
|
-
* Unregister a tool
|
|
30
|
-
*/
|
|
31
|
-
unregister(name: string): void;
|
|
32
|
-
/**
|
|
33
|
-
* Get tool by name
|
|
34
|
-
*/
|
|
35
|
-
get(name: string): ITool | undefined;
|
|
36
|
-
/**
|
|
37
|
-
* Get all registered tools
|
|
38
|
-
*/
|
|
39
|
-
getAll(): ITool[];
|
|
40
|
-
/**
|
|
41
|
-
* Get tool schemas
|
|
42
|
-
*/
|
|
43
|
-
getSchemas(): IToolSchema[];
|
|
44
|
-
/**
|
|
45
|
-
* Check if tool exists
|
|
46
|
-
*/
|
|
47
|
-
has(name: string): boolean;
|
|
48
|
-
/**
|
|
49
|
-
* Clear all tools
|
|
50
|
-
*/
|
|
51
|
-
clear(): void;
|
|
52
|
-
/**
|
|
53
|
-
* Get tool names
|
|
54
|
-
*/
|
|
55
|
-
getToolNames(): string[];
|
|
56
|
-
/**
|
|
57
|
-
* Get tools by pattern
|
|
58
|
-
*/
|
|
59
|
-
getToolsByPattern(pattern: string | RegExp): ITool[];
|
|
60
|
-
/**
|
|
61
|
-
* Get tool count
|
|
62
|
-
*/
|
|
63
|
-
size(): number;
|
|
64
|
-
/**
|
|
65
|
-
* Validate tool schema
|
|
66
|
-
*/
|
|
67
|
-
private validateToolSchema;
|
|
68
|
-
}
|
|
69
|
-
//#endregion
|
|
70
|
-
//#region src/implementations/function-tool.d.ts
|
|
20
|
+
declare function createFunctionTool(name: string, description: string, parameters: IToolSchema['parameters'], fn: TToolExecutor): FunctionTool;
|
|
71
21
|
/**
|
|
72
|
-
*
|
|
73
|
-
* Wraps a JavaScript function as a tool with schema validation
|
|
22
|
+
* What a tool declares about itself beyond its callable shape (CLI-1990).
|
|
74
23
|
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
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.
|
|
77
26
|
*/
|
|
78
|
-
|
|
79
|
-
readonly schema: IToolSchema;
|
|
80
|
-
readonly fn: TToolExecutor;
|
|
81
|
-
private eventService;
|
|
82
|
-
constructor(schema: IToolSchema, fn: TToolExecutor);
|
|
83
|
-
/**
|
|
84
|
-
* Get tool name
|
|
85
|
-
*/
|
|
86
|
-
getName(): string;
|
|
87
|
-
/**
|
|
88
|
-
* Set EventService for post-construction injection.
|
|
89
|
-
* Accepts EventService as-is without transformation.
|
|
90
|
-
* Caller is responsible for providing properly configured EventService.
|
|
91
|
-
*/
|
|
92
|
-
setEventService(eventService: IEventService | undefined): void;
|
|
93
|
-
/**
|
|
94
|
-
* Execute the function tool
|
|
95
|
-
*/
|
|
96
|
-
execute(parameters: TToolParameters, context?: IToolExecutionContext): Promise<IToolResult>;
|
|
97
|
-
/**
|
|
98
|
-
* Validate parameters (simple boolean result)
|
|
99
|
-
*/
|
|
100
|
-
validate(parameters: TToolParameters): boolean;
|
|
27
|
+
interface IFunctionToolResidencyOptions {
|
|
101
28
|
/**
|
|
102
|
-
*
|
|
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.
|
|
103
32
|
*/
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Get tool description
|
|
107
|
-
*/
|
|
108
|
-
getDescription(): string;
|
|
109
|
-
/**
|
|
110
|
-
* Validate constructor inputs
|
|
111
|
-
*/
|
|
112
|
-
private validateConstructorInputs;
|
|
33
|
+
deferLoading?: boolean;
|
|
113
34
|
}
|
|
114
|
-
/**
|
|
115
|
-
* Helper function to create a function tool from a simple function
|
|
116
|
-
*/
|
|
117
|
-
declare function createFunctionTool(name: string, description: string, parameters: IToolSchema['parameters'], fn: TToolExecutor): FunctionTool;
|
|
118
35
|
/**
|
|
119
36
|
* Helper function to create a function tool from Zod schema
|
|
120
37
|
*/
|
|
121
|
-
declare function createZodFunctionTool<S extends ZodType>(name: string, description: string, zodSchema: S, fn: TToolExecutor<TypeOf<S
|
|
38
|
+
declare function createZodFunctionTool<S extends ZodType>(name: string, description: string, zodSchema: S, fn: TToolExecutor<TypeOf<S>>, residency?: IFunctionToolResidencyOptions): FunctionTool;
|
|
122
39
|
//#endregion
|
|
123
40
|
//#region src/implementations/function-tool/types.d.ts
|
|
124
41
|
/**
|
|
@@ -146,5 +63,5 @@ interface IFunctionToolResult {
|
|
|
146
63
|
metadata?: IFunctionToolExecutionMetadata;
|
|
147
64
|
}
|
|
148
65
|
//#endregion
|
|
149
|
-
export {
|
|
66
|
+
export { type IFunctionToolExecutionMetadata, type IFunctionToolResult, type IFunctionToolValidationOptions, type IToolInvocationResult, createFunctionTool, createZodFunctionTool };
|
|
150
67
|
//# sourceMappingURL=browser.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser.d.ts","names":[],"sources":["../../src/types/tool-result.ts","../../src/
|
|
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"}
|
package/dist/browser/browser.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{
|
|
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
2
|
//# sourceMappingURL=browser.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser.js","names":[],"sources":["../../src/registry/tool-registry.ts","../../src/implementations/function-tool/parameter-validator.ts","../../src/implementations/function-tool.ts"],"sourcesContent":["import { ValidationError } from '@robota-sdk/agent-core';\nimport { logger } from '@robota-sdk/agent-core';\n\nimport type { ITool, IToolRegistry } from '@robota-sdk/agent-core';\nimport type { IToolSchema } from '@robota-sdk/agent-core';\n\n/**\n * Tool registry implementation\n * Manages tool registration, validation, and retrieval\n */\nexport class ToolRegistry implements IToolRegistry {\n private tools = new Map<string, ITool>();\n\n /**\n * Register a tool\n */\n register(tool: ITool): void {\n if (!tool.schema?.name) {\n throw new ValidationError('Tool must have a valid schema with name');\n }\n\n const toolName = tool.schema.name;\n\n // Validate tool schema\n this.validateToolSchema(tool.schema);\n\n // Check for duplicate registration\n if (this.tools.has(toolName)) {\n logger.warn(`Tool \"${toolName}\" is already registered, overriding`, {\n toolName,\n existingTool: this.tools.get(toolName)?.constructor.name,\n });\n }\n\n this.tools.set(toolName, tool);\n logger.debug(`Tool \"${toolName}\" registered successfully`, {\n toolName,\n toolType: tool.constructor.name,\n parameters: Object.keys(tool.schema.parameters?.properties || {}),\n });\n }\n\n /**\n * Unregister a tool\n */\n unregister(name: string): void {\n if (!this.tools.has(name)) {\n logger.warn(`Attempted to unregister non-existent tool \"${name}\"`);\n return;\n }\n\n this.tools.delete(name);\n logger.debug(`Tool \"${name}\" unregistered successfully`);\n }\n\n /**\n * Get tool by name\n */\n get(name: string): ITool | undefined {\n return this.tools.get(name);\n }\n\n /**\n * Get all registered tools\n */\n getAll(): ITool[] {\n return Array.from(this.tools.values());\n }\n\n /**\n * Get tool schemas\n */\n getSchemas(): IToolSchema[] {\n const tools = this.getAll();\n\n // 🔍 [TOOL-FLOW] ToolRegistry.getSchemas() - Extracting schemas from tools\n logger.debug('[TOOL-FLOW] ToolRegistry.getSchemas() - Tools before schema extraction', {\n count: tools.length,\n tools: tools.map((t) => ({\n name: t.schema?.name ?? 'unnamed',\n hasSchema: !!t.schema,\n schemaType: typeof t.schema,\n toolType: t.constructor?.name || 'unknown',\n })),\n });\n\n return this.getAll().map((tool) => tool.schema);\n }\n\n /**\n * Check if tool exists\n */\n has(name: string): boolean {\n return this.tools.has(name);\n }\n\n /**\n * Clear all tools\n */\n clear(): void {\n const toolCount = this.tools.size;\n this.tools.clear();\n logger.debug(`Cleared ${toolCount} tools from registry`);\n }\n\n /**\n * Get tool names\n */\n getToolNames(): string[] {\n return Array.from(this.tools.keys());\n }\n\n /**\n * Get tools by pattern\n */\n getToolsByPattern(pattern: string | RegExp): ITool[] {\n const regex = typeof pattern === 'string' ? new RegExp(pattern) : pattern;\n return this.getAll().filter((tool) => regex.test(tool.schema.name));\n }\n\n /**\n * Get tool count\n */\n size(): number {\n return this.tools.size;\n }\n\n /**\n * Validate tool schema\n */\n private validateToolSchema(schema: IToolSchema): void {\n if (!schema.name || typeof schema.name !== 'string') {\n throw new ValidationError('Tool schema must have a valid name');\n }\n\n if (!schema.description || typeof schema.description !== 'string') {\n throw new ValidationError('Tool schema must have a description');\n }\n\n if (\n !schema.parameters ||\n typeof schema.parameters !== 'object' ||\n schema.parameters === null ||\n Array.isArray(schema.parameters)\n ) {\n throw new ValidationError('Tool schema must have parameters object');\n }\n\n if (schema.parameters.type !== 'object') {\n throw new ValidationError('Tool parameters type must be \"object\"');\n }\n\n // Validate parameter properties\n if (schema.parameters.properties) {\n for (const propName of Object.keys(schema.parameters.properties)) {\n const propSchema = schema.parameters.properties[propName];\n if (!propSchema?.type) {\n throw new ValidationError(`Parameter \"${propName}\" must have a type`);\n }\n\n const validTypes = ['string', 'number', 'boolean', 'array', 'object'];\n if (!validTypes.includes(propSchema.type)) {\n throw new ValidationError(\n `Parameter \"${propName}\" has invalid type \"${propSchema.type}\"`,\n );\n }\n }\n }\n\n // Validate required fields exist in properties\n if (schema.parameters.required) {\n const properties = schema.parameters.properties || {};\n for (const requiredField of schema.parameters.required) {\n if (!properties[requiredField]) {\n throw new ValidationError(\n `Required parameter \"${requiredField}\" is not defined in properties`,\n );\n }\n }\n }\n }\n}\n","import type {\n IParameterSchema,\n TToolParameters,\n IParameterValidationResult,\n} from '@robota-sdk/agent-core';\nimport type { TUniversalValue } from '@robota-sdk/agent-core';\n\n/**\n * Validate individual parameter type against its schema.\n * Returns an error string if invalid, undefined if valid.\n */\nexport function validateParameterType(\n key: string,\n value: TUniversalValue,\n schema: IParameterSchema,\n): string | undefined {\n const expectedType = schema['type'];\n\n switch (expectedType) {\n case 'string':\n if (typeof value !== 'string') {\n return `Parameter \"${key}\" must be a string, got ${typeof value}`;\n }\n break;\n\n case 'number':\n if (typeof value !== 'number' || isNaN(value)) {\n return `Parameter \"${key}\" must be a number, got ${typeof value}`;\n }\n break;\n\n case 'boolean':\n if (typeof value !== 'boolean') {\n return `Parameter \"${key}\" must be a boolean, got ${typeof value}`;\n }\n break;\n\n case 'array':\n if (!Array.isArray(value)) {\n return `Parameter \"${key}\" must be an array, got ${typeof value}`;\n }\n // Check array items if specified\n if (schema.items) {\n for (let i = 0; i < value.length; i++) {\n const itemError = validateParameterType(`${key}[${i}]`, value[i], schema.items);\n if (itemError) {\n return itemError;\n }\n }\n }\n break;\n\n case 'object':\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n return `Parameter \"${key}\" must be an object, got ${typeof value}`;\n }\n break;\n }\n\n // Check enum constraints\n if (schema.enum && schema.enum.length > 0) {\n const enumValues = schema.enum;\n let isValidEnum = false;\n\n // Type-safe enum checking based on JSONSchemaEnum type\n for (const enumValue of enumValues) {\n if (value === enumValue) {\n isValidEnum = true;\n break;\n }\n }\n\n if (!isValidEnum) {\n return `Parameter \"${key}\" must be one of: ${enumValues.join(', ')}, got ${value}`;\n }\n }\n\n return undefined;\n}\n\n/**\n * Collect all validation errors for the given parameters against a schema.\n */\nexport function getValidationErrors(\n parameters: TToolParameters,\n schemaRequired: string[],\n schemaProperties: Record<string, IParameterSchema>,\n additionalProperties?: boolean | IParameterSchema,\n): string[] {\n const errors: string[] = [];\n\n // Check required parameters\n for (const field of schemaRequired) {\n if (!(field in parameters)) {\n errors.push(`Missing required parameter: ${field}`);\n }\n }\n\n // Check parameter types and constraints\n for (const [key, value] of Object.entries(parameters)) {\n const paramSchema = schemaProperties[key];\n if (!paramSchema) {\n if (additionalProperties === true) {\n continue;\n }\n if (additionalProperties && typeof additionalProperties === 'object') {\n const additionalTypeError = validateParameterType(key, value, additionalProperties);\n if (additionalTypeError) errors.push(additionalTypeError);\n continue;\n }\n errors.push(`Unknown parameter: ${key}`);\n continue;\n }\n\n const typeError = validateParameterType(key, value, paramSchema);\n if (typeError) {\n errors.push(typeError);\n }\n }\n\n return errors;\n}\n\n/**\n * Validate parameters and return a structured result.\n */\nexport function validateToolParameters(\n parameters: TToolParameters,\n schemaRequired: string[],\n schemaProperties: Record<string, IParameterSchema>,\n additionalProperties?: boolean | IParameterSchema,\n): IParameterValidationResult {\n const errors = getValidationErrors(\n parameters,\n schemaRequired,\n schemaProperties,\n additionalProperties,\n );\n return {\n isValid: errors.length === 0,\n errors,\n };\n}\n","import { ToolExecutionError, ValidationError, zodToJsonSchema } from '@robota-sdk/agent-core';\n\nimport { getValidationErrors, validateToolParameters } from './function-tool/parameter-validator';\n\nimport type {\n IFunctionTool,\n IToolResult,\n IToolExecutionContext,\n IParameterValidationResult,\n TToolExecutor,\n TToolParameters,\n IEventService,\n} 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// Import from Facade pattern modules for type safety\n\n/**\n * Function tool implementation\n * Wraps a JavaScript function as a tool with schema validation\n *\n * Implements IFunctionTool without extending AbstractTool to avoid\n * circular runtime dependency (tools → agents → tools).\n */\nexport class FunctionTool implements IFunctionTool {\n readonly schema: IToolSchema;\n readonly fn: TToolExecutor;\n private eventService: IEventService | undefined;\n\n constructor(schema: IToolSchema, fn: TToolExecutor) {\n this.schema = schema;\n this.fn = fn;\n this.validateConstructorInputs();\n }\n\n /**\n * Get tool name\n */\n getName(): string {\n return this.schema.name;\n }\n\n /**\n * Set EventService for post-construction injection.\n * Accepts EventService as-is without transformation.\n * Caller is responsible for providing properly configured EventService.\n */\n setEventService(eventService: IEventService | undefined): void {\n this.eventService = eventService;\n }\n\n /**\n * Execute the function tool\n */\n async execute(\n parameters: TToolParameters,\n context?: IToolExecutionContext,\n ): Promise<IToolResult> {\n const toolName = this.schema.name;\n\n // Validate parameters before execution\n if (!this.validate(parameters)) {\n const errors = getValidationErrors(\n parameters,\n this.schema.parameters.required || [],\n this.schema.parameters.properties || {},\n this.schema.parameters.additionalProperties,\n );\n throw new ValidationError(`Invalid parameters for tool \"${toolName}\": ${errors.join(', ')}`);\n }\n\n // Execute the function\n const startTime = Date.now();\n let result: TUniversalValue;\n try {\n result = await this.fn(parameters, context);\n } catch (error) {\n if (error instanceof ToolExecutionError || error instanceof ValidationError) {\n throw error;\n }\n\n throw new ToolExecutionError(\n `Function tool execution failed: ${error instanceof Error ? error.message : String(error)}`,\n toolName,\n error instanceof Error ? error : new Error(String(error)),\n {\n parameterCount: Object.keys(parameters || {}).length,\n hasContext: !!context,\n },\n );\n }\n\n const executionTime = Date.now() - startTime;\n\n return {\n success: true,\n data: result,\n metadata: {\n executionTime,\n toolName,\n parameters,\n },\n };\n }\n\n /**\n * Validate parameters (simple boolean result)\n */\n validate(parameters: TToolParameters): boolean {\n return (\n getValidationErrors(\n parameters,\n this.schema.parameters.required || [],\n this.schema.parameters.properties || {},\n this.schema.parameters.additionalProperties,\n ).length === 0\n );\n }\n\n /**\n * Validate tool parameters with detailed result\n */\n validateParameters(parameters: TToolParameters): IParameterValidationResult {\n return validateToolParameters(\n parameters,\n this.schema.parameters.required || [],\n this.schema.parameters.properties || {},\n this.schema.parameters.additionalProperties,\n );\n }\n\n /**\n * Get tool description\n */\n getDescription(): string {\n return this.schema.description;\n }\n\n /**\n * Validate constructor inputs\n */\n private validateConstructorInputs(): void {\n if (!this.schema) {\n throw new ValidationError('Tool schema is required');\n }\n\n if (!this.fn || typeof this.fn !== 'function') {\n throw new ValidationError('Tool function is required and must be a function');\n }\n\n if (!this.schema.name) {\n throw new ValidationError('Tool schema must have a name');\n }\n }\n}\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 * 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): 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 };\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":"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"}
|
|
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"}
|