@cogitator-ai/self-modifying 17.0.10 → 17.0.13

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.
Files changed (37) hide show
  1. package/dist/architecture-evolution/capability-analyzer.d.ts +2 -0
  2. package/dist/architecture-evolution/capability-analyzer.d.ts.map +1 -1
  3. package/dist/architecture-evolution/capability-analyzer.js +3 -1
  4. package/dist/architecture-evolution/capability-analyzer.js.map +1 -1
  5. package/dist/architecture-evolution/parameter-optimizer.d.ts +2 -0
  6. package/dist/architecture-evolution/parameter-optimizer.d.ts.map +1 -1
  7. package/dist/architecture-evolution/parameter-optimizer.js +4 -1
  8. package/dist/architecture-evolution/parameter-optimizer.js.map +1 -1
  9. package/dist/self-modifying-agent.d.ts +1 -0
  10. package/dist/self-modifying-agent.d.ts.map +1 -1
  11. package/dist/self-modifying-agent.js +81 -16
  12. package/dist/self-modifying-agent.js.map +1 -1
  13. package/dist/tool-generation/gap-analyzer.d.ts +2 -0
  14. package/dist/tool-generation/gap-analyzer.d.ts.map +1 -1
  15. package/dist/tool-generation/gap-analyzer.js +3 -1
  16. package/dist/tool-generation/gap-analyzer.js.map +1 -1
  17. package/dist/tool-generation/prompts.d.ts +1 -1
  18. package/dist/tool-generation/prompts.d.ts.map +1 -1
  19. package/dist/tool-generation/prompts.js +16 -12
  20. package/dist/tool-generation/prompts.js.map +1 -1
  21. package/dist/tool-generation/tool-generator.d.ts +2 -0
  22. package/dist/tool-generation/tool-generator.d.ts.map +1 -1
  23. package/dist/tool-generation/tool-generator.js +4 -1
  24. package/dist/tool-generation/tool-generator.js.map +1 -1
  25. package/dist/tool-generation/tool-validator.d.ts +2 -0
  26. package/dist/tool-generation/tool-validator.d.ts.map +1 -1
  27. package/dist/tool-generation/tool-validator.js +3 -4
  28. package/dist/tool-generation/tool-validator.js.map +1 -1
  29. package/package.json +1 -1
  30. package/src/__tests__/self-modifying-agent.test.ts +197 -0
  31. package/src/architecture-evolution/capability-analyzer.ts +4 -1
  32. package/src/architecture-evolution/parameter-optimizer.ts +5 -1
  33. package/src/self-modifying-agent.ts +90 -16
  34. package/src/tool-generation/gap-analyzer.ts +4 -1
  35. package/src/tool-generation/prompts.ts +16 -12
  36. package/src/tool-generation/tool-generator.ts +5 -1
  37. package/src/tool-generation/tool-validator.ts +4 -6
@@ -11,6 +11,9 @@ import type {
11
11
  ModificationCheckpoint,
12
12
  SelfModifyingEvent,
13
13
  CapabilityGap,
14
+ Message,
15
+ ToolSchema,
16
+ ToolContext,
14
17
  } from '@cogitator-ai/types';
15
18
 
16
19
  import { SelfModifyingEventEmitter } from './events';
@@ -67,18 +70,19 @@ export class SelfModifyingAgent {
67
70
  this.config = this.mergeConfig(options.config);
68
71
 
69
72
  const toolGenConfig = this.config.toolGeneration;
70
- this.gapAnalyzer = new GapAnalyzer({ llm: this.llm, config: toolGenConfig });
71
- this.toolGenerator = new ToolGenerator({ llm: this.llm, config: toolGenConfig });
73
+ const agentModel = this.agent.model;
74
+ this.gapAnalyzer = new GapAnalyzer({ llm: this.llm, config: toolGenConfig, model: agentModel });
75
+ this.toolGenerator = new ToolGenerator({ llm: this.llm, config: toolGenConfig, model: agentModel });
72
76
  this.toolStore = new InMemoryGeneratedToolStore();
73
77
 
74
78
  this.metaReasoner = new MetaReasoner({
75
79
  llm: this.llm,
76
- model: 'default',
80
+ model: agentModel ?? 'default',
77
81
  config: this.config.metaReasoning,
78
82
  });
79
83
 
80
84
  const baseArchConfig: ArchitectureConfig = {
81
- model: 'default',
85
+ model: agentModel ?? 'default',
82
86
  temperature: 0.7,
83
87
  maxTokens: 4096,
84
88
  toolStrategy: 'sequential',
@@ -89,11 +93,13 @@ export class SelfModifyingAgent {
89
93
  llm: this.llm,
90
94
  config: this.config.architectureEvolution,
91
95
  baseConfig: baseArchConfig,
96
+ model: agentModel,
92
97
  });
93
98
 
94
99
  this.capabilityAnalyzer = new CapabilityAnalyzer({
95
100
  llm: this.llm,
96
101
  enableLLMAnalysis: true,
102
+ model: agentModel,
97
103
  });
98
104
 
99
105
  this.modificationValidator = new ModificationValidator({
@@ -372,11 +378,8 @@ export class SelfModifyingAgent {
372
378
  reflective: { mode: 'reflective', temperature: 0.4, depth: 3 },
373
379
  exploratory: { mode: 'exploratory', temperature: 0.7, depth: 2 },
374
380
  },
375
- maxAssessmentsPerRun: 5,
376
- maxAdaptationsPerRun: 3,
377
381
  maxMetaAssessments: 5,
378
382
  maxAdaptations: 3,
379
- assessmentCooldown: 10000,
380
383
  metaAssessmentCooldown: 10000,
381
384
  adaptationCooldown: 15000,
382
385
  triggers: ['on_failure', 'on_low_confidence', 'periodic'],
@@ -598,19 +601,90 @@ export class SelfModifyingAgent {
598
601
  }
599
602
 
600
603
  private async executeAgentStep(input: string): Promise<string> {
601
- const response = await this.llm.chat({
602
- model: this.currentContext?.currentConfig.model ?? this.agent.model ?? 'default',
603
- messages: [
604
- ...(this.agent.instructions
605
- ? [{ role: 'system' as const, content: this.agent.instructions }]
606
- : []),
607
- { role: 'user' as const, content: input },
608
- ],
604
+ const tools = this.currentContext?.tools ?? [];
605
+ const toolSchemas = this.buildToolSchemas(tools);
606
+ const toolMap = new Map<string, Tool>();
607
+ for (const t of tools) {
608
+ toolMap.set(t.name, t);
609
+ }
610
+
611
+ const model = this.currentContext?.currentConfig.model ?? this.agent.model ?? 'default';
612
+ const messages: Message[] = [
613
+ ...(this.agent.instructions
614
+ ? [{ role: 'system' as const, content: this.agent.instructions }]
615
+ : []),
616
+ { role: 'user' as const, content: input },
617
+ ];
618
+
619
+ const maxToolRounds = 10;
620
+ for (let round = 0; round < maxToolRounds; round++) {
621
+ const response = await this.llm.chat({
622
+ model,
623
+ messages,
624
+ tools: toolSchemas.length > 0 ? toolSchemas : undefined,
625
+ temperature: this.currentContext?.currentConfig.temperature,
626
+ maxTokens: this.currentContext?.currentConfig.maxTokens,
627
+ });
628
+
629
+ if (response.finishReason !== 'tool_calls' || !response.toolCalls?.length) {
630
+ return response.content;
631
+ }
632
+
633
+ messages.push({
634
+ role: 'assistant',
635
+ content: response.content,
636
+ toolCalls: response.toolCalls,
637
+ } as Message);
638
+
639
+ for (const toolCall of response.toolCalls) {
640
+ const t = toolMap.get(toolCall.name);
641
+ let result: unknown;
642
+
643
+ if (!t) {
644
+ result = { error: `Tool "${toolCall.name}" not found` };
645
+ } else {
646
+ try {
647
+ const ctx: ToolContext = {
648
+ agentId: this.agent.name || 'self-modifying',
649
+ runId: this.currentContext?.runId || 'unknown',
650
+ signal: AbortSignal.timeout(30_000),
651
+ };
652
+ result = await t.execute(toolCall.arguments, ctx);
653
+ } catch (err) {
654
+ result = { error: err instanceof Error ? err.message : String(err) };
655
+ }
656
+ }
657
+
658
+ messages.push({
659
+ role: 'tool' as const,
660
+ content: typeof result === 'string' ? result : JSON.stringify(result),
661
+ toolCallId: toolCall.id,
662
+ name: toolCall.name,
663
+ });
664
+ }
665
+ }
666
+
667
+ const finalResponse = await this.llm.chat({
668
+ model,
669
+ messages,
609
670
  temperature: this.currentContext?.currentConfig.temperature,
610
671
  maxTokens: this.currentContext?.currentConfig.maxTokens,
611
672
  });
673
+ return finalResponse.content;
674
+ }
612
675
 
613
- return response.content;
676
+ private buildToolSchemas(tools: Tool[]): ToolSchema[] {
677
+ return tools
678
+ .map((t) => {
679
+ if (typeof t.toJSON === 'function') {
680
+ return t.toJSON() as ToolSchema;
681
+ }
682
+ return {
683
+ name: t.name,
684
+ description: t.description,
685
+ parameters: { type: 'object' as const, properties: {} },
686
+ };
687
+ });
614
688
  }
615
689
 
616
690
  private estimateConfidence(output: string): number {
@@ -10,16 +10,19 @@ import { buildGapAnalysisPrompt, parseGapAnalysisResponse } from './prompts';
10
10
  export interface GapAnalyzerOptions {
11
11
  llm: LLMBackend;
12
12
  config: ToolSelfGenerationConfig;
13
+ model?: string;
13
14
  }
14
15
 
15
16
  export class GapAnalyzer {
16
17
  private readonly llm: LLMBackend;
17
18
  private readonly config: ToolSelfGenerationConfig;
19
+ private readonly model: string;
18
20
  private readonly analysisCache = new Map<string, GapAnalysisResult>();
19
21
 
20
22
  constructor(options: GapAnalyzerOptions) {
21
23
  this.llm = options.llm;
22
24
  this.config = options.config;
25
+ this.model = options.model ?? 'default';
23
26
  }
24
27
 
25
28
  async analyze(
@@ -233,6 +236,6 @@ Consider tool composition before suggesting new tools.`,
233
236
  if (this.llm.complete) {
234
237
  return this.llm.complete({ messages, temperature });
235
238
  }
236
- return this.llm.chat({ model: 'default', messages, temperature });
239
+ return this.llm.chat({ model: this.model, messages, temperature });
237
240
  }
238
241
  }
@@ -1,23 +1,24 @@
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 are an expert TypeScript developer specializing in creating tools for AI agents.
5
- Your task is to generate safe, efficient, and well-typed tool implementations.
4
+ export const TOOL_GENERATION_SYSTEM_PROMPT = `You are an expert JavaScript developer specializing in creating tools for AI agents.
5
+ Your task is to generate safe, efficient tool implementations.
6
6
 
7
7
  CRITICAL CONSTRAINTS:
8
- 1. Generate ONLY pure TypeScript functions - no external dependencies beyond built-in modules
9
- 2. All generated code must be self-contained and synchronous where possible
10
- 3. Never generate code that accesses file system, network, or system resources unless explicitly requested
11
- 4. Always include proper error handling
12
- 5. Use Zod for parameter validation when schemas are provided
13
- 6. Follow the exact Tool interface structure
8
+ 1. Generate ONLY plain JavaScript (ES2020+) - NO TypeScript syntax, NO type annotations, NO interfaces
9
+ 2. No external dependencies - only built-in globals (Math, JSON, Date, Array, Object, String, Number, Boolean, RegExp, Map, Set, Error)
10
+ 3. All generated code must be self-contained
11
+ 4. Never generate code that accesses file system, network, or system resources
12
+ 5. Always include proper error handling with try-catch
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
14
15
 
15
16
  OUTPUT FORMAT:
16
17
  Return a JSON object with:
17
18
  {
18
19
  "name": "tool_name",
19
20
  "description": "Clear description of what the tool does",
20
- "implementation": "// TypeScript code as a string",
21
+ "implementation": "async function execute(params) { ... }",
21
22
  "parameters": { "type": "object", "properties": {...}, "required": [...] },
22
23
  "reasoning": "Why this implementation was chosen"
23
24
  }`;
@@ -92,7 +93,7 @@ export function buildToolGenerationPrompt(
92
93
  const security = constraints?.securityLevel || 'strict';
93
94
  const maxLines = constraints?.maxLines || 100;
94
95
 
95
- return `Generate a TypeScript tool implementation for the following capability gap.
96
+ return `Generate a plain JavaScript tool implementation for the following capability gap.
96
97
 
97
98
  CAPABILITY GAP:
98
99
  - Description: ${gap.description}
@@ -106,6 +107,8 @@ ${existingTools.map((t) => `- ${t.name}: ${t.description}`).join('\n')}
106
107
  CONSTRAINTS:
107
108
  - Maximum ${maxLines} lines of code
108
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"
109
112
  ${securityRules[security]}
110
113
  ${constraints?.allowedModules ? `- Allowed modules: ${constraints.allowedModules.join(', ')}` : ''}
111
114
 
@@ -113,7 +116,7 @@ Generate a complete, self-contained tool following this exact structure:
113
116
  {
114
117
  "name": "${gap.suggestedToolName}",
115
118
  "description": "Clear description",
116
- "implementation": "async function execute(params: Params): Promise<Result> { ... }",
119
+ "implementation": "async function execute(params) { ... }",
117
120
  "parameters": {
118
121
  "type": "object",
119
122
  "properties": { ... },
@@ -190,11 +193,12 @@ SUGGESTIONS:
190
193
  ${validationResult.suggestions.map((s, idx) => `${idx + 1}. ${s}`).join('\n')}
191
194
 
192
195
  Generate an improved implementation that addresses ALL issues.
196
+ IMPORTANT: Use plain JavaScript only (NO TypeScript, NO type annotations). The execute function signature must be: async function execute(params) { ... }
193
197
  Respond with the same JSON format as before:
194
198
  {
195
199
  "name": "${tool.name}",
196
200
  "description": "Updated description if needed",
197
- "implementation": "// Improved TypeScript code",
201
+ "implementation": "async function execute(params) { ... }",
198
202
  "parameters": { ... },
199
203
  "reasoning": "What was changed and why"
200
204
  }`;
@@ -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
  }
@@ -240,6 +244,6 @@ export class ToolGenerator {
240
244
  if (this.llm.complete) {
241
245
  return this.llm.complete({ messages, temperature });
242
246
  }
243
- return this.llm.chat({ model: 'default', messages, temperature });
247
+ return this.llm.chat({ model: this.model, messages, temperature });
244
248
  }
245
249
  }
@@ -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
 
@@ -303,11 +306,6 @@ Be thorough but practical - focus on real issues.`,
303
306
  validInput[key] = this.generateSampleValue(schema.type, schema.default);
304
307
  }
305
308
  testCases.push({ input: validInput });
306
-
307
- const required = params.required as string[] | undefined;
308
- testCases.push({ input: {}, shouldThrow: (required?.length ?? 0) > 0 });
309
-
310
- testCases.push({ input: null, shouldThrow: true });
311
309
  }
312
310
 
313
311
  return testCases;
@@ -364,6 +362,6 @@ Be thorough but practical - focus on real issues.`,
364
362
  if (this.llm.complete) {
365
363
  return this.llm.complete({ messages, temperature });
366
364
  }
367
- return this.llm.chat({ model: 'default', messages, temperature });
365
+ return this.llm.chat({ model: this.model, messages, temperature });
368
366
  }
369
367
  }