@cogitator-ai/self-modifying 17.0.13 → 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.js +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.js +3 -3
- 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 +15 -9
- package/dist/self-modifying-agent.js.map +1 -1
- package/dist/tool-generation/gap-analyzer.js +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.map +1 -1
- package/dist/tool-generation/tool-generator.js +4 -10
- 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.js +2 -2
- 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/constraints/modification-validator.ts +4 -1
- package/src/meta-reasoning/meta-reasoner.ts +3 -1
- package/src/self-modifying-agent.ts +19 -13
- package/src/tool-generation/prompts.ts +55 -98
- package/src/tool-generation/tool-generator.ts +1 -7
- package/src/tool-generation/tool-sandbox.ts +2 -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 {
|
|
@@ -71,13 +71,7 @@ export class ToolGenerator {
|
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
if (!currentTool) {
|
|
74
|
-
|
|
75
|
-
tool: null,
|
|
76
|
-
validationResult: null,
|
|
77
|
-
iterations,
|
|
78
|
-
success: false,
|
|
79
|
-
error: 'Failed to generate tool implementation',
|
|
80
|
-
};
|
|
74
|
+
continue;
|
|
81
75
|
}
|
|
82
76
|
|
|
83
77
|
validationResult = await this.validator.validate(currentTool, testCases);
|
|
@@ -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
|
),
|
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
|
}
|