@robota-sdk/agent-tools 3.0.0-beta.52 → 3.0.0-beta.54

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.
@@ -294,6 +294,87 @@ function isRequiredField(typeObj) {
294
294
  return typeDef.typeName !== "ZodOptional" && typeDef.typeName !== "ZodNullable" && typeDef.typeName !== "ZodDefault";
295
295
  }
296
296
 
297
+ // src/implementations/function-tool/parameter-validator.ts
298
+ function validateParameterType(key, value, schema) {
299
+ const expectedType = schema["type"];
300
+ switch (expectedType) {
301
+ case "string":
302
+ if (typeof value !== "string") {
303
+ return `Parameter "${key}" must be a string, got ${typeof value}`;
304
+ }
305
+ break;
306
+ case "number":
307
+ if (typeof value !== "number" || isNaN(value)) {
308
+ return `Parameter "${key}" must be a number, got ${typeof value}`;
309
+ }
310
+ break;
311
+ case "boolean":
312
+ if (typeof value !== "boolean") {
313
+ return `Parameter "${key}" must be a boolean, got ${typeof value}`;
314
+ }
315
+ break;
316
+ case "array":
317
+ if (!Array.isArray(value)) {
318
+ return `Parameter "${key}" must be an array, got ${typeof value}`;
319
+ }
320
+ if (schema.items) {
321
+ for (let i = 0; i < value.length; i++) {
322
+ const itemError = validateParameterType(`${key}[${i}]`, value[i], schema.items);
323
+ if (itemError) {
324
+ return itemError;
325
+ }
326
+ }
327
+ }
328
+ break;
329
+ case "object":
330
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
331
+ return `Parameter "${key}" must be an object, got ${typeof value}`;
332
+ }
333
+ break;
334
+ }
335
+ if (schema.enum && schema.enum.length > 0) {
336
+ const enumValues = schema.enum;
337
+ let isValidEnum = false;
338
+ for (const enumValue of enumValues) {
339
+ if (value === enumValue) {
340
+ isValidEnum = true;
341
+ break;
342
+ }
343
+ }
344
+ if (!isValidEnum) {
345
+ return `Parameter "${key}" must be one of: ${enumValues.join(", ")}, got ${value}`;
346
+ }
347
+ }
348
+ return void 0;
349
+ }
350
+ function getValidationErrors(parameters, schemaRequired, schemaProperties) {
351
+ const errors = [];
352
+ for (const field of schemaRequired) {
353
+ if (!(field in parameters)) {
354
+ errors.push(`Missing required parameter: ${field}`);
355
+ }
356
+ }
357
+ for (const [key, value] of Object.entries(parameters)) {
358
+ const paramSchema = schemaProperties[key];
359
+ if (!paramSchema) {
360
+ errors.push(`Unknown parameter: ${key}`);
361
+ continue;
362
+ }
363
+ const typeError = validateParameterType(key, value, paramSchema);
364
+ if (typeError) {
365
+ errors.push(typeError);
366
+ }
367
+ }
368
+ return errors;
369
+ }
370
+ function validateToolParameters(parameters, schemaRequired, schemaProperties) {
371
+ const errors = getValidationErrors(parameters, schemaRequired, schemaProperties);
372
+ return {
373
+ isValid: errors.length === 0,
374
+ errors
375
+ };
376
+ }
377
+
297
378
  // src/implementations/function-tool.ts
298
379
  var FunctionTool = class {
299
380
  schema;
@@ -324,7 +405,11 @@ var FunctionTool = class {
324
405
  async execute(parameters, context) {
325
406
  const toolName = this.schema.name;
326
407
  if (!this.validate(parameters)) {
327
- const errors = this.getValidationErrors(parameters);
408
+ const errors = getValidationErrors(
409
+ parameters,
410
+ this.schema.parameters.required || [],
411
+ this.schema.parameters.properties || {}
412
+ );
328
413
  throw new import_agent_core3.ValidationError(`Invalid parameters for tool "${toolName}": ${errors.join(", ")}`);
329
414
  }
330
415
  const startTime = Date.now();
@@ -360,17 +445,21 @@ var FunctionTool = class {
360
445
  * Validate parameters (simple boolean result)
361
446
  */
362
447
  validate(parameters) {
363
- return this.getValidationErrors(parameters).length === 0;
448
+ return getValidationErrors(
449
+ parameters,
450
+ this.schema.parameters.required || [],
451
+ this.schema.parameters.properties || {}
452
+ ).length === 0;
364
453
  }
365
454
  /**
366
455
  * Validate tool parameters with detailed result
367
456
  */
368
457
  validateParameters(parameters) {
369
- const errors = this.getValidationErrors(parameters);
370
- return {
371
- isValid: errors.length === 0,
372
- errors
373
- };
458
+ return validateToolParameters(
459
+ parameters,
460
+ this.schema.parameters.required || [],
461
+ this.schema.parameters.properties || {}
462
+ );
374
463
  }
375
464
  /**
376
465
  * Get tool description
@@ -378,86 +467,6 @@ var FunctionTool = class {
378
467
  getDescription() {
379
468
  return this.schema.description;
380
469
  }
381
- /**
382
- * Get detailed validation errors
383
- */
384
- getValidationErrors(parameters) {
385
- const errors = [];
386
- const required = this.schema.parameters.required || [];
387
- const properties = this.schema.parameters.properties || {};
388
- for (const field of required) {
389
- if (!(field in parameters)) {
390
- errors.push(`Missing required parameter: ${field}`);
391
- }
392
- }
393
- for (const [key, value] of Object.entries(parameters)) {
394
- const paramSchema = properties[key];
395
- if (!paramSchema) {
396
- errors.push(`Unknown parameter: ${key}`);
397
- continue;
398
- }
399
- const typeError = this.validateParameterType(key, value, paramSchema);
400
- if (typeError) {
401
- errors.push(typeError);
402
- }
403
- }
404
- return errors;
405
- }
406
- /**
407
- * Validate individual parameter type
408
- */
409
- validateParameterType(key, value, schema) {
410
- const expectedType = schema["type"];
411
- switch (expectedType) {
412
- case "string":
413
- if (typeof value !== "string") {
414
- return `Parameter "${key}" must be a string, got ${typeof value}`;
415
- }
416
- break;
417
- case "number":
418
- if (typeof value !== "number" || isNaN(value)) {
419
- return `Parameter "${key}" must be a number, got ${typeof value}`;
420
- }
421
- break;
422
- case "boolean":
423
- if (typeof value !== "boolean") {
424
- return `Parameter "${key}" must be a boolean, got ${typeof value}`;
425
- }
426
- break;
427
- case "array":
428
- if (!Array.isArray(value)) {
429
- return `Parameter "${key}" must be an array, got ${typeof value}`;
430
- }
431
- if (schema.items) {
432
- for (let i = 0; i < value.length; i++) {
433
- const itemError = this.validateParameterType(`${key}[${i}]`, value[i], schema.items);
434
- if (itemError) {
435
- return itemError;
436
- }
437
- }
438
- }
439
- break;
440
- case "object":
441
- if (typeof value !== "object" || value === null || Array.isArray(value)) {
442
- return `Parameter "${key}" must be an object, got ${typeof value}`;
443
- }
444
- break;
445
- }
446
- if (schema.enum && schema.enum.length > 0) {
447
- const enumValues = schema.enum;
448
- let isValidEnum = false;
449
- for (const enumValue of enumValues) {
450
- if (value === enumValue) {
451
- isValidEnum = true;
452
- break;
453
- }
454
- }
455
- if (!isValidEnum) {
456
- return `Parameter "${key}" must be one of: ${enumValues.join(", ")}, got ${value}`;
457
- }
458
- }
459
- return void 0;
460
- }
461
470
  /**
462
471
  * Validate constructor inputs
463
472
  */
@@ -501,6 +510,132 @@ function createZodFunctionTool(name, description, zodSchema, fn) {
501
510
 
502
511
  // src/implementations/openapi-tool.ts
503
512
  var import_agent_core4 = require("@robota-sdk/agent-core");
513
+
514
+ // src/implementations/openapi-schema-converter.ts
515
+ var HTTP_METHODS = [
516
+ "get",
517
+ "post",
518
+ "put",
519
+ "delete",
520
+ "patch",
521
+ "head",
522
+ "options"
523
+ ];
524
+ function findOperation(apiSpec, operationId) {
525
+ for (const [path, pathItem] of Object.entries(apiSpec.paths || {})) {
526
+ if (!pathItem) continue;
527
+ for (const method of HTTP_METHODS) {
528
+ const operation = pathItem[method];
529
+ if (operation?.operationId === operationId) {
530
+ return { method, path, operation };
531
+ }
532
+ }
533
+ }
534
+ return void 0;
535
+ }
536
+ function mapOpenAPIType(type) {
537
+ switch (type) {
538
+ case "string":
539
+ return "string";
540
+ case "number":
541
+ return "number";
542
+ case "integer":
543
+ return "integer";
544
+ case "boolean":
545
+ return "boolean";
546
+ case "array":
547
+ return "array";
548
+ case "object":
549
+ return "object";
550
+ default:
551
+ return "string";
552
+ }
553
+ }
554
+ function convertOpenAPISchemaToParameterSchema(schema) {
555
+ if ("$ref" in schema) {
556
+ return { type: "object" };
557
+ }
558
+ const result = {
559
+ type: mapOpenAPIType(schema.type)
560
+ };
561
+ if (schema.description) {
562
+ result.description = schema.description;
563
+ }
564
+ if (schema.enum) {
565
+ result.enum = schema.enum;
566
+ }
567
+ if (schema.minimum !== void 0) {
568
+ result.minimum = schema.minimum;
569
+ }
570
+ if (schema.maximum !== void 0) {
571
+ result.maximum = schema.maximum;
572
+ }
573
+ if (schema.pattern) {
574
+ result.pattern = schema.pattern;
575
+ }
576
+ if (schema.format) {
577
+ result.format = schema.format;
578
+ }
579
+ if (schema.default !== void 0) {
580
+ result.default = schema.default;
581
+ }
582
+ if (schema.type === "array" && schema.items) {
583
+ result.items = convertOpenAPISchemaToParameterSchema(schema.items);
584
+ }
585
+ if (schema.type === "object" && schema.properties) {
586
+ result.properties = {};
587
+ for (const [propName, propSchema] of Object.entries(schema.properties)) {
588
+ result.properties[propName] = convertOpenAPISchemaToParameterSchema(propSchema);
589
+ }
590
+ if (schema.required && schema.required.length > 0) {
591
+ result.required = schema.required;
592
+ }
593
+ }
594
+ return result;
595
+ }
596
+ function convertOpenAPIParamToSchema(param) {
597
+ const schema = param.schema;
598
+ return convertOpenAPISchemaToParameterSchema(schema);
599
+ }
600
+ function createSchemaFromOperation(operationId, opSpec) {
601
+ const properties = {};
602
+ const required = [];
603
+ const params = opSpec.parameters || [];
604
+ for (const param of params) {
605
+ properties[param.name] = convertOpenAPIParamToSchema(param);
606
+ if (param.required) {
607
+ required.push(param.name);
608
+ }
609
+ }
610
+ if (opSpec.requestBody) {
611
+ const requestBody = opSpec.requestBody;
612
+ const jsonContent = requestBody.content?.["application/json"];
613
+ if (jsonContent?.schema) {
614
+ const bodySchema = convertOpenAPISchemaToParameterSchema(jsonContent.schema);
615
+ if (bodySchema.type === "object" && bodySchema.properties) {
616
+ Object.assign(properties, bodySchema.properties);
617
+ const schemaWithRequired = bodySchema;
618
+ if (schemaWithRequired.required) {
619
+ required.push(...schemaWithRequired.required);
620
+ }
621
+ }
622
+ }
623
+ }
624
+ const schemaParams = {
625
+ type: "object",
626
+ properties
627
+ };
628
+ if (required.length > 0) {
629
+ schemaParams.required = required;
630
+ }
631
+ return {
632
+ name: operationId,
633
+ description: opSpec.summary || opSpec.description || `OpenAPI operation: ${operationId}`,
634
+ parameters: schemaParams
635
+ };
636
+ }
637
+
638
+ // src/implementations/openapi-tool.ts
504
639
  var OpenAPITool = class {
505
640
  schema;
506
641
  apiSpec;
@@ -607,36 +742,13 @@ var OpenAPITool = class {
607
742
  * @private
608
743
  */
609
744
  async executeAPICall(parameters, _context) {
610
- const operation = this.findOperation();
745
+ const operation = findOperation(this.apiSpec, this.operationId);
611
746
  if (!operation) {
612
747
  throw new Error(`Operation ${this.operationId} not found in OpenAPI spec`);
613
748
  }
614
- const requestConfig = this.buildRequestConfig(operation, parameters);
749
+ this.buildRequestConfig(operation, parameters);
615
750
  throw new Error("Not implemented: actual API execution is not yet available");
616
751
  }
617
- /**
618
- * Find the operation in the OpenAPI specification
619
- */
620
- findOperation() {
621
- for (const [path, pathItem] of Object.entries(this.apiSpec.paths || {})) {
622
- if (!pathItem) continue;
623
- for (const method of [
624
- "get",
625
- "post",
626
- "put",
627
- "delete",
628
- "patch",
629
- "head",
630
- "options"
631
- ]) {
632
- const operation = pathItem[method];
633
- if (operation?.operationId === this.operationId) {
634
- return { method, path, operation };
635
- }
636
- }
637
- }
638
- return void 0;
639
- }
640
752
  /**
641
753
  * Build HTTP request configuration from OpenAPI operation and parameters
642
754
  */
@@ -708,121 +820,13 @@ var OpenAPITool = class {
708
820
  * Create tool schema from OpenAPI operation specification
709
821
  */
710
822
  createSchemaFromOpenAPI() {
711
- const operation = this.findOperation();
823
+ const operation = findOperation(this.apiSpec, this.operationId);
712
824
  if (!operation) {
713
825
  throw new Error(
714
826
  `[STRICT-POLICY][EMITTER-CONTRACT] OpenAPI operation not found: ${this.operationId}. Emitter contract must provide a valid operationId present in the OpenAPI document.`
715
827
  );
716
828
  }
717
- const { operation: opSpec } = operation;
718
- const properties = {};
719
- const required = [];
720
- const params = opSpec.parameters || [];
721
- for (const param of params) {
722
- properties[param.name] = this.convertOpenAPIParamToSchema(param);
723
- if (param.required) {
724
- required.push(param.name);
725
- }
726
- }
727
- if (opSpec.requestBody) {
728
- const requestBody = opSpec.requestBody;
729
- const jsonContent = requestBody.content?.["application/json"];
730
- if (jsonContent?.schema) {
731
- const bodySchema = this.convertOpenAPISchemaToParameterSchema(jsonContent.schema);
732
- if (bodySchema.type === "object" && bodySchema.properties) {
733
- Object.assign(properties, bodySchema.properties);
734
- const schemaWithRequired = bodySchema;
735
- if (schemaWithRequired.required) {
736
- required.push(...schemaWithRequired.required);
737
- }
738
- }
739
- }
740
- }
741
- const schemaParams = {
742
- type: "object",
743
- properties
744
- };
745
- if (required.length > 0) {
746
- schemaParams.required = required;
747
- }
748
- return {
749
- name: this.operationId,
750
- description: opSpec.summary || opSpec.description || `OpenAPI operation: ${this.operationId}`,
751
- parameters: schemaParams
752
- };
753
- }
754
- /**
755
- * Convert OpenAPI parameter to tool parameter schema
756
- */
757
- convertOpenAPIParamToSchema(param) {
758
- const schema = param.schema;
759
- return this.convertOpenAPISchemaToParameterSchema(schema);
760
- }
761
- /**
762
- * Convert OpenAPI schema to parameter schema
763
- */
764
- convertOpenAPISchemaToParameterSchema(schema) {
765
- if ("$ref" in schema) {
766
- return { type: "object" };
767
- }
768
- const result = {
769
- type: this.mapOpenAPIType(schema.type)
770
- };
771
- if (schema.description) {
772
- result.description = schema.description;
773
- }
774
- if (schema.enum) {
775
- result.enum = schema.enum;
776
- }
777
- if (schema.minimum !== void 0) {
778
- result.minimum = schema.minimum;
779
- }
780
- if (schema.maximum !== void 0) {
781
- result.maximum = schema.maximum;
782
- }
783
- if (schema.pattern) {
784
- result.pattern = schema.pattern;
785
- }
786
- if (schema.format) {
787
- result.format = schema.format;
788
- }
789
- if (schema.default !== void 0) {
790
- result.default = schema.default;
791
- }
792
- if (schema.type === "array" && schema.items) {
793
- result.items = this.convertOpenAPISchemaToParameterSchema(schema.items);
794
- }
795
- if (schema.type === "object" && schema.properties) {
796
- result.properties = {};
797
- for (const [propName, propSchema] of Object.entries(schema.properties)) {
798
- result.properties[propName] = this.convertOpenAPISchemaToParameterSchema(propSchema);
799
- }
800
- if (schema.required && schema.required.length > 0) {
801
- result.required = schema.required;
802
- }
803
- }
804
- return result;
805
- }
806
- /**
807
- * Map OpenAPI type to JSON schema type
808
- */
809
- mapOpenAPIType(type) {
810
- switch (type) {
811
- case "string":
812
- return "string";
813
- case "number":
814
- return "number";
815
- case "integer":
816
- return "integer";
817
- case "boolean":
818
- return "boolean";
819
- case "array":
820
- return "array";
821
- case "object":
822
- return "object";
823
- default:
824
- return "string";
825
- }
829
+ return createSchemaFromOperation(this.operationId, operation.operation);
826
830
  }
827
831
  };
828
832
  function createOpenAPITool(config) {
@@ -174,14 +174,6 @@ declare class FunctionTool implements IFunctionTool {
174
174
  * Get tool description
175
175
  */
176
176
  getDescription(): string;
177
- /**
178
- * Get detailed validation errors
179
- */
180
- private getValidationErrors;
181
- /**
182
- * Validate individual parameter type
183
- */
184
- private validateParameterType;
185
177
  /**
186
178
  * Validate constructor inputs
187
179
  */
@@ -240,10 +232,6 @@ declare class OpenAPITool implements ITool {
240
232
  * @private
241
233
  */
242
234
  private executeAPICall;
243
- /**
244
- * Find the operation in the OpenAPI specification
245
- */
246
- private findOperation;
247
235
  /**
248
236
  * Build HTTP request configuration from OpenAPI operation and parameters
249
237
  */
@@ -252,18 +240,6 @@ declare class OpenAPITool implements ITool {
252
240
  * Create tool schema from OpenAPI operation specification
253
241
  */
254
242
  private createSchemaFromOpenAPI;
255
- /**
256
- * Convert OpenAPI parameter to tool parameter schema
257
- */
258
- private convertOpenAPIParamToSchema;
259
- /**
260
- * Convert OpenAPI schema to parameter schema
261
- */
262
- private convertOpenAPISchemaToParameterSchema;
263
- /**
264
- * Map OpenAPI type to JSON schema type
265
- */
266
- private mapOpenAPIType;
267
243
  }
268
244
  /**
269
245
  * Factory function to create OpenAPI tools from specification
@@ -174,14 +174,6 @@ declare class FunctionTool implements IFunctionTool {
174
174
  * Get tool description
175
175
  */
176
176
  getDescription(): string;
177
- /**
178
- * Get detailed validation errors
179
- */
180
- private getValidationErrors;
181
- /**
182
- * Validate individual parameter type
183
- */
184
- private validateParameterType;
185
177
  /**
186
178
  * Validate constructor inputs
187
179
  */
@@ -240,10 +232,6 @@ declare class OpenAPITool implements ITool {
240
232
  * @private
241
233
  */
242
234
  private executeAPICall;
243
- /**
244
- * Find the operation in the OpenAPI specification
245
- */
246
- private findOperation;
247
235
  /**
248
236
  * Build HTTP request configuration from OpenAPI operation and parameters
249
237
  */
@@ -252,18 +240,6 @@ declare class OpenAPITool implements ITool {
252
240
  * Create tool schema from OpenAPI operation specification
253
241
  */
254
242
  private createSchemaFromOpenAPI;
255
- /**
256
- * Convert OpenAPI parameter to tool parameter schema
257
- */
258
- private convertOpenAPIParamToSchema;
259
- /**
260
- * Convert OpenAPI schema to parameter schema
261
- */
262
- private convertOpenAPISchemaToParameterSchema;
263
- /**
264
- * Map OpenAPI type to JSON schema type
265
- */
266
- private mapOpenAPIType;
267
243
  }
268
244
  /**
269
245
  * Factory function to create OpenAPI tools from specification
@@ -244,6 +244,87 @@ function isRequiredField(typeObj) {
244
244
  return typeDef.typeName !== "ZodOptional" && typeDef.typeName !== "ZodNullable" && typeDef.typeName !== "ZodDefault";
245
245
  }
246
246
 
247
+ // src/implementations/function-tool/parameter-validator.ts
248
+ function validateParameterType(key, value, schema) {
249
+ const expectedType = schema["type"];
250
+ switch (expectedType) {
251
+ case "string":
252
+ if (typeof value !== "string") {
253
+ return `Parameter "${key}" must be a string, got ${typeof value}`;
254
+ }
255
+ break;
256
+ case "number":
257
+ if (typeof value !== "number" || isNaN(value)) {
258
+ return `Parameter "${key}" must be a number, got ${typeof value}`;
259
+ }
260
+ break;
261
+ case "boolean":
262
+ if (typeof value !== "boolean") {
263
+ return `Parameter "${key}" must be a boolean, got ${typeof value}`;
264
+ }
265
+ break;
266
+ case "array":
267
+ if (!Array.isArray(value)) {
268
+ return `Parameter "${key}" must be an array, got ${typeof value}`;
269
+ }
270
+ if (schema.items) {
271
+ for (let i = 0; i < value.length; i++) {
272
+ const itemError = validateParameterType(`${key}[${i}]`, value[i], schema.items);
273
+ if (itemError) {
274
+ return itemError;
275
+ }
276
+ }
277
+ }
278
+ break;
279
+ case "object":
280
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
281
+ return `Parameter "${key}" must be an object, got ${typeof value}`;
282
+ }
283
+ break;
284
+ }
285
+ if (schema.enum && schema.enum.length > 0) {
286
+ const enumValues = schema.enum;
287
+ let isValidEnum = false;
288
+ for (const enumValue of enumValues) {
289
+ if (value === enumValue) {
290
+ isValidEnum = true;
291
+ break;
292
+ }
293
+ }
294
+ if (!isValidEnum) {
295
+ return `Parameter "${key}" must be one of: ${enumValues.join(", ")}, got ${value}`;
296
+ }
297
+ }
298
+ return void 0;
299
+ }
300
+ function getValidationErrors(parameters, schemaRequired, schemaProperties) {
301
+ const errors = [];
302
+ for (const field of schemaRequired) {
303
+ if (!(field in parameters)) {
304
+ errors.push(`Missing required parameter: ${field}`);
305
+ }
306
+ }
307
+ for (const [key, value] of Object.entries(parameters)) {
308
+ const paramSchema = schemaProperties[key];
309
+ if (!paramSchema) {
310
+ errors.push(`Unknown parameter: ${key}`);
311
+ continue;
312
+ }
313
+ const typeError = validateParameterType(key, value, paramSchema);
314
+ if (typeError) {
315
+ errors.push(typeError);
316
+ }
317
+ }
318
+ return errors;
319
+ }
320
+ function validateToolParameters(parameters, schemaRequired, schemaProperties) {
321
+ const errors = getValidationErrors(parameters, schemaRequired, schemaProperties);
322
+ return {
323
+ isValid: errors.length === 0,
324
+ errors
325
+ };
326
+ }
327
+
247
328
  // src/implementations/function-tool.ts
248
329
  var FunctionTool = class {
249
330
  schema;
@@ -274,7 +355,11 @@ var FunctionTool = class {
274
355
  async execute(parameters, context) {
275
356
  const toolName = this.schema.name;
276
357
  if (!this.validate(parameters)) {
277
- const errors = this.getValidationErrors(parameters);
358
+ const errors = getValidationErrors(
359
+ parameters,
360
+ this.schema.parameters.required || [],
361
+ this.schema.parameters.properties || {}
362
+ );
278
363
  throw new ValidationError2(`Invalid parameters for tool "${toolName}": ${errors.join(", ")}`);
279
364
  }
280
365
  const startTime = Date.now();
@@ -310,17 +395,21 @@ var FunctionTool = class {
310
395
  * Validate parameters (simple boolean result)
311
396
  */
312
397
  validate(parameters) {
313
- return this.getValidationErrors(parameters).length === 0;
398
+ return getValidationErrors(
399
+ parameters,
400
+ this.schema.parameters.required || [],
401
+ this.schema.parameters.properties || {}
402
+ ).length === 0;
314
403
  }
315
404
  /**
316
405
  * Validate tool parameters with detailed result
317
406
  */
318
407
  validateParameters(parameters) {
319
- const errors = this.getValidationErrors(parameters);
320
- return {
321
- isValid: errors.length === 0,
322
- errors
323
- };
408
+ return validateToolParameters(
409
+ parameters,
410
+ this.schema.parameters.required || [],
411
+ this.schema.parameters.properties || {}
412
+ );
324
413
  }
325
414
  /**
326
415
  * Get tool description
@@ -328,86 +417,6 @@ var FunctionTool = class {
328
417
  getDescription() {
329
418
  return this.schema.description;
330
419
  }
331
- /**
332
- * Get detailed validation errors
333
- */
334
- getValidationErrors(parameters) {
335
- const errors = [];
336
- const required = this.schema.parameters.required || [];
337
- const properties = this.schema.parameters.properties || {};
338
- for (const field of required) {
339
- if (!(field in parameters)) {
340
- errors.push(`Missing required parameter: ${field}`);
341
- }
342
- }
343
- for (const [key, value] of Object.entries(parameters)) {
344
- const paramSchema = properties[key];
345
- if (!paramSchema) {
346
- errors.push(`Unknown parameter: ${key}`);
347
- continue;
348
- }
349
- const typeError = this.validateParameterType(key, value, paramSchema);
350
- if (typeError) {
351
- errors.push(typeError);
352
- }
353
- }
354
- return errors;
355
- }
356
- /**
357
- * Validate individual parameter type
358
- */
359
- validateParameterType(key, value, schema) {
360
- const expectedType = schema["type"];
361
- switch (expectedType) {
362
- case "string":
363
- if (typeof value !== "string") {
364
- return `Parameter "${key}" must be a string, got ${typeof value}`;
365
- }
366
- break;
367
- case "number":
368
- if (typeof value !== "number" || isNaN(value)) {
369
- return `Parameter "${key}" must be a number, got ${typeof value}`;
370
- }
371
- break;
372
- case "boolean":
373
- if (typeof value !== "boolean") {
374
- return `Parameter "${key}" must be a boolean, got ${typeof value}`;
375
- }
376
- break;
377
- case "array":
378
- if (!Array.isArray(value)) {
379
- return `Parameter "${key}" must be an array, got ${typeof value}`;
380
- }
381
- if (schema.items) {
382
- for (let i = 0; i < value.length; i++) {
383
- const itemError = this.validateParameterType(`${key}[${i}]`, value[i], schema.items);
384
- if (itemError) {
385
- return itemError;
386
- }
387
- }
388
- }
389
- break;
390
- case "object":
391
- if (typeof value !== "object" || value === null || Array.isArray(value)) {
392
- return `Parameter "${key}" must be an object, got ${typeof value}`;
393
- }
394
- break;
395
- }
396
- if (schema.enum && schema.enum.length > 0) {
397
- const enumValues = schema.enum;
398
- let isValidEnum = false;
399
- for (const enumValue of enumValues) {
400
- if (value === enumValue) {
401
- isValidEnum = true;
402
- break;
403
- }
404
- }
405
- if (!isValidEnum) {
406
- return `Parameter "${key}" must be one of: ${enumValues.join(", ")}, got ${value}`;
407
- }
408
- }
409
- return void 0;
410
- }
411
420
  /**
412
421
  * Validate constructor inputs
413
422
  */
@@ -451,6 +460,132 @@ function createZodFunctionTool(name, description, zodSchema, fn) {
451
460
 
452
461
  // src/implementations/openapi-tool.ts
453
462
  import { ToolExecutionError as ToolExecutionError2, ValidationError as ValidationError3 } from "@robota-sdk/agent-core";
463
+
464
+ // src/implementations/openapi-schema-converter.ts
465
+ var HTTP_METHODS = [
466
+ "get",
467
+ "post",
468
+ "put",
469
+ "delete",
470
+ "patch",
471
+ "head",
472
+ "options"
473
+ ];
474
+ function findOperation(apiSpec, operationId) {
475
+ for (const [path, pathItem] of Object.entries(apiSpec.paths || {})) {
476
+ if (!pathItem) continue;
477
+ for (const method of HTTP_METHODS) {
478
+ const operation = pathItem[method];
479
+ if (operation?.operationId === operationId) {
480
+ return { method, path, operation };
481
+ }
482
+ }
483
+ }
484
+ return void 0;
485
+ }
486
+ function mapOpenAPIType(type) {
487
+ switch (type) {
488
+ case "string":
489
+ return "string";
490
+ case "number":
491
+ return "number";
492
+ case "integer":
493
+ return "integer";
494
+ case "boolean":
495
+ return "boolean";
496
+ case "array":
497
+ return "array";
498
+ case "object":
499
+ return "object";
500
+ default:
501
+ return "string";
502
+ }
503
+ }
504
+ function convertOpenAPISchemaToParameterSchema(schema) {
505
+ if ("$ref" in schema) {
506
+ return { type: "object" };
507
+ }
508
+ const result = {
509
+ type: mapOpenAPIType(schema.type)
510
+ };
511
+ if (schema.description) {
512
+ result.description = schema.description;
513
+ }
514
+ if (schema.enum) {
515
+ result.enum = schema.enum;
516
+ }
517
+ if (schema.minimum !== void 0) {
518
+ result.minimum = schema.minimum;
519
+ }
520
+ if (schema.maximum !== void 0) {
521
+ result.maximum = schema.maximum;
522
+ }
523
+ if (schema.pattern) {
524
+ result.pattern = schema.pattern;
525
+ }
526
+ if (schema.format) {
527
+ result.format = schema.format;
528
+ }
529
+ if (schema.default !== void 0) {
530
+ result.default = schema.default;
531
+ }
532
+ if (schema.type === "array" && schema.items) {
533
+ result.items = convertOpenAPISchemaToParameterSchema(schema.items);
534
+ }
535
+ if (schema.type === "object" && schema.properties) {
536
+ result.properties = {};
537
+ for (const [propName, propSchema] of Object.entries(schema.properties)) {
538
+ result.properties[propName] = convertOpenAPISchemaToParameterSchema(propSchema);
539
+ }
540
+ if (schema.required && schema.required.length > 0) {
541
+ result.required = schema.required;
542
+ }
543
+ }
544
+ return result;
545
+ }
546
+ function convertOpenAPIParamToSchema(param) {
547
+ const schema = param.schema;
548
+ return convertOpenAPISchemaToParameterSchema(schema);
549
+ }
550
+ function createSchemaFromOperation(operationId, opSpec) {
551
+ const properties = {};
552
+ const required = [];
553
+ const params = opSpec.parameters || [];
554
+ for (const param of params) {
555
+ properties[param.name] = convertOpenAPIParamToSchema(param);
556
+ if (param.required) {
557
+ required.push(param.name);
558
+ }
559
+ }
560
+ if (opSpec.requestBody) {
561
+ const requestBody = opSpec.requestBody;
562
+ const jsonContent = requestBody.content?.["application/json"];
563
+ if (jsonContent?.schema) {
564
+ const bodySchema = convertOpenAPISchemaToParameterSchema(jsonContent.schema);
565
+ if (bodySchema.type === "object" && bodySchema.properties) {
566
+ Object.assign(properties, bodySchema.properties);
567
+ const schemaWithRequired = bodySchema;
568
+ if (schemaWithRequired.required) {
569
+ required.push(...schemaWithRequired.required);
570
+ }
571
+ }
572
+ }
573
+ }
574
+ const schemaParams = {
575
+ type: "object",
576
+ properties
577
+ };
578
+ if (required.length > 0) {
579
+ schemaParams.required = required;
580
+ }
581
+ return {
582
+ name: operationId,
583
+ description: opSpec.summary || opSpec.description || `OpenAPI operation: ${operationId}`,
584
+ parameters: schemaParams
585
+ };
586
+ }
587
+
588
+ // src/implementations/openapi-tool.ts
454
589
  var OpenAPITool = class {
455
590
  schema;
456
591
  apiSpec;
@@ -557,36 +692,13 @@ var OpenAPITool = class {
557
692
  * @private
558
693
  */
559
694
  async executeAPICall(parameters, _context) {
560
- const operation = this.findOperation();
695
+ const operation = findOperation(this.apiSpec, this.operationId);
561
696
  if (!operation) {
562
697
  throw new Error(`Operation ${this.operationId} not found in OpenAPI spec`);
563
698
  }
564
- const requestConfig = this.buildRequestConfig(operation, parameters);
699
+ this.buildRequestConfig(operation, parameters);
565
700
  throw new Error("Not implemented: actual API execution is not yet available");
566
701
  }
567
- /**
568
- * Find the operation in the OpenAPI specification
569
- */
570
- findOperation() {
571
- for (const [path, pathItem] of Object.entries(this.apiSpec.paths || {})) {
572
- if (!pathItem) continue;
573
- for (const method of [
574
- "get",
575
- "post",
576
- "put",
577
- "delete",
578
- "patch",
579
- "head",
580
- "options"
581
- ]) {
582
- const operation = pathItem[method];
583
- if (operation?.operationId === this.operationId) {
584
- return { method, path, operation };
585
- }
586
- }
587
- }
588
- return void 0;
589
- }
590
702
  /**
591
703
  * Build HTTP request configuration from OpenAPI operation and parameters
592
704
  */
@@ -658,121 +770,13 @@ var OpenAPITool = class {
658
770
  * Create tool schema from OpenAPI operation specification
659
771
  */
660
772
  createSchemaFromOpenAPI() {
661
- const operation = this.findOperation();
773
+ const operation = findOperation(this.apiSpec, this.operationId);
662
774
  if (!operation) {
663
775
  throw new Error(
664
776
  `[STRICT-POLICY][EMITTER-CONTRACT] OpenAPI operation not found: ${this.operationId}. Emitter contract must provide a valid operationId present in the OpenAPI document.`
665
777
  );
666
778
  }
667
- const { operation: opSpec } = operation;
668
- const properties = {};
669
- const required = [];
670
- const params = opSpec.parameters || [];
671
- for (const param of params) {
672
- properties[param.name] = this.convertOpenAPIParamToSchema(param);
673
- if (param.required) {
674
- required.push(param.name);
675
- }
676
- }
677
- if (opSpec.requestBody) {
678
- const requestBody = opSpec.requestBody;
679
- const jsonContent = requestBody.content?.["application/json"];
680
- if (jsonContent?.schema) {
681
- const bodySchema = this.convertOpenAPISchemaToParameterSchema(jsonContent.schema);
682
- if (bodySchema.type === "object" && bodySchema.properties) {
683
- Object.assign(properties, bodySchema.properties);
684
- const schemaWithRequired = bodySchema;
685
- if (schemaWithRequired.required) {
686
- required.push(...schemaWithRequired.required);
687
- }
688
- }
689
- }
690
- }
691
- const schemaParams = {
692
- type: "object",
693
- properties
694
- };
695
- if (required.length > 0) {
696
- schemaParams.required = required;
697
- }
698
- return {
699
- name: this.operationId,
700
- description: opSpec.summary || opSpec.description || `OpenAPI operation: ${this.operationId}`,
701
- parameters: schemaParams
702
- };
703
- }
704
- /**
705
- * Convert OpenAPI parameter to tool parameter schema
706
- */
707
- convertOpenAPIParamToSchema(param) {
708
- const schema = param.schema;
709
- return this.convertOpenAPISchemaToParameterSchema(schema);
710
- }
711
- /**
712
- * Convert OpenAPI schema to parameter schema
713
- */
714
- convertOpenAPISchemaToParameterSchema(schema) {
715
- if ("$ref" in schema) {
716
- return { type: "object" };
717
- }
718
- const result = {
719
- type: this.mapOpenAPIType(schema.type)
720
- };
721
- if (schema.description) {
722
- result.description = schema.description;
723
- }
724
- if (schema.enum) {
725
- result.enum = schema.enum;
726
- }
727
- if (schema.minimum !== void 0) {
728
- result.minimum = schema.minimum;
729
- }
730
- if (schema.maximum !== void 0) {
731
- result.maximum = schema.maximum;
732
- }
733
- if (schema.pattern) {
734
- result.pattern = schema.pattern;
735
- }
736
- if (schema.format) {
737
- result.format = schema.format;
738
- }
739
- if (schema.default !== void 0) {
740
- result.default = schema.default;
741
- }
742
- if (schema.type === "array" && schema.items) {
743
- result.items = this.convertOpenAPISchemaToParameterSchema(schema.items);
744
- }
745
- if (schema.type === "object" && schema.properties) {
746
- result.properties = {};
747
- for (const [propName, propSchema] of Object.entries(schema.properties)) {
748
- result.properties[propName] = this.convertOpenAPISchemaToParameterSchema(propSchema);
749
- }
750
- if (schema.required && schema.required.length > 0) {
751
- result.required = schema.required;
752
- }
753
- }
754
- return result;
755
- }
756
- /**
757
- * Map OpenAPI type to JSON schema type
758
- */
759
- mapOpenAPIType(type) {
760
- switch (type) {
761
- case "string":
762
- return "string";
763
- case "number":
764
- return "number";
765
- case "integer":
766
- return "integer";
767
- case "boolean":
768
- return "boolean";
769
- case "array":
770
- return "array";
771
- case "object":
772
- return "object";
773
- default:
774
- return "string";
775
- }
779
+ return createSchemaFromOperation(this.operationId, operation.operation);
776
780
  }
777
781
  };
778
782
  function createOpenAPITool(config) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@robota-sdk/agent-tools",
3
- "version": "3.0.0-beta.52",
3
+ "version": "3.0.0-beta.54",
4
4
  "description": "Tool registry and implementations for Robota SDK",
5
5
  "type": "module",
6
6
  "main": "dist/node/index.js",
@@ -34,7 +34,7 @@
34
34
  "zod": "^3.24.0"
35
35
  },
36
36
  "peerDependencies": {
37
- "@robota-sdk/agent-core": "3.0.0-beta.52"
37
+ "@robota-sdk/agent-core": "3.0.0-beta.54"
38
38
  },
39
39
  "devDependencies": {
40
40
  "openapi-types": "^12.1.3",
@@ -42,7 +42,7 @@
42
42
  "tsup": "^8.0.1",
43
43
  "typescript": "^5.3.3",
44
44
  "vitest": "^1.6.1",
45
- "@robota-sdk/agent-core": "3.0.0-beta.52"
45
+ "@robota-sdk/agent-core": "3.0.0-beta.54"
46
46
  },
47
47
  "license": "MIT",
48
48
  "publishConfig": {
@@ -50,6 +50,8 @@
50
50
  },
51
51
  "scripts": {
52
52
  "build": "tsup src/index.ts --format esm,cjs --dts --out-dir dist/node --clean",
53
+ "build:js": "tsup src/index.ts --format esm,cjs --out-dir dist/node --clean",
54
+ "build:types": "tsup src/index.ts --format esm,cjs --dts-only --out-dir dist/node",
53
55
  "test": "vitest run --passWithNoTests",
54
56
  "typecheck": "tsc --noEmit",
55
57
  "lint": "eslint src/ --ext .ts,.tsx",