@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # @robota-sdk/agent-tools
2
2
 
3
- Tool registry, tool creation infrastructure, and 8 built-in CLI tools for the Robota SDK.
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 `child_process.spawn` |
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 | Description |
67
- | ----------------------- | ------------------------------------------------------ |
68
- | `ToolRegistry` | Central tool registration and schema lookup |
69
- | `FunctionTool` | JS function tool with Zod schema validation |
70
- | `createFunctionTool` | Factory for creating function tools |
71
- | `createZodFunctionTool` | Factory with Zod validation and JSON Schema conversion |
72
- | `OpenAPITool` | Tool generated from OpenAPI specification |
73
- | `createOpenAPITool` | Factory for creating OpenAPI tools |
74
- | `zodToJsonSchema` | Converts Zod schemas to JSON Schema format |
75
- | `TToolResult` | Result type for built-in CLI tool invocations |
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};