@cogitator-ai/self-modifying 17.0.18 → 18.0.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 +112 -48
- package/dist/architecture-evolution/capability-analyzer.d.ts.map +1 -1
- package/dist/architecture-evolution/capability-analyzer.js +38 -37
- package/dist/architecture-evolution/capability-analyzer.js.map +1 -1
- package/dist/architecture-evolution/index.d.ts +2 -2
- package/dist/architecture-evolution/index.d.ts.map +1 -1
- package/dist/architecture-evolution/index.js +1 -1
- package/dist/architecture-evolution/index.js.map +1 -1
- package/dist/architecture-evolution/parameter-optimizer.d.ts +5 -4
- package/dist/architecture-evolution/parameter-optimizer.d.ts.map +1 -1
- package/dist/architecture-evolution/parameter-optimizer.js +36 -31
- package/dist/architecture-evolution/parameter-optimizer.js.map +1 -1
- package/dist/architecture-evolution/prompts.d.ts +21 -2
- package/dist/architecture-evolution/prompts.d.ts.map +1 -1
- package/dist/architecture-evolution/prompts.js +150 -36
- package/dist/architecture-evolution/prompts.js.map +1 -1
- package/dist/constraints/modification-validator.d.ts +1 -0
- package/dist/constraints/modification-validator.d.ts.map +1 -1
- package/dist/constraints/modification-validator.js +30 -14
- package/dist/constraints/modification-validator.js.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/meta-reasoning/meta-reasoner.d.ts +3 -0
- package/dist/meta-reasoning/meta-reasoner.d.ts.map +1 -1
- package/dist/meta-reasoning/meta-reasoner.js +101 -33
- package/dist/meta-reasoning/meta-reasoner.js.map +1 -1
- package/dist/meta-reasoning/prompts.d.ts +10 -14
- package/dist/meta-reasoning/prompts.d.ts.map +1 -1
- package/dist/meta-reasoning/prompts.js +109 -1
- package/dist/meta-reasoning/prompts.js.map +1 -1
- package/dist/self-modifying-agent.d.ts +83 -17
- package/dist/self-modifying-agent.d.ts.map +1 -1
- package/dist/self-modifying-agent.js +557 -444
- package/dist/self-modifying-agent.js.map +1 -1
- package/dist/tool-generation/gap-analyzer.d.ts +0 -1
- package/dist/tool-generation/gap-analyzer.d.ts.map +1 -1
- package/dist/tool-generation/gap-analyzer.js +14 -14
- package/dist/tool-generation/gap-analyzer.js.map +1 -1
- package/dist/tool-generation/index.d.ts +3 -3
- package/dist/tool-generation/index.d.ts.map +1 -1
- package/dist/tool-generation/index.js +2 -2
- package/dist/tool-generation/index.js.map +1 -1
- package/dist/tool-generation/prompts.d.ts +1 -0
- package/dist/tool-generation/prompts.d.ts.map +1 -1
- package/dist/tool-generation/prompts.js +33 -8
- package/dist/tool-generation/prompts.js.map +1 -1
- package/dist/tool-generation/tool-generator.d.ts +5 -5
- package/dist/tool-generation/tool-generator.d.ts.map +1 -1
- package/dist/tool-generation/tool-generator.js +41 -28
- package/dist/tool-generation/tool-generator.js.map +1 -1
- package/dist/tool-generation/tool-sandbox.d.ts +9 -6
- package/dist/tool-generation/tool-sandbox.d.ts.map +1 -1
- package/dist/tool-generation/tool-sandbox.js +257 -157
- package/dist/tool-generation/tool-sandbox.js.map +1 -1
- package/dist/tool-generation/tool-validator.d.ts +3 -8
- package/dist/tool-generation/tool-validator.d.ts.map +1 -1
- package/dist/tool-generation/tool-validator.js +53 -54
- package/dist/tool-generation/tool-validator.js.map +1 -1
- package/dist/utils/llm-helper.d.ts.map +1 -1
- package/dist/utils/llm-helper.js +1 -0
- package/dist/utils/llm-helper.js.map +1 -1
- package/package.json +3 -12
- package/src/__tests__/component-regressions.test.ts +599 -0
- package/src/__tests__/meta-reasoning.test.ts +5 -1
- package/src/__tests__/sandbox-security.test.ts +186 -0
- package/src/__tests__/self-modifying-agent.test.ts +363 -1
- package/src/architecture-evolution/capability-analyzer.ts +56 -40
- package/src/architecture-evolution/index.ts +2 -0
- package/src/architecture-evolution/parameter-optimizer.ts +52 -34
- package/src/architecture-evolution/prompts.ts +179 -41
- package/src/constraints/modification-validator.ts +30 -14
- package/src/index.ts +14 -0
- package/src/meta-reasoning/meta-reasoner.ts +105 -40
- package/src/meta-reasoning/prompts.ts +129 -15
- package/src/self-modifying-agent.ts +764 -489
- package/src/tool-generation/gap-analyzer.ts +19 -18
- package/src/tool-generation/index.ts +13 -3
- package/src/tool-generation/prompts.ts +41 -8
- package/src/tool-generation/tool-generator.ts +59 -33
- package/src/tool-generation/tool-sandbox.ts +306 -175
- package/src/tool-generation/tool-validator.ts +66 -63
- package/src/utils/llm-helper.ts +1 -0
|
@@ -7,6 +7,7 @@ import type {
|
|
|
7
7
|
ToolSelfGenerationConfig,
|
|
8
8
|
} from '@cogitator-ai/types';
|
|
9
9
|
import { buildGapAnalysisPrompt, parseGapAnalysisResponse } from './prompts';
|
|
10
|
+
import { llmChat } from '../utils/llm-helper';
|
|
10
11
|
|
|
11
12
|
export interface GapAnalyzerOptions {
|
|
12
13
|
llm: LLMBackend;
|
|
@@ -34,7 +35,7 @@ export class GapAnalyzer {
|
|
|
34
35
|
previousGaps?: CapabilityGap[];
|
|
35
36
|
}
|
|
36
37
|
): Promise<GapAnalysisResult> {
|
|
37
|
-
const cacheKey = this.buildCacheKey(userIntent, availableTools);
|
|
38
|
+
const cacheKey = this.buildCacheKey(userIntent, availableTools, context);
|
|
38
39
|
const cached = this.analysisCache.get(cacheKey);
|
|
39
40
|
if (cached && Date.now() - cached.timestamp.getTime() < 60000) {
|
|
40
41
|
return cached;
|
|
@@ -47,7 +48,8 @@ export class GapAnalyzer {
|
|
|
47
48
|
|
|
48
49
|
const prompt = buildGapAnalysisPrompt(userIntent, toolSummaries, context?.failedAttempts);
|
|
49
50
|
|
|
50
|
-
const
|
|
51
|
+
const content = await llmChat(
|
|
52
|
+
this.llm,
|
|
51
53
|
[
|
|
52
54
|
{
|
|
53
55
|
role: 'system',
|
|
@@ -58,10 +60,10 @@ Consider tool composition before suggesting new tools.`,
|
|
|
58
60
|
},
|
|
59
61
|
{ role: 'user', content: prompt },
|
|
60
62
|
],
|
|
61
|
-
0.3
|
|
63
|
+
{ model: this.model, temperature: 0.3 }
|
|
62
64
|
);
|
|
63
65
|
|
|
64
|
-
const parsed = parseGapAnalysisResponse(
|
|
66
|
+
const parsed = parseGapAnalysisResponse(content);
|
|
65
67
|
const filteredGaps = this.filterAndPrioritizeGaps(
|
|
66
68
|
parsed.gaps,
|
|
67
69
|
availableTools,
|
|
@@ -217,26 +219,25 @@ Consider tool composition before suggesting new tools.`,
|
|
|
217
219
|
return `Identified ${gaps.length} capability gap(s):\n${gapDescriptions}`;
|
|
218
220
|
}
|
|
219
221
|
|
|
220
|
-
private buildCacheKey(
|
|
222
|
+
private buildCacheKey(
|
|
223
|
+
userIntent: string,
|
|
224
|
+
tools: Tool[],
|
|
225
|
+
context?: { failedAttempts?: string[]; previousGaps?: CapabilityGap[] }
|
|
226
|
+
): string {
|
|
221
227
|
const toolSignature = tools
|
|
222
|
-
.map((t) => t.name)
|
|
228
|
+
.map((t) => `${t.name}:${t.description}`)
|
|
223
229
|
.sort()
|
|
224
|
-
.join('
|
|
225
|
-
const raw =
|
|
230
|
+
.join('\n');
|
|
231
|
+
const raw = JSON.stringify([
|
|
232
|
+
userIntent,
|
|
233
|
+
toolSignature,
|
|
234
|
+
context?.failedAttempts ?? [],
|
|
235
|
+
(context?.previousGaps ?? []).map((g) => g.id).sort(),
|
|
236
|
+
]);
|
|
226
237
|
return createHash('sha256').update(raw).digest('hex');
|
|
227
238
|
}
|
|
228
239
|
|
|
229
240
|
clearCache(): void {
|
|
230
241
|
this.analysisCache.clear();
|
|
231
242
|
}
|
|
232
|
-
|
|
233
|
-
private async callLLM(
|
|
234
|
-
messages: Array<{ role: 'system' | 'user' | 'assistant'; content: string }>,
|
|
235
|
-
temperature: number
|
|
236
|
-
) {
|
|
237
|
-
if (this.llm.complete) {
|
|
238
|
-
return this.llm.complete({ messages, temperature });
|
|
239
|
-
}
|
|
240
|
-
return this.llm.chat({ model: this.model, messages, temperature });
|
|
241
|
-
}
|
|
242
243
|
}
|
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
export { GapAnalyzer, type GapAnalyzerOptions } from './gap-analyzer';
|
|
2
|
-
export {
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
export {
|
|
3
|
+
ToolGenerator,
|
|
4
|
+
type ToolGeneratorOptions,
|
|
5
|
+
type GenerateOptions,
|
|
6
|
+
type GenerationResult,
|
|
7
|
+
} from './tool-generator';
|
|
8
|
+
export { ToolValidator, type ToolValidatorOptions, type ValidationRule } from './tool-validator';
|
|
9
|
+
export {
|
|
10
|
+
ToolSandbox,
|
|
11
|
+
DEFAULT_SANDBOX_CONFIG,
|
|
12
|
+
deepEqual,
|
|
13
|
+
type SandboxTestCase,
|
|
14
|
+
} from './tool-sandbox';
|
|
5
15
|
export {
|
|
6
16
|
InMemoryGeneratedToolStore,
|
|
7
17
|
type ToolUsageRecord,
|
|
@@ -78,6 +78,7 @@ export function buildToolGenerationPrompt(
|
|
|
78
78
|
maxLines?: number;
|
|
79
79
|
allowedModules?: string[];
|
|
80
80
|
securityLevel?: 'strict' | 'moderate' | 'permissive';
|
|
81
|
+
parameters?: Record<string, unknown>;
|
|
81
82
|
}
|
|
82
83
|
): string {
|
|
83
84
|
const toolName = sanitizeToolName(gap.suggestedToolName);
|
|
@@ -112,12 +113,19 @@ export function buildToolGenerationPrompt(
|
|
|
112
113
|
const constraintsText =
|
|
113
114
|
constraintsSection.length > 0 ? `\nCONSTRAINTS:\n${constraintsSection.join('\n')}\n` : '';
|
|
114
115
|
|
|
116
|
+
const parametersJson = constraints?.parameters
|
|
117
|
+
? JSON.stringify(constraints.parameters)
|
|
118
|
+
: '{"type":"object","properties":{/* DEFINE PARAMS */},"required":[/* REQUIRED PARAMS */]}';
|
|
119
|
+
const parametersText = constraints?.parameters
|
|
120
|
+
? `\nThe tool MUST accept exactly this parameters JSON Schema: ${parametersJson}\n`
|
|
121
|
+
: '';
|
|
122
|
+
|
|
115
123
|
return `Create a tool named "${toolName}".
|
|
116
124
|
Task: ${description}
|
|
117
125
|
Formula/Logic: ${capability}
|
|
118
|
-
${existingToolsSection}${constraintsText}
|
|
126
|
+
${existingToolsSection}${constraintsText}${parametersText}
|
|
119
127
|
Respond with ONLY this JSON (no other text):
|
|
120
|
-
{"name":"${toolName}","description":"${description}","implementation":"async function execute(params) { /* YOUR CODE HERE — throw on invalid input */ }","parameters"
|
|
128
|
+
{"name":"${toolName}","description":"${description}","implementation":"async function execute(params) { /* YOUR CODE HERE — throw on invalid input */ }","parameters":${parametersJson},"reasoning":"explanation"}`;
|
|
121
129
|
}
|
|
122
130
|
|
|
123
131
|
export function buildToolValidationPrompt(
|
|
@@ -224,7 +232,10 @@ export function parseGapAnalysisResponse(response: string): {
|
|
|
224
232
|
complexity: (['simple', 'moderate', 'complex'].includes(String(g.complexity))
|
|
225
233
|
? g.complexity
|
|
226
234
|
: 'moderate') as 'simple' | 'moderate' | 'complex',
|
|
227
|
-
confidence:
|
|
235
|
+
confidence:
|
|
236
|
+
typeof g.confidence === 'number' && Number.isFinite(g.confidence)
|
|
237
|
+
? Math.min(1, Math.max(0, g.confidence))
|
|
238
|
+
: 0.5,
|
|
228
239
|
reasoning: String(g.reasoning || ''),
|
|
229
240
|
}))
|
|
230
241
|
: [],
|
|
@@ -279,16 +290,38 @@ export function parseToolGenerationResponse(response: string): GeneratedTool | n
|
|
|
279
290
|
return null;
|
|
280
291
|
}
|
|
281
292
|
|
|
293
|
+
function normalizeParameters(value: unknown): Record<string, unknown> {
|
|
294
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
295
|
+
return { type: 'object', properties: {} };
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
const schema = value as Record<string, unknown>;
|
|
299
|
+
const properties =
|
|
300
|
+
schema.properties && typeof schema.properties === 'object' && !Array.isArray(schema.properties)
|
|
301
|
+
? (schema.properties as Record<string, unknown>)
|
|
302
|
+
: {};
|
|
303
|
+
const required = Array.isArray(schema.required)
|
|
304
|
+
? schema.required.filter(
|
|
305
|
+
(key): key is string => typeof key === 'string' && Object.hasOwn(properties, key)
|
|
306
|
+
)
|
|
307
|
+
: [];
|
|
308
|
+
|
|
309
|
+
const normalized: Record<string, unknown> = { ...schema, type: 'object', properties };
|
|
310
|
+
if (required.length > 0) {
|
|
311
|
+
normalized.required = required;
|
|
312
|
+
} else {
|
|
313
|
+
delete normalized.required;
|
|
314
|
+
}
|
|
315
|
+
return normalized;
|
|
316
|
+
}
|
|
317
|
+
|
|
282
318
|
function buildToolFromParsed(parsed: Record<string, unknown>): GeneratedTool {
|
|
283
319
|
return {
|
|
284
320
|
id: `gen_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,
|
|
285
|
-
name: String(parsed.name),
|
|
321
|
+
name: sanitizeToolName(String(parsed.name)),
|
|
286
322
|
description: String(parsed.description || ''),
|
|
287
323
|
implementation: String(parsed.implementation),
|
|
288
|
-
parameters: (parsed.parameters
|
|
289
|
-
type: 'object',
|
|
290
|
-
properties: {},
|
|
291
|
-
},
|
|
324
|
+
parameters: normalizeParameters(parsed.parameters),
|
|
292
325
|
createdAt: new Date(),
|
|
293
326
|
version: 1,
|
|
294
327
|
status: 'pending_validation',
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
Tool,
|
|
3
|
+
ToolSchema,
|
|
3
4
|
LLMBackend,
|
|
4
5
|
CapabilityGap,
|
|
5
6
|
GeneratedTool,
|
|
@@ -8,7 +9,8 @@ import type {
|
|
|
8
9
|
} from '@cogitator-ai/types';
|
|
9
10
|
import { z, type ZodType } from 'zod';
|
|
10
11
|
import { ToolValidator } from './tool-validator';
|
|
11
|
-
import { ToolSandbox } from './tool-sandbox';
|
|
12
|
+
import { ToolSandbox, type SandboxTestCase } from './tool-sandbox';
|
|
13
|
+
import { llmChat } from '../utils/llm-helper';
|
|
12
14
|
import {
|
|
13
15
|
TOOL_GENERATION_SYSTEM_PROMPT,
|
|
14
16
|
buildToolGenerationPrompt,
|
|
@@ -22,6 +24,10 @@ export interface ToolGeneratorOptions {
|
|
|
22
24
|
model?: string;
|
|
23
25
|
}
|
|
24
26
|
|
|
27
|
+
export interface GenerateOptions {
|
|
28
|
+
parameters?: Record<string, unknown>;
|
|
29
|
+
}
|
|
30
|
+
|
|
25
31
|
export interface GenerationResult {
|
|
26
32
|
tool: GeneratedTool | null;
|
|
27
33
|
validationResult: ToolValidationResult | null;
|
|
@@ -52,7 +58,8 @@ export class ToolGenerator {
|
|
|
52
58
|
async generate(
|
|
53
59
|
gap: CapabilityGap,
|
|
54
60
|
existingTools: Tool[],
|
|
55
|
-
testCases?:
|
|
61
|
+
testCases?: SandboxTestCase[],
|
|
62
|
+
options: GenerateOptions = {}
|
|
56
63
|
): Promise<GenerationResult> {
|
|
57
64
|
let currentTool: GeneratedTool | null = null;
|
|
58
65
|
let validationResult: ToolValidationResult | null = null;
|
|
@@ -65,15 +72,23 @@ export class ToolGenerator {
|
|
|
65
72
|
|
|
66
73
|
try {
|
|
67
74
|
if (currentTool === null) {
|
|
68
|
-
currentTool = await this.generateInitial(gap, existingTools);
|
|
75
|
+
currentTool = await this.generateInitial(gap, existingTools, options.parameters);
|
|
69
76
|
} else if (validationResult) {
|
|
70
|
-
|
|
77
|
+
const improved = await this.improve(currentTool, validationResult, iterations);
|
|
78
|
+
if (!improved) {
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
currentTool = improved;
|
|
71
82
|
}
|
|
72
83
|
|
|
73
84
|
if (!currentTool) {
|
|
74
85
|
continue;
|
|
75
86
|
}
|
|
76
87
|
|
|
88
|
+
if (options.parameters) {
|
|
89
|
+
currentTool.parameters = options.parameters;
|
|
90
|
+
}
|
|
91
|
+
|
|
77
92
|
validationResult = await this.validator.validate(currentTool, testCases);
|
|
78
93
|
|
|
79
94
|
if (validationResult.isValid) {
|
|
@@ -132,21 +147,22 @@ export class ToolGenerator {
|
|
|
132
147
|
reasoning: 'User-requested quick generation',
|
|
133
148
|
};
|
|
134
149
|
|
|
135
|
-
const result = await this.generate(
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
properties: parameters
|
|
141
|
-
|
|
142
|
-
|
|
150
|
+
const result = await this.generate(
|
|
151
|
+
gap,
|
|
152
|
+
[],
|
|
153
|
+
undefined,
|
|
154
|
+
Object.keys(parameters).length > 0
|
|
155
|
+
? { parameters: { type: 'object', properties: parameters } }
|
|
156
|
+
: {}
|
|
157
|
+
);
|
|
143
158
|
|
|
144
|
-
return result.tool;
|
|
159
|
+
return result.success ? result.tool : null;
|
|
145
160
|
}
|
|
146
161
|
|
|
147
162
|
private async generateInitial(
|
|
148
163
|
gap: CapabilityGap,
|
|
149
|
-
existingTools: Tool[]
|
|
164
|
+
existingTools: Tool[],
|
|
165
|
+
parameters?: Record<string, unknown>
|
|
150
166
|
): Promise<GeneratedTool | null> {
|
|
151
167
|
const toolSummaries = existingTools.map((t) => ({
|
|
152
168
|
name: t.name,
|
|
@@ -157,17 +173,19 @@ export class ToolGenerator {
|
|
|
157
173
|
maxLines: 100,
|
|
158
174
|
securityLevel: 'strict',
|
|
159
175
|
allowedModules: this.config.sandboxConfig?.allowedModules,
|
|
176
|
+
parameters,
|
|
160
177
|
});
|
|
161
178
|
|
|
162
|
-
const
|
|
179
|
+
const content = await llmChat(
|
|
180
|
+
this.llm,
|
|
163
181
|
[
|
|
164
182
|
{ role: 'system', content: TOOL_GENERATION_SYSTEM_PROMPT },
|
|
165
183
|
{ role: 'user', content: prompt },
|
|
166
184
|
],
|
|
167
|
-
0.4
|
|
185
|
+
{ model: this.model, temperature: 0.4 }
|
|
168
186
|
);
|
|
169
187
|
|
|
170
|
-
const tool = parseToolGenerationResponse(
|
|
188
|
+
const tool = parseToolGenerationResponse(content);
|
|
171
189
|
|
|
172
190
|
if (tool) {
|
|
173
191
|
tool.metadata = {
|
|
@@ -187,18 +205,21 @@ export class ToolGenerator {
|
|
|
187
205
|
): Promise<GeneratedTool | null> {
|
|
188
206
|
const prompt = buildToolImprovementPrompt(tool, validationResult, iteration);
|
|
189
207
|
|
|
190
|
-
const
|
|
208
|
+
const content = await llmChat(
|
|
209
|
+
this.llm,
|
|
191
210
|
[
|
|
192
211
|
{ role: 'system', content: TOOL_GENERATION_SYSTEM_PROMPT },
|
|
193
212
|
{ role: 'user', content: prompt },
|
|
194
213
|
],
|
|
195
|
-
0.3
|
|
214
|
+
{ model: this.model, temperature: 0.3 }
|
|
196
215
|
);
|
|
197
216
|
|
|
198
|
-
const improved = parseToolGenerationResponse(
|
|
217
|
+
const improved = parseToolGenerationResponse(content);
|
|
199
218
|
|
|
200
219
|
if (improved) {
|
|
201
220
|
improved.id = tool.id;
|
|
221
|
+
improved.name = tool.name;
|
|
222
|
+
improved.createdAt = tool.createdAt;
|
|
202
223
|
improved.version = tool.version + 1;
|
|
203
224
|
improved.metadata = {
|
|
204
225
|
...tool.metadata,
|
|
@@ -215,6 +236,7 @@ export class ToolGenerator {
|
|
|
215
236
|
const sandbox = this.sandbox;
|
|
216
237
|
const tool = generated;
|
|
217
238
|
const paramSchema = buildZodSchema(generated.parameters);
|
|
239
|
+
const jsonSchema = toToolJsonSchema(generated.parameters);
|
|
218
240
|
|
|
219
241
|
const execute = async (params: unknown): Promise<unknown> => {
|
|
220
242
|
const parsed = paramSchema.safeParse(params);
|
|
@@ -239,23 +261,27 @@ export class ToolGenerator {
|
|
|
239
261
|
toJSON: () => ({
|
|
240
262
|
name: generated.name,
|
|
241
263
|
description: generated.description,
|
|
242
|
-
parameters:
|
|
243
|
-
type: 'object' as const,
|
|
244
|
-
properties: generated.parameters as Record<string, unknown>,
|
|
245
|
-
},
|
|
264
|
+
parameters: jsonSchema,
|
|
246
265
|
}),
|
|
247
266
|
};
|
|
248
267
|
}
|
|
268
|
+
}
|
|
249
269
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
270
|
+
function toToolJsonSchema(parameters: Record<string, unknown>): ToolSchema['parameters'] {
|
|
271
|
+
const properties =
|
|
272
|
+
parameters.type === 'object' &&
|
|
273
|
+
parameters.properties &&
|
|
274
|
+
typeof parameters.properties === 'object' &&
|
|
275
|
+
!Array.isArray(parameters.properties)
|
|
276
|
+
? (parameters.properties as Record<string, unknown>)
|
|
277
|
+
: {};
|
|
278
|
+
const required = Array.isArray(parameters.required)
|
|
279
|
+
? parameters.required.filter((key): key is string => typeof key === 'string')
|
|
280
|
+
: [];
|
|
281
|
+
|
|
282
|
+
return required.length > 0
|
|
283
|
+
? { type: 'object', properties, required }
|
|
284
|
+
: { type: 'object', properties };
|
|
259
285
|
}
|
|
260
286
|
|
|
261
287
|
function buildZodSchema(parameters: Record<string, unknown>): ZodType<unknown> {
|