@cogitator-ai/self-modifying 17.0.16 → 17.0.18
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/LICENSE +21 -0
- package/dist/architecture-evolution/capability-analyzer.d.ts.map +1 -1
- package/dist/architecture-evolution/capability-analyzer.js +6 -3
- package/dist/architecture-evolution/capability-analyzer.js.map +1 -1
- package/dist/architecture-evolution/evolution-strategy.d.ts.map +1 -1
- package/dist/architecture-evolution/evolution-strategy.js +4 -2
- package/dist/architecture-evolution/evolution-strategy.js.map +1 -1
- package/dist/architecture-evolution/parameter-optimizer.d.ts.map +1 -1
- package/dist/architecture-evolution/parameter-optimizer.js +32 -9
- package/dist/architecture-evolution/parameter-optimizer.js.map +1 -1
- package/dist/architecture-evolution/prompts.d.ts.map +1 -1
- package/dist/architecture-evolution/prompts.js +42 -4
- package/dist/architecture-evolution/prompts.js.map +1 -1
- package/dist/constraints/modification-validator.d.ts.map +1 -1
- package/dist/constraints/modification-validator.js +16 -5
- package/dist/constraints/modification-validator.js.map +1 -1
- package/dist/constraints/rollback-manager.d.ts +1 -0
- package/dist/constraints/rollback-manager.d.ts.map +1 -1
- package/dist/constraints/rollback-manager.js +25 -1
- package/dist/constraints/rollback-manager.js.map +1 -1
- package/dist/events/event-emitter.d.ts +0 -1
- package/dist/events/event-emitter.d.ts.map +1 -1
- package/dist/events/event-emitter.js +6 -10
- package/dist/events/event-emitter.js.map +1 -1
- 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 +22 -13
- package/dist/meta-reasoning/meta-reasoner.js.map +1 -1
- package/dist/meta-reasoning/observation-collector.d.ts.map +1 -1
- package/dist/meta-reasoning/observation-collector.js +6 -2
- package/dist/meta-reasoning/observation-collector.js.map +1 -1
- package/dist/meta-reasoning/prompts.d.ts.map +1 -1
- package/dist/meta-reasoning/prompts.js +5 -38
- package/dist/meta-reasoning/prompts.js.map +1 -1
- package/dist/meta-reasoning/strategy-selector.d.ts.map +1 -1
- package/dist/meta-reasoning/strategy-selector.js +6 -0
- package/dist/meta-reasoning/strategy-selector.js.map +1 -1
- package/dist/self-modifying-agent.d.ts +8 -1
- package/dist/self-modifying-agent.d.ts.map +1 -1
- package/dist/self-modifying-agent.js +108 -14
- package/dist/self-modifying-agent.js.map +1 -1
- package/dist/tool-generation/gap-analyzer.d.ts.map +1 -1
- package/dist/tool-generation/gap-analyzer.js +3 -2
- package/dist/tool-generation/gap-analyzer.js.map +1 -1
- package/dist/tool-generation/generated-tool-store.d.ts.map +1 -1
- package/dist/tool-generation/generated-tool-store.js +90 -10
- package/dist/tool-generation/generated-tool-store.js.map +1 -1
- package/dist/tool-generation/index.d.ts +1 -1
- package/dist/tool-generation/index.d.ts.map +1 -1
- package/dist/tool-generation/index.js +1 -1
- package/dist/tool-generation/index.js.map +1 -1
- 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 +65 -12
- package/dist/tool-generation/prompts.js.map +1 -1
- package/dist/tool-generation/tool-generator.d.ts +1 -1
- package/dist/tool-generation/tool-generator.d.ts.map +1 -1
- package/dist/tool-generation/tool-generator.js +55 -3
- package/dist/tool-generation/tool-generator.js.map +1 -1
- package/dist/tool-generation/tool-sandbox.d.ts +2 -6
- package/dist/tool-generation/tool-sandbox.d.ts.map +1 -1
- package/dist/tool-generation/tool-sandbox.js +220 -130
- package/dist/tool-generation/tool-sandbox.js.map +1 -1
- package/dist/tool-generation/tool-validator.d.ts +1 -0
- package/dist/tool-generation/tool-validator.d.ts.map +1 -1
- package/dist/tool-generation/tool-validator.js +48 -1
- package/dist/tool-generation/tool-validator.js.map +1 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +30 -5
- package/dist/utils/index.js.map +1 -1
- package/package.json +14 -14
- package/src/__tests__/self-modifying-agent.test.ts +42 -10
- package/src/architecture-evolution/capability-analyzer.ts +7 -4
- package/src/architecture-evolution/evolution-strategy.ts +5 -2
- package/src/architecture-evolution/parameter-optimizer.ts +39 -15
- package/src/architecture-evolution/prompts.ts +48 -4
- package/src/constraints/modification-validator.ts +19 -8
- package/src/constraints/rollback-manager.ts +20 -1
- package/src/events/event-emitter.ts +6 -15
- package/src/meta-reasoning/meta-reasoner.ts +22 -15
- package/src/meta-reasoning/observation-collector.ts +6 -2
- package/src/meta-reasoning/prompts.ts +5 -44
- package/src/meta-reasoning/strategy-selector.ts +6 -0
- package/src/self-modifying-agent.ts +123 -14
- package/src/tool-generation/gap-analyzer.ts +3 -2
- package/src/tool-generation/generated-tool-store.ts +97 -10
- package/src/tool-generation/index.ts +1 -1
- package/src/tool-generation/prompts.ts +81 -12
- package/src/tool-generation/tool-generator.ts +71 -3
- package/src/tool-generation/tool-sandbox.ts +241 -170
- package/src/tool-generation/tool-validator.ts +51 -1
- package/src/utils/index.ts +29 -5
|
@@ -7,9 +7,30 @@ Rules:
|
|
|
7
7
|
- Plain JavaScript only, no TypeScript
|
|
8
8
|
- No require/import/eval/process/fetch
|
|
9
9
|
- Must have an async function called "execute"
|
|
10
|
+
- Always propagate errors with throw, never silently swallow them
|
|
10
11
|
|
|
11
12
|
Example response:
|
|
12
|
-
{"name":"add","description":"Add two numbers","implementation":"async function execute(params) {
|
|
13
|
+
{"name":"add","description":"Add two numbers","implementation":"async function execute(params) { if (typeof params.a !== 'number' || typeof params.b !== 'number') { throw new Error('Parameters a and b must be numbers'); } return params.a + params.b; }","parameters":{"type":"object","properties":{"a":{"type":"number"},"b":{"type":"number"}},"required":["a","b"]},"reasoning":"Simple addition"}`;
|
|
14
|
+
|
|
15
|
+
const TOOL_NAME_REGEX = /^[a-z_][a-z0-9_]*$/;
|
|
16
|
+
|
|
17
|
+
function sanitizeForPrompt(value: string): string {
|
|
18
|
+
return value
|
|
19
|
+
.replace(/\\/g, '\\\\')
|
|
20
|
+
.replace(/"/g, '\\"')
|
|
21
|
+
.replace(/\n/g, '\\n')
|
|
22
|
+
.replace(/\r/g, '\\r')
|
|
23
|
+
.replace(/\t/g, '\\t');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function sanitizeToolName(name: string): string {
|
|
27
|
+
const cleaned = name
|
|
28
|
+
.toLowerCase()
|
|
29
|
+
.replace(/[^a-z0-9_]/g, '_')
|
|
30
|
+
.replace(/^[0-9]/, '_$&')
|
|
31
|
+
.slice(0, 64);
|
|
32
|
+
return TOOL_NAME_REGEX.test(cleaned) ? cleaned : `generated_tool_${Date.now()}`;
|
|
33
|
+
}
|
|
13
34
|
|
|
14
35
|
export function buildGapAnalysisPrompt(
|
|
15
36
|
userIntent: string,
|
|
@@ -52,19 +73,51 @@ Respond with a JSON object:
|
|
|
52
73
|
|
|
53
74
|
export function buildToolGenerationPrompt(
|
|
54
75
|
gap: CapabilityGap,
|
|
55
|
-
|
|
56
|
-
|
|
76
|
+
existingTools: Array<{ name: string; description: string }>,
|
|
77
|
+
constraints?: {
|
|
57
78
|
maxLines?: number;
|
|
58
79
|
allowedModules?: string[];
|
|
59
80
|
securityLevel?: 'strict' | 'moderate' | 'permissive';
|
|
60
81
|
}
|
|
61
82
|
): string {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
83
|
+
const toolName = sanitizeToolName(gap.suggestedToolName);
|
|
84
|
+
const description = sanitizeForPrompt(gap.description);
|
|
85
|
+
const capability = sanitizeForPrompt(gap.requiredCapability);
|
|
86
|
+
|
|
87
|
+
const existingToolsSection =
|
|
88
|
+
existingTools.length > 0
|
|
89
|
+
? `\nEXISTING TOOLS (avoid duplication, consider composing with these):\n${existingTools.map((t) => `- ${t.name}: ${t.description}`).join('\n')}\n`
|
|
90
|
+
: '';
|
|
91
|
+
|
|
92
|
+
const constraintsSection: string[] = [];
|
|
93
|
+
if (constraints?.maxLines) {
|
|
94
|
+
constraintsSection.push(`- Maximum ${constraints.maxLines} lines of code`);
|
|
95
|
+
}
|
|
96
|
+
if (constraints?.securityLevel) {
|
|
97
|
+
constraintsSection.push(`- Security level: ${constraints.securityLevel}`);
|
|
98
|
+
}
|
|
99
|
+
if (constraints?.allowedModules && constraints.allowedModules.length > 0) {
|
|
100
|
+
constraintsSection.push(
|
|
101
|
+
`- Only these modules may be referenced: ${constraints.allowedModules.join(', ')}`
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
if (constraints?.securityLevel === 'strict') {
|
|
105
|
+
constraintsSection.push(
|
|
106
|
+
'- No eval, Function constructor, process, global, globalThis, fetch, setTimeout, setInterval',
|
|
107
|
+
'- No bracket notation access to global objects',
|
|
108
|
+
'- No prototype chain manipulation'
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const constraintsText =
|
|
113
|
+
constraintsSection.length > 0 ? `\nCONSTRAINTS:\n${constraintsSection.join('\n')}\n` : '';
|
|
65
114
|
|
|
115
|
+
return `Create a tool named "${toolName}".
|
|
116
|
+
Task: ${description}
|
|
117
|
+
Formula/Logic: ${capability}
|
|
118
|
+
${existingToolsSection}${constraintsText}
|
|
66
119
|
Respond with ONLY this JSON (no other text):
|
|
67
|
-
{"name":"${
|
|
120
|
+
{"name":"${toolName}","description":"${description}","implementation":"async function execute(params) { /* YOUR CODE HERE — throw on invalid input */ }","parameters":{"type":"object","properties":{/* DEFINE PARAMS */},"required":[/* REQUIRED PARAMS */]},"reasoning":"explanation"}`;
|
|
68
121
|
}
|
|
69
122
|
|
|
70
123
|
export function buildToolValidationPrompt(
|
|
@@ -78,7 +131,7 @@ Name: ${tool.name}
|
|
|
78
131
|
Description: ${tool.description}
|
|
79
132
|
|
|
80
133
|
IMPLEMENTATION:
|
|
81
|
-
\`\`\`
|
|
134
|
+
\`\`\`javascript
|
|
82
135
|
${tool.implementation}
|
|
83
136
|
\`\`\`
|
|
84
137
|
|
|
@@ -123,7 +176,7 @@ Name: ${tool.name}
|
|
|
123
176
|
Description: ${tool.description}
|
|
124
177
|
|
|
125
178
|
CURRENT IMPLEMENTATION:
|
|
126
|
-
\`\`\`
|
|
179
|
+
\`\`\`javascript
|
|
127
180
|
${tool.implementation}
|
|
128
181
|
\`\`\`
|
|
129
182
|
|
|
@@ -165,7 +218,9 @@ export function parseGapAnalysisResponse(response: string): {
|
|
|
165
218
|
id: String(g.id || `gap_${idx}`),
|
|
166
219
|
description: String(g.description || ''),
|
|
167
220
|
requiredCapability: String(g.requiredCapability || ''),
|
|
168
|
-
suggestedToolName:
|
|
221
|
+
suggestedToolName: sanitizeToolName(
|
|
222
|
+
String(g.suggestedToolName || `generated_tool_${idx}`)
|
|
223
|
+
),
|
|
169
224
|
complexity: (['simple', 'moderate', 'complex'].includes(String(g.complexity))
|
|
170
225
|
? g.complexity
|
|
171
226
|
: 'moderate') as 'simple' | 'moderate' | 'complex',
|
|
@@ -194,15 +249,29 @@ export function parseToolGenerationResponse(response: string): GeneratedTool | n
|
|
|
194
249
|
} catch {}
|
|
195
250
|
}
|
|
196
251
|
|
|
197
|
-
const fnRegex = /(?:async\s+)?function\s+execute\s*\([^)]*\)\s*\{[\s\S]
|
|
252
|
+
const fnRegex = /(?:async\s+)?function\s+execute\s*\([^)]*\)\s*\{[\s\S]*\}/;
|
|
198
253
|
const fnMatch = fnRegex.exec(response);
|
|
199
254
|
if (fnMatch) {
|
|
255
|
+
let impl = fnMatch[0];
|
|
256
|
+
let braceDepth = 0;
|
|
257
|
+
let endIdx = impl.length;
|
|
258
|
+
const firstBrace = impl.indexOf('{');
|
|
259
|
+
for (let i = firstBrace; i < impl.length; i++) {
|
|
260
|
+
if (impl[i] === '{') braceDepth++;
|
|
261
|
+
if (impl[i] === '}') braceDepth--;
|
|
262
|
+
if (braceDepth === 0) {
|
|
263
|
+
endIdx = i + 1;
|
|
264
|
+
break;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
impl = impl.slice(0, endIdx);
|
|
268
|
+
|
|
200
269
|
const nameRegex = /["']?name["']?\s*[:=]\s*["']([^"']+)["']/;
|
|
201
270
|
const nameMatch = nameRegex.exec(response);
|
|
202
271
|
return buildToolFromParsed({
|
|
203
272
|
name: nameMatch?.[1] ?? 'generated_tool',
|
|
204
273
|
description: '',
|
|
205
|
-
implementation:
|
|
274
|
+
implementation: impl,
|
|
206
275
|
parameters: { type: 'object', properties: {} },
|
|
207
276
|
});
|
|
208
277
|
}
|
|
@@ -120,7 +120,7 @@ export class ToolGenerator {
|
|
|
120
120
|
async generateQuick(
|
|
121
121
|
description: string,
|
|
122
122
|
name: string,
|
|
123
|
-
|
|
123
|
+
parameters: Record<string, unknown>
|
|
124
124
|
): Promise<GeneratedTool | null> {
|
|
125
125
|
const gap: CapabilityGap = {
|
|
126
126
|
id: `quick_${Date.now()}`,
|
|
@@ -133,6 +133,14 @@ export class ToolGenerator {
|
|
|
133
133
|
};
|
|
134
134
|
|
|
135
135
|
const result = await this.generate(gap, []);
|
|
136
|
+
|
|
137
|
+
if (result.tool && Object.keys(parameters).length > 0) {
|
|
138
|
+
result.tool.parameters = {
|
|
139
|
+
type: 'object',
|
|
140
|
+
properties: parameters,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
|
|
136
144
|
return result.tool;
|
|
137
145
|
}
|
|
138
146
|
|
|
@@ -206,9 +214,17 @@ export class ToolGenerator {
|
|
|
206
214
|
createExecutableTool(generated: GeneratedTool): Tool {
|
|
207
215
|
const sandbox = this.sandbox;
|
|
208
216
|
const tool = generated;
|
|
217
|
+
const paramSchema = buildZodSchema(generated.parameters);
|
|
209
218
|
|
|
210
219
|
const execute = async (params: unknown): Promise<unknown> => {
|
|
211
|
-
const
|
|
220
|
+
const parsed = paramSchema.safeParse(params);
|
|
221
|
+
if (!parsed.success) {
|
|
222
|
+
throw new Error(
|
|
223
|
+
`Invalid parameters: ${parsed.error.issues.map((i) => `${i.path.join('.')}: ${i.message}`).join('; ')}`
|
|
224
|
+
);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
const result = await sandbox.execute(tool, parsed.data);
|
|
212
228
|
if (!result.success) {
|
|
213
229
|
throw new Error(result.error ?? 'Tool execution failed');
|
|
214
230
|
}
|
|
@@ -218,7 +234,7 @@ export class ToolGenerator {
|
|
|
218
234
|
return {
|
|
219
235
|
name: generated.name,
|
|
220
236
|
description: generated.description,
|
|
221
|
-
parameters:
|
|
237
|
+
parameters: paramSchema as ZodType<unknown>,
|
|
222
238
|
execute,
|
|
223
239
|
toJSON: () => ({
|
|
224
240
|
name: generated.name,
|
|
@@ -241,3 +257,55 @@ export class ToolGenerator {
|
|
|
241
257
|
return this.llm.chat({ model: this.model, messages, temperature });
|
|
242
258
|
}
|
|
243
259
|
}
|
|
260
|
+
|
|
261
|
+
function buildZodSchema(parameters: Record<string, unknown>): ZodType<unknown> {
|
|
262
|
+
if (
|
|
263
|
+
parameters.type !== 'object' ||
|
|
264
|
+
!parameters.properties ||
|
|
265
|
+
typeof parameters.properties !== 'object'
|
|
266
|
+
) {
|
|
267
|
+
return z.record(z.string(), z.unknown());
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
const properties = parameters.properties as Record<string, Record<string, unknown>>;
|
|
271
|
+
const required = Array.isArray(parameters.required)
|
|
272
|
+
? new Set(parameters.required as string[])
|
|
273
|
+
: new Set<string>();
|
|
274
|
+
|
|
275
|
+
const shape: Record<string, ZodType<unknown>> = {};
|
|
276
|
+
|
|
277
|
+
for (const [key, propSchema] of Object.entries(properties)) {
|
|
278
|
+
let fieldSchema: ZodType<unknown> = jsonTypeToZod(propSchema.type as string | undefined);
|
|
279
|
+
|
|
280
|
+
if (!required.has(key)) {
|
|
281
|
+
fieldSchema = fieldSchema.optional() as ZodType<unknown>;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
shape[key] = fieldSchema;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
if (Object.keys(shape).length === 0) {
|
|
288
|
+
return z.record(z.string(), z.unknown());
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
return z.object(shape).passthrough() as ZodType<unknown>;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
function jsonTypeToZod(type?: string): ZodType<unknown> {
|
|
295
|
+
switch (type) {
|
|
296
|
+
case 'string':
|
|
297
|
+
return z.string();
|
|
298
|
+
case 'number':
|
|
299
|
+
return z.number();
|
|
300
|
+
case 'integer':
|
|
301
|
+
return z.number().int();
|
|
302
|
+
case 'boolean':
|
|
303
|
+
return z.boolean();
|
|
304
|
+
case 'array':
|
|
305
|
+
return z.array(z.unknown());
|
|
306
|
+
case 'object':
|
|
307
|
+
return z.record(z.string(), z.unknown());
|
|
308
|
+
default:
|
|
309
|
+
return z.unknown();
|
|
310
|
+
}
|
|
311
|
+
}
|