@cogitator-ai/self-modifying 17.0.18 → 19.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 (84) hide show
  1. package/README.md +114 -50
  2. package/dist/architecture-evolution/capability-analyzer.d.ts.map +1 -1
  3. package/dist/architecture-evolution/capability-analyzer.js +38 -37
  4. package/dist/architecture-evolution/capability-analyzer.js.map +1 -1
  5. package/dist/architecture-evolution/index.d.ts +2 -2
  6. package/dist/architecture-evolution/index.d.ts.map +1 -1
  7. package/dist/architecture-evolution/index.js +1 -1
  8. package/dist/architecture-evolution/index.js.map +1 -1
  9. package/dist/architecture-evolution/parameter-optimizer.d.ts +5 -4
  10. package/dist/architecture-evolution/parameter-optimizer.d.ts.map +1 -1
  11. package/dist/architecture-evolution/parameter-optimizer.js +36 -31
  12. package/dist/architecture-evolution/parameter-optimizer.js.map +1 -1
  13. package/dist/architecture-evolution/prompts.d.ts +21 -2
  14. package/dist/architecture-evolution/prompts.d.ts.map +1 -1
  15. package/dist/architecture-evolution/prompts.js +150 -36
  16. package/dist/architecture-evolution/prompts.js.map +1 -1
  17. package/dist/constraints/modification-validator.d.ts +1 -0
  18. package/dist/constraints/modification-validator.d.ts.map +1 -1
  19. package/dist/constraints/modification-validator.js +30 -14
  20. package/dist/constraints/modification-validator.js.map +1 -1
  21. package/dist/index.d.ts +4 -4
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +3 -3
  24. package/dist/index.js.map +1 -1
  25. package/dist/meta-reasoning/meta-reasoner.d.ts +3 -0
  26. package/dist/meta-reasoning/meta-reasoner.d.ts.map +1 -1
  27. package/dist/meta-reasoning/meta-reasoner.js +101 -33
  28. package/dist/meta-reasoning/meta-reasoner.js.map +1 -1
  29. package/dist/meta-reasoning/prompts.d.ts +10 -14
  30. package/dist/meta-reasoning/prompts.d.ts.map +1 -1
  31. package/dist/meta-reasoning/prompts.js +109 -1
  32. package/dist/meta-reasoning/prompts.js.map +1 -1
  33. package/dist/self-modifying-agent.d.ts +83 -17
  34. package/dist/self-modifying-agent.d.ts.map +1 -1
  35. package/dist/self-modifying-agent.js +557 -444
  36. package/dist/self-modifying-agent.js.map +1 -1
  37. package/dist/tool-generation/gap-analyzer.d.ts +0 -1
  38. package/dist/tool-generation/gap-analyzer.d.ts.map +1 -1
  39. package/dist/tool-generation/gap-analyzer.js +14 -14
  40. package/dist/tool-generation/gap-analyzer.js.map +1 -1
  41. package/dist/tool-generation/index.d.ts +3 -3
  42. package/dist/tool-generation/index.d.ts.map +1 -1
  43. package/dist/tool-generation/index.js +2 -2
  44. package/dist/tool-generation/index.js.map +1 -1
  45. package/dist/tool-generation/prompts.d.ts +1 -0
  46. package/dist/tool-generation/prompts.d.ts.map +1 -1
  47. package/dist/tool-generation/prompts.js +33 -8
  48. package/dist/tool-generation/prompts.js.map +1 -1
  49. package/dist/tool-generation/tool-generator.d.ts +5 -5
  50. package/dist/tool-generation/tool-generator.d.ts.map +1 -1
  51. package/dist/tool-generation/tool-generator.js +41 -28
  52. package/dist/tool-generation/tool-generator.js.map +1 -1
  53. package/dist/tool-generation/tool-sandbox.d.ts +9 -6
  54. package/dist/tool-generation/tool-sandbox.d.ts.map +1 -1
  55. package/dist/tool-generation/tool-sandbox.js +257 -157
  56. package/dist/tool-generation/tool-sandbox.js.map +1 -1
  57. package/dist/tool-generation/tool-validator.d.ts +3 -8
  58. package/dist/tool-generation/tool-validator.d.ts.map +1 -1
  59. package/dist/tool-generation/tool-validator.js +53 -54
  60. package/dist/tool-generation/tool-validator.js.map +1 -1
  61. package/dist/utils/llm-helper.d.ts.map +1 -1
  62. package/dist/utils/llm-helper.js +1 -0
  63. package/dist/utils/llm-helper.js.map +1 -1
  64. package/package.json +11 -18
  65. package/src/__tests__/component-regressions.test.ts +599 -0
  66. package/src/__tests__/meta-reasoning.test.ts +5 -1
  67. package/src/__tests__/sandbox-security.test.ts +186 -0
  68. package/src/__tests__/self-modifying-agent.test.ts +363 -1
  69. package/src/architecture-evolution/capability-analyzer.ts +56 -40
  70. package/src/architecture-evolution/index.ts +2 -0
  71. package/src/architecture-evolution/parameter-optimizer.ts +52 -34
  72. package/src/architecture-evolution/prompts.ts +179 -41
  73. package/src/constraints/modification-validator.ts +30 -14
  74. package/src/index.ts +14 -0
  75. package/src/meta-reasoning/meta-reasoner.ts +105 -40
  76. package/src/meta-reasoning/prompts.ts +129 -15
  77. package/src/self-modifying-agent.ts +764 -489
  78. package/src/tool-generation/gap-analyzer.ts +19 -18
  79. package/src/tool-generation/index.ts +13 -3
  80. package/src/tool-generation/prompts.ts +41 -8
  81. package/src/tool-generation/tool-generator.ts +59 -33
  82. package/src/tool-generation/tool-sandbox.ts +306 -175
  83. package/src/tool-generation/tool-validator.ts +66 -63
  84. package/src/utils/llm-helper.ts +1 -0
@@ -1,31 +1,41 @@
1
1
  import { nanoid } from 'nanoid';
2
+ import { DEFAULT_META_REASONING_CONFIG } from '@cogitator-ai/types';
2
3
  import { SelfModifyingEventEmitter } from './events/index.js';
3
4
  import { GapAnalyzer, ToolGenerator, InMemoryGeneratedToolStore } from './tool-generation/index.js';
4
5
  import { MetaReasoner } from './meta-reasoning/index.js';
5
- import { ParameterOptimizer, CapabilityAnalyzer } from './architecture-evolution/index.js';
6
+ import { ParameterOptimizer } from './architecture-evolution/index.js';
6
7
  import { ModificationValidator, RollbackManager, DEFAULT_SAFETY_CONSTRAINTS, DEFAULT_CAPABILITY_CONSTRAINTS, DEFAULT_RESOURCE_CONSTRAINTS, } from './constraints/index.js';
8
+ const DEFAULT_TOOL_TIMEOUT_MS = 30_000;
9
+ function resolveModelName(model, provider) {
10
+ if (!model)
11
+ return 'default';
12
+ const prefix = `${provider}/`;
13
+ return model.startsWith(prefix) ? model.slice(prefix.length) : model;
14
+ }
15
+ const DEFAULT_MAX_TOOL_ROUNDS = 10;
7
16
  export class SelfModifyingAgent {
8
17
  agent;
9
18
  llm;
19
+ modelName;
10
20
  config;
11
21
  emitter = new SelfModifyingEventEmitter();
22
+ listenerWrappers = new Map();
12
23
  gapAnalyzer;
13
24
  toolGenerator;
14
25
  toolStore;
15
26
  metaReasoner;
16
27
  parameterOptimizer;
17
- capabilityAnalyzer;
18
28
  modificationValidator;
19
29
  rollbackManager;
20
30
  currentContext = null;
21
- isInitialized = false;
22
- storedExecutableTools = [];
31
+ runQueue = Promise.resolve();
23
32
  constructor(options) {
24
33
  this.agent = options.agent;
25
34
  this.llm = options.llm;
35
+ this.modelName = resolveModelName(options.agent.model, options.llm.provider);
26
36
  this.config = this.mergeConfig(options.config);
27
37
  const toolGenConfig = this.config.toolGeneration;
28
- const agentModel = this.agent.model;
38
+ const agentModel = this.modelName;
29
39
  this.gapAnalyzer = new GapAnalyzer({ llm: this.llm, config: toolGenConfig, model: agentModel });
30
40
  this.toolGenerator = new ToolGenerator({
31
41
  llm: this.llm,
@@ -35,32 +45,28 @@ export class SelfModifyingAgent {
35
45
  this.toolStore = new InMemoryGeneratedToolStore();
36
46
  this.metaReasoner = new MetaReasoner({
37
47
  llm: this.llm,
38
- model: agentModel ?? 'default',
48
+ model: agentModel,
39
49
  config: this.config.metaReasoning,
40
50
  });
41
- const baseArchConfig = {
42
- model: agentModel ?? 'default',
43
- temperature: 0.7,
44
- maxTokens: 4096,
45
- toolStrategy: 'sequential',
46
- reflectionDepth: 1,
47
- };
48
51
  this.parameterOptimizer = new ParameterOptimizer({
49
52
  llm: this.llm,
50
53
  config: this.config.architectureEvolution,
51
- baseConfig: baseArchConfig,
52
- model: agentModel,
53
- });
54
- this.capabilityAnalyzer = new CapabilityAnalyzer({
55
- llm: this.llm,
56
- enableLLMAnalysis: true,
54
+ baseConfig: this.createBaseArchitectureConfig(),
57
55
  model: agentModel,
56
+ availableModels: options.availableModels,
58
57
  });
59
58
  this.modificationValidator = new ModificationValidator({
60
59
  constraints: {
61
- safety: DEFAULT_SAFETY_CONSTRAINTS,
62
- capability: DEFAULT_CAPABILITY_CONSTRAINTS,
63
- resource: DEFAULT_RESOURCE_CONSTRAINTS,
60
+ safety: [...DEFAULT_SAFETY_CONSTRAINTS, ...(options.modificationConstraints?.safety ?? [])],
61
+ capability: [
62
+ ...DEFAULT_CAPABILITY_CONSTRAINTS,
63
+ ...(options.modificationConstraints?.capability ?? []),
64
+ ],
65
+ resource: [
66
+ ...DEFAULT_RESOURCE_CONSTRAINTS,
67
+ ...(options.modificationConstraints?.resource ?? []),
68
+ ],
69
+ custom: options.modificationConstraints?.custom,
64
70
  },
65
71
  });
66
72
  this.rollbackManager = new RollbackManager({
@@ -68,93 +74,150 @@ export class SelfModifyingAgent {
68
74
  });
69
75
  }
70
76
  on(event, handler) {
71
- this.emitter.on(event, handler);
77
+ let wrappers = this.listenerWrappers.get(event);
78
+ if (!wrappers) {
79
+ wrappers = new Map();
80
+ this.listenerWrappers.set(event, wrappers);
81
+ }
82
+ const existing = wrappers.get(handler);
83
+ if (existing)
84
+ this.emitter.off(event, existing);
85
+ const wrapped = (e) => handler(e);
86
+ wrappers.set(handler, wrapped);
87
+ this.emitter.on(event, wrapped);
88
+ return () => this.off(event, handler);
72
89
  }
73
90
  off(event, handler) {
74
- this.emitter.off(event, handler);
91
+ const wrappers = this.listenerWrappers.get(event);
92
+ const wrapped = wrappers?.get(handler);
93
+ if (!wrappers || !wrapped)
94
+ return;
95
+ this.emitter.off(event, wrapped);
96
+ wrappers.delete(handler);
75
97
  }
76
- async run(input) {
77
- await this.ensureInitialized();
78
- const runId = `run_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
79
- const tools = this.getAvailableTools();
80
- const baseConfig = {
81
- model: this.agent.model ?? 'default',
82
- temperature: 0.7,
83
- maxTokens: 4096,
84
- toolStrategy: 'sequential',
85
- reflectionDepth: 1,
98
+ run(input) {
99
+ const result = this.runQueue.then(() => this.executeRun(input));
100
+ this.runQueue = result.catch(() => undefined);
101
+ return result;
102
+ }
103
+ async generateTool(gap) {
104
+ if (!this.config.toolGeneration.enabled) {
105
+ return null;
106
+ }
107
+ return this.generateAndRegisterTool(gap, this.currentContext?.tools ?? this.getAgentTools());
108
+ }
109
+ async recordToolUsage(toolId, success, executionTime) {
110
+ await this.toolStore.recordUsage({
111
+ toolId,
112
+ timestamp: new Date(),
113
+ success,
114
+ executionTime,
115
+ });
116
+ }
117
+ getGeneratedTools() {
118
+ return this.toolStore.list({ status: 'active' });
119
+ }
120
+ async createCheckpoint() {
121
+ const ctx = this.currentContext;
122
+ if (!ctx)
123
+ return null;
124
+ const agentConfig = {
125
+ name: this.agent.name || 'agent',
126
+ model: ctx.currentConfig.model,
127
+ instructions: this.agent.instructions || '',
128
+ temperature: ctx.currentConfig.temperature,
129
+ maxTokens: ctx.currentConfig.maxTokens,
86
130
  };
87
- this.currentContext = {
131
+ const checkpoint = await this.rollbackManager.createCheckpoint(this.agent.name || 'agent', agentConfig, ctx.tools, [...ctx.appliedModifications]);
132
+ ctx.checkpoints.push(checkpoint);
133
+ this.emit('checkpoint_created', ctx.runId, { checkpointId: checkpoint.id });
134
+ return checkpoint;
135
+ }
136
+ async rollbackToCheckpoint(checkpointId, reason = 'Manual rollback') {
137
+ const checkpoint = await this.rollbackManager.getCheckpoint(checkpointId);
138
+ const restored = await this.rollbackManager.rollbackTo(checkpointId);
139
+ if (!checkpoint || !restored)
140
+ return false;
141
+ const ctx = this.currentContext;
142
+ if (ctx) {
143
+ ctx.tools = restored.tools;
144
+ ctx.currentConfig = {
145
+ ...ctx.currentConfig,
146
+ model: restored.agentConfig.model ?? ctx.currentConfig.model,
147
+ temperature: restored.agentConfig.temperature ?? ctx.currentConfig.temperature,
148
+ maxTokens: restored.agentConfig.maxTokens ?? ctx.currentConfig.maxTokens,
149
+ };
150
+ ctx.appliedModifications = [...checkpoint.modifications];
151
+ const restoredNames = new Set(restored.tools.map((t) => t.name));
152
+ const discarded = ctx.generatedTools.filter((t) => !restoredNames.has(t.name));
153
+ for (const tool of discarded) {
154
+ await this.toolStore.deprecate(tool.id, `Rolled back to checkpoint ${checkpointId}`);
155
+ }
156
+ ctx.generatedTools = ctx.generatedTools.filter((t) => restoredNames.has(t.name));
157
+ }
158
+ this.emit('rollback_performed', ctx?.runId ?? 'manual', { checkpointId, reason });
159
+ return true;
160
+ }
161
+ async executeRun(input) {
162
+ const runId = `run_${nanoid(12)}`;
163
+ const selfModification = this.config.enabled;
164
+ const tools = selfModification ? await this.loadAvailableTools() : this.getAgentTools();
165
+ const ctx = {
88
166
  runId,
89
167
  input,
90
168
  startTime: Date.now(),
91
- tools: [...tools],
92
- currentConfig: baseConfig,
169
+ tools,
170
+ currentConfig: this.createBaseArchitectureConfig(),
93
171
  generatedTools: [],
94
172
  observations: [],
95
173
  adaptations: [],
96
174
  checkpoints: [],
97
175
  modificationsCount: 0,
98
176
  appliedModifications: [],
177
+ tokensUsed: 0,
99
178
  };
100
- void this.emitter.emit({
101
- type: 'run_started',
102
- runId,
103
- timestamp: new Date(),
104
- data: { input },
105
- });
179
+ this.currentContext = ctx;
180
+ this.emit('run_started', runId, { input });
181
+ let optimization = null;
106
182
  try {
107
- if (this.config.constraints.enabled && this.config.constraints.autoRollback) {
183
+ if (selfModification &&
184
+ this.config.constraints.enabled &&
185
+ this.config.constraints.autoRollback) {
108
186
  await this.createCheckpoint();
109
187
  }
110
- if (this.config.architectureEvolution.enabled) {
111
- await this.optimizeArchitecture(input);
188
+ if (selfModification && this.config.architectureEvolution.enabled) {
189
+ optimization = await this.optimizeArchitecture(ctx);
112
190
  }
113
- if (this.config.toolGeneration.enabled && this.config.toolGeneration.autoGenerate) {
114
- await this.analyzeAndGenerateTools(input);
191
+ if (selfModification &&
192
+ this.config.toolGeneration.enabled &&
193
+ this.config.toolGeneration.autoGenerate) {
194
+ await this.analyzeAndGenerateTools(ctx);
115
195
  }
116
- const modeConfig = this.metaReasoner.initializeRun(runId);
117
- void this.emitter.emit({
118
- type: 'strategy_changed',
119
- runId,
120
- timestamp: new Date(),
121
- data: {
122
- previousMode: 'analytical',
123
- newMode: modeConfig.mode,
124
- reason: 'Initial mode selection',
125
- },
126
- });
127
- const output = await this.executeWithMetaReasoning(input, runId);
196
+ const execution = await this.executeWithMetaReasoning(ctx, selfModification);
197
+ await this.recordArchitectureOutcome(ctx, optimization, true, execution.confidence);
128
198
  const result = {
129
- output,
130
- toolsGenerated: [...this.currentContext.generatedTools],
131
- adaptationsMade: [...this.currentContext.adaptations],
132
- finalConfig: { ...this.currentContext.currentConfig },
199
+ output: execution.output,
200
+ toolsGenerated: [...ctx.generatedTools],
201
+ adaptationsMade: [...ctx.adaptations],
202
+ finalConfig: { ...ctx.currentConfig },
133
203
  };
134
- void this.emitter.emit({
135
- type: 'run_completed',
136
- runId,
137
- timestamp: new Date(),
138
- data: {
139
- success: true,
140
- toolsGenerated: result.toolsGenerated.length,
141
- adaptationsMade: result.adaptationsMade.length,
142
- },
204
+ this.emit('run_completed', runId, {
205
+ success: true,
206
+ toolsGenerated: result.toolsGenerated.length,
207
+ adaptationsMade: result.adaptationsMade.length,
143
208
  });
144
209
  return result;
145
210
  }
146
211
  catch (error) {
147
- if (this.config.constraints.enabled && this.config.constraints.autoRollback) {
148
- await this.autoRollbackOnError();
212
+ await this.recordArchitectureOutcome(ctx, optimization, false, 0).catch(() => undefined);
213
+ if (selfModification &&
214
+ this.config.constraints.enabled &&
215
+ this.config.constraints.autoRollback) {
216
+ await this.autoRollback(ctx, 'Run failed');
149
217
  }
150
- void this.emitter.emit({
151
- type: 'run_completed',
152
- runId,
153
- timestamp: new Date(),
154
- data: {
155
- success: false,
156
- error: error instanceof Error ? error.message : String(error),
157
- },
218
+ this.emit('run_completed', runId, {
219
+ success: false,
220
+ error: error instanceof Error ? error.message : String(error),
158
221
  });
159
222
  throw error;
160
223
  }
@@ -163,101 +226,23 @@ export class SelfModifyingAgent {
163
226
  this.currentContext = null;
164
227
  }
165
228
  }
166
- async generateTool(gap) {
167
- if (!this.config.toolGeneration.enabled) {
168
- return null;
169
- }
170
- const tools = this.getAvailableTools();
171
- const result = await this.toolGenerator.generate(gap, tools);
172
- if (result.success && result.tool) {
173
- await this.toolStore.save(result.tool);
174
- void this.emitter.emit({
175
- type: 'tool_generation_completed',
176
- runId: this.currentContext?.runId || 'manual',
177
- timestamp: new Date(),
178
- data: {
179
- toolId: result.tool.id,
180
- name: result.tool.name,
181
- success: true,
182
- iterations: result.iterations,
183
- },
184
- });
185
- return result.tool;
186
- }
229
+ emit(type, runId, data) {
187
230
  void this.emitter.emit({
188
- type: 'tool_generation_completed',
189
- runId: this.currentContext?.runId || 'manual',
190
- timestamp: new Date(),
191
- data: {
192
- toolId: '',
193
- name: gap.suggestedToolName,
194
- success: false,
195
- error: result.error,
196
- },
197
- });
198
- return null;
199
- }
200
- async recordToolUsage(toolId, success, executionTime) {
201
- await this.toolStore.recordUsage({
202
- toolId,
231
+ type,
232
+ runId,
233
+ agentId: this.agent.id,
203
234
  timestamp: new Date(),
204
- success,
205
- executionTime,
235
+ data,
206
236
  });
207
237
  }
208
- getGeneratedTools() {
209
- return this.toolStore.list({ status: 'active' });
210
- }
211
- async createCheckpoint() {
212
- if (!this.currentContext)
213
- return null;
214
- const agentConfig = {
215
- name: this.agent.name || 'agent',
216
- model: this.currentContext.currentConfig.model,
217
- instructions: this.agent.instructions || '',
218
- temperature: this.currentContext.currentConfig.temperature,
219
- maxTokens: this.currentContext.currentConfig.maxTokens,
238
+ createBaseArchitectureConfig() {
239
+ return {
240
+ model: this.modelName,
241
+ temperature: this.agent.config?.temperature ?? 0.7,
242
+ maxTokens: this.agent.config?.maxTokens ?? 4096,
243
+ toolStrategy: 'sequential',
244
+ reflectionDepth: 0,
220
245
  };
221
- const checkpoint = await this.rollbackManager.createCheckpoint(this.agent.name || 'agent', agentConfig, this.currentContext.tools, [...this.currentContext.appliedModifications]);
222
- this.currentContext.checkpoints.push(checkpoint);
223
- void this.emitter.emit({
224
- type: 'checkpoint_created',
225
- runId: this.currentContext.runId,
226
- timestamp: new Date(),
227
- data: { checkpointId: checkpoint.id },
228
- });
229
- return checkpoint;
230
- }
231
- async rollbackToCheckpoint(checkpointId) {
232
- const restored = await this.rollbackManager.rollbackTo(checkpointId);
233
- if (!restored)
234
- return false;
235
- if (this.currentContext) {
236
- this.currentContext.tools = restored.tools;
237
- this.currentContext.currentConfig = {
238
- ...this.currentContext.currentConfig,
239
- model: restored.agentConfig.model ?? this.currentContext.currentConfig.model,
240
- temperature: restored.agentConfig.temperature ?? this.currentContext.currentConfig.temperature,
241
- maxTokens: restored.agentConfig.maxTokens ?? this.currentContext.currentConfig.maxTokens,
242
- };
243
- }
244
- void this.emitter.emit({
245
- type: 'rollback_performed',
246
- runId: this.currentContext?.runId || 'manual',
247
- timestamp: new Date(),
248
- data: {
249
- checkpointId,
250
- reason: 'Manual rollback',
251
- },
252
- });
253
- return true;
254
- }
255
- async ensureInitialized() {
256
- if (this.isInitialized)
257
- return;
258
- const activeTools = await this.toolStore.list({ status: 'active' });
259
- this.storedExecutableTools = activeTools.map((t) => this.toolGenerator.createExecutableTool(t));
260
- this.isInitialized = true;
261
246
  }
262
247
  mergeConfig(partial) {
263
248
  const defaults = {
@@ -277,40 +262,7 @@ export class SelfModifyingAgent {
277
262
  isolationLevel: 'strict',
278
263
  },
279
264
  },
280
- metaReasoning: {
281
- enabled: true,
282
- defaultMode: 'analytical',
283
- allowedModes: [
284
- 'analytical',
285
- 'creative',
286
- 'systematic',
287
- 'intuitive',
288
- 'reflective',
289
- 'exploratory',
290
- ],
291
- modeProfiles: {
292
- analytical: { mode: 'analytical', temperature: 0.3, depth: 3 },
293
- creative: { mode: 'creative', temperature: 0.9, depth: 2 },
294
- systematic: { mode: 'systematic', temperature: 0.2, depth: 4 },
295
- intuitive: { mode: 'intuitive', temperature: 0.6, depth: 1 },
296
- reflective: { mode: 'reflective', temperature: 0.4, depth: 3 },
297
- exploratory: { mode: 'exploratory', temperature: 0.7, depth: 2 },
298
- },
299
- maxMetaAssessments: 5,
300
- maxAdaptations: 3,
301
- metaAssessmentCooldown: 10000,
302
- adaptationCooldown: 15000,
303
- triggers: ['on_failure', 'on_low_confidence', 'periodic'],
304
- triggerAfterIterations: 3,
305
- triggerOnConfidenceDrop: 0.3,
306
- triggerOnProgressStall: 2,
307
- tokenBudget: 2000,
308
- maxMetaTokens: 1000,
309
- minConfidenceToAdapt: 0.6,
310
- enableRollback: true,
311
- rollbackWindow: 30000,
312
- rollbackOnDecline: true,
313
- },
265
+ metaReasoning: { ...DEFAULT_META_REASONING_CONFIG },
314
266
  architectureEvolution: {
315
267
  enabled: true,
316
268
  strategy: { type: 'ucb', explorationConstant: 2 },
@@ -328,14 +280,19 @@ export class SelfModifyingAgent {
328
280
  };
329
281
  if (!partial)
330
282
  return defaults;
283
+ const defaultSandbox = defaults.toolGeneration.sandboxConfig ?? {
284
+ enabled: true,
285
+ maxExecutionTime: 5000,
286
+ maxMemory: 50 * 1024 * 1024,
287
+ allowedModules: [],
288
+ isolationLevel: 'strict',
289
+ };
331
290
  return {
332
291
  enabled: partial.enabled ?? defaults.enabled,
333
292
  toolGeneration: {
334
293
  ...defaults.toolGeneration,
335
294
  ...partial.toolGeneration,
336
- sandboxConfig: partial.toolGeneration?.sandboxConfig
337
- ? { ...defaults.toolGeneration.sandboxConfig, ...partial.toolGeneration.sandboxConfig }
338
- : defaults.toolGeneration.sandboxConfig,
295
+ sandboxConfig: { ...defaultSandbox, ...partial.toolGeneration?.sandboxConfig },
339
296
  },
340
297
  metaReasoning: {
341
298
  ...defaults.metaReasoning,
@@ -348,318 +305,474 @@ export class SelfModifyingAgent {
348
305
  architectureEvolution: {
349
306
  ...defaults.architectureEvolution,
350
307
  ...partial.architectureEvolution,
351
- strategy: partial.architectureEvolution?.strategy
352
- ? {
353
- ...defaults.architectureEvolution.strategy,
354
- ...partial.architectureEvolution.strategy,
355
- }
356
- : defaults.architectureEvolution.strategy,
308
+ strategy: {
309
+ ...defaults.architectureEvolution.strategy,
310
+ ...partial.architectureEvolution?.strategy,
311
+ },
357
312
  },
358
313
  constraints: { ...defaults.constraints, ...partial.constraints },
359
314
  };
360
315
  }
361
- getAvailableTools() {
362
- return [...(this.agent.tools ?? []), ...this.storedExecutableTools];
316
+ getAgentTools() {
317
+ return [...(this.agent.tools ?? [])];
363
318
  }
364
- async optimizeArchitecture(input) {
365
- if (!this.currentContext)
366
- return;
319
+ async loadAvailableTools() {
320
+ const tools = this.getAgentTools();
321
+ const names = new Set(tools.map((t) => t.name));
322
+ const stored = await this.toolStore.list({ status: 'active' });
323
+ for (const generated of stored) {
324
+ if (names.has(generated.name))
325
+ continue;
326
+ names.add(generated.name);
327
+ tools.push(this.toolGenerator.createExecutableTool(generated));
328
+ }
329
+ return tools;
330
+ }
331
+ async optimizeArchitecture(ctx) {
367
332
  try {
368
- const result = await this.parameterOptimizer.optimize(input);
369
- if (result.shouldAdopt && result.confidence > 0.6 && this.canApplyModification()) {
370
- const validation = await this.validateModification({
371
- type: 'config_change',
372
- target: 'architecture',
373
- changes: result.recommendedConfig,
374
- reason: result.reasoning,
375
- });
376
- if (validation) {
377
- this.currentContext.currentConfig = result.recommendedConfig;
378
- this.recordModification('config_change', result.recommendedConfig);
379
- void this.emitter.emit({
380
- type: 'architecture_evolved',
381
- runId: this.currentContext.runId,
382
- timestamp: new Date(),
383
- data: {
384
- success: true,
385
- candidateId: result.candidate?.id,
386
- changes: result.recommendedConfig,
387
- metrics: result.metrics,
388
- },
389
- });
390
- }
333
+ const result = await this.parameterOptimizer.optimize(ctx.input);
334
+ const candidate = result.candidate;
335
+ if (!candidate)
336
+ return null;
337
+ const isNoop = Object.keys(candidate.config).length === 0;
338
+ if (isNoop) {
339
+ return { result, candidateId: candidate.id };
340
+ }
341
+ if (!result.shouldAdopt || !this.canApplyModification(ctx)) {
342
+ return { result, candidateId: 'baseline' };
391
343
  }
344
+ const valid = await this.validateModification(ctx, {
345
+ type: 'config_change',
346
+ target: 'architecture',
347
+ changes: result.recommendedConfig,
348
+ reason: result.reasoning,
349
+ payload: { candidateId: candidate.id, changedKeys: Object.keys(candidate.config) },
350
+ });
351
+ if (!valid) {
352
+ return { result, candidateId: 'baseline' };
353
+ }
354
+ ctx.currentConfig = { ...result.recommendedConfig };
355
+ this.recordModification(ctx, 'config_change', {
356
+ candidateId: candidate.id,
357
+ config: result.recommendedConfig,
358
+ });
359
+ this.emit('architecture_evolved', ctx.runId, {
360
+ success: true,
361
+ candidateId: candidate.id,
362
+ changes: result.recommendedConfig,
363
+ metrics: result.metrics,
364
+ });
365
+ return { result, candidateId: candidate.id };
392
366
  }
393
367
  catch (error) {
394
- void this.emitter.emit({
395
- type: 'architecture_evolved',
396
- runId: this.currentContext.runId,
397
- timestamp: new Date(),
398
- data: {
399
- success: false,
400
- error: error instanceof Error ? error.message : String(error),
401
- },
368
+ this.emit('architecture_evolved', ctx.runId, {
369
+ success: false,
370
+ error: error instanceof Error ? error.message : String(error),
402
371
  });
372
+ return null;
403
373
  }
404
374
  }
405
- async analyzeAndGenerateTools(input) {
406
- if (!this.currentContext)
375
+ async recordArchitectureOutcome(ctx, optimization, success, quality) {
376
+ if (!optimization)
407
377
  return;
378
+ await this.parameterOptimizer.recordOutcome(optimization.candidateId, optimization.result.taskProfile, {
379
+ successRate: success ? 1 : 0,
380
+ latency: Date.now() - ctx.startTime,
381
+ tokenUsage: ctx.tokensUsed,
382
+ qualityScore: quality,
383
+ });
384
+ }
385
+ async analyzeAndGenerateTools(ctx) {
408
386
  try {
409
- const analysis = await this.gapAnalyzer.analyze(input, this.currentContext.tools);
387
+ const analysis = await this.gapAnalyzer.analyze(ctx.input, ctx.tools);
410
388
  for (const gap of analysis.gaps) {
411
- if (this.currentContext.generatedTools.length >= this.config.toolGeneration.maxToolsPerSession) {
389
+ if (ctx.generatedTools.length >= this.config.toolGeneration.maxToolsPerSession)
412
390
  break;
413
- }
414
- if (gap.confidence >= this.config.toolGeneration.minConfidenceForGeneration) {
415
- void this.emitter.emit({
416
- type: 'tool_generation_started',
417
- runId: this.currentContext.runId,
418
- timestamp: new Date(),
419
- data: { gap },
420
- });
421
- const tool = await this.generateTool(gap);
422
- if (!tool)
423
- continue;
424
- const linesOfCode = tool.implementation.split('\n').length;
425
- const validated = await this.validateModification({
426
- type: 'tool_generation',
427
- target: tool.name,
428
- changes: { name: tool.name, implementation: tool.implementation },
429
- reason: `Generated tool for gap: ${gap.suggestedToolName}`,
430
- payload: {
431
- sandboxExecution: this.config.toolGeneration.sandboxConfig?.enabled ?? false,
432
- linesOfCode,
433
- complexity: linesOfCode,
434
- modificationDepth: 1,
435
- },
436
- });
437
- if (!validated || !this.canApplyModification()) {
438
- void this.emitter.emit({
439
- type: 'tool_generation_completed',
440
- runId: this.currentContext.runId,
441
- timestamp: new Date(),
442
- data: {
443
- toolId: tool.id,
444
- name: tool.name,
445
- success: false,
446
- error: 'Rejected by safety constraints or modification limit',
447
- },
448
- });
449
- continue;
450
- }
451
- this.currentContext.generatedTools.push(tool);
452
- const executableTool = this.toolGenerator.createExecutableTool(tool);
453
- this.currentContext.tools.push(executableTool);
454
- this.recordModification('tool_generation', { toolId: tool.id, name: tool.name });
455
- }
391
+ if (!this.canApplyModification(ctx))
392
+ break;
393
+ if (gap.confidence < this.config.toolGeneration.minConfidenceForGeneration)
394
+ continue;
395
+ const tool = await this.generateAndRegisterTool(gap, ctx.tools);
396
+ if (!tool)
397
+ continue;
398
+ ctx.generatedTools.push(tool);
399
+ ctx.tools.push(this.toolGenerator.createExecutableTool(tool));
400
+ this.recordModification(ctx, 'tool_generation', { toolId: tool.id, name: tool.name });
456
401
  }
457
402
  }
458
403
  catch (error) {
459
- void this.emitter.emit({
460
- type: 'tool_generation_completed',
461
- runId: this.currentContext.runId,
462
- timestamp: new Date(),
463
- data: {
464
- toolId: '',
465
- name: '',
466
- success: false,
467
- error: error instanceof Error ? error.message : String(error),
468
- },
404
+ this.emit('tool_generation_completed', ctx.runId, {
405
+ toolId: '',
406
+ name: '',
407
+ success: false,
408
+ error: error instanceof Error ? error.message : String(error),
409
+ });
410
+ }
411
+ }
412
+ async generateAndRegisterTool(gap, existingTools) {
413
+ const ctx = this.currentContext;
414
+ const runId = ctx?.runId ?? 'manual';
415
+ this.emit('tool_generation_started', runId, { gap });
416
+ const result = await this.toolGenerator.generate(gap, existingTools);
417
+ const generated = result.tool;
418
+ if (!result.success || !generated) {
419
+ this.emit('tool_generation_completed', runId, {
420
+ toolId: generated?.id ?? '',
421
+ name: generated?.name ?? gap.suggestedToolName,
422
+ success: false,
423
+ iterations: result.iterations,
424
+ error: result.error,
469
425
  });
426
+ return null;
470
427
  }
428
+ const rejection = await this.checkGeneratedTool(generated, existingTools);
429
+ if (rejection) {
430
+ this.emit('tool_generation_completed', runId, {
431
+ toolId: generated.id,
432
+ name: generated.name,
433
+ success: false,
434
+ iterations: result.iterations,
435
+ error: rejection,
436
+ });
437
+ return null;
438
+ }
439
+ const activeTool = { ...generated, status: 'active' };
440
+ await this.toolStore.save(activeTool);
441
+ const saved = (await this.toolStore.get(activeTool.id)) ?? activeTool;
442
+ this.emit('tool_generation_completed', runId, {
443
+ toolId: saved.id,
444
+ name: saved.name,
445
+ success: true,
446
+ iterations: result.iterations,
447
+ });
448
+ return saved;
471
449
  }
472
- async executeWithMetaReasoning(input, runId) {
473
- if (!this.currentContext) {
474
- throw new Error('No active run context');
450
+ async checkGeneratedTool(tool, existingTools) {
451
+ if (existingTools.some((t) => t.name === tool.name)) {
452
+ return `A tool named "${tool.name}" already exists`;
475
453
  }
476
- let output = '';
477
- let iteration = 0;
478
- const maxIterations = 10;
479
- while (iteration < maxIterations) {
480
- iteration++;
481
- const currentMode = this.metaReasoner.getCurrentMode(runId);
454
+ const linesOfCode = tool.implementation.split('\n').length;
455
+ const valid = await this.validateModification(this.currentContext, {
456
+ type: 'tool_generation',
457
+ target: tool.name,
458
+ changes: { name: tool.name, implementation: tool.implementation },
459
+ reason: `Generated tool for capability gap: ${tool.name}`,
460
+ payload: {
461
+ sandboxExecution: this.config.toolGeneration.sandboxConfig?.enabled ?? false,
462
+ linesOfCode,
463
+ complexity: linesOfCode,
464
+ modificationDepth: 1,
465
+ },
466
+ });
467
+ return valid ? null : 'Rejected by modification constraints';
468
+ }
469
+ async executeWithMetaReasoning(ctx, selfModification) {
470
+ const runId = ctx.runId;
471
+ const metaEnabled = selfModification && this.config.metaReasoning.enabled;
472
+ const maxAttempts = metaEnabled ? Math.max(1, this.config.metaReasoning.maxAdaptations + 1) : 1;
473
+ const contextAdditions = [];
474
+ let modeAdapted = false;
475
+ let pendingAdaptation = null;
476
+ if (metaEnabled) {
477
+ const modeConfig = this.metaReasoner.initializeRun(runId);
478
+ this.emit('strategy_changed', runId, {
479
+ previousMode: this.config.metaReasoning.defaultMode,
480
+ newMode: modeConfig.mode,
481
+ reason: 'Initial mode selection',
482
+ });
483
+ }
484
+ let step = null;
485
+ let confidence = 0;
486
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
487
+ const temperature = modeAdapted
488
+ ? this.metaReasoner.getCurrentConfig(runId).temperature
489
+ : ctx.currentConfig.temperature;
490
+ step = await this.executeAgentStep(ctx, { temperature, contextAdditions });
491
+ ctx.tokensUsed += step.tokensUsed;
492
+ confidence = this.stepConfidence(step);
493
+ if (!metaEnabled)
494
+ break;
495
+ this.metaReasoner.recordConfidence(runId, confidence);
496
+ if (pendingAdaptation) {
497
+ this.metaReasoner.recordOutcome(runId, pendingAdaptation.adaptation.id, {
498
+ improved: step.complete || confidence > pendingAdaptation.confidence,
499
+ progressDelta: step.complete ? 1 : 0,
500
+ confidenceDelta: confidence - pendingAdaptation.confidence,
501
+ });
502
+ pendingAdaptation = null;
503
+ }
504
+ if (step.complete || attempt === maxAttempts)
505
+ break;
482
506
  const observation = this.metaReasoner.observe({
483
507
  runId,
484
- iteration,
485
- goal: input,
486
- currentMode,
487
- tokensUsed: Math.round(output.length * 1.3),
488
- timeElapsed: Date.now() - this.currentContext.startTime,
489
- iterationsRemaining: maxIterations - iteration,
490
- budgetRemaining: 10000 - Math.round(output.length * 1.3),
508
+ iteration: attempt,
509
+ goal: ctx.input,
510
+ currentMode: this.metaReasoner.getCurrentMode(runId),
511
+ tokensUsed: ctx.tokensUsed,
512
+ timeElapsed: Date.now() - ctx.startTime,
513
+ iterationsRemaining: maxAttempts - attempt,
514
+ budgetRemaining: (maxAttempts - attempt) / maxAttempts,
491
515
  }, []);
492
- this.currentContext.observations.push(observation);
493
- if (this.metaReasoner.shouldTrigger(runId, 'periodic', {
494
- iteration,
495
- confidence: this.estimateConfidence(output),
496
- progressDelta: output.length > 0 ? 0.1 : 0,
497
- stagnationCount: 0,
498
- })) {
499
- const assessment = await this.metaReasoner.assess(observation);
500
- void this.emitter.emit({
501
- type: 'meta_assessment',
502
- runId,
503
- timestamp: new Date(),
504
- data: {
505
- observation,
506
- assessment,
507
- },
508
- });
509
- if (assessment.requiresAdaptation) {
510
- const adaptation = await this.metaReasoner.adapt(runId, assessment);
511
- if (adaptation) {
512
- this.currentContext.adaptations.push(adaptation);
513
- void this.emitter.emit({
514
- type: 'strategy_changed',
515
- runId,
516
- timestamp: new Date(),
517
- data: {
518
- previousMode: adaptation.before?.mode || 'analytical',
519
- newMode: adaptation.after?.mode || 'analytical',
520
- reason: adaptation.type,
521
- },
522
- });
523
- }
524
- }
525
- }
526
- output = await this.executeAgentStep(input);
527
- if (this.isTaskComplete(output)) {
516
+ ctx.observations.push(observation);
517
+ if (!this.selectTrigger(runId, attempt, confidence, observation))
518
+ continue;
519
+ const assessment = await this.metaReasoner.assess(observation);
520
+ this.emit('meta_assessment', runId, { observation, assessment });
521
+ if (!assessment.requiresAdaptation)
522
+ continue;
523
+ if (assessment.recommendation.action === 'abort')
528
524
  break;
525
+ const adaptation = await this.metaReasoner.adapt(runId, assessment);
526
+ if (!adaptation)
527
+ continue;
528
+ ctx.adaptations.push(adaptation);
529
+ pendingAdaptation = { adaptation, confidence };
530
+ if (adaptation.type === 'context_injection' && assessment.recommendation.contextAddition) {
531
+ contextAdditions.push(assessment.recommendation.contextAddition);
532
+ }
533
+ else {
534
+ modeAdapted = true;
529
535
  }
536
+ this.emit('strategy_changed', runId, {
537
+ previousMode: adaptation.previousMode ?? this.metaReasoner.getCurrentMode(runId),
538
+ newMode: adaptation.newMode ?? this.metaReasoner.getCurrentMode(runId),
539
+ reason: adaptation.reason ?? adaptation.type,
540
+ });
530
541
  }
531
- return output;
542
+ return { output: step?.content ?? '', confidence };
532
543
  }
533
- async executeAgentStep(input) {
534
- const tools = this.currentContext?.tools ?? [];
535
- const toolSchemas = this.buildToolSchemas(tools);
536
- const toolMap = new Map();
537
- for (const t of tools) {
538
- toolMap.set(t.name, t);
544
+ selectTrigger(runId, iteration, confidence, observation) {
545
+ const context = {
546
+ iteration,
547
+ confidence,
548
+ progressDelta: observation.progressDelta,
549
+ stagnationCount: observation.stagnationCount,
550
+ };
551
+ const candidates = [
552
+ 'on_failure',
553
+ 'on_low_confidence',
554
+ 'on_stagnation',
555
+ 'iteration_complete',
556
+ 'periodic',
557
+ ];
558
+ return candidates.find((t) => this.metaReasoner.shouldTrigger(runId, t, context)) ?? null;
559
+ }
560
+ async executeAgentStep(ctx, options) {
561
+ const toolMap = new Map(ctx.tools.map((t) => [t.name, t]));
562
+ const toolSchemas = this.buildToolSchemas(ctx.tools);
563
+ const generatedIds = new Map(ctx.generatedTools.map((t) => [t.name, t.id]));
564
+ for (const stored of await this.toolStore.list({ status: 'active' })) {
565
+ if (!generatedIds.has(stored.name))
566
+ generatedIds.set(stored.name, stored.id);
539
567
  }
540
- const model = this.currentContext?.currentConfig.model ?? this.agent.model ?? 'default';
568
+ const model = ctx.currentConfig.model;
569
+ const maxTokens = ctx.currentConfig.maxTokens;
541
570
  const messages = [
542
571
  ...(this.agent.instructions
543
572
  ? [{ role: 'system', content: this.agent.instructions }]
544
573
  : []),
545
- { role: 'user', content: input },
574
+ ...options.contextAdditions.map((content) => ({ role: 'system', content })),
575
+ { role: 'user', content: ctx.input },
546
576
  ];
547
- const maxToolRounds = 10;
577
+ let tokensUsed = 0;
578
+ let toolCalls = 0;
579
+ let toolErrors = 0;
580
+ let response = null;
581
+ const maxToolRounds = this.agent.config?.maxIterations ?? DEFAULT_MAX_TOOL_ROUNDS;
548
582
  for (let round = 0; round < maxToolRounds; round++) {
549
- const response = await this.llm.chat({
583
+ response = await this.llm.chat({
550
584
  model,
551
585
  messages,
552
586
  tools: toolSchemas.length > 0 ? toolSchemas : undefined,
553
- temperature: this.currentContext?.currentConfig.temperature,
554
- maxTokens: this.currentContext?.currentConfig.maxTokens,
587
+ temperature: options.temperature,
588
+ maxTokens,
555
589
  });
590
+ tokensUsed += response.usage?.totalTokens ?? 0;
556
591
  if (response.finishReason !== 'tool_calls' || !response.toolCalls?.length) {
557
- return response.content;
592
+ break;
558
593
  }
559
- messages.push({
594
+ const assistantMessage = {
560
595
  role: 'assistant',
561
596
  content: response.content,
562
597
  toolCalls: response.toolCalls,
563
- });
564
- for (const toolCall of response.toolCalls) {
565
- const t = toolMap.get(toolCall.name);
566
- let result;
567
- if (!t) {
568
- result = { error: `Tool "${toolCall.name}" not found` };
569
- }
570
- else {
571
- try {
572
- const ctx = {
573
- agentId: this.agent.name || 'self-modifying',
574
- runId: this.currentContext?.runId || 'unknown',
575
- signal: AbortSignal.timeout(30_000),
576
- };
577
- result = await t.execute(toolCall.arguments, ctx);
578
- }
579
- catch (err) {
580
- result = { error: err instanceof Error ? err.message : String(err) };
581
- }
582
- }
598
+ };
599
+ messages.push(assistantMessage);
600
+ const outcomes = await this.executeToolCalls(ctx, response.toolCalls, toolMap, generatedIds);
601
+ for (const outcome of outcomes) {
602
+ toolCalls++;
603
+ if (outcome.failed)
604
+ toolErrors++;
583
605
  messages.push({
584
606
  role: 'tool',
585
- content: typeof result === 'string' ? result : JSON.stringify(result),
586
- toolCallId: toolCall.id,
587
- name: toolCall.name,
607
+ content: outcome.content,
608
+ toolCallId: outcome.call.id,
609
+ name: outcome.call.name,
588
610
  });
589
611
  }
612
+ response = null;
590
613
  }
591
- const finalResponse = await this.llm.chat({
592
- model,
593
- messages,
594
- temperature: this.currentContext?.currentConfig.temperature,
595
- maxTokens: this.currentContext?.currentConfig.maxTokens,
596
- });
597
- return finalResponse.content;
614
+ if (!response) {
615
+ response = await this.llm.chat({
616
+ model,
617
+ messages,
618
+ temperature: options.temperature,
619
+ maxTokens,
620
+ });
621
+ tokensUsed += response.usage?.totalTokens ?? 0;
622
+ }
623
+ let content = response.content;
624
+ let finishReason = response.finishReason;
625
+ for (let depth = 0; depth < ctx.currentConfig.reflectionDepth && content.trim(); depth++) {
626
+ const reflection = await this.llm.chat({
627
+ model,
628
+ messages: [
629
+ ...messages,
630
+ { role: 'assistant', content },
631
+ {
632
+ role: 'user',
633
+ content: 'Review your previous answer for mistakes or omissions. Reply with the final, corrected answer only. If it is already correct, repeat it unchanged.',
634
+ },
635
+ ],
636
+ temperature: options.temperature,
637
+ maxTokens,
638
+ });
639
+ tokensUsed += reflection.usage?.totalTokens ?? 0;
640
+ if (!reflection.content.trim() || reflection.finishReason === 'error')
641
+ break;
642
+ content = reflection.content;
643
+ finishReason = reflection.finishReason;
644
+ }
645
+ return {
646
+ content,
647
+ finishReason,
648
+ tokensUsed,
649
+ toolCalls,
650
+ toolErrors,
651
+ complete: content.trim().length > 0 && finishReason !== 'length' && finishReason !== 'error',
652
+ };
598
653
  }
599
- buildToolSchemas(tools) {
600
- return tools.map((t) => {
601
- if (typeof t.toJSON === 'function') {
602
- return t.toJSON();
654
+ async executeToolCalls(ctx, calls, toolMap, generatedIds) {
655
+ const strategy = ctx.currentConfig.toolStrategy;
656
+ const parallel = strategy === 'parallel' ||
657
+ (strategy === 'adaptive' && new Set(calls.map((c) => c.name)).size === calls.length);
658
+ if (parallel) {
659
+ return Promise.all(calls.map((call) => this.executeToolCall(ctx, call, toolMap, generatedIds)));
660
+ }
661
+ const outcomes = [];
662
+ for (const call of calls) {
663
+ outcomes.push(await this.executeToolCall(ctx, call, toolMap, generatedIds));
664
+ }
665
+ return outcomes;
666
+ }
667
+ async executeToolCall(ctx, call, toolMap, generatedIds) {
668
+ const t = toolMap.get(call.name);
669
+ const startedAt = Date.now();
670
+ let result;
671
+ let error;
672
+ if (!t) {
673
+ error = `Tool "${call.name}" not found`;
674
+ }
675
+ else {
676
+ const parsed = t.parameters.safeParse(call.arguments);
677
+ if (!parsed.success) {
678
+ error = `Invalid arguments for "${call.name}": ${parsed.error.issues
679
+ .map((i) => `${i.path.join('.') || '(root)'}: ${i.message}`)
680
+ .join('; ')}`;
603
681
  }
604
- return {
682
+ else {
683
+ try {
684
+ const toolContext = {
685
+ agentId: this.agent.id ?? this.agent.name ?? 'self-modifying',
686
+ runId: ctx.runId,
687
+ signal: AbortSignal.timeout(t.timeout ?? DEFAULT_TOOL_TIMEOUT_MS),
688
+ };
689
+ result = await t.execute(parsed.data, toolContext);
690
+ }
691
+ catch (err) {
692
+ error = err instanceof Error ? err.message : String(err);
693
+ }
694
+ }
695
+ }
696
+ const duration = Date.now() - startedAt;
697
+ const generatedId = generatedIds.get(call.name);
698
+ if (generatedId) {
699
+ await this.toolStore.recordUsage({
700
+ toolId: generatedId,
701
+ timestamp: new Date(),
702
+ success: error === undefined,
703
+ executionTime: duration,
704
+ error,
705
+ });
706
+ }
707
+ if (this.config.enabled && this.config.metaReasoning.enabled) {
708
+ this.metaReasoner.recordAction(ctx.runId, {
709
+ type: 'tool_call',
710
+ toolName: call.name,
711
+ input: call.arguments,
712
+ output: error === undefined ? result : undefined,
713
+ error,
714
+ duration,
715
+ timestamp: startedAt,
716
+ });
717
+ }
718
+ if (error !== undefined) {
719
+ return { call, content: JSON.stringify({ error }), failed: true };
720
+ }
721
+ return {
722
+ call,
723
+ content: typeof result === 'string' ? result : (JSON.stringify(result) ?? 'null'),
724
+ failed: false,
725
+ };
726
+ }
727
+ buildToolSchemas(tools) {
728
+ return tools.map((t) => typeof t.toJSON === 'function'
729
+ ? t.toJSON()
730
+ : {
605
731
  name: t.name,
606
732
  description: t.description,
607
733
  parameters: { type: 'object', properties: {} },
608
- };
609
- });
734
+ });
735
+ }
736
+ stepConfidence(step) {
737
+ if (!step.complete)
738
+ return 0.2;
739
+ if (step.toolCalls > 0 && step.toolErrors > 0) {
740
+ return step.toolErrors >= step.toolCalls ? 0.4 : 0.6;
741
+ }
742
+ return 0.9;
610
743
  }
611
- async validateModification(request) {
744
+ async validateModification(ctx, request) {
612
745
  if (!this.config.constraints.enabled)
613
746
  return true;
614
747
  const validation = await this.modificationValidator.validate(request);
615
- if (validation.rollbackRequired && this.config.constraints.autoRollback) {
616
- await this.autoRollbackOnError();
748
+ if (validation.rollbackRequired && this.config.constraints.autoRollback && ctx) {
749
+ await this.autoRollback(ctx, `Critical constraint violation: ${request.type}`);
617
750
  }
618
751
  return validation.valid;
619
752
  }
620
- canApplyModification() {
753
+ canApplyModification(ctx) {
621
754
  if (!this.config.constraints.enabled)
622
755
  return true;
623
- if (!this.currentContext)
624
- return true;
625
- return this.currentContext.modificationsCount < this.config.constraints.maxModificationsPerRun;
756
+ return ctx.modificationsCount < this.config.constraints.maxModificationsPerRun;
626
757
  }
627
- recordModification(type, data) {
628
- if (!this.currentContext)
629
- return;
630
- this.currentContext.modificationsCount++;
631
- this.currentContext.appliedModifications.push({
758
+ recordModification(ctx, type, data) {
759
+ ctx.modificationsCount++;
760
+ ctx.appliedModifications.push({
632
761
  id: `mod_${nanoid(8)}`,
633
762
  type,
634
763
  appliedAt: new Date(),
635
764
  data,
636
765
  });
637
766
  }
638
- async autoRollbackOnError() {
639
- if (!this.currentContext)
640
- return;
767
+ async autoRollback(ctx, reason) {
641
768
  const now = Date.now();
642
769
  const window = this.config.constraints.rollbackWindow;
643
- const target = this.currentContext.checkpoints
770
+ const target = ctx.checkpoints
644
771
  .filter((c) => now - c.timestamp.getTime() <= window)
645
772
  .sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime())[0];
646
773
  if (target) {
647
- await this.rollbackToCheckpoint(target.id);
774
+ await this.rollbackToCheckpoint(target.id, reason);
648
775
  }
649
776
  }
650
- estimateConfidence(output) {
651
- if (!output)
652
- return 0.3;
653
- if (output.length < 50)
654
- return 0.4;
655
- if (output.length < 200)
656
- return 0.6;
657
- return 0.8;
658
- }
659
- isTaskComplete(output) {
660
- if (!output.trim())
661
- return false;
662
- return this.estimateConfidence(output) >= 0.6;
663
- }
664
777
  }
665
778
  //# sourceMappingURL=self-modifying-agent.js.map