@openserv-labs/sdk 2.3.0 → 2.4.1

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
@@ -232,7 +232,7 @@ npm install @openserv-labs/sdk
232
232
  agent.addCapability({
233
233
  name: 'greet',
234
234
  description: 'Greet a user by name',
235
- schema: z.object({
235
+ inputSchema: z.object({
236
236
  name: z.string().describe('The name of the user to greet')
237
237
  }),
238
238
  async run({ args }) {
@@ -273,7 +273,7 @@ const agent = new Agent({
273
273
  agent.addCapability({
274
274
  name: 'greet',
275
275
  description: 'Greet a user by name',
276
- schema: z.object({
276
+ inputSchema: z.object({
277
277
  name: z.string().describe('The name of the user to greet')
278
278
  }),
279
279
  async run({ args }) {
@@ -286,7 +286,7 @@ agent.addCapabilities([
286
286
  {
287
287
  name: 'farewell',
288
288
  description: 'Say goodbye to a user',
289
- schema: z.object({
289
+ inputSchema: z.object({
290
290
  name: z.string().describe('The name of the user to bid farewell')
291
291
  }),
292
292
  async run({ args }) {
@@ -296,7 +296,7 @@ agent.addCapabilities([
296
296
  {
297
297
  name: 'help',
298
298
  description: 'Show available commands',
299
- schema: z.object({}),
299
+ inputSchema: z.object({}),
300
300
  async run() {
301
301
  return 'Available commands: greet, farewell, help'
302
302
  }
@@ -316,13 +316,13 @@ agent.start()
316
316
  | Variable | Description | Required | Default |
317
317
  | --------------------- | ------------------------------------------ | -------- | ---------------------------------- |
318
318
  | `OPENSERV_API_KEY` | Your OpenServ API key | Yes | - |
319
- | `OPENAI_API_KEY` | OpenAI API key (for process() method) | No\* | - |
319
+ | `OPENAI_API_KEY` | OpenAI API key (only for process() method) | No | - |
320
320
  | `PORT` | Server port | No | 7378 |
321
321
  | `OPENSERV_AUTH_TOKEN` | Token for authenticating incoming requests | No | - |
322
322
  | `OPENSERV_PROXY_URL` | Custom proxy URL for tunnel connections | No | `https://agents-proxy.openserv.ai` |
323
323
  | `DISABLE_TUNNEL` | Skip tunnel and run HTTP server only | No | - |
324
324
 
325
- \*Required if using OpenAI integration features
325
+ **Note:** `OPENAI_API_KEY` is only needed if you use the `process()` method for direct OpenAI calls. Most agents don't need it -- use run-less capabilities or `generate()` instead.
326
326
 
327
327
  ## Core Concepts
328
328
 
@@ -334,8 +334,10 @@ Each capability must include:
334
334
 
335
335
  - `name`: Unique identifier for the capability
336
336
  - `description`: What the capability does
337
- - `schema`: Zod schema defining the parameters
338
- - `run`: Function that executes the capability, receiving validated args and action context
337
+ - `inputSchema`: Zod schema defining the input parameters (optional for run-less capabilities, defaults to `z.object({ input: z.string() })`)
338
+ - `run`: Function that executes the capability (optional -- omit for run-less capabilities handled by the runtime)
339
+ - `outputSchema`: Zod schema for structured LLM output (only for run-less capabilities)
340
+ - `schema`: **Deprecated** -- use `inputSchema` instead (kept for backwards compatibility)
339
341
 
340
342
  ```typescript
341
343
  import { Agent } from '@openserv-labs/sdk'
@@ -349,7 +351,7 @@ const agent = new Agent({
349
351
  agent.addCapability({
350
352
  name: 'summarize',
351
353
  description: 'Summarize a piece of text',
352
- schema: z.object({
354
+ inputSchema: z.object({
353
355
  text: z.string().describe('Text content to summarize'),
354
356
  maxLength: z.number().optional().describe('Maximum length of summary')
355
357
  }),
@@ -377,7 +379,7 @@ agent.addCapabilities([
377
379
  {
378
380
  name: 'analyze',
379
381
  description: 'Analyze text for sentiment and keywords',
380
- schema: z.object({
382
+ inputSchema: z.object({
381
383
  text: z.string().describe('Text to analyze')
382
384
  }),
383
385
  async run({ args, action }) {
@@ -388,7 +390,7 @@ agent.addCapabilities([
388
390
  {
389
391
  name: 'help',
390
392
  description: 'Show available commands',
391
- schema: z.object({}),
393
+ inputSchema: z.object({}),
392
394
  async run({ args, action }) {
393
395
  return 'Available commands: summarize, analyze, help'
394
396
  }
@@ -399,8 +401,8 @@ agent.addCapabilities([
399
401
  Each capability's run function receives:
400
402
 
401
403
  - `params`: Object containing:
402
- - `args`: The validated arguments matching the capability's schema
403
- - `action`: The action context containing:
404
+ - `args`: The validated arguments matching the capability's inputSchema
405
+ - `action`: The action context provided by the runtime, containing:
404
406
  - `task`: The current task context (if running as part of a task)
405
407
  - `workspace`: The current workspace context
406
408
  - `me`: Information about the current agent
@@ -408,6 +410,92 @@ Each capability's run function receives:
408
410
 
409
411
  The run function must return a string or Promise<string>.
410
412
 
413
+ ### Run-less Capabilities
414
+
415
+ Run-less capabilities let you define tools without a `run` function. The OpenServ runtime handles execution via its own LLM, using the capability's `description` as instructions. This means you don't need your own OpenAI key.
416
+
417
+ ```typescript
418
+ import { Agent, run } from '@openserv-labs/sdk'
419
+ import { z } from 'zod'
420
+
421
+ const agent = new Agent({
422
+ systemPrompt: 'You are a creative writing assistant.'
423
+ })
424
+
425
+ // Simplest form: just name + description (default inputSchema: { input: string })
426
+ agent.addCapability({
427
+ name: 'generate_haiku',
428
+ description:
429
+ 'Generate a haiku poem (5-7-5 syllables) about the given input. Only output the haiku.'
430
+ })
431
+
432
+ // With custom inputSchema
433
+ agent.addCapability({
434
+ name: 'translate',
435
+ description: 'Translate the given text to the target language. Return only the translated text.',
436
+ inputSchema: z.object({
437
+ text: z.string().describe('The text to translate'),
438
+ targetLanguage: z.string().describe('The target language')
439
+ })
440
+ })
441
+
442
+ // With structured output via outputSchema
443
+ agent.addCapability({
444
+ name: 'analyze_sentiment',
445
+ description: 'Analyze the sentiment of the given input text.',
446
+ outputSchema: z.object({
447
+ sentiment: z.enum(['positive', 'negative', 'neutral']),
448
+ confidence: z.number().min(0).max(1)
449
+ })
450
+ })
451
+
452
+ run(agent)
453
+ ```
454
+
455
+ ### The `generate()` Method
456
+
457
+ Inside custom `run` functions, use `this.generate()` to delegate LLM calls to the OpenServ runtime without needing your own OpenAI key. The `action` parameter is required for billing. You can optionally pass `messages` for conversation context.
458
+
459
+ ```typescript
460
+ agent.addCapability({
461
+ name: 'write_and_save_poem',
462
+ description: 'Write a poem and save it to the workspace',
463
+ inputSchema: z.object({ topic: z.string() }),
464
+ async run({ args, action }, messages) {
465
+ // Text generation
466
+ const poem = await this.generate({
467
+ prompt: `Write a short poem about ${args.topic}`,
468
+ action
469
+ })
470
+
471
+ // Structured output generation
472
+ const metadata = await this.generate({
473
+ prompt: `Suggest a title and 3 tags for this poem: ${poem}`,
474
+ outputSchema: z.object({
475
+ title: z.string(),
476
+ tags: z.array(z.string()).length(3)
477
+ }),
478
+ action
479
+ })
480
+
481
+ // With conversation history for context
482
+ const followUp = await this.generate({
483
+ prompt: 'Based on our conversation, suggest a related topic.',
484
+ messages, // pass conversation history from the run function
485
+ action
486
+ })
487
+
488
+ await this.uploadFile({
489
+ workspaceId: action.workspace.id,
490
+ path: `poems/${metadata.title}.txt`,
491
+ file: poem
492
+ })
493
+
494
+ return `Saved "${metadata.title}" with tags: ${metadata.tags.join(', ')}`
495
+ }
496
+ })
497
+ ```
498
+
411
499
  ### Tasks
412
500
 
413
501
  Tasks are units of work that agents can execute. They can have dependencies, require human assistance, and maintain state:
@@ -451,7 +539,7 @@ const customerSupportAgent = new Agent({
451
539
  {
452
540
  name: 'respondToCustomer',
453
541
  description: 'Generate a response to a customer inquiry',
454
- schema: z.object({
542
+ inputSchema: z.object({
455
543
  query: z.string(),
456
544
  context: z.string().optional()
457
545
  }),
@@ -771,7 +859,7 @@ const agent = new Agent({
771
859
  agent.addCapability({
772
860
  name: 'greet',
773
861
  description: 'Greet someone',
774
- schema: z.object({ name: z.string() }),
862
+ inputSchema: z.object({ name: z.string() }),
775
863
  async run({ args }) {
776
864
  return `Hello, ${args.name}!`
777
865
  }
@@ -795,13 +883,13 @@ The `run()` function automatically:
795
883
 
796
884
  #### Tunnel vs. Deployed Endpoint
797
885
 
798
- | Aspect | Tunnel (Local Development) | Deployed Endpoint (Production) |
799
- | ----------------- | -------------------------- | ------------------------------------ |
800
- | Setup | Just run your code | Deploy to cloud/server |
801
- | URL Configuration | Not needed | Set Agent Endpoint in platform |
802
- | Connection | WebSocket via proxy | Direct HTTP |
803
- | Tunnel | Enabled (default) | Disabled (`DISABLE_TUNNEL=true`) |
804
- | Use case | Development & testing | Production |
886
+ | Aspect | Tunnel (Local Development) | Deployed Endpoint (Production) |
887
+ | ----------------- | -------------------------- | -------------------------------- |
888
+ | Setup | Just run your code | Deploy to cloud/server |
889
+ | URL Configuration | Not needed | Set Agent Endpoint in platform |
890
+ | Connection | WebSocket via proxy | Direct HTTP |
891
+ | Tunnel | Enabled (default) | Disabled (`DISABLE_TUNNEL=true`) |
892
+ | Use case | Development & testing | Production |
805
893
 
806
894
  When deploying to a hosting provider like Cloud Run, set `DISABLE_TUNNEL=true` as an environment variable. This makes `run()` start only the HTTP server without opening a WebSocket tunnel to the proxy — the platform reaches your agent directly at its public URL.
807
895
 
package/dist/agent.d.ts CHANGED
@@ -2,9 +2,47 @@ import { type AxiosInstance } from 'axios';
2
2
  import type { GetFilesParams, GetSecretsParams, GetSecretValueParams, UploadFileParams, DeleteFileParams, MarkTaskAsErroredParams, CompleteTaskParams, SendChatMessageParams, GetTaskDetailParams, GetAgentsParams, GetTasksParams, CreateTaskParams, AddLogToTaskParams, RequestHumanAssistanceParams, UpdateTaskStatusParams, ProcessParams, IntegrationCallRequest, GetChatMessagesParams, AgentChatMessagesResponse, GetFilesResponse, GetSecretsResponse, UploadFileResponse, DeleteFileResponse, GetTaskDetailResponse, GetAgentsResponse, GetTasksResponse, CreateTaskResponse, ActionSchema, DoTaskActionSchema, RespondChatMessageActionSchema } from './types';
3
3
  import type { ChatCompletionMessageParam, ChatCompletion } from 'openai/resources/chat/completions';
4
4
  import OpenAI from 'openai';
5
- import type { z } from 'zod';
5
+ import { z } from 'zod';
6
6
  import { Capability } from './capability';
7
7
  import { type MCPServerConfig, MCPClient } from './mcp';
8
+ /** Accept inputSchema (preferred) or schema (deprecated), never both */
9
+ type WithInputSchema<S extends z.ZodTypeAny> = {
10
+ inputSchema: S;
11
+ schema?: never;
12
+ } | {
13
+ schema: S;
14
+ inputSchema?: never;
15
+ };
16
+ /** Optional inputSchema for run-less caps -- can omit entirely (uses default) */
17
+ type WithOptionalInputSchema<S extends z.ZodTypeAny> = {
18
+ inputSchema: S;
19
+ schema?: never;
20
+ } | {
21
+ schema: S;
22
+ inputSchema?: never;
23
+ } | {
24
+ inputSchema?: never;
25
+ schema?: never;
26
+ };
27
+ /** Capability with a run function -- inputSchema required, outputSchema not allowed */
28
+ type RunnableCapabilityConfig<M extends string, S extends z.ZodTypeAny> = {
29
+ name: string;
30
+ description: string;
31
+ run(this: Agent<M>, params: {
32
+ args: z.infer<S>;
33
+ action: ActionSchema;
34
+ }, messages: ChatCompletionMessageParam[]): string | Promise<string>;
35
+ outputSchema?: never;
36
+ } & WithInputSchema<S>;
37
+ /** Capability without run -- inputSchema optional, outputSchema optional */
38
+ type RunlessCapabilityConfig<S extends z.ZodTypeAny = z.ZodTypeAny> = {
39
+ name: string;
40
+ description: string;
41
+ run?: never;
42
+ outputSchema?: z.ZodTypeAny;
43
+ } & WithOptionalInputSchema<S>;
44
+ /** Union of all valid capability forms */
45
+ export type CapabilityConfig<M extends string, S extends z.ZodTypeAny> = RunnableCapabilityConfig<M, S> | RunlessCapabilityConfig<S>;
8
46
  /**
9
47
  * Configuration options for creating a new Agent instance.
10
48
  */
@@ -31,9 +69,9 @@ export interface AgentOptions<T extends string> {
31
69
  */
32
70
  systemPrompt: string;
33
71
  /**
34
- * The OpenAI API key for chat completions.
72
+ * Optional OpenAI API key for direct LLM access via process().
73
+ * NOT required for platform-deployed agents -- use generate() or run-less capabilities instead.
35
74
  * Can also be provided via OPENAI_API_KEY environment variable.
36
- * Required when using the process() method.
37
75
  */
38
76
  openaiApiKey?: string;
39
77
  /**
@@ -82,7 +120,8 @@ export declare class Agent<M extends string = string> {
82
120
  protected systemPrompt: string;
83
121
  /**
84
122
  * Array of capabilities (tools) available to the agent.
85
- * Each capability is an instance of the Capability class with a name, description, schema, and run function.
123
+ * Each capability is an instance of the Capability class with a name, description, inputSchema,
124
+ * and optionally a run function and/or outputSchema.
86
125
  * @protected
87
126
  */
88
127
  protected tools: Array<Capability<M, z.ZodTypeAny>>;
@@ -167,53 +206,32 @@ export declare class Agent<M extends string = string> {
167
206
  private initializeMCPClients;
168
207
  /**
169
208
  * Adds a single capability (tool) to the agent.
170
- * Each capability must have a unique name and defines a function that can be called via the API.
209
+ * Each capability must have a unique name. Capabilities can be:
210
+ * - **Runnable**: has a `run` function and requires `inputSchema` (or deprecated `schema`)
211
+ * - **Run-less**: no `run` function -- the runtime handles execution via LLM.
212
+ * `inputSchema` is optional (defaults to `{ input: z.string() }`), `outputSchema` is optional.
171
213
  *
172
214
  * @template S - The Zod schema type for the capability's parameters
173
- * @param {Object} capability - The capability configuration
174
- * @param {string} capability.name - Unique name for the capability
175
- * @param {string} capability.description - Description of what the capability does
176
- * @param {S} capability.schema - Zod schema defining the capability's parameters
177
- * @param {Function} capability.run - Function that implements the capability's behavior
178
- * @param {Object} capability.run.params - Parameters for the run function
179
- * @param {z.infer<S>} capability.run.params.args - Validated arguments matching the schema
180
- * @param {ActionSchema} [capability.run.params.action] - Optional action context
181
- * @param {ChatCompletionMessageParam[]} capability.run.messages - Chat message history
182
- * @returns {this} The agent instance for method chaining
215
+ * @param capability - The capability configuration
216
+ * @returns The agent instance for method chaining
183
217
  * @throws {Error} If a capability with the same name already exists
218
+ * @throws {Error} If both `inputSchema` and `schema` are provided
219
+ * @throws {Error} If both `run` and `outputSchema` are provided
220
+ * @throws {Error} If a runnable capability omits `inputSchema`/`schema`
184
221
  */
185
- addCapability<S extends z.ZodTypeAny>({ name, description, schema, run }: {
186
- name: string;
187
- description: string;
188
- schema: S;
189
- run(this: Agent<M>, params: {
190
- args: z.infer<S>;
191
- action?: ActionSchema;
192
- }, messages: ChatCompletionMessageParam[]): string | Promise<string>;
193
- }): this;
222
+ addCapability<S extends z.ZodTypeAny>(capability: CapabilityConfig<M, S>): this;
194
223
  /**
195
224
  * Adds multiple capabilities (tools) to the agent at once.
196
225
  * Each capability must have a unique name and not conflict with existing capabilities.
226
+ * Each element can be runnable or run-less independently.
197
227
  *
198
228
  * @template T - Tuple of Zod schema types for the capabilities' parameters
199
- * @param {Object} capabilities - Array of capability configurations
200
- * @param {string} capabilities[].name - Unique name for each capability
201
- * @param {string} capabilities[].description - Description of what each capability does
202
- * @param {T[number]} capabilities[].schema - Zod schema defining each capability's parameters
203
- * @param {Function} capabilities[].run - Function that implements each capability's behavior
204
- * @returns {this} The agent instance for method chaining
229
+ * @param capabilities - Array of capability configurations
230
+ * @returns The agent instance for method chaining
205
231
  * @throws {Error} If any capability has a name that already exists
206
232
  */
207
233
  addCapabilities<T extends readonly [z.ZodTypeAny, ...z.ZodTypeAny[]]>(capabilities: {
208
- [K in keyof T]: {
209
- name: string;
210
- description: string;
211
- schema: T[K];
212
- run(this: Agent<M>, params: {
213
- args: z.infer<T[K]>;
214
- action?: ActionSchema;
215
- }, messages: ChatCompletionMessageParam[]): string | Promise<string>;
216
- };
234
+ [K in keyof T]: CapabilityConfig<M, T[K]>;
217
235
  }): this;
218
236
  /**
219
237
  * Gets files in a workspace.
@@ -370,6 +388,37 @@ export declare class Agent<M extends string = string> {
370
388
  * @returns {Promise<UpdateTaskStatusResponse>} The updated task details
371
389
  */
372
390
  updateTaskStatus(params: UpdateTaskStatusParams): Promise<undefined>;
391
+ /**
392
+ * Generate text via the OpenServ runtime.
393
+ * Billed to the workspace/task in the action.
394
+ * Use this inside custom `run` functions when you need LLM generation without your own OpenAI key.
395
+ *
396
+ * @param params.prompt - The prompt for the LLM
397
+ * @param params.messages - Optional conversation history for context
398
+ * @param params.action - Action context (required for billing)
399
+ * @returns The generated text
400
+ */
401
+ generate(params: {
402
+ prompt: string;
403
+ messages?: ChatCompletionMessageParam[];
404
+ action: ActionSchema;
405
+ }): Promise<string>;
406
+ /**
407
+ * Generate a structured object via the OpenServ runtime.
408
+ * Billed to the workspace/task in the action.
409
+ *
410
+ * @param params.prompt - The prompt for the LLM
411
+ * @param params.messages - Optional conversation history for context
412
+ * @param params.outputSchema - Zod schema for structured output
413
+ * @param params.action - Action context (required for billing)
414
+ * @returns The generated object, validated against the schema
415
+ */
416
+ generate<T extends z.ZodTypeAny>(params: {
417
+ prompt: string;
418
+ messages?: ChatCompletionMessageParam[];
419
+ outputSchema: T;
420
+ action: ActionSchema;
421
+ }): Promise<z.infer<T>>;
373
422
  /**
374
423
  * Processes a conversation with OpenAI, handling tool calls iteratively until completion.
375
424
  *
@@ -394,15 +443,18 @@ export declare class Agent<M extends string = string> {
394
443
  /**
395
444
  * Handles execution of a specific tool/capability.
396
445
  *
446
+ * The runtime calls this for both task execution (do-task) and chat (respond-chat-message),
447
+ * always providing the action context in the request body.
448
+ *
397
449
  * @param {Object} req - The request object
398
450
  * @param {Object} req.params - Request parameters
399
451
  * @param {string} req.params.toolName - Name of the tool to execute
400
452
  * @param {Object} req.body - Request body
401
453
  * @param {z.infer<z.ZodTypeAny>} [req.body.args] - Arguments for the tool
402
- * @param {ActionSchema} [req.body.action] - Action context
454
+ * @param {ActionSchema} req.body.action - Action context (required)
403
455
  * @param {ChatCompletionMessageParam[]} [req.body.messages] - Message history
404
456
  * @returns {Promise<{result: string}>} The result of the tool execution
405
- * @throws {BadRequest} If tool name is missing or tool is not found
457
+ * @throws {BadRequest} If tool name is missing, tool is not found, or action is missing
406
458
  * @throws {Error} If tool execution fails
407
459
  */
408
460
  handleToolRoute(req: {
@@ -479,4 +531,5 @@ export declare class Agent<M extends string = string> {
479
531
  */
480
532
  private addMCPToolsAsCapabilities;
481
533
  }
534
+ export {};
482
535
  //# sourceMappingURL=agent.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}
package/dist/agent.js CHANGED
@@ -13,14 +13,61 @@ const helmet_1 = __importDefault(require("helmet"));
13
13
  const hpp_1 = __importDefault(require("hpp"));
14
14
  const logger_1 = require("./logger");
15
15
  const http_errors_1 = require("http-errors");
16
+ const openai_1 = __importDefault(require("openai"));
17
+ const zod_1 = require("zod");
16
18
  const zod_to_json_schema_1 = require("zod-to-json-schema");
17
19
  const json_schema_to_zod_1 = require("@n8n/json-schema-to-zod");
18
- const openai_1 = __importDefault(require("openai"));
20
+ // Zod v4 has native toJSONSchema/fromJSONSchema. For v3 we use third-party libs.
21
+ function zodToJsonSchema(schema, opts) {
22
+ if (typeof zod_1.z.toJSONSchema === 'function') {
23
+ return zod_1.z.toJSONSchema(schema);
24
+ }
25
+ return (0, zod_to_json_schema_1.zodToJsonSchema)(schema, opts);
26
+ }
27
+ function jsonSchemaToZodSchema(jsonSchema) {
28
+ if (typeof zod_1.z.fromJSONSchema === 'function') {
29
+ return zod_1.z.fromJSONSchema(jsonSchema);
30
+ }
31
+ return (0, json_schema_to_zod_1.jsonSchemaToZod)(jsonSchema);
32
+ }
19
33
  const capability_1 = require("./capability");
20
34
  const mcp_1 = require("./mcp");
21
35
  const PLATFORM_URL = process.env.OPENSERV_API_URL || 'https://api.openserv.ai';
22
36
  const RUNTIME_URL = process.env.OPENSERV_RUNTIME_URL || 'https://agents.openserv.ai';
23
37
  const DEFAULT_PORT = Number.parseInt(process.env.PORT || '') || 7378;
38
+ /** Default input schema for run-less capabilities that omit inputSchema */
39
+ const DEFAULT_INPUT_SCHEMA = zod_1.z.object({ input: zod_1.z.string() });
40
+ /** Runtime validation schema for capability configs */
41
+ const capabilityConfigSchema = zod_1.z
42
+ .object({
43
+ name: zod_1.z.string().min(1),
44
+ description: zod_1.z.string().min(1),
45
+ inputSchema: zod_1.z.any().optional(),
46
+ schema: zod_1.z.any().optional(),
47
+ run: zod_1.z.any().optional(),
48
+ outputSchema: zod_1.z.any().optional()
49
+ })
50
+ .superRefine((data, ctx) => {
51
+ if (data.inputSchema && data.schema) {
52
+ ctx.addIssue({
53
+ code: zod_1.z.ZodIssueCode.custom,
54
+ message: 'Cannot provide both "inputSchema" and "schema". Use "inputSchema" ("schema" is deprecated).'
55
+ });
56
+ }
57
+ if (data.run && data.outputSchema) {
58
+ ctx.addIssue({
59
+ code: zod_1.z.ZodIssueCode.custom,
60
+ message: 'Cannot provide both "run" and "outputSchema". "outputSchema" is only for run-less capabilities.'
61
+ });
62
+ }
63
+ if (!data.inputSchema && !data.schema && data.run) {
64
+ ctx.addIssue({
65
+ code: zod_1.z.ZodIssueCode.custom,
66
+ message: 'Runnable capabilities require "inputSchema" (or deprecated "schema"). ' +
67
+ 'Only run-less capabilities can omit it.'
68
+ });
69
+ }
70
+ });
24
71
  class Agent {
25
72
  options;
26
73
  /**
@@ -55,7 +102,8 @@ class Agent {
55
102
  systemPrompt;
56
103
  /**
57
104
  * Array of capabilities (tools) available to the agent.
58
- * Each capability is an instance of the Capability class with a name, description, schema, and run function.
105
+ * Each capability is an instance of the Capability class with a name, description, inputSchema,
106
+ * and optionally a run function and/or outputSchema.
59
107
  * @protected
60
108
  */
61
109
  tools = [];
@@ -127,7 +175,7 @@ class Agent {
127
175
  function: {
128
176
  name: tool.name,
129
177
  description: tool.description,
130
- parameters: (0, zod_to_json_schema_1.zodToJsonSchema)(tool.schema)
178
+ parameters: zodToJsonSchema(tool.inputSchema)
131
179
  }
132
180
  }));
133
181
  }
@@ -142,7 +190,8 @@ class Agent {
142
190
  if (!this._openai) {
143
191
  const apiKey = this.options.openaiApiKey || process.env.OPENAI_API_KEY;
144
192
  if (!apiKey) {
145
- throw new Error('OpenAI API key is required for process(). Please provide it in options or set OPENAI_API_KEY environment variable.');
193
+ throw new Error('OpenAI API key is required for process(). Provide it via options or OPENAI_API_KEY env var. ' +
194
+ 'Alternatively, use generate() for runtime-delegated LLM calls, or run-less capabilities.');
146
195
  }
147
196
  this._openai = new openai_1.default({ apiKey });
148
197
  }
@@ -180,41 +229,42 @@ class Agent {
180
229
  }
181
230
  /**
182
231
  * Adds a single capability (tool) to the agent.
183
- * Each capability must have a unique name and defines a function that can be called via the API.
232
+ * Each capability must have a unique name. Capabilities can be:
233
+ * - **Runnable**: has a `run` function and requires `inputSchema` (or deprecated `schema`)
234
+ * - **Run-less**: no `run` function -- the runtime handles execution via LLM.
235
+ * `inputSchema` is optional (defaults to `{ input: z.string() }`), `outputSchema` is optional.
184
236
  *
185
237
  * @template S - The Zod schema type for the capability's parameters
186
- * @param {Object} capability - The capability configuration
187
- * @param {string} capability.name - Unique name for the capability
188
- * @param {string} capability.description - Description of what the capability does
189
- * @param {S} capability.schema - Zod schema defining the capability's parameters
190
- * @param {Function} capability.run - Function that implements the capability's behavior
191
- * @param {Object} capability.run.params - Parameters for the run function
192
- * @param {z.infer<S>} capability.run.params.args - Validated arguments matching the schema
193
- * @param {ActionSchema} [capability.run.params.action] - Optional action context
194
- * @param {ChatCompletionMessageParam[]} capability.run.messages - Chat message history
195
- * @returns {this} The agent instance for method chaining
238
+ * @param capability - The capability configuration
239
+ * @returns The agent instance for method chaining
196
240
  * @throws {Error} If a capability with the same name already exists
241
+ * @throws {Error} If both `inputSchema` and `schema` are provided
242
+ * @throws {Error} If both `run` and `outputSchema` are provided
243
+ * @throws {Error} If a runnable capability omits `inputSchema`/`schema`
197
244
  */
198
- addCapability({ name, description, schema, run }) {
199
- // Validate tool name uniqueness
245
+ addCapability(capability) {
246
+ const result = capabilityConfigSchema.safeParse(capability);
247
+ if (!result.success) {
248
+ throw new Error(result.error.issues[0]?.message ?? 'Invalid capability configuration');
249
+ }
250
+ const { name, description, run, outputSchema } = result.data;
251
+ const resolvedSchema = (result.data.inputSchema ??
252
+ result.data.schema ??
253
+ DEFAULT_INPUT_SCHEMA);
200
254
  if (this.tools.some(tool => tool.name === name)) {
201
255
  throw new Error(`Tool with name "${name}" already exists`);
202
256
  }
203
- // Type assertion through unknown for safe conversion between compatible generic types
204
- this.tools.push(new capability_1.Capability(name, description, schema, run));
257
+ this.tools.push(new capability_1.Capability(name, description, resolvedSchema, typeof run === 'function' ? run : undefined, outputSchema));
205
258
  return this;
206
259
  }
207
260
  /**
208
261
  * Adds multiple capabilities (tools) to the agent at once.
209
262
  * Each capability must have a unique name and not conflict with existing capabilities.
263
+ * Each element can be runnable or run-less independently.
210
264
  *
211
265
  * @template T - Tuple of Zod schema types for the capabilities' parameters
212
- * @param {Object} capabilities - Array of capability configurations
213
- * @param {string} capabilities[].name - Unique name for each capability
214
- * @param {string} capabilities[].description - Description of what each capability does
215
- * @param {T[number]} capabilities[].schema - Zod schema defining each capability's parameters
216
- * @param {Function} capabilities[].run - Function that implements each capability's behavior
217
- * @returns {this} The agent instance for method chaining
266
+ * @param capabilities - Array of capability configurations
267
+ * @returns The agent instance for method chaining
218
268
  * @throws {Error} If any capability has a name that already exists
219
269
  */
220
270
  addCapabilities(capabilities) {
@@ -479,6 +529,24 @@ class Agent {
479
529
  });
480
530
  return response.data;
481
531
  }
532
+ async generate(params) {
533
+ const response = await this.runtimeClient.post('/generate', {
534
+ prompt: params.prompt,
535
+ ...(params.messages ? { messages: params.messages } : {}),
536
+ ...(params.outputSchema ? { outputSchema: zodToJsonSchema(params.outputSchema) } : {}),
537
+ action: params.action
538
+ });
539
+ if (params.outputSchema) {
540
+ if (response.data.object === undefined || response.data.object === null) {
541
+ throw new Error('Runtime returned no structured output for generate() with outputSchema');
542
+ }
543
+ return params.outputSchema.parse(response.data.object);
544
+ }
545
+ if (typeof response.data.text !== 'string') {
546
+ throw new Error('Runtime returned no text for generate()');
547
+ }
548
+ return response.data.text;
549
+ }
482
550
  /**
483
551
  * Processes a conversation with OpenAI, handling tool calls iteratively until completion.
484
552
  *
@@ -491,7 +559,8 @@ class Agent {
491
559
  try {
492
560
  const apiKey = this.options.openaiApiKey || process.env.OPENAI_API_KEY;
493
561
  if (!apiKey) {
494
- throw new Error('OpenAI API key is required for process(). Please provide it in options or set OPENAI_API_KEY environment variable.');
562
+ throw new Error('OpenAI API key is required for process(). Provide it via options or OPENAI_API_KEY env var. ' +
563
+ 'Alternatively, use generate() for runtime-delegated LLM calls, or run-less capabilities.');
495
564
  }
496
565
  const currentMessages = [...messages];
497
566
  if (!currentMessages.find(m => m.content === this.systemPrompt)) {
@@ -530,8 +599,35 @@ class Agent {
530
599
  if (!tool) {
531
600
  throw new Error(`Tool "${name}" not found`);
532
601
  }
533
- // Call the tool's run method with the parsed arguments and bind this
534
- const result = await tool.run.bind(this)({ args: parsedArgs }, currentMessages);
602
+ let result;
603
+ if (tool.run) {
604
+ // Call the tool's run method with the parsed arguments and bind this
605
+ result = await tool.run.bind(this)({ args: parsedArgs }, currentMessages);
606
+ }
607
+ else {
608
+ // Shim: use OpenAI with conversation history + description for run-less capabilities
609
+ const shimCompletion = await this.openai.chat.completions.create({
610
+ model: 'gpt-4o',
611
+ messages: [
612
+ ...currentMessages,
613
+ { role: 'system', content: tool.description },
614
+ { role: 'user', content: JSON.stringify(parsedArgs) }
615
+ ],
616
+ ...(tool.outputSchema
617
+ ? {
618
+ response_format: {
619
+ type: 'json_schema',
620
+ json_schema: {
621
+ name: tool.name,
622
+ schema: zodToJsonSchema(tool.outputSchema),
623
+ strict: true
624
+ }
625
+ }
626
+ }
627
+ : {})
628
+ });
629
+ result = shimCompletion.choices[0]?.message?.content || '';
630
+ }
535
631
  return {
536
632
  role: 'tool',
537
633
  content: JSON.stringify(result),
@@ -582,9 +678,12 @@ class Agent {
582
678
  content: action.task.description
583
679
  });
584
680
  }
681
+ const proxyTools = this.tools.filter(t => t.run);
682
+ const runtimeTools = this.tools.filter(t => !t.run);
585
683
  try {
586
684
  await this.runtimeClient.post('/execute', {
587
- tools: this.tools.map(convertToolToJsonSchema),
685
+ tools: proxyTools.map(convertProxyToolToJsonSchema),
686
+ runtimeTools: runtimeTools.map(convertRuntimeToolToJsonSchema),
588
687
  messages,
589
688
  action
590
689
  });
@@ -616,9 +715,12 @@ class Agent {
616
715
  });
617
716
  }
618
717
  }
718
+ const proxyTools = this.tools.filter(t => t.run);
719
+ const runtimeTools = this.tools.filter(t => !t.run);
619
720
  try {
620
721
  await this.runtimeClient.post('/chat', {
621
- tools: this.tools.map(convertToolToJsonSchema),
722
+ tools: proxyTools.map(convertProxyToolToJsonSchema),
723
+ runtimeTools: runtimeTools.map(convertRuntimeToolToJsonSchema),
622
724
  messages,
623
725
  action
624
726
  });
@@ -633,15 +735,18 @@ class Agent {
633
735
  /**
634
736
  * Handles execution of a specific tool/capability.
635
737
  *
738
+ * The runtime calls this for both task execution (do-task) and chat (respond-chat-message),
739
+ * always providing the action context in the request body.
740
+ *
636
741
  * @param {Object} req - The request object
637
742
  * @param {Object} req.params - Request parameters
638
743
  * @param {string} req.params.toolName - Name of the tool to execute
639
744
  * @param {Object} req.body - Request body
640
745
  * @param {z.infer<z.ZodTypeAny>} [req.body.args] - Arguments for the tool
641
- * @param {ActionSchema} [req.body.action] - Action context
746
+ * @param {ActionSchema} req.body.action - Action context (required)
642
747
  * @param {ChatCompletionMessageParam[]} [req.body.messages] - Message history
643
748
  * @returns {Promise<{result: string}>} The result of the tool execution
644
- * @throws {BadRequest} If tool name is missing or tool is not found
749
+ * @throws {BadRequest} If tool name is missing, tool is not found, or action is missing
645
750
  * @throws {Error} If tool execution fails
646
751
  */
647
752
  async handleToolRoute(req) {
@@ -653,7 +758,13 @@ class Agent {
653
758
  if (!tool) {
654
759
  throw new http_errors_1.BadRequest(`Tool "${req.params.toolName}" not found`);
655
760
  }
656
- const args = await tool.schema.parseAsync(req.body?.args);
761
+ if (!tool.run) {
762
+ throw new http_errors_1.BadRequest(`Tool "${req.params.toolName}" is a run-less capability handled by the runtime, not by this agent.`);
763
+ }
764
+ if (!req.body?.action) {
765
+ throw new http_errors_1.BadRequest('Action context is required for tool execution');
766
+ }
767
+ const args = await tool.inputSchema.parseAsync(req.body?.args);
657
768
  const messages = req.body.messages || [];
658
769
  const result = await tool.run.call(this, { args, action: req.body.action }, messages);
659
770
  return { result };
@@ -905,7 +1016,7 @@ class Agent {
905
1016
  this.addCapability({
906
1017
  name: capabilityName,
907
1018
  description: tool.description || `Tool from MCP server ${serverId}`,
908
- schema: (0, json_schema_to_zod_1.jsonSchemaToZod)(inputSchema),
1019
+ inputSchema: jsonSchemaToZodSchema(inputSchema),
909
1020
  async run({ args }) {
910
1021
  const mcpClient = this.mcpClients[serverId];
911
1022
  if (!mcpClient) {
@@ -930,10 +1041,18 @@ class Agent {
930
1041
  }
931
1042
  }
932
1043
  exports.Agent = Agent;
933
- function convertToolToJsonSchema(tool) {
1044
+ function convertProxyToolToJsonSchema(tool) {
1045
+ return {
1046
+ name: tool.name,
1047
+ description: tool.description,
1048
+ schema: zodToJsonSchema(tool.inputSchema)
1049
+ };
1050
+ }
1051
+ function convertRuntimeToolToJsonSchema(tool) {
934
1052
  return {
935
1053
  name: tool.name,
936
1054
  description: tool.description,
937
- schema: (0, zod_to_json_schema_1.zodToJsonSchema)(tool.schema)
1055
+ schema: zodToJsonSchema(tool.inputSchema),
1056
+ ...(tool.outputSchema ? { outputSchema: zodToJsonSchema(tool.outputSchema) } : {})
938
1057
  };
939
1058
  }
@@ -5,8 +5,11 @@ import type { Agent } from './agent';
5
5
  export declare class Capability<M extends string, Schema extends z.ZodTypeAny> {
6
6
  readonly name: string;
7
7
  readonly description: string;
8
+ readonly run?: ((this: Agent<M>, params: CapabilityFuncParams<Schema>, messages: ChatCompletionMessageParam[]) => string | Promise<string>) | undefined;
9
+ readonly outputSchema?: z.ZodTypeAny | undefined;
10
+ readonly inputSchema: Schema;
11
+ /** @deprecated Use `inputSchema` instead */
8
12
  readonly schema: Schema;
9
- readonly run: (this: Agent<M>, params: CapabilityFuncParams<Schema>, messages: ChatCompletionMessageParam[]) => string | Promise<string>;
10
- constructor(name: string, description: string, schema: Schema, run: (this: Agent<M>, params: CapabilityFuncParams<Schema>, messages: ChatCompletionMessageParam[]) => string | Promise<string>);
13
+ constructor(name: string, description: string, inputSchema: Schema, run?: ((this: Agent<M>, params: CapabilityFuncParams<Schema>, messages: ChatCompletionMessageParam[]) => string | Promise<string>) | undefined, outputSchema?: z.ZodTypeAny | undefined);
11
14
  }
12
15
  //# sourceMappingURL=capability.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"capability.d.ts","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAC5B,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,mCAAmC,CAAA;AACnF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAA;AACnD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAEpC,qBAAa,UAAU,CAAC,CAAC,SAAS,MAAM,EAAE,MAAM,SAAS,CAAC,CAAC,UAAU;aAEjD,IAAI,EAAE,MAAM;aACZ,WAAW,EAAE,MAAM;aACnB,MAAM,EAAE,MAAM;aACd,GAAG,EAAE,CACnB,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EACd,MAAM,EAAE,oBAAoB,CAAC,MAAM,CAAC,EACpC,QAAQ,EAAE,0BAA0B,EAAE,KACnC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;gBAPb,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,CACnB,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EACd,MAAM,EAAE,oBAAoB,CAAC,MAAM,CAAC,EACpC,QAAQ,EAAE,0BAA0B,EAAE,KACnC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAEhC"}
1
+ {"version":3,"file":"capability.d.ts","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAC5B,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,mCAAmC,CAAA;AACnF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAA;AACnD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAEpC,qBAAa,UAAU,CAAC,CAAC,SAAS,MAAM,EAAE,MAAM,SAAS,CAAC,CAAC,UAAU;aAMjD,IAAI,EAAE,MAAM;aACZ,WAAW,EAAE,MAAM;aAEnB,GAAG,CAAC,GAAE,CACpB,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EACd,MAAM,EAAE,oBAAoB,CAAC,MAAM,CAAC,EACpC,QAAQ,EAAE,0BAA0B,EAAE,KACnC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;aACb,YAAY,CAAC,EAAE,CAAC,CAAC,UAAU;IAb7C,SAAgB,WAAW,EAAE,MAAM,CAAA;IACnC,4CAA4C;IAC5C,SAAgB,MAAM,EAAE,MAAM,CAAA;gBAGZ,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnC,WAAW,EAAE,MAAM,EACH,GAAG,CAAC,GAAE,CACpB,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EACd,MAAM,EAAE,oBAAoB,CAAC,MAAM,CAAC,EACpC,QAAQ,EAAE,0BAA0B,EAAE,KACnC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,aAAA,EACb,YAAY,CAAC,EAAE,CAAC,CAAC,UAAU,YAAA;CAK9C"}
@@ -4,13 +4,18 @@ exports.Capability = void 0;
4
4
  class Capability {
5
5
  name;
6
6
  description;
7
- schema;
8
7
  run;
9
- constructor(name, description, schema, run) {
8
+ outputSchema;
9
+ inputSchema;
10
+ /** @deprecated Use `inputSchema` instead */
11
+ schema;
12
+ constructor(name, description, inputSchema, run, outputSchema) {
10
13
  this.name = name;
11
14
  this.description = description;
12
- this.schema = schema;
13
15
  this.run = run;
16
+ this.outputSchema = outputSchema;
17
+ this.inputSchema = inputSchema;
18
+ this.schema = inputSchema;
14
19
  }
15
20
  }
16
21
  exports.Capability = Capability;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { Agent } from './agent';
2
- export type { AgentOptions } from './agent';
2
+ export type { AgentOptions, CapabilityConfig } from './agent';
3
3
  export { Capability } from './capability';
4
4
  export { OpenServTunnel } from './tunnel';
5
5
  export type { OpenServTunnelOptions, RequestData, ResponseData, TunnelState, TunnelEvent } from './tunnel';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAC/B,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AACzC,YAAY,EACV,qBAAqB,EACrB,WAAW,EACX,YAAY,EACZ,WAAW,EACX,WAAW,EACZ,MAAM,UAAU,CAAA;AACjB,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAA;AAC3B,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAElD,YAAY,EACV,UAAU,EACV,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,uBAAuB,EACvB,kBAAkB,EAClB,qBAAqB,EACrB,mBAAmB,EACnB,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,4BAA4B,EAC5B,sBAAsB,EACtB,aAAa,EACb,oBAAoB,EACpB,qBAAqB,EACtB,MAAM,SAAS,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAC/B,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AACzC,YAAY,EACV,qBAAqB,EACrB,WAAW,EACX,YAAY,EACZ,WAAW,EACX,WAAW,EACZ,MAAM,UAAU,CAAA;AACjB,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAA;AAC3B,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAElD,YAAY,EACV,UAAU,EACV,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,uBAAuB,EACvB,kBAAkB,EAClB,qBAAqB,EACrB,mBAAmB,EACnB,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,4BAA4B,EAC5B,sBAAsB,EACtB,aAAa,EACb,oBAAoB,EACpB,qBAAqB,EACtB,MAAM,SAAS,CAAA"}
package/dist/run.d.ts CHANGED
@@ -45,7 +45,7 @@ export interface RunResult {
45
45
  * agent.addCapability({
46
46
  * name: 'greet',
47
47
  * description: 'Greet someone',
48
- * schema: z.object({ name: z.string() }),
48
+ * inputSchema: z.object({ name: z.string() }),
49
49
  * run: async ({ args }) => `Hello, ${args.name}!`
50
50
  * })
51
51
  *
package/dist/run.js CHANGED
@@ -28,7 +28,7 @@ const tunnel_1 = require("./tunnel");
28
28
  * agent.addCapability({
29
29
  * name: 'greet',
30
30
  * description: 'Greet someone',
31
- * schema: z.object({ name: z.string() }),
31
+ * inputSchema: z.object({ name: z.string() }),
32
32
  * run: async ({ args }) => `Hello, ${args.name}!`
33
33
  * })
34
34
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openserv-labs/sdk",
3
- "version": "2.3.0",
3
+ "version": "2.4.1",
4
4
  "description": "OpenServ Agent SDK - Create AI agents easily",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -44,7 +44,6 @@
44
44
  "dependencies": {
45
45
  "@asteasolutions/zod-to-openapi": "^7.3.0",
46
46
  "@modelcontextprotocol/sdk": "^1.10.2",
47
- "@n8n/json-schema-to-zod": "^1.1.0",
48
47
  "axios": "^1.6.8",
49
48
  "axios-retry": "^4.1.0",
50
49
  "bcryptjs": "^3.0.2",
@@ -57,8 +56,8 @@
57
56
  "pino": "^9.6.0",
58
57
  "pino-pretty": "^13.1.3",
59
58
  "ws": "^8.18.0",
60
- "zod": "^3.22.4",
61
- "zod-to-json-schema": "^3.22.4"
59
+ "zod-to-json-schema": "^3.25.0",
60
+ "@n8n/json-schema-to-zod": "^1.1.0"
62
61
  },
63
62
  "devDependencies": {
64
63
  "@tsconfig/strictest": "^2.0.3",
@@ -92,6 +91,7 @@
92
91
  "node": ">=18.0.0"
93
92
  },
94
93
  "peerDependencies": {
95
- "openai": "^5.0.1"
94
+ "openai": "^5.0.1",
95
+ "zod": "^3.22.4 || ^4.0.0"
96
96
  }
97
97
  }