@robota-sdk/agent-tools 3.0.0-beta.60 → 3.0.0-beta.62
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 +67 -21
- package/dist/browser/browser.d.ts +268 -0
- package/dist/browser/browser.js +1 -0
- package/dist/node/index.cjs +505 -257
- package/dist/node/index.d.cts +170 -15
- package/dist/node/index.d.ts +170 -15
- package/dist/node/index.js +444 -173
- package/package.json +10 -6
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, 8 built-in CLI tools, sandbox execution ports, and sandbox workspace manifests for the Robota SDK.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -46,16 +46,57 @@ const agent = new Robota({
|
|
|
46
46
|
|
|
47
47
|
## Built-in Tools (8)
|
|
48
48
|
|
|
49
|
-
| Export | Tool Name | Description
|
|
50
|
-
| --------------- | --------- |
|
|
51
|
-
| `bashTool` | Bash | Execute shell commands via
|
|
52
|
-
| `readTool` | Read | Read file contents with line numbers (cat -n)
|
|
53
|
-
| `writeTool` | Write | Write content to a file (creates parent dirs)
|
|
54
|
-
| `editTool` | Edit | Replace a specific string in a file
|
|
55
|
-
| `globTool` | Glob | Find files matching a glob pattern (fast-glob)
|
|
56
|
-
| `grepTool` | Grep | Search file contents with regex patterns
|
|
57
|
-
| `webFetchTool` | WebFetch | Fetch URL content (HTML-to-text conversion)
|
|
58
|
-
| `webSearchTool` | WebSearch | Web search via Brave Search API
|
|
49
|
+
| Export | Tool Name | Description |
|
|
50
|
+
| --------------- | --------- | --------------------------------------------------------- |
|
|
51
|
+
| `bashTool` | Bash | Execute shell commands via host process or sandbox client |
|
|
52
|
+
| `readTool` | Read | Read file contents with line numbers (cat -n) |
|
|
53
|
+
| `writeTool` | Write | Write content to a file (creates parent dirs) |
|
|
54
|
+
| `editTool` | Edit | Replace a specific string in a file |
|
|
55
|
+
| `globTool` | Glob | Find files matching a glob pattern (fast-glob) |
|
|
56
|
+
| `grepTool` | Grep | Search file contents with regex patterns |
|
|
57
|
+
| `webFetchTool` | WebFetch | Fetch URL content (HTML-to-text conversion) |
|
|
58
|
+
| `webSearchTool` | WebSearch | Web search via Brave Search API |
|
|
59
|
+
|
|
60
|
+
Factory exports (`createBashTool`, `createReadTool`, `createWriteTool`, `createEditTool`) accept an optional `sandboxClient`. The default singleton exports keep host-local behavior.
|
|
61
|
+
|
|
62
|
+
## Sandbox Execution
|
|
63
|
+
|
|
64
|
+
`ISandboxClient` is the provider-neutral execution-plane port used by sandbox-aware built-in tools:
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
import { E2BSandboxClient, createBashTool, createReadTool } from '@robota-sdk/agent-tools';
|
|
68
|
+
import { Sandbox } from 'e2b';
|
|
69
|
+
|
|
70
|
+
const e2b = await Sandbox.create();
|
|
71
|
+
const sandboxClient = new E2BSandboxClient({ sandbox: e2b });
|
|
72
|
+
|
|
73
|
+
const bashTool = createBashTool({ sandboxClient });
|
|
74
|
+
const readTool = createReadTool({ sandboxClient });
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
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.
|
|
78
|
+
|
|
79
|
+
### Workspace Manifests
|
|
80
|
+
|
|
81
|
+
`IWorkspaceManifest` declares the fresh sandbox workspace before a session starts. Paths are workspace-relative and cannot escape the target root.
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
import { applyWorkspaceManifest, E2BSandboxClient } from '@robota-sdk/agent-tools';
|
|
85
|
+
import { Sandbox } from 'e2b';
|
|
86
|
+
|
|
87
|
+
const sandbox = await Sandbox.create();
|
|
88
|
+
const sandboxClient = new E2BSandboxClient({ sandbox });
|
|
89
|
+
|
|
90
|
+
await applyWorkspaceManifest(sandboxClient, {
|
|
91
|
+
entries: {
|
|
92
|
+
'task.md': { type: 'file', content: 'Analyze this repository.\n' },
|
|
93
|
+
repo: { type: 'gitRepo', url: 'https://github.com/example/project.git', ref: 'main' },
|
|
94
|
+
output: { type: 'dir' },
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
The generic applicator writes inline/local files, creates directories, and clones Git repositories through `ISandboxClient`. Cloud storage mount entries are part of the contract, but they return `unsupported` until a provider-specific adapter implements native mounting.
|
|
59
100
|
|
|
60
101
|
## Edit and Write Safety
|
|
61
102
|
|
|
@@ -63,16 +104,21 @@ Recent file tool updates keep write/edit behavior atomic and make Edit tool resu
|
|
|
63
104
|
|
|
64
105
|
## Tool Infrastructure
|
|
65
106
|
|
|
66
|
-
| Export
|
|
67
|
-
|
|
|
68
|
-
| `ToolRegistry`
|
|
69
|
-
| `FunctionTool`
|
|
70
|
-
| `createFunctionTool`
|
|
71
|
-
| `createZodFunctionTool`
|
|
72
|
-
| `OpenAPITool`
|
|
73
|
-
| `createOpenAPITool`
|
|
74
|
-
| `zodToJsonSchema`
|
|
75
|
-
| `TToolResult`
|
|
107
|
+
| Export | Description |
|
|
108
|
+
| ------------------------ | ---------------------------------------------------------- |
|
|
109
|
+
| `ToolRegistry` | Central tool registration and schema lookup |
|
|
110
|
+
| `FunctionTool` | JS function tool with Zod schema validation |
|
|
111
|
+
| `createFunctionTool` | Factory for creating function tools |
|
|
112
|
+
| `createZodFunctionTool` | Factory with Zod validation and JSON Schema conversion |
|
|
113
|
+
| `OpenAPITool` | Tool generated from OpenAPI specification |
|
|
114
|
+
| `createOpenAPITool` | Factory for creating OpenAPI tools |
|
|
115
|
+
| `zodToJsonSchema` | Converts Zod schemas to JSON Schema format |
|
|
116
|
+
| `TToolResult` | Result type for built-in CLI tool invocations |
|
|
117
|
+
| `ISandboxClient` | Provider-neutral sandbox execution port |
|
|
118
|
+
| `IWorkspaceManifest` | Declarative sandbox workspace setup contract |
|
|
119
|
+
| `applyWorkspaceManifest` | Generic manifest applicator for sandbox clients |
|
|
120
|
+
| `E2BSandboxClient` | Adapter for E2B-compatible sandbox instances and snapshots |
|
|
121
|
+
| `InMemorySandboxClient` | Deterministic sandbox client for tests |
|
|
76
122
|
|
|
77
123
|
## TToolResult Shape
|
|
78
124
|
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
import { IToolRegistry, ITool, IToolSchema, TToolParameters, TUniversalValue, IFunctionTool, TToolExecutor, IEventService, IToolExecutionContext, IToolResult, IParameterValidationResult, IOpenAPIToolConfig } from '@robota-sdk/agent-core';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Result returned by a CLI tool invocation
|
|
5
|
+
*/
|
|
6
|
+
interface TToolResult {
|
|
7
|
+
success: boolean;
|
|
8
|
+
output: string;
|
|
9
|
+
error?: string;
|
|
10
|
+
exitCode?: number;
|
|
11
|
+
/** Start line number of the edit in the original file (Edit tool only) */
|
|
12
|
+
startLine?: number;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Tool registry implementation
|
|
17
|
+
* Manages tool registration, validation, and retrieval
|
|
18
|
+
*/
|
|
19
|
+
declare class ToolRegistry implements IToolRegistry {
|
|
20
|
+
private tools;
|
|
21
|
+
/**
|
|
22
|
+
* Register a tool
|
|
23
|
+
*/
|
|
24
|
+
register(tool: ITool): void;
|
|
25
|
+
/**
|
|
26
|
+
* Unregister a tool
|
|
27
|
+
*/
|
|
28
|
+
unregister(name: string): void;
|
|
29
|
+
/**
|
|
30
|
+
* Get tool by name
|
|
31
|
+
*/
|
|
32
|
+
get(name: string): ITool | undefined;
|
|
33
|
+
/**
|
|
34
|
+
* Get all registered tools
|
|
35
|
+
*/
|
|
36
|
+
getAll(): ITool[];
|
|
37
|
+
/**
|
|
38
|
+
* Get tool schemas
|
|
39
|
+
*/
|
|
40
|
+
getSchemas(): IToolSchema[];
|
|
41
|
+
/**
|
|
42
|
+
* Check if tool exists
|
|
43
|
+
*/
|
|
44
|
+
has(name: string): boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Clear all tools
|
|
47
|
+
*/
|
|
48
|
+
clear(): void;
|
|
49
|
+
/**
|
|
50
|
+
* Get tool names
|
|
51
|
+
*/
|
|
52
|
+
getToolNames(): string[];
|
|
53
|
+
/**
|
|
54
|
+
* Get tools by pattern
|
|
55
|
+
*/
|
|
56
|
+
getToolsByPattern(pattern: string | RegExp): ITool[];
|
|
57
|
+
/**
|
|
58
|
+
* Get tool count
|
|
59
|
+
*/
|
|
60
|
+
size(): number;
|
|
61
|
+
/**
|
|
62
|
+
* Validate tool schema
|
|
63
|
+
*/
|
|
64
|
+
private validateToolSchema;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* FunctionTool - Type definitions for Facade pattern implementation
|
|
69
|
+
*
|
|
70
|
+
* REASON: Complex Zod schema type compatibility requires separation of concerns
|
|
71
|
+
* ALTERNATIVES_CONSIDERED:
|
|
72
|
+
* 1. Fix all Zod undefined issues in single file (creates maintenance burden)
|
|
73
|
+
* 2. Use any types strategically (reduces type safety)
|
|
74
|
+
* 3. Remove Zod support entirely (breaks existing functionality)
|
|
75
|
+
* 4. Create complex conditional types (adds cognitive overhead)
|
|
76
|
+
* 5. Use type assertions everywhere (increases runtime risk)
|
|
77
|
+
* NOTE: Tool functionality is now integrated into @robota-sdk/agent-tools package
|
|
78
|
+
*/
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Zod schema compatibility types
|
|
82
|
+
*/
|
|
83
|
+
interface IZodParseResult {
|
|
84
|
+
success: boolean;
|
|
85
|
+
data?: TToolParameters;
|
|
86
|
+
error?: string | Error;
|
|
87
|
+
}
|
|
88
|
+
interface IZodSchemaDef {
|
|
89
|
+
typeName?: string;
|
|
90
|
+
innerType?: IZodSchema;
|
|
91
|
+
valueType?: IZodSchema;
|
|
92
|
+
checks?: Array<{
|
|
93
|
+
kind: string;
|
|
94
|
+
value?: TUniversalValue;
|
|
95
|
+
}>;
|
|
96
|
+
shape?: () => Record<string, IZodSchema>;
|
|
97
|
+
type?: IZodSchema;
|
|
98
|
+
values?: TUniversalValue[];
|
|
99
|
+
description?: string;
|
|
100
|
+
unknownKeys?: 'passthrough' | 'strip' | 'strict';
|
|
101
|
+
}
|
|
102
|
+
interface IZodSchema {
|
|
103
|
+
parse(value: TToolParameters): TToolParameters;
|
|
104
|
+
safeParse(value: TToolParameters): IZodParseResult;
|
|
105
|
+
_def?: IZodSchemaDef;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Parameter type validation options
|
|
109
|
+
*/
|
|
110
|
+
interface IFunctionToolValidationOptions {
|
|
111
|
+
strict?: boolean;
|
|
112
|
+
allowUnknown?: boolean;
|
|
113
|
+
validateTypes?: boolean;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Schema conversion options
|
|
117
|
+
*/
|
|
118
|
+
interface ISchemaConversionOptions {
|
|
119
|
+
includeDescription?: boolean;
|
|
120
|
+
strictTypes?: boolean;
|
|
121
|
+
allowAdditionalProperties?: boolean;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Tool execution metadata
|
|
125
|
+
*/
|
|
126
|
+
interface IFunctionToolExecutionMetadata {
|
|
127
|
+
executionTime: number;
|
|
128
|
+
toolName: string;
|
|
129
|
+
parameters: TToolParameters;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Tool result with metadata
|
|
133
|
+
*/
|
|
134
|
+
interface IFunctionToolResult {
|
|
135
|
+
success: boolean;
|
|
136
|
+
data: TUniversalValue;
|
|
137
|
+
metadata?: IFunctionToolExecutionMetadata;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Function tool implementation
|
|
142
|
+
* Wraps a JavaScript function as a tool with schema validation
|
|
143
|
+
*
|
|
144
|
+
* Implements IFunctionTool without extending AbstractTool to avoid
|
|
145
|
+
* circular runtime dependency (tools → agents → tools).
|
|
146
|
+
*/
|
|
147
|
+
declare class FunctionTool implements IFunctionTool {
|
|
148
|
+
readonly schema: IToolSchema;
|
|
149
|
+
readonly fn: TToolExecutor;
|
|
150
|
+
private eventService;
|
|
151
|
+
constructor(schema: IToolSchema, fn: TToolExecutor);
|
|
152
|
+
/**
|
|
153
|
+
* Get tool name
|
|
154
|
+
*/
|
|
155
|
+
getName(): string;
|
|
156
|
+
/**
|
|
157
|
+
* Set EventService for post-construction injection.
|
|
158
|
+
* Accepts EventService as-is without transformation.
|
|
159
|
+
* Caller is responsible for providing properly configured EventService.
|
|
160
|
+
*/
|
|
161
|
+
setEventService(eventService: IEventService | undefined): void;
|
|
162
|
+
/**
|
|
163
|
+
* Execute the function tool
|
|
164
|
+
*/
|
|
165
|
+
execute(parameters: TToolParameters, context?: IToolExecutionContext): Promise<IToolResult>;
|
|
166
|
+
/**
|
|
167
|
+
* Validate parameters (simple boolean result)
|
|
168
|
+
*/
|
|
169
|
+
validate(parameters: TToolParameters): boolean;
|
|
170
|
+
/**
|
|
171
|
+
* Validate tool parameters with detailed result
|
|
172
|
+
*/
|
|
173
|
+
validateParameters(parameters: TToolParameters): IParameterValidationResult;
|
|
174
|
+
/**
|
|
175
|
+
* Get tool description
|
|
176
|
+
*/
|
|
177
|
+
getDescription(): string;
|
|
178
|
+
/**
|
|
179
|
+
* Validate constructor inputs
|
|
180
|
+
*/
|
|
181
|
+
private validateConstructorInputs;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Helper function to create a function tool from a simple function
|
|
185
|
+
*/
|
|
186
|
+
declare function createFunctionTool(name: string, description: string, parameters: IToolSchema['parameters'], fn: TToolExecutor): FunctionTool;
|
|
187
|
+
/**
|
|
188
|
+
* Helper function to create a function tool from Zod schema
|
|
189
|
+
*/
|
|
190
|
+
declare function createZodFunctionTool(name: string, description: string, zodSchema: IZodSchema, fn: TToolExecutor): FunctionTool;
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* OpenAPI tool implementation
|
|
194
|
+
* Executes API calls based on OpenAPI 3.0 specifications
|
|
195
|
+
*
|
|
196
|
+
* Implements ITool without extending AbstractTool to avoid
|
|
197
|
+
* circular runtime dependency (tools → agents → tools).
|
|
198
|
+
*/
|
|
199
|
+
declare class OpenAPITool implements ITool {
|
|
200
|
+
readonly schema: IToolSchema;
|
|
201
|
+
private readonly apiSpec;
|
|
202
|
+
private readonly operationId;
|
|
203
|
+
private readonly baseURL;
|
|
204
|
+
private readonly config;
|
|
205
|
+
private eventService;
|
|
206
|
+
constructor(config: IOpenAPIToolConfig);
|
|
207
|
+
/**
|
|
208
|
+
* Execute the OpenAPI tool
|
|
209
|
+
*/
|
|
210
|
+
execute(parameters: TToolParameters, context?: IToolExecutionContext): Promise<IToolResult>;
|
|
211
|
+
/**
|
|
212
|
+
* Validate tool parameters
|
|
213
|
+
*/
|
|
214
|
+
validate(parameters: TToolParameters): boolean;
|
|
215
|
+
/**
|
|
216
|
+
* Validate tool parameters with detailed result
|
|
217
|
+
*/
|
|
218
|
+
validateParameters(parameters: TToolParameters): IParameterValidationResult;
|
|
219
|
+
/**
|
|
220
|
+
* Get tool name
|
|
221
|
+
*/
|
|
222
|
+
getName(): string;
|
|
223
|
+
/**
|
|
224
|
+
* Set EventService for post-construction injection.
|
|
225
|
+
*/
|
|
226
|
+
setEventService(eventService: IEventService | undefined): void;
|
|
227
|
+
/**
|
|
228
|
+
* Get tool description
|
|
229
|
+
*/
|
|
230
|
+
getDescription(): string;
|
|
231
|
+
/**
|
|
232
|
+
* Execute the actual API call
|
|
233
|
+
* @private
|
|
234
|
+
*/
|
|
235
|
+
private executeAPICall;
|
|
236
|
+
/**
|
|
237
|
+
* Build HTTP request configuration from OpenAPI operation and parameters
|
|
238
|
+
*/
|
|
239
|
+
private buildRequestConfig;
|
|
240
|
+
/**
|
|
241
|
+
* Create tool schema from OpenAPI operation specification
|
|
242
|
+
*/
|
|
243
|
+
private createSchemaFromOpenAPI;
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Factory function to create OpenAPI tools from specification
|
|
247
|
+
*/
|
|
248
|
+
declare function createOpenAPITool(config: IOpenAPIToolConfig): OpenAPITool;
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* FunctionTool - Schema conversion utilities for Facade pattern
|
|
252
|
+
*
|
|
253
|
+
* REASON: Complex Zod to JSON schema conversion requires isolated utility functions
|
|
254
|
+
* ALTERNATIVES_CONSIDERED:
|
|
255
|
+
* 1. Keep conversion logic in main class (violates single responsibility)
|
|
256
|
+
* 2. Use third-party library (adds external dependency)
|
|
257
|
+
* 3. Manual conversion each time (code duplication)
|
|
258
|
+
* 4. Runtime type checking only (loses compile-time safety)
|
|
259
|
+
* 5. Remove Zod support (breaks backward compatibility)
|
|
260
|
+
* TODO: Consider caching conversion results for performance
|
|
261
|
+
*/
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Convert Zod schema to JSON Schema format with safe undefined handling
|
|
265
|
+
*/
|
|
266
|
+
declare function zodToJsonSchema(schema: IZodSchema, options?: ISchemaConversionOptions): IToolSchema['parameters'];
|
|
267
|
+
|
|
268
|
+
export { FunctionTool, type IFunctionToolExecutionMetadata, type IFunctionToolResult, type IFunctionToolValidationOptions, type ISchemaConversionOptions, type IZodParseResult, type IZodSchema, type IZodSchemaDef, OpenAPITool, type TToolResult, ToolRegistry, createFunctionTool, createOpenAPITool, createZodFunctionTool, zodToJsonSchema };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import {ValidationError,logger,ToolExecutionError}from'@robota-sdk/agent-core';var S=class{tools=new Map;register(e){if(!e.schema?.name)throw new ValidationError("Tool must have a valid schema with name");let t=e.schema.name;this.validateToolSchema(e.schema),this.tools.has(t)&&logger.warn(`Tool "${t}" is already registered, overriding`,{toolName:t,existingTool:this.tools.get(t)?.constructor.name}),this.tools.set(t,e),logger.debug(`Tool "${t}" registered successfully`,{toolName:t,toolType:e.constructor.name,parameters:Object.keys(e.schema.parameters?.properties||{})});}unregister(e){if(!this.tools.has(e)){logger.warn(`Attempted to unregister non-existent tool "${e}"`);return}this.tools.delete(e),logger.debug(`Tool "${e}" unregistered successfully`);}get(e){return this.tools.get(e)}getAll(){return Array.from(this.tools.values())}getSchemas(){let e=this.getAll();return logger.debug("[TOOL-FLOW] ToolRegistry.getSchemas() - Tools before schema extraction",{count:e.length,tools:e.map(t=>({name:t.schema?.name??"unnamed",hasSchema:!!t.schema,schemaType:typeof t.schema,toolType:t.constructor?.name||"unknown"}))}),this.getAll().map(t=>t.schema)}has(e){return this.tools.has(e)}clear(){let e=this.tools.size;this.tools.clear(),logger.debug(`Cleared ${e} tools from registry`);}getToolNames(){return Array.from(this.tools.keys())}getToolsByPattern(e){let t=typeof e=="string"?new RegExp(e):e;return this.getAll().filter(o=>t.test(o.schema.name))}size(){return this.tools.size}validateToolSchema(e){if(!e.name||typeof e.name!="string")throw new ValidationError("Tool schema must have a valid name");if(!e.description||typeof e.description!="string")throw new ValidationError("Tool schema must have a description");if(!e.parameters||typeof e.parameters!="object"||e.parameters===null||Array.isArray(e.parameters))throw new ValidationError("Tool schema must have parameters object");if(e.parameters.type!=="object")throw new ValidationError('Tool parameters type must be "object"');if(e.parameters.properties)for(let t of Object.keys(e.parameters.properties)){let o=e.parameters.properties[t];if(!o?.type)throw new ValidationError(`Parameter "${t}" must have a type`);if(!["string","number","boolean","array","object"].includes(o.type))throw new ValidationError(`Parameter "${t}" has invalid type "${o.type}"`)}if(e.parameters.required){let t=e.parameters.properties||{};for(let o of e.parameters.required)if(!t[o])throw new ValidationError(`Required parameter "${o}" is not defined in properties`)}}};function v(r,e={}){let t={},o=[],n=r._def;if(!n)throw new Error("Zod schema is missing _def; cannot convert to JSON schema.");if(n.typeName==="ZodObject"&&n.shape){let a=typeof n.shape=="function"?n.shape():n.shape;for(let[s,i]of Object.entries(a)){let c=f(i);t[s]=c,Z(i)&&o.push(s);}}return {type:"object",properties:t,required:o,...(e.allowAdditionalProperties||n.unknownKeys==="passthrough")&&{additionalProperties:true}}}function f(r){let e=r._def;if(!e)throw new Error("Zod type is missing _def; cannot convert to JSON schema.");let t={};switch(e.description&&(t.description=e.description),e.typeName){case "ZodString":return {type:"string",...t};case "ZodNumber":return {type:"number",...t};case "ZodBoolean":return {type:"boolean",...t};case "ZodArray":{if(!e.type)throw new Error("ZodArray is missing item type; cannot convert to JSON schema.");return {type:"array",items:f(e.type),...t}}case "ZodObject":return {type:"object",...t};case "ZodEnum":{let o=e.values;if(!o||!Array.isArray(o))throw new Error("ZodEnum is missing enum values; cannot convert to JSON schema.");return {type:"string",enum:o,...t}}case "ZodOptional":if(e.innerType)return {...f(e.innerType),...t};throw new Error("ZodOptional is missing innerType; cannot convert to JSON schema.");case "ZodNullable":if(e.innerType)return {...f(e.innerType),...t};throw new Error("ZodNullable is missing innerType; cannot convert to JSON schema.");case "ZodDefault":if(e.innerType)return {...f(e.innerType),...t};throw new Error("ZodDefault is missing innerType; cannot convert to JSON schema.");case "ZodRecord":return e.valueType?{type:"object",additionalProperties:f(e.valueType),...t}:{type:"object",additionalProperties:{type:"string"},...t};default:throw new Error(`Unsupported Zod type: ${String(e.typeName)}`)}}function Z(r){let e=r._def;if(!e)throw new Error("Zod schema is missing _def; cannot determine required fields.");return e.typeName!=="ZodOptional"&&e.typeName!=="ZodNullable"&&e.typeName!=="ZodDefault"}function w(r,e,t){switch(t.type){case "string":if(typeof e!="string")return `Parameter "${r}" must be a string, got ${typeof e}`;break;case "number":if(typeof e!="number"||isNaN(e))return `Parameter "${r}" must be a number, got ${typeof e}`;break;case "boolean":if(typeof e!="boolean")return `Parameter "${r}" must be a boolean, got ${typeof e}`;break;case "array":if(!Array.isArray(e))return `Parameter "${r}" must be an array, got ${typeof e}`;if(t.items)for(let n=0;n<e.length;n++){let a=w(`${r}[${n}]`,e[n],t.items);if(a)return a}break;case "object":if(typeof e!="object"||e===null||Array.isArray(e))return `Parameter "${r}" must be an object, got ${typeof e}`;break}if(t.enum&&t.enum.length>0){let n=t.enum,a=false;for(let s of n)if(e===s){a=true;break}if(!a)return `Parameter "${r}" must be one of: ${n.join(", ")}, got ${e}`}}function I(r,e,t,o){let n=[];for(let a of e)a in r||n.push(`Missing required parameter: ${a}`);for(let[a,s]of Object.entries(r)){let i=t[a];if(!i){if(o===true)continue;if(o&&typeof o=="object"){let p=w(a,s,o);p&&n.push(p);continue}n.push(`Unknown parameter: ${a}`);continue}let c=w(a,s,i);c&&n.push(c);}return n}function E(r,e,t,o){let n=I(r,e,t,o);return {isValid:n.length===0,errors:n}}var T=class{schema;fn;eventService;constructor(e,t){this.schema=e,this.fn=t,this.validateConstructorInputs();}getName(){return this.schema.name}setEventService(e){this.eventService=e;}async execute(e,t){let o=this.schema.name;if(!this.validate(e)){let i=I(e,this.schema.parameters.required||[],this.schema.parameters.properties||{},this.schema.parameters.additionalProperties);throw new ValidationError(`Invalid parameters for tool "${o}": ${i.join(", ")}`)}let n=Date.now(),a;try{a=await this.fn(e,t);}catch(i){throw i instanceof ToolExecutionError||i instanceof ValidationError?i:new ToolExecutionError(`Function tool execution failed: ${i instanceof Error?i.message:String(i)}`,o,i instanceof Error?i:new Error(String(i)),{parameterCount:Object.keys(e||{}).length,hasContext:!!t})}let s=Date.now()-n;return {success:true,data:a,metadata:{executionTime:s,toolName:o,parameters:e}}}validate(e){return I(e,this.schema.parameters.required||[],this.schema.parameters.properties||{},this.schema.parameters.additionalProperties).length===0}validateParameters(e){return E(e,this.schema.parameters.required||[],this.schema.parameters.properties||{},this.schema.parameters.additionalProperties)}getDescription(){return this.schema.description}validateConstructorInputs(){if(!this.schema)throw new ValidationError("Tool schema is required");if(!this.fn||typeof this.fn!="function")throw new ValidationError("Tool function is required and must be a function");if(!this.schema.name)throw new ValidationError("Tool schema must have a name")}};function N(r,e,t,o){let n={name:r,description:e,parameters:t};return new T(n,o)}function C(r,e,t,o){let n=v(t),a={name:r,description:e,parameters:n},s=async(i,c)=>{let p=t.safeParse(i);if(!p.success)throw new ValidationError(`Zod validation failed: ${p.error}`);let d=await o(p.data||i,c);return typeof d=="string"?d:JSON.stringify(d)};return new T(a,s)}var k=["get","post","put","delete","patch","head","options"];function O(r,e){for(let[t,o]of Object.entries(r.paths||{}))if(o)for(let n of k){let a=o[n];if(a?.operationId===e)return {method:n,path:t,operation:a}}}function U(r){switch(r){case "string":return "string";case "number":return "number";case "integer":return "integer";case "boolean":return "boolean";case "array":return "array";case "object":return "object";default:return "string"}}function P(r){if("$ref"in r)return {type:"object"};let e={type:U(r.type)};if(r.description&&(e.description=r.description),r.enum&&(e.enum=r.enum),r.minimum!==void 0&&(e.minimum=r.minimum),r.maximum!==void 0&&(e.maximum=r.maximum),r.pattern&&(e.pattern=r.pattern),r.format&&(e.format=r.format),r.default!==void 0&&(e.default=r.default),r.type==="array"&&r.items&&(e.items=P(r.items)),r.type==="object"&&r.properties){e.properties={};for(let[t,o]of Object.entries(r.properties))e.properties[t]=P(o);r.required&&r.required.length>0&&(e.required=r.required);}return e}function D(r){let e=r.schema;return P(e)}function j(r,e){let t={},o=[],n=e.parameters||[];for(let s of n)t[s.name]=D(s),s.required&&o.push(s.name);if(e.requestBody){let i=e.requestBody.content?.["application/json"];if(i?.schema){let c=P(i.schema);if(c.type==="object"&&c.properties){Object.assign(t,c.properties);let p=c;p.required&&o.push(...p.required);}}}let a={type:"object",properties:t};return o.length>0&&(a.required=o),{name:r,description:e.summary||e.description||`OpenAPI operation: ${r}`,parameters:a}}var b=class{schema;apiSpec;operationId;baseURL;config;eventService;constructor(e){if(this.config=e,typeof e.spec!="object"||e.spec===null||typeof e.spec.openapi!="string"||typeof e.spec.paths!="object")throw new Error('Invalid OpenAPI spec: must contain "openapi" (string) and "paths" (object) fields');this.apiSpec=e.spec,this.operationId=e.operationId,this.baseURL=e.baseURL,this.schema=this.createSchemaFromOpenAPI();}async execute(e,t){let o=this.schema.name,n=this.validateParameters(e);if(!n.isValid)throw new ValidationError(`Invalid parameters for OpenAPI tool "${o}": ${n.errors.join(", ")}`);try{let a=Date.now(),s=await this.executeAPICall(e,t),i=Date.now()-a;return {success:!0,data:s,metadata:{executionTime:i,toolName:o,operationId:this.operationId,baseURL:this.baseURL}}}catch(a){if(a instanceof ToolExecutionError||a instanceof ValidationError)throw a;let s=a instanceof Error?a:new Error(String(a));throw new ToolExecutionError(`OpenAPI tool execution failed: ${s.message}`,o,s,{operationId:this.operationId,baseURL:this.baseURL,parametersCount:Object.keys(e).length})}}validate(e){return this.validateParameters(e).isValid}validateParameters(e){let t=this.schema.parameters.required||[],o=[];for(let n of t)n in e||o.push(`Missing required parameter: ${n}`);return {isValid:o.length===0,errors:o}}getName(){return this.schema.name}setEventService(e){this.eventService=e;}getDescription(){return this.schema.description}async executeAPICall(e,t){let o=O(this.apiSpec,this.operationId);throw o?(this.buildRequestConfig(o,e),new Error("Not implemented: actual API execution is not yet available")):new Error(`Operation ${this.operationId} not found in OpenAPI spec`)}buildRequestConfig(e,t){let{method:o,path:n,operation:a}=e,s=this.baseURL+n,i={},c,p=a.parameters||[];for(let m of p){let l=t[m.name];if(l===void 0&&m.required)throw new Error(`Required parameter ${m.name} is missing`);if(l!==void 0)switch(m.in){case "path":s=s.replace(`{${m.name}}`,encodeURIComponent(String(l)));break;case "query":{let g=s.includes("?")?"&":"?";s+=`${g}${m.name}=${encodeURIComponent(String(l))}`;break}case "header":i[m.name]=String(l);break}}if(["post","put","patch"].includes(o)&&a.requestBody&&a.requestBody.content?.["application/json"]){i["Content-Type"]="application/json";let g={};for(let[x,$]of Object.entries(t))p.some(q=>q.name===x)||(g[x]=$);c=JSON.stringify(g);}if(this.config.auth)switch(this.config.auth.type){case "bearer":i.Authorization=`Bearer ${this.config.auth.token}`;break;case "apiKey":{let m=this.config.auth.header||"X-API-Key";i[m]=this.config.auth.apiKey||"";break}}let d={method:o,url:s,headers:i};return c!==void 0&&(d.body=c),d}createSchemaFromOpenAPI(){let e=O(this.apiSpec,this.operationId);if(!e)throw new Error(`[STRICT-POLICY][EMITTER-CONTRACT] OpenAPI operation not found: ${this.operationId}. Emitter contract must provide a valid operationId present in the OpenAPI document.`);return j(this.operationId,e.operation)}};function F(r){return new b(r)}export{T as FunctionTool,b as OpenAPITool,S as ToolRegistry,N as createFunctionTool,F as createOpenAPITool,C as createZodFunctionTool,v as zodToJsonSchema};
|