musubi-sdd 3.10.0 → 5.1.0
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 +24 -19
- package/package.json +1 -1
- package/src/agents/agent-loop.js +532 -0
- package/src/agents/agentic/code-generator.js +767 -0
- package/src/agents/agentic/code-reviewer.js +698 -0
- package/src/agents/agentic/index.js +43 -0
- package/src/agents/function-tool.js +432 -0
- package/src/agents/index.js +45 -0
- package/src/agents/schema-generator.js +514 -0
- package/src/analyzers/ast-extractor.js +870 -0
- package/src/analyzers/context-optimizer.js +681 -0
- package/src/analyzers/repository-map.js +692 -0
- package/src/integrations/index.js +7 -1
- package/src/integrations/mcp/index.js +175 -0
- package/src/integrations/mcp/mcp-context-provider.js +472 -0
- package/src/integrations/mcp/mcp-discovery.js +436 -0
- package/src/integrations/mcp/mcp-tool-registry.js +467 -0
- package/src/integrations/mcp-connector.js +818 -0
- package/src/integrations/tool-discovery.js +589 -0
- package/src/managers/index.js +7 -0
- package/src/managers/skill-tools.js +565 -0
- package/src/monitoring/cost-tracker.js +7 -0
- package/src/monitoring/incident-manager.js +10 -0
- package/src/monitoring/observability.js +10 -0
- package/src/monitoring/quality-dashboard.js +491 -0
- package/src/monitoring/release-manager.js +10 -0
- package/src/orchestration/agent-skill-binding.js +655 -0
- package/src/orchestration/error-handler.js +827 -0
- package/src/orchestration/index.js +235 -1
- package/src/orchestration/mcp-tool-adapters.js +896 -0
- package/src/orchestration/reasoning/index.js +58 -0
- package/src/orchestration/reasoning/planning-engine.js +831 -0
- package/src/orchestration/reasoning/reasoning-engine.js +710 -0
- package/src/orchestration/reasoning/self-correction.js +751 -0
- package/src/orchestration/skill-executor.js +665 -0
- package/src/orchestration/skill-registry.js +650 -0
- package/src/orchestration/workflow-examples.js +1072 -0
- package/src/orchestration/workflow-executor.js +779 -0
- package/src/phase4-integration.js +248 -0
- package/src/phase5-integration.js +402 -0
- package/src/steering/steering-auto-update.js +572 -0
- package/src/steering/steering-validator.js +547 -0
- package/src/templates/template-constraints.js +646 -0
- package/src/validators/advanced-validation.js +580 -0
|
@@ -0,0 +1,514 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MUSUBI Schema Generator
|
|
3
|
+
*
|
|
4
|
+
* Generates JSON Schema from various sources including
|
|
5
|
+
* JavaScript functions, TypeScript types, and JSDoc comments.
|
|
6
|
+
*
|
|
7
|
+
* @module agents/schema-generator
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const fs = require('fs');
|
|
11
|
+
const path = require('path');
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @typedef {Object} SchemaGeneratorOptions
|
|
15
|
+
* @property {boolean} [strict=false] - Enable strict mode
|
|
16
|
+
* @property {boolean} [includeExamples=true] - Include examples in schema
|
|
17
|
+
* @property {string} [defaultType='string'] - Default type for unknown
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Schema Generator for function tools
|
|
22
|
+
*/
|
|
23
|
+
class SchemaGenerator {
|
|
24
|
+
/**
|
|
25
|
+
* @param {SchemaGeneratorOptions} options
|
|
26
|
+
*/
|
|
27
|
+
constructor(options = {}) {
|
|
28
|
+
this.strict = options.strict ?? false;
|
|
29
|
+
this.includeExamples = options.includeExamples ?? true;
|
|
30
|
+
this.defaultType = options.defaultType ?? 'string';
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Generate schema from a function
|
|
35
|
+
* @param {Function} fn
|
|
36
|
+
* @returns {Object} JSON Schema
|
|
37
|
+
*/
|
|
38
|
+
fromFunction(fn) {
|
|
39
|
+
const fnString = fn.toString();
|
|
40
|
+
const params = this.extractParameters(fnString);
|
|
41
|
+
const jsdoc = this.extractJSDoc(fnString);
|
|
42
|
+
|
|
43
|
+
return this.buildSchema(params, jsdoc);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Generate schema from JSDoc comment
|
|
48
|
+
* @param {string} jsdoc
|
|
49
|
+
* @returns {Object} JSON Schema
|
|
50
|
+
*/
|
|
51
|
+
fromJSDoc(jsdoc) {
|
|
52
|
+
const parsed = this.parseJSDoc(jsdoc);
|
|
53
|
+
return this.buildSchemaFromParsed(parsed);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Generate schema from a class method
|
|
58
|
+
* @param {Object} instance - Class instance
|
|
59
|
+
* @param {string} methodName - Method name
|
|
60
|
+
* @returns {Object} JSON Schema
|
|
61
|
+
*/
|
|
62
|
+
fromMethod(instance, methodName) {
|
|
63
|
+
const method = instance[methodName];
|
|
64
|
+
if (typeof method !== 'function') {
|
|
65
|
+
throw new Error(`${methodName} is not a method`);
|
|
66
|
+
}
|
|
67
|
+
return this.fromFunction(method.bind(instance));
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Generate schema from file (extracts functions)
|
|
72
|
+
* @param {string} filePath
|
|
73
|
+
* @returns {Object<string, Object>} Map of function names to schemas
|
|
74
|
+
*/
|
|
75
|
+
fromFile(filePath) {
|
|
76
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
77
|
+
const functions = this.extractFunctions(content);
|
|
78
|
+
const schemas = {};
|
|
79
|
+
|
|
80
|
+
for (const fn of functions) {
|
|
81
|
+
schemas[fn.name] = this.buildSchema(fn.params, fn.jsdoc);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return schemas;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Extract function parameters from function string
|
|
89
|
+
* @param {string} fnString
|
|
90
|
+
* @returns {Array}
|
|
91
|
+
*/
|
|
92
|
+
extractParameters(fnString) {
|
|
93
|
+
// Match function parameters
|
|
94
|
+
const paramMatch = fnString.match(/\(([^)]*)\)/);
|
|
95
|
+
if (!paramMatch) return [];
|
|
96
|
+
|
|
97
|
+
const paramString = paramMatch[1];
|
|
98
|
+
if (!paramString.trim()) return [];
|
|
99
|
+
|
|
100
|
+
return this.parseParameterString(paramString);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Parse parameter string into structured format
|
|
105
|
+
* @param {string} paramString
|
|
106
|
+
* @returns {Array}
|
|
107
|
+
*/
|
|
108
|
+
parseParameterString(paramString) {
|
|
109
|
+
const params = [];
|
|
110
|
+
let depth = 0;
|
|
111
|
+
let current = '';
|
|
112
|
+
let inDefault = false;
|
|
113
|
+
|
|
114
|
+
for (const char of paramString) {
|
|
115
|
+
if (char === '{' || char === '[' || char === '(') depth++;
|
|
116
|
+
if (char === '}' || char === ']' || char === ')') depth--;
|
|
117
|
+
|
|
118
|
+
if (char === '=' && depth === 0) {
|
|
119
|
+
inDefault = true;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (char === ',' && depth === 0) {
|
|
123
|
+
if (current.trim()) {
|
|
124
|
+
params.push(this.parseParameter(current.trim()));
|
|
125
|
+
}
|
|
126
|
+
current = '';
|
|
127
|
+
inDefault = false;
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
current += char;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (current.trim()) {
|
|
135
|
+
params.push(this.parseParameter(current.trim()));
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return params;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Parse a single parameter
|
|
143
|
+
* @param {string} param
|
|
144
|
+
* @returns {Object}
|
|
145
|
+
*/
|
|
146
|
+
parseParameter(param) {
|
|
147
|
+
// Handle destructuring
|
|
148
|
+
if (param.startsWith('{')) {
|
|
149
|
+
const match = param.match(/\{([^}]+)\}/);
|
|
150
|
+
if (match) {
|
|
151
|
+
const destructured = match[1].split(',').map(p => p.trim().split(':')[0].split('=')[0].trim());
|
|
152
|
+
return {
|
|
153
|
+
name: 'options',
|
|
154
|
+
type: 'object',
|
|
155
|
+
destructured,
|
|
156
|
+
required: !param.includes('=')
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Handle default values
|
|
162
|
+
const [nameWithType, defaultValue] = param.split('=').map(p => p.trim());
|
|
163
|
+
const name = nameWithType.replace(/:\s*\w+$/, '').trim();
|
|
164
|
+
|
|
165
|
+
// Try to infer type from default value
|
|
166
|
+
let type = this.defaultType;
|
|
167
|
+
if (defaultValue !== undefined) {
|
|
168
|
+
type = this.inferTypeFromValue(defaultValue);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return {
|
|
172
|
+
name,
|
|
173
|
+
type,
|
|
174
|
+
required: defaultValue === undefined,
|
|
175
|
+
default: defaultValue ? this.parseDefaultValue(defaultValue) : undefined
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Infer type from a default value string
|
|
181
|
+
* @param {string} valueStr
|
|
182
|
+
* @returns {string}
|
|
183
|
+
*/
|
|
184
|
+
inferTypeFromValue(valueStr) {
|
|
185
|
+
valueStr = valueStr.trim();
|
|
186
|
+
|
|
187
|
+
if (valueStr === 'true' || valueStr === 'false') return 'boolean';
|
|
188
|
+
if (valueStr === 'null') return 'null';
|
|
189
|
+
if (valueStr === '[]' || valueStr.startsWith('[')) return 'array';
|
|
190
|
+
if (valueStr === '{}' || valueStr.startsWith('{')) return 'object';
|
|
191
|
+
if (/^['"`]/.test(valueStr)) return 'string';
|
|
192
|
+
if (/^-?\d+$/.test(valueStr)) return 'integer';
|
|
193
|
+
if (/^-?\d+\.\d+$/.test(valueStr)) return 'number';
|
|
194
|
+
|
|
195
|
+
return this.defaultType;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Parse default value string to actual value
|
|
200
|
+
* @param {string} valueStr
|
|
201
|
+
* @returns {*}
|
|
202
|
+
*/
|
|
203
|
+
parseDefaultValue(valueStr) {
|
|
204
|
+
try {
|
|
205
|
+
// Handle string literals
|
|
206
|
+
if (/^['"`]/.test(valueStr)) {
|
|
207
|
+
return valueStr.slice(1, -1);
|
|
208
|
+
}
|
|
209
|
+
return JSON.parse(valueStr);
|
|
210
|
+
} catch {
|
|
211
|
+
return valueStr;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Extract JSDoc comment from function string
|
|
217
|
+
* @param {string} fnString
|
|
218
|
+
* @returns {Object|null}
|
|
219
|
+
*/
|
|
220
|
+
extractJSDoc(fnString) {
|
|
221
|
+
const match = fnString.match(/\/\*\*[\s\S]*?\*\//);
|
|
222
|
+
if (!match) return null;
|
|
223
|
+
return this.parseJSDoc(match[0]);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Parse JSDoc comment
|
|
228
|
+
* @param {string} jsdoc
|
|
229
|
+
* @returns {Object}
|
|
230
|
+
*/
|
|
231
|
+
parseJSDoc(jsdoc) {
|
|
232
|
+
const result = {
|
|
233
|
+
description: '',
|
|
234
|
+
params: [],
|
|
235
|
+
returns: null,
|
|
236
|
+
example: null,
|
|
237
|
+
throws: []
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
const lines = jsdoc.split('\n')
|
|
241
|
+
.map(l => l.replace(/^\s*\*\s?/, '').trim())
|
|
242
|
+
.filter(l => l && !l.startsWith('/'));
|
|
243
|
+
|
|
244
|
+
let currentTag = null;
|
|
245
|
+
let buffer = [];
|
|
246
|
+
|
|
247
|
+
for (const line of lines) {
|
|
248
|
+
if (line.startsWith('@')) {
|
|
249
|
+
// Process previous buffer
|
|
250
|
+
if (currentTag === null && buffer.length) {
|
|
251
|
+
result.description = buffer.join(' ');
|
|
252
|
+
}
|
|
253
|
+
buffer = [];
|
|
254
|
+
|
|
255
|
+
if (line.startsWith('@param')) {
|
|
256
|
+
currentTag = 'param';
|
|
257
|
+
const parsed = this.parseParamTag(line);
|
|
258
|
+
if (parsed) result.params.push(parsed);
|
|
259
|
+
} else if (line.startsWith('@returns') || line.startsWith('@return')) {
|
|
260
|
+
currentTag = 'returns';
|
|
261
|
+
const match = line.match(/@returns?\s+\{([^}]+)\}\s*(.*)/);
|
|
262
|
+
if (match) {
|
|
263
|
+
result.returns = { type: match[1], description: match[2] || '' };
|
|
264
|
+
}
|
|
265
|
+
} else if (line.startsWith('@example')) {
|
|
266
|
+
currentTag = 'example';
|
|
267
|
+
result.example = '';
|
|
268
|
+
} else if (line.startsWith('@throws')) {
|
|
269
|
+
currentTag = 'throws';
|
|
270
|
+
const match = line.match(/@throws\s+\{([^}]+)\}\s*(.*)/);
|
|
271
|
+
if (match) {
|
|
272
|
+
result.throws.push({ type: match[1], description: match[2] || '' });
|
|
273
|
+
}
|
|
274
|
+
} else {
|
|
275
|
+
currentTag = 'other';
|
|
276
|
+
}
|
|
277
|
+
} else {
|
|
278
|
+
buffer.push(line);
|
|
279
|
+
if (currentTag === 'example') {
|
|
280
|
+
result.example += (result.example ? '\n' : '') + line;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
if (currentTag === null && buffer.length) {
|
|
286
|
+
result.description = buffer.join(' ');
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
return result;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Parse @param tag
|
|
294
|
+
* @param {string} line
|
|
295
|
+
* @returns {Object|null}
|
|
296
|
+
*/
|
|
297
|
+
parseParamTag(line) {
|
|
298
|
+
const match = line.match(/@param\s+\{([^}]+)\}\s+(\[)?(\w+)(?:\])?(?:\s*-?\s*(.*))?/);
|
|
299
|
+
if (!match) return null;
|
|
300
|
+
|
|
301
|
+
const [, type, optional, name, description] = match;
|
|
302
|
+
return {
|
|
303
|
+
name,
|
|
304
|
+
type: type.toLowerCase(),
|
|
305
|
+
required: !optional,
|
|
306
|
+
description: description || ''
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Build schema from extracted params and JSDoc
|
|
312
|
+
* @param {Array} params
|
|
313
|
+
* @param {Object|null} jsdoc
|
|
314
|
+
* @returns {Object}
|
|
315
|
+
*/
|
|
316
|
+
buildSchema(params, jsdoc) {
|
|
317
|
+
const properties = {};
|
|
318
|
+
const required = [];
|
|
319
|
+
|
|
320
|
+
// Merge param info from function signature and JSDoc
|
|
321
|
+
const paramMap = new Map();
|
|
322
|
+
|
|
323
|
+
for (const param of params) {
|
|
324
|
+
paramMap.set(param.name, { ...param });
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
if (jsdoc?.params) {
|
|
328
|
+
for (const docParam of jsdoc.params) {
|
|
329
|
+
const existing = paramMap.get(docParam.name);
|
|
330
|
+
if (existing) {
|
|
331
|
+
Object.assign(existing, {
|
|
332
|
+
type: docParam.type || existing.type,
|
|
333
|
+
description: docParam.description || existing.description,
|
|
334
|
+
required: docParam.required ?? existing.required
|
|
335
|
+
});
|
|
336
|
+
} else {
|
|
337
|
+
paramMap.set(docParam.name, docParam);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// Build properties
|
|
343
|
+
for (const [name, param] of paramMap) {
|
|
344
|
+
if (param.destructured) {
|
|
345
|
+
// Expand destructured object
|
|
346
|
+
for (const prop of param.destructured) {
|
|
347
|
+
properties[prop] = {
|
|
348
|
+
type: 'string',
|
|
349
|
+
description: `Property: ${prop}`
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
} else {
|
|
353
|
+
properties[name] = this.typeToSchema(param.type, param);
|
|
354
|
+
if (param.description) {
|
|
355
|
+
properties[name].description = param.description;
|
|
356
|
+
}
|
|
357
|
+
if (param.default !== undefined) {
|
|
358
|
+
properties[name].default = param.default;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
if (param.required && !param.destructured) {
|
|
363
|
+
required.push(name);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
const schema = {
|
|
368
|
+
type: 'object',
|
|
369
|
+
properties
|
|
370
|
+
};
|
|
371
|
+
|
|
372
|
+
if (required.length > 0) {
|
|
373
|
+
schema.required = required;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
if (this.strict) {
|
|
377
|
+
schema.additionalProperties = false;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
return schema;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* Build schema from parsed JSDoc
|
|
385
|
+
* @param {Object} parsed
|
|
386
|
+
* @returns {Object}
|
|
387
|
+
*/
|
|
388
|
+
buildSchemaFromParsed(parsed) {
|
|
389
|
+
return this.buildSchema([], parsed);
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* Convert type string to JSON Schema
|
|
394
|
+
* @param {string} typeStr
|
|
395
|
+
* @param {Object} [param]
|
|
396
|
+
* @returns {Object}
|
|
397
|
+
*/
|
|
398
|
+
typeToSchema(typeStr, param = {}) {
|
|
399
|
+
const type = typeStr.toLowerCase();
|
|
400
|
+
|
|
401
|
+
// Handle array types
|
|
402
|
+
if (type.endsWith('[]')) {
|
|
403
|
+
const itemType = type.slice(0, -2);
|
|
404
|
+
return {
|
|
405
|
+
type: 'array',
|
|
406
|
+
items: this.typeToSchema(itemType)
|
|
407
|
+
};
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
// Handle union types
|
|
411
|
+
if (type.includes('|')) {
|
|
412
|
+
const types = type.split('|').map(t => this.typeToSchema(t.trim()));
|
|
413
|
+
return { anyOf: types };
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
// Handle common types
|
|
417
|
+
const typeMap = {
|
|
418
|
+
'string': { type: 'string' },
|
|
419
|
+
'number': { type: 'number' },
|
|
420
|
+
'integer': { type: 'integer' },
|
|
421
|
+
'int': { type: 'integer' },
|
|
422
|
+
'boolean': { type: 'boolean' },
|
|
423
|
+
'bool': { type: 'boolean' },
|
|
424
|
+
'object': { type: 'object' },
|
|
425
|
+
'array': { type: 'array' },
|
|
426
|
+
'any': { type: 'object' },
|
|
427
|
+
'null': { type: 'null' },
|
|
428
|
+
'*': { type: 'object' }
|
|
429
|
+
};
|
|
430
|
+
|
|
431
|
+
return typeMap[type] || { type: 'string' };
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
/**
|
|
435
|
+
* Extract all functions from file content
|
|
436
|
+
* @param {string} content
|
|
437
|
+
* @returns {Array}
|
|
438
|
+
*/
|
|
439
|
+
extractFunctions(content) {
|
|
440
|
+
const functions = [];
|
|
441
|
+
|
|
442
|
+
// Match function declarations with JSDoc
|
|
443
|
+
const regex = /(\/\*\*[\s\S]*?\*\/)\s*(?:async\s+)?function\s+(\w+)\s*\(([^)]*)\)/g;
|
|
444
|
+
let match;
|
|
445
|
+
|
|
446
|
+
while ((match = regex.exec(content)) !== null) {
|
|
447
|
+
const [, jsdoc, name, params] = match;
|
|
448
|
+
functions.push({
|
|
449
|
+
name,
|
|
450
|
+
params: this.parseParameterString(params),
|
|
451
|
+
jsdoc: this.parseJSDoc(jsdoc)
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
// Match arrow functions with JSDoc
|
|
456
|
+
const arrowRegex = /(\/\*\*[\s\S]*?\*\/)\s*(?:const|let|var)\s+(\w+)\s*=\s*(?:async\s+)?\(([^)]*)\)\s*=>/g;
|
|
457
|
+
|
|
458
|
+
while ((match = arrowRegex.exec(content)) !== null) {
|
|
459
|
+
const [, jsdoc, name, params] = match;
|
|
460
|
+
functions.push({
|
|
461
|
+
name,
|
|
462
|
+
params: this.parseParameterString(params),
|
|
463
|
+
jsdoc: this.parseJSDoc(jsdoc)
|
|
464
|
+
});
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
return functions;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
/**
|
|
471
|
+
* Generate OpenAI function tool schema
|
|
472
|
+
* @param {string} name
|
|
473
|
+
* @param {string} description
|
|
474
|
+
* @param {Object} parameters
|
|
475
|
+
* @returns {Object}
|
|
476
|
+
*/
|
|
477
|
+
toOpenAITool(name, description, parameters) {
|
|
478
|
+
return {
|
|
479
|
+
type: 'function',
|
|
480
|
+
function: {
|
|
481
|
+
name,
|
|
482
|
+
description,
|
|
483
|
+
parameters
|
|
484
|
+
}
|
|
485
|
+
};
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
/**
|
|
489
|
+
* Generate Anthropic tool schema
|
|
490
|
+
* @param {string} name
|
|
491
|
+
* @param {string} description
|
|
492
|
+
* @param {Object} parameters
|
|
493
|
+
* @returns {Object}
|
|
494
|
+
*/
|
|
495
|
+
toAnthropicTool(name, description, parameters) {
|
|
496
|
+
return {
|
|
497
|
+
name,
|
|
498
|
+
description,
|
|
499
|
+
input_schema: parameters
|
|
500
|
+
};
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
/**
|
|
505
|
+
* Create a schema generator with default options
|
|
506
|
+
*/
|
|
507
|
+
function createSchemaGenerator(options = {}) {
|
|
508
|
+
return new SchemaGenerator(options);
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
module.exports = {
|
|
512
|
+
SchemaGenerator,
|
|
513
|
+
createSchemaGenerator
|
|
514
|
+
};
|