@robota-sdk/agent-tools 3.0.0-beta.52 → 3.0.0-beta.53
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/dist/node/index.cjs +226 -222
- package/dist/node/index.d.cts +0 -24
- package/dist/node/index.d.ts +0 -24
- package/dist/node/index.js +226 -222
- package/package.json +3 -3
package/dist/node/index.cjs
CHANGED
|
@@ -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 =
|
|
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
|
|
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
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
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) {
|
package/dist/node/index.d.cts
CHANGED
|
@@ -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
|
package/dist/node/index.d.ts
CHANGED
|
@@ -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
|
package/dist/node/index.js
CHANGED
|
@@ -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 =
|
|
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
|
|
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
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
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.
|
|
3
|
+
"version": "3.0.0-beta.53",
|
|
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.
|
|
37
|
+
"@robota-sdk/agent-core": "3.0.0-beta.53"
|
|
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.
|
|
45
|
+
"@robota-sdk/agent-core": "3.0.0-beta.53"
|
|
46
46
|
},
|
|
47
47
|
"license": "MIT",
|
|
48
48
|
"publishConfig": {
|