@cogitator-ai/self-modifying 17.0.17 → 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.
Files changed (114) hide show
  1. package/README.md +112 -48
  2. package/dist/architecture-evolution/capability-analyzer.d.ts.map +1 -1
  3. package/dist/architecture-evolution/capability-analyzer.js +44 -40
  4. package/dist/architecture-evolution/capability-analyzer.js.map +1 -1
  5. package/dist/architecture-evolution/evolution-strategy.d.ts.map +1 -1
  6. package/dist/architecture-evolution/evolution-strategy.js +4 -2
  7. package/dist/architecture-evolution/evolution-strategy.js.map +1 -1
  8. package/dist/architecture-evolution/index.d.ts +2 -2
  9. package/dist/architecture-evolution/index.d.ts.map +1 -1
  10. package/dist/architecture-evolution/index.js +1 -1
  11. package/dist/architecture-evolution/index.js.map +1 -1
  12. package/dist/architecture-evolution/parameter-optimizer.d.ts +5 -4
  13. package/dist/architecture-evolution/parameter-optimizer.d.ts.map +1 -1
  14. package/dist/architecture-evolution/parameter-optimizer.js +62 -34
  15. package/dist/architecture-evolution/parameter-optimizer.js.map +1 -1
  16. package/dist/architecture-evolution/prompts.d.ts +21 -2
  17. package/dist/architecture-evolution/prompts.d.ts.map +1 -1
  18. package/dist/architecture-evolution/prompts.js +189 -37
  19. package/dist/architecture-evolution/prompts.js.map +1 -1
  20. package/dist/constraints/modification-validator.d.ts +1 -0
  21. package/dist/constraints/modification-validator.d.ts.map +1 -1
  22. package/dist/constraints/modification-validator.js +45 -18
  23. package/dist/constraints/modification-validator.js.map +1 -1
  24. package/dist/constraints/rollback-manager.d.ts +1 -0
  25. package/dist/constraints/rollback-manager.d.ts.map +1 -1
  26. package/dist/constraints/rollback-manager.js +25 -1
  27. package/dist/constraints/rollback-manager.js.map +1 -1
  28. package/dist/events/event-emitter.d.ts +0 -1
  29. package/dist/events/event-emitter.d.ts.map +1 -1
  30. package/dist/events/event-emitter.js +6 -10
  31. package/dist/events/event-emitter.js.map +1 -1
  32. package/dist/index.d.ts +4 -4
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +3 -3
  35. package/dist/index.js.map +1 -1
  36. package/dist/meta-reasoning/meta-reasoner.d.ts +4 -1
  37. package/dist/meta-reasoning/meta-reasoner.d.ts.map +1 -1
  38. package/dist/meta-reasoning/meta-reasoner.js +120 -43
  39. package/dist/meta-reasoning/meta-reasoner.js.map +1 -1
  40. package/dist/meta-reasoning/observation-collector.d.ts.map +1 -1
  41. package/dist/meta-reasoning/observation-collector.js +6 -2
  42. package/dist/meta-reasoning/observation-collector.js.map +1 -1
  43. package/dist/meta-reasoning/prompts.d.ts +10 -14
  44. package/dist/meta-reasoning/prompts.d.ts.map +1 -1
  45. package/dist/meta-reasoning/prompts.js +108 -33
  46. package/dist/meta-reasoning/prompts.js.map +1 -1
  47. package/dist/meta-reasoning/strategy-selector.d.ts.map +1 -1
  48. package/dist/meta-reasoning/strategy-selector.js +6 -0
  49. package/dist/meta-reasoning/strategy-selector.js.map +1 -1
  50. package/dist/self-modifying-agent.d.ts +88 -15
  51. package/dist/self-modifying-agent.d.ts.map +1 -1
  52. package/dist/self-modifying-agent.js +583 -376
  53. package/dist/self-modifying-agent.js.map +1 -1
  54. package/dist/tool-generation/gap-analyzer.d.ts +0 -1
  55. package/dist/tool-generation/gap-analyzer.d.ts.map +1 -1
  56. package/dist/tool-generation/gap-analyzer.js +16 -15
  57. package/dist/tool-generation/gap-analyzer.js.map +1 -1
  58. package/dist/tool-generation/generated-tool-store.d.ts.map +1 -1
  59. package/dist/tool-generation/generated-tool-store.js +90 -10
  60. package/dist/tool-generation/generated-tool-store.js.map +1 -1
  61. package/dist/tool-generation/index.d.ts +3 -3
  62. package/dist/tool-generation/index.d.ts.map +1 -1
  63. package/dist/tool-generation/index.js +2 -2
  64. package/dist/tool-generation/index.js.map +1 -1
  65. package/dist/tool-generation/prompts.d.ts +4 -3
  66. package/dist/tool-generation/prompts.d.ts.map +1 -1
  67. package/dist/tool-generation/prompts.js +96 -18
  68. package/dist/tool-generation/prompts.js.map +1 -1
  69. package/dist/tool-generation/tool-generator.d.ts +6 -6
  70. package/dist/tool-generation/tool-generator.d.ts.map +1 -1
  71. package/dist/tool-generation/tool-generator.js +88 -23
  72. package/dist/tool-generation/tool-generator.js.map +1 -1
  73. package/dist/tool-generation/tool-sandbox.d.ts +10 -11
  74. package/dist/tool-generation/tool-sandbox.d.ts.map +1 -1
  75. package/dist/tool-generation/tool-sandbox.js +346 -156
  76. package/dist/tool-generation/tool-sandbox.js.map +1 -1
  77. package/dist/tool-generation/tool-validator.d.ts +4 -8
  78. package/dist/tool-generation/tool-validator.d.ts.map +1 -1
  79. package/dist/tool-generation/tool-validator.js +74 -28
  80. package/dist/tool-generation/tool-validator.js.map +1 -1
  81. package/dist/utils/index.d.ts.map +1 -1
  82. package/dist/utils/index.js +30 -5
  83. package/dist/utils/index.js.map +1 -1
  84. package/dist/utils/llm-helper.d.ts.map +1 -1
  85. package/dist/utils/llm-helper.js +1 -0
  86. package/dist/utils/llm-helper.js.map +1 -1
  87. package/package.json +3 -12
  88. package/src/__tests__/component-regressions.test.ts +599 -0
  89. package/src/__tests__/meta-reasoning.test.ts +5 -1
  90. package/src/__tests__/sandbox-security.test.ts +186 -0
  91. package/src/__tests__/self-modifying-agent.test.ts +405 -11
  92. package/src/architecture-evolution/capability-analyzer.ts +63 -44
  93. package/src/architecture-evolution/evolution-strategy.ts +5 -2
  94. package/src/architecture-evolution/index.ts +2 -0
  95. package/src/architecture-evolution/parameter-optimizer.ts +82 -40
  96. package/src/architecture-evolution/prompts.ts +224 -42
  97. package/src/constraints/modification-validator.ts +48 -21
  98. package/src/constraints/rollback-manager.ts +20 -1
  99. package/src/events/event-emitter.ts +6 -15
  100. package/src/index.ts +14 -0
  101. package/src/meta-reasoning/meta-reasoner.ts +124 -52
  102. package/src/meta-reasoning/observation-collector.ts +6 -2
  103. package/src/meta-reasoning/prompts.ts +131 -56
  104. package/src/meta-reasoning/strategy-selector.ts +6 -0
  105. package/src/self-modifying-agent.ts +797 -413
  106. package/src/tool-generation/gap-analyzer.ts +21 -19
  107. package/src/tool-generation/generated-tool-store.ts +97 -10
  108. package/src/tool-generation/index.ts +13 -3
  109. package/src/tool-generation/prompts.ts +120 -18
  110. package/src/tool-generation/tool-generator.ts +120 -26
  111. package/src/tool-generation/tool-sandbox.ts +408 -206
  112. package/src/tool-generation/tool-validator.ts +90 -37
  113. package/src/utils/index.ts +29 -5
  114. package/src/utils/llm-helper.ts +1 -0
@@ -4,8 +4,9 @@ import type {
4
4
  LLMBackend,
5
5
  ToolSelfGenerationConfig,
6
6
  } from '@cogitator-ai/types';
7
- import { ToolSandbox } from './tool-sandbox';
7
+ import { ToolSandbox, type SandboxTestCase } from './tool-sandbox';
8
8
  import { buildToolValidationPrompt, parseValidationResponse } from './prompts';
9
+ import { llmChat } from '../utils/llm-helper';
9
10
 
10
11
  export interface ToolValidatorOptions {
11
12
  llm?: LLMBackend;
@@ -13,7 +14,14 @@ export interface ToolValidatorOptions {
13
14
  model?: string;
14
15
  }
15
16
 
16
- interface ValidationRule {
17
+ interface JsonPropertySchema {
18
+ type?: string;
19
+ default?: unknown;
20
+ enum?: unknown[];
21
+ examples?: unknown[];
22
+ }
23
+
24
+ export interface ValidationRule {
17
25
  id: string;
18
26
  name: string;
19
27
  severity: 'error' | 'warning' | 'info';
@@ -109,9 +117,9 @@ const STATIC_VALIDATION_RULES: ValidationRule[] = [
109
117
  severity: 'error',
110
118
  check: (code) => {
111
119
  if (code.includes('child_process')) return 'Uses child_process';
112
- if (/\bexec\s*\(/.test(code)) return 'Uses exec()';
113
- if (/\bspawn\s*\(/.test(code)) return 'Uses spawn()';
114
- if (/\bexecSync\s*\(/.test(code)) return 'Uses execSync()';
120
+ if (/(?<![.\w$])exec\s*\(/.test(code)) return 'Uses exec()';
121
+ if (/\bspawn(?:Sync)?\s*\(/.test(code)) return 'Uses spawn()';
122
+ if (/\bexec(?:Sync|File|FileSync)\s*\(/.test(code)) return 'Uses execSync()/execFile()';
115
123
  return null;
116
124
  },
117
125
  },
@@ -155,7 +163,7 @@ export class ToolValidator {
155
163
 
156
164
  async validate(
157
165
  tool: GeneratedTool,
158
- testCases?: Array<{ input: unknown; expectedOutput?: unknown; shouldThrow?: boolean }>
166
+ testCases?: SandboxTestCase[]
159
167
  ): Promise<ToolValidationResult> {
160
168
  const securityIssues: string[] = [];
161
169
  const logicIssues: string[] = [];
@@ -244,7 +252,7 @@ export class ToolValidator {
244
252
  if (result) {
245
253
  if (rule.severity === 'error') {
246
254
  errors.push(`[${rule.id}] ${result}`);
247
- } else if (rule.severity === 'warning') {
255
+ } else {
248
256
  warnings.push(`[${rule.id}] ${result}`);
249
257
  }
250
258
  }
@@ -255,7 +263,7 @@ export class ToolValidator {
255
263
 
256
264
  private async runLLMValidation(
257
265
  tool: GeneratedTool,
258
- testCases: Array<{ input: unknown; expectedOutput?: unknown; shouldThrow?: boolean }>
266
+ testCases: SandboxTestCase[]
259
267
  ): Promise<ToolValidationResult | null> {
260
268
  if (!this.llm) return null;
261
269
 
@@ -268,11 +276,14 @@ export class ToolValidator {
268
276
  ? `Should return ${JSON.stringify(tc.expectedOutput)}`
269
277
  : tc.shouldThrow
270
278
  ? 'Should throw an error'
271
- : 'Should execute successfully',
279
+ : tc.allowThrow
280
+ ? 'Should either return a result or throw a descriptive error'
281
+ : 'Should execute successfully',
272
282
  }))
273
283
  );
274
284
 
275
- const response = await this.callLLM(
285
+ const content = await llmChat(
286
+ this.llm,
276
287
  [
277
288
  {
278
289
  role: 'system',
@@ -282,39 +293,73 @@ Be thorough but practical - focus on real issues.`,
282
293
  },
283
294
  { role: 'user', content: prompt },
284
295
  ],
285
- 0.2
296
+ { model: this.model, temperature: 0.2 }
286
297
  );
287
298
 
288
- return response ? parseValidationResponse(response.content) : null;
299
+ return parseValidationResponse(content);
289
300
  } catch {
290
301
  return null;
291
302
  }
292
303
  }
293
304
 
294
- private generateBasicTestCases(
295
- tool: GeneratedTool
296
- ): Array<{ input: unknown; expectedOutput?: unknown; shouldThrow?: boolean }> {
297
- const testCases: Array<{ input: unknown; expectedOutput?: unknown; shouldThrow?: boolean }> =
298
- [];
305
+ private generateBasicTestCases(tool: GeneratedTool): SandboxTestCase[] {
299
306
  const params = tool.parameters;
300
307
 
301
- if (params.type === 'object' && params.properties) {
302
- const validInput: Record<string, unknown> = {};
303
- const properties = params.properties as Record<string, { type?: string; default?: unknown }>;
308
+ if (params.type !== 'object' || !params.properties || typeof params.properties !== 'object') {
309
+ return [{ input: {} }];
310
+ }
311
+
312
+ const properties = params.properties as Record<string, JsonPropertySchema>;
313
+ const required = new Set(
314
+ Array.isArray(params.required)
315
+ ? params.required.filter((r): r is string => typeof r === 'string')
316
+ : []
317
+ );
318
+ const entries = Object.entries(properties);
319
+ const testCases: SandboxTestCase[] = [];
304
320
 
305
- for (const [key, schema] of Object.entries(properties)) {
306
- validInput[key] = this.generateSampleValue(schema.type, schema.default);
321
+ const validInput: Record<string, unknown> = {};
322
+ for (const [key, schema] of entries) {
323
+ validInput[key] = this.generateSampleValue(schema);
324
+ }
325
+ testCases.push({ input: validInput });
326
+
327
+ const hasOptional = entries.some(([key]) => !required.has(key));
328
+ if (required.size > 0 && hasOptional) {
329
+ const requiredOnlyInput: Record<string, unknown> = {};
330
+ for (const [key, schema] of entries) {
331
+ if (required.has(key)) {
332
+ requiredOnlyInput[key] = this.generateSampleValue(schema);
333
+ }
307
334
  }
308
- testCases.push({ input: validInput });
335
+ testCases.push({ input: requiredOnlyInput });
336
+ }
337
+
338
+ const edgeInput: Record<string, unknown> = {};
339
+ for (const [key, schema] of entries) {
340
+ edgeInput[key] = this.generateEdgeValue(schema.type);
341
+ }
342
+ testCases.push({ input: edgeInput, allowThrow: true });
343
+
344
+ if (required.size > 0) {
345
+ const missingRequired: Record<string, unknown> = {};
346
+ for (const [key, schema] of entries) {
347
+ if (!required.has(key)) {
348
+ missingRequired[key] = this.generateSampleValue(schema);
349
+ }
350
+ }
351
+ testCases.push({ input: missingRequired, shouldThrow: true });
309
352
  }
310
353
 
311
354
  return testCases;
312
355
  }
313
356
 
314
- private generateSampleValue(type?: string, defaultValue?: unknown): unknown {
315
- if (defaultValue !== undefined) return defaultValue;
357
+ private generateSampleValue(schema: JsonPropertySchema): unknown {
358
+ if (schema.default !== undefined) return schema.default;
359
+ if (Array.isArray(schema.examples) && schema.examples.length > 0) return schema.examples[0];
360
+ if (Array.isArray(schema.enum) && schema.enum.length > 0) return schema.enum[0];
316
361
 
317
- switch (type) {
362
+ switch (schema.type) {
318
363
  case 'string':
319
364
  return 'test';
320
365
  case 'number':
@@ -331,6 +376,25 @@ Be thorough but practical - focus on real issues.`,
331
376
  }
332
377
  }
333
378
 
379
+ private generateEdgeValue(type?: string): unknown {
380
+ switch (type) {
381
+ case 'string':
382
+ return '';
383
+ case 'number':
384
+ return 0;
385
+ case 'integer':
386
+ return -1;
387
+ case 'boolean':
388
+ return false;
389
+ case 'array':
390
+ return [null, 0, ''];
391
+ case 'object':
392
+ return { unexpected: true };
393
+ default:
394
+ return undefined;
395
+ }
396
+ }
397
+
334
398
  private calculateScore(
335
399
  securityCount: number,
336
400
  logicCount: number,
@@ -353,15 +417,4 @@ Be thorough but practical - focus on real issues.`,
353
417
 
354
418
  return Math.max(0, Math.min(1, score));
355
419
  }
356
-
357
- private async callLLM(
358
- messages: Array<{ role: 'system' | 'user' | 'assistant'; content: string }>,
359
- temperature: number
360
- ) {
361
- if (!this.llm) return null;
362
- if (this.llm.complete) {
363
- return this.llm.complete({ messages, temperature });
364
- }
365
- return this.llm.chat({ model: this.model, messages, temperature });
366
- }
367
420
  }
@@ -9,8 +9,32 @@ export function extractJson(text: string): string | null {
9
9
  cleaned = codeBlockMatch[1].trim();
10
10
  }
11
11
 
12
- const start = cleaned.indexOf('{');
13
- if (start === -1) return null;
12
+ const objectStart = cleaned.indexOf('{');
13
+ const arrayStart = cleaned.indexOf('[');
14
+
15
+ let start: number;
16
+ let open: string;
17
+ let close: string;
18
+
19
+ if (objectStart === -1 && arrayStart === -1) {
20
+ return null;
21
+ } else if (objectStart === -1) {
22
+ start = arrayStart;
23
+ open = '[';
24
+ close = ']';
25
+ } else if (arrayStart === -1) {
26
+ start = objectStart;
27
+ open = '{';
28
+ close = '}';
29
+ } else if (objectStart < arrayStart) {
30
+ start = objectStart;
31
+ open = '{';
32
+ close = '}';
33
+ } else {
34
+ start = arrayStart;
35
+ open = '[';
36
+ close = ']';
37
+ }
14
38
 
15
39
  let depth = 0;
16
40
  let inString = false;
@@ -36,8 +60,8 @@ export function extractJson(text: string): string | null {
36
60
 
37
61
  if (inString) continue;
38
62
 
39
- if (ch === '{') depth++;
40
- else if (ch === '}') {
63
+ if (ch === open) depth++;
64
+ else if (ch === close) {
41
65
  depth--;
42
66
  if (depth === 0) {
43
67
  return cleaned.slice(start, i + 1);
@@ -48,7 +72,7 @@ export function extractJson(text: string): string | null {
48
72
  if (depth > 0) {
49
73
  let repaired = cleaned.slice(start);
50
74
  repaired = repaired.replace(/,\s*$/, '');
51
- repaired += '}'.repeat(depth);
75
+ repaired += close.repeat(depth);
52
76
  try {
53
77
  JSON.parse(repaired);
54
78
  return repaired;
@@ -8,6 +8,7 @@ export async function llmChat(
8
8
  if (llm.complete) {
9
9
  const response = await llm.complete({
10
10
  messages,
11
+ model: options?.model,
11
12
  temperature: options?.temperature,
12
13
  maxTokens: options?.maxTokens,
13
14
  });