@cogitator-ai/self-modifying 17.0.11 → 17.0.16
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 +3 -3
- package/dist/architecture-evolution/capability-analyzer.d.ts +2 -0
- package/dist/architecture-evolution/capability-analyzer.d.ts.map +1 -1
- package/dist/architecture-evolution/capability-analyzer.js +4 -2
- package/dist/architecture-evolution/capability-analyzer.js.map +1 -1
- package/dist/architecture-evolution/index.d.ts +4 -4
- package/dist/architecture-evolution/index.js +4 -4
- package/dist/architecture-evolution/parameter-optimizer.d.ts +2 -0
- package/dist/architecture-evolution/parameter-optimizer.d.ts.map +1 -1
- package/dist/architecture-evolution/parameter-optimizer.js +7 -4
- package/dist/architecture-evolution/parameter-optimizer.js.map +1 -1
- package/dist/architecture-evolution/prompts.js +1 -1
- package/dist/constraints/index.d.ts +3 -3
- package/dist/constraints/index.js +3 -3
- package/dist/constraints/modification-validator.d.ts.map +1 -1
- package/dist/constraints/modification-validator.js +1 -1
- package/dist/constraints/modification-validator.js.map +1 -1
- package/dist/events/index.d.ts +1 -1
- package/dist/events/index.js +1 -1
- package/dist/index.d.ts +7 -7
- package/dist/index.js +7 -7
- package/dist/meta-reasoning/index.d.ts +4 -4
- package/dist/meta-reasoning/index.js +4 -4
- package/dist/meta-reasoning/meta-reasoner.d.ts +1 -1
- package/dist/meta-reasoning/meta-reasoner.d.ts.map +1 -1
- package/dist/meta-reasoning/meta-reasoner.js +4 -4
- package/dist/meta-reasoning/meta-reasoner.js.map +1 -1
- package/dist/self-modifying-agent.d.ts.map +1 -1
- package/dist/self-modifying-agent.js +21 -12
- package/dist/self-modifying-agent.js.map +1 -1
- package/dist/tool-generation/gap-analyzer.d.ts +2 -0
- package/dist/tool-generation/gap-analyzer.d.ts.map +1 -1
- package/dist/tool-generation/gap-analyzer.js +4 -2
- package/dist/tool-generation/gap-analyzer.js.map +1 -1
- package/dist/tool-generation/index.d.ts +6 -6
- package/dist/tool-generation/index.js +6 -6
- package/dist/tool-generation/prompts.d.ts +3 -3
- package/dist/tool-generation/prompts.d.ts.map +1 -1
- package/dist/tool-generation/prompts.js +51 -93
- package/dist/tool-generation/prompts.js.map +1 -1
- package/dist/tool-generation/tool-generator.d.ts +2 -0
- package/dist/tool-generation/tool-generator.d.ts.map +1 -1
- package/dist/tool-generation/tool-generator.js +8 -11
- package/dist/tool-generation/tool-generator.js.map +1 -1
- package/dist/tool-generation/tool-sandbox.d.ts.map +1 -1
- package/dist/tool-generation/tool-sandbox.js.map +1 -1
- package/dist/tool-generation/tool-validator.d.ts +2 -0
- package/dist/tool-generation/tool-validator.d.ts.map +1 -1
- package/dist/tool-generation/tool-validator.js +5 -3
- package/dist/tool-generation/tool-validator.js.map +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +23 -5
- package/dist/utils/index.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/self-modifying-agent.test.ts +24 -20
- package/src/__tests__/utils.test.ts +22 -1
- package/src/architecture-evolution/capability-analyzer.ts +4 -1
- package/src/architecture-evolution/parameter-optimizer.ts +5 -1
- package/src/constraints/modification-validator.ts +4 -1
- package/src/meta-reasoning/meta-reasoner.ts +3 -1
- package/src/self-modifying-agent.ts +25 -16
- package/src/tool-generation/gap-analyzer.ts +4 -1
- package/src/tool-generation/prompts.ts +55 -98
- package/src/tool-generation/tool-generator.ts +6 -8
- package/src/tool-generation/tool-sandbox.ts +2 -1
- package/src/tool-generation/tool-validator.ts +4 -1
- package/src/utils/index.ts +24 -4
|
@@ -1,27 +1,15 @@
|
|
|
1
1
|
import type { CapabilityGap, GeneratedTool, ToolValidationResult } from '@cogitator-ai/types';
|
|
2
2
|
import { extractJson } from '../utils';
|
|
3
3
|
|
|
4
|
-
export const TOOL_GENERATION_SYSTEM_PROMPT = `You
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
6. The implementation MUST define an async function called "execute" that takes a params object and returns a result
|
|
14
|
-
7. Do NOT use: eval, Function, import, require, process, global, fetch, setTimeout, setInterval, constructor
|
|
15
|
-
|
|
16
|
-
OUTPUT FORMAT:
|
|
17
|
-
Return a JSON object with:
|
|
18
|
-
{
|
|
19
|
-
"name": "tool_name",
|
|
20
|
-
"description": "Clear description of what the tool does",
|
|
21
|
-
"implementation": "async function execute(params) { ... }",
|
|
22
|
-
"parameters": { "type": "object", "properties": {...}, "required": [...] },
|
|
23
|
-
"reasoning": "Why this implementation was chosen"
|
|
24
|
-
}`;
|
|
4
|
+
export const TOOL_GENERATION_SYSTEM_PROMPT = `You generate JavaScript tools. Respond with ONLY a JSON object, no other text.
|
|
5
|
+
|
|
6
|
+
Rules:
|
|
7
|
+
- Plain JavaScript only, no TypeScript
|
|
8
|
+
- No require/import/eval/process/fetch
|
|
9
|
+
- Must have an async function called "execute"
|
|
10
|
+
|
|
11
|
+
Example response:
|
|
12
|
+
{"name":"add","description":"Add two numbers","implementation":"async function execute(params) { try { return params.a + params.b; } catch(e) { return 0; } }","parameters":{"type":"object","properties":{"a":{"type":"number"},"b":{"type":"number"}},"required":["a","b"]},"reasoning":"Simple addition"}`;
|
|
25
13
|
|
|
26
14
|
export function buildGapAnalysisPrompt(
|
|
27
15
|
userIntent: string,
|
|
@@ -64,66 +52,19 @@ Respond with a JSON object:
|
|
|
64
52
|
|
|
65
53
|
export function buildToolGenerationPrompt(
|
|
66
54
|
gap: CapabilityGap,
|
|
67
|
-
|
|
68
|
-
|
|
55
|
+
_existingTools: Array<{ name: string; description: string }>,
|
|
56
|
+
_constraints?: {
|
|
69
57
|
maxLines?: number;
|
|
70
58
|
allowedModules?: string[];
|
|
71
59
|
securityLevel?: 'strict' | 'moderate' | 'permissive';
|
|
72
60
|
}
|
|
73
61
|
): string {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
- NO network requests
|
|
78
|
-
- NO eval() or Function constructor
|
|
79
|
-
- NO dynamic imports
|
|
80
|
-
- NO process or child_process access
|
|
81
|
-
- ONLY pure computation`,
|
|
82
|
-
moderate: `
|
|
83
|
-
- File system access ONLY if explicitly requested
|
|
84
|
-
- Network requests ONLY to whitelisted domains
|
|
85
|
-
- NO eval() or Function constructor
|
|
86
|
-
- NO dynamic imports`,
|
|
87
|
-
permissive: `
|
|
88
|
-
- File system access allowed with path validation
|
|
89
|
-
- Network requests allowed
|
|
90
|
-
- NO eval() or Function constructor`,
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
const security = constraints?.securityLevel || 'strict';
|
|
94
|
-
const maxLines = constraints?.maxLines || 100;
|
|
62
|
+
return `Create a tool named "${gap.suggestedToolName}".
|
|
63
|
+
Task: ${gap.description}
|
|
64
|
+
Formula/Logic: ${gap.requiredCapability}
|
|
95
65
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
CAPABILITY GAP:
|
|
99
|
-
- Description: ${gap.description}
|
|
100
|
-
- Required: ${gap.requiredCapability}
|
|
101
|
-
- Suggested name: ${gap.suggestedToolName}
|
|
102
|
-
- Complexity: ${gap.complexity}
|
|
103
|
-
|
|
104
|
-
EXISTING TOOLS (avoid duplication):
|
|
105
|
-
${existingTools.map((t) => `- ${t.name}: ${t.description}`).join('\n')}
|
|
106
|
-
|
|
107
|
-
CONSTRAINTS:
|
|
108
|
-
- Maximum ${maxLines} lines of code
|
|
109
|
-
- Security level: ${security}
|
|
110
|
-
- MUST use plain JavaScript (ES2020+), NO TypeScript syntax, NO type annotations, NO interfaces
|
|
111
|
-
- The "implementation" field must define an async function called "execute" that takes a plain object "params"
|
|
112
|
-
${securityRules[security]}
|
|
113
|
-
${constraints?.allowedModules ? `- Allowed modules: ${constraints.allowedModules.join(', ')}` : ''}
|
|
114
|
-
|
|
115
|
-
Generate a complete, self-contained tool following this exact structure:
|
|
116
|
-
{
|
|
117
|
-
"name": "${gap.suggestedToolName}",
|
|
118
|
-
"description": "Clear description",
|
|
119
|
-
"implementation": "async function execute(params) { ... }",
|
|
120
|
-
"parameters": {
|
|
121
|
-
"type": "object",
|
|
122
|
-
"properties": { ... },
|
|
123
|
-
"required": [ ... ]
|
|
124
|
-
},
|
|
125
|
-
"reasoning": "Implementation rationale"
|
|
126
|
-
}`;
|
|
66
|
+
Respond with ONLY this JSON (no other text):
|
|
67
|
+
{"name":"${gap.suggestedToolName}","description":"${gap.description}","implementation":"async function execute(params) { try { /* YOUR CODE HERE */ } catch(e) { throw e; } }","parameters":{"type":"object","properties":{/* DEFINE PARAMS */},"required":[/* REQUIRED PARAMS */]},"reasoning":"explanation"}`;
|
|
127
68
|
}
|
|
128
69
|
|
|
129
70
|
export function buildToolValidationPrompt(
|
|
@@ -244,32 +185,48 @@ export function parseGapAnalysisResponse(response: string): {
|
|
|
244
185
|
|
|
245
186
|
export function parseToolGenerationResponse(response: string): GeneratedTool | null {
|
|
246
187
|
const json = extractJson(response);
|
|
247
|
-
if (
|
|
248
|
-
|
|
188
|
+
if (json) {
|
|
189
|
+
try {
|
|
190
|
+
const parsed = JSON.parse(json);
|
|
191
|
+
if (parsed.name && parsed.implementation) {
|
|
192
|
+
return buildToolFromParsed(parsed);
|
|
193
|
+
}
|
|
194
|
+
} catch {}
|
|
249
195
|
}
|
|
250
196
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
parameters: parsed.parameters || { type: 'object', properties: {} },
|
|
263
|
-
createdAt: new Date(),
|
|
264
|
-
version: 1,
|
|
265
|
-
status: 'pending_validation',
|
|
266
|
-
metadata: {
|
|
267
|
-
reasoning: parsed.reasoning ? String(parsed.reasoning) : undefined,
|
|
268
|
-
},
|
|
269
|
-
};
|
|
270
|
-
} catch {
|
|
271
|
-
return null;
|
|
197
|
+
const fnRegex = /(?:async\s+)?function\s+execute\s*\([^)]*\)\s*\{[\s\S]*?\n\}/;
|
|
198
|
+
const fnMatch = fnRegex.exec(response);
|
|
199
|
+
if (fnMatch) {
|
|
200
|
+
const nameRegex = /["']?name["']?\s*[:=]\s*["']([^"']+)["']/;
|
|
201
|
+
const nameMatch = nameRegex.exec(response);
|
|
202
|
+
return buildToolFromParsed({
|
|
203
|
+
name: nameMatch?.[1] ?? 'generated_tool',
|
|
204
|
+
description: '',
|
|
205
|
+
implementation: fnMatch[0],
|
|
206
|
+
parameters: { type: 'object', properties: {} },
|
|
207
|
+
});
|
|
272
208
|
}
|
|
209
|
+
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
function buildToolFromParsed(parsed: Record<string, unknown>): GeneratedTool {
|
|
214
|
+
return {
|
|
215
|
+
id: `gen_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,
|
|
216
|
+
name: String(parsed.name),
|
|
217
|
+
description: String(parsed.description || ''),
|
|
218
|
+
implementation: String(parsed.implementation),
|
|
219
|
+
parameters: (parsed.parameters as GeneratedTool['parameters']) || {
|
|
220
|
+
type: 'object',
|
|
221
|
+
properties: {},
|
|
222
|
+
},
|
|
223
|
+
createdAt: new Date(),
|
|
224
|
+
version: 1,
|
|
225
|
+
status: 'pending_validation',
|
|
226
|
+
metadata: {
|
|
227
|
+
reasoning: parsed.reasoning ? String(parsed.reasoning) : undefined,
|
|
228
|
+
},
|
|
229
|
+
};
|
|
273
230
|
}
|
|
274
231
|
|
|
275
232
|
export function parseValidationResponse(response: string): ToolValidationResult | null {
|
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
export interface ToolGeneratorOptions {
|
|
20
20
|
llm: LLMBackend;
|
|
21
21
|
config: ToolSelfGenerationConfig;
|
|
22
|
+
model?: string;
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
export interface GenerationResult {
|
|
@@ -32,15 +33,18 @@ export interface GenerationResult {
|
|
|
32
33
|
export class ToolGenerator {
|
|
33
34
|
private readonly llm: LLMBackend;
|
|
34
35
|
private readonly config: ToolSelfGenerationConfig;
|
|
36
|
+
private readonly model: string;
|
|
35
37
|
private readonly validator: ToolValidator;
|
|
36
38
|
private readonly sandbox: ToolSandbox;
|
|
37
39
|
|
|
38
40
|
constructor(options: ToolGeneratorOptions) {
|
|
39
41
|
this.llm = options.llm;
|
|
40
42
|
this.config = options.config;
|
|
43
|
+
this.model = options.model ?? 'default';
|
|
41
44
|
this.validator = new ToolValidator({
|
|
42
45
|
llm: options.llm,
|
|
43
46
|
config: options.config,
|
|
47
|
+
model: options.model,
|
|
44
48
|
});
|
|
45
49
|
this.sandbox = new ToolSandbox(options.config.sandboxConfig);
|
|
46
50
|
}
|
|
@@ -67,13 +71,7 @@ export class ToolGenerator {
|
|
|
67
71
|
}
|
|
68
72
|
|
|
69
73
|
if (!currentTool) {
|
|
70
|
-
|
|
71
|
-
tool: null,
|
|
72
|
-
validationResult: null,
|
|
73
|
-
iterations,
|
|
74
|
-
success: false,
|
|
75
|
-
error: 'Failed to generate tool implementation',
|
|
76
|
-
};
|
|
74
|
+
continue;
|
|
77
75
|
}
|
|
78
76
|
|
|
79
77
|
validationResult = await this.validator.validate(currentTool, testCases);
|
|
@@ -240,6 +238,6 @@ export class ToolGenerator {
|
|
|
240
238
|
if (this.llm.complete) {
|
|
241
239
|
return this.llm.complete({ messages, temperature });
|
|
242
240
|
}
|
|
243
|
-
return this.llm.chat({ model:
|
|
241
|
+
return this.llm.chat({ model: this.model, messages, temperature });
|
|
244
242
|
}
|
|
245
243
|
}
|
|
@@ -273,7 +273,8 @@ export class ToolSandbox {
|
|
|
273
273
|
execute(params),
|
|
274
274
|
new Promise((_, reject) =>
|
|
275
275
|
setTimeout(
|
|
276
|
-
() =>
|
|
276
|
+
() =>
|
|
277
|
+
reject(new Error(`Execution timeout: exceeded ${this.config.maxExecutionTime}ms`)),
|
|
277
278
|
this.config.maxExecutionTime
|
|
278
279
|
)
|
|
279
280
|
),
|
|
@@ -10,6 +10,7 @@ import { buildToolValidationPrompt, parseValidationResponse } from './prompts';
|
|
|
10
10
|
export interface ToolValidatorOptions {
|
|
11
11
|
llm?: LLMBackend;
|
|
12
12
|
config: ToolSelfGenerationConfig;
|
|
13
|
+
model?: string;
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
interface ValidationRule {
|
|
@@ -141,12 +142,14 @@ const STATIC_VALIDATION_RULES: ValidationRule[] = [
|
|
|
141
142
|
export class ToolValidator {
|
|
142
143
|
private readonly llm?: LLMBackend;
|
|
143
144
|
private readonly config: ToolSelfGenerationConfig;
|
|
145
|
+
private readonly model: string;
|
|
144
146
|
private readonly sandbox: ToolSandbox;
|
|
145
147
|
private readonly customRules: ValidationRule[] = [];
|
|
146
148
|
|
|
147
149
|
constructor(options: ToolValidatorOptions) {
|
|
148
150
|
this.llm = options.llm;
|
|
149
151
|
this.config = options.config;
|
|
152
|
+
this.model = options.model ?? 'default';
|
|
150
153
|
this.sandbox = new ToolSandbox(options.config.sandboxConfig);
|
|
151
154
|
}
|
|
152
155
|
|
|
@@ -359,6 +362,6 @@ Be thorough but practical - focus on real issues.`,
|
|
|
359
362
|
if (this.llm.complete) {
|
|
360
363
|
return this.llm.complete({ messages, temperature });
|
|
361
364
|
}
|
|
362
|
-
return this.llm.chat({ model:
|
|
365
|
+
return this.llm.chat({ model: this.model, messages, temperature });
|
|
363
366
|
}
|
|
364
367
|
}
|
package/src/utils/index.ts
CHANGED
|
@@ -1,15 +1,23 @@
|
|
|
1
1
|
export { llmChat } from './llm-helper';
|
|
2
2
|
|
|
3
3
|
export function extractJson(text: string): string | null {
|
|
4
|
-
|
|
4
|
+
let cleaned = text;
|
|
5
|
+
|
|
6
|
+
const codeBlockRegex = /```(?:json)?\s*\n?([\s\S]*?)```/;
|
|
7
|
+
const codeBlockMatch = codeBlockRegex.exec(cleaned);
|
|
8
|
+
if (codeBlockMatch) {
|
|
9
|
+
cleaned = codeBlockMatch[1].trim();
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const start = cleaned.indexOf('{');
|
|
5
13
|
if (start === -1) return null;
|
|
6
14
|
|
|
7
15
|
let depth = 0;
|
|
8
16
|
let inString = false;
|
|
9
17
|
let escape = false;
|
|
10
18
|
|
|
11
|
-
for (let i = start; i <
|
|
12
|
-
const ch =
|
|
19
|
+
for (let i = start; i < cleaned.length; i++) {
|
|
20
|
+
const ch = cleaned[i];
|
|
13
21
|
|
|
14
22
|
if (escape) {
|
|
15
23
|
escape = false;
|
|
@@ -32,10 +40,22 @@ export function extractJson(text: string): string | null {
|
|
|
32
40
|
else if (ch === '}') {
|
|
33
41
|
depth--;
|
|
34
42
|
if (depth === 0) {
|
|
35
|
-
return
|
|
43
|
+
return cleaned.slice(start, i + 1);
|
|
36
44
|
}
|
|
37
45
|
}
|
|
38
46
|
}
|
|
39
47
|
|
|
48
|
+
if (depth > 0) {
|
|
49
|
+
let repaired = cleaned.slice(start);
|
|
50
|
+
repaired = repaired.replace(/,\s*$/, '');
|
|
51
|
+
repaired += '}'.repeat(depth);
|
|
52
|
+
try {
|
|
53
|
+
JSON.parse(repaired);
|
|
54
|
+
return repaired;
|
|
55
|
+
} catch {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
40
60
|
return null;
|
|
41
61
|
}
|