@cogitator-ai/self-modifying 17.0.18 → 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.
- package/README.md +112 -48
- package/dist/architecture-evolution/capability-analyzer.d.ts.map +1 -1
- package/dist/architecture-evolution/capability-analyzer.js +38 -37
- package/dist/architecture-evolution/capability-analyzer.js.map +1 -1
- package/dist/architecture-evolution/index.d.ts +2 -2
- package/dist/architecture-evolution/index.d.ts.map +1 -1
- package/dist/architecture-evolution/index.js +1 -1
- package/dist/architecture-evolution/index.js.map +1 -1
- package/dist/architecture-evolution/parameter-optimizer.d.ts +5 -4
- package/dist/architecture-evolution/parameter-optimizer.d.ts.map +1 -1
- package/dist/architecture-evolution/parameter-optimizer.js +36 -31
- package/dist/architecture-evolution/parameter-optimizer.js.map +1 -1
- package/dist/architecture-evolution/prompts.d.ts +21 -2
- package/dist/architecture-evolution/prompts.d.ts.map +1 -1
- package/dist/architecture-evolution/prompts.js +150 -36
- package/dist/architecture-evolution/prompts.js.map +1 -1
- package/dist/constraints/modification-validator.d.ts +1 -0
- package/dist/constraints/modification-validator.d.ts.map +1 -1
- package/dist/constraints/modification-validator.js +30 -14
- package/dist/constraints/modification-validator.js.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/meta-reasoning/meta-reasoner.d.ts +3 -0
- package/dist/meta-reasoning/meta-reasoner.d.ts.map +1 -1
- package/dist/meta-reasoning/meta-reasoner.js +101 -33
- package/dist/meta-reasoning/meta-reasoner.js.map +1 -1
- package/dist/meta-reasoning/prompts.d.ts +10 -14
- package/dist/meta-reasoning/prompts.d.ts.map +1 -1
- package/dist/meta-reasoning/prompts.js +109 -1
- package/dist/meta-reasoning/prompts.js.map +1 -1
- package/dist/self-modifying-agent.d.ts +83 -17
- package/dist/self-modifying-agent.d.ts.map +1 -1
- package/dist/self-modifying-agent.js +557 -444
- package/dist/self-modifying-agent.js.map +1 -1
- package/dist/tool-generation/gap-analyzer.d.ts +0 -1
- package/dist/tool-generation/gap-analyzer.d.ts.map +1 -1
- package/dist/tool-generation/gap-analyzer.js +14 -14
- package/dist/tool-generation/gap-analyzer.js.map +1 -1
- package/dist/tool-generation/index.d.ts +3 -3
- package/dist/tool-generation/index.d.ts.map +1 -1
- package/dist/tool-generation/index.js +2 -2
- package/dist/tool-generation/index.js.map +1 -1
- package/dist/tool-generation/prompts.d.ts +1 -0
- package/dist/tool-generation/prompts.d.ts.map +1 -1
- package/dist/tool-generation/prompts.js +33 -8
- package/dist/tool-generation/prompts.js.map +1 -1
- package/dist/tool-generation/tool-generator.d.ts +5 -5
- package/dist/tool-generation/tool-generator.d.ts.map +1 -1
- package/dist/tool-generation/tool-generator.js +41 -28
- package/dist/tool-generation/tool-generator.js.map +1 -1
- package/dist/tool-generation/tool-sandbox.d.ts +9 -6
- package/dist/tool-generation/tool-sandbox.d.ts.map +1 -1
- package/dist/tool-generation/tool-sandbox.js +257 -157
- package/dist/tool-generation/tool-sandbox.js.map +1 -1
- package/dist/tool-generation/tool-validator.d.ts +3 -8
- package/dist/tool-generation/tool-validator.d.ts.map +1 -1
- package/dist/tool-generation/tool-validator.js +53 -54
- package/dist/tool-generation/tool-validator.js.map +1 -1
- package/dist/utils/llm-helper.d.ts.map +1 -1
- package/dist/utils/llm-helper.js +1 -0
- package/dist/utils/llm-helper.js.map +1 -1
- package/package.json +3 -12
- package/src/__tests__/component-regressions.test.ts +599 -0
- package/src/__tests__/meta-reasoning.test.ts +5 -1
- package/src/__tests__/sandbox-security.test.ts +186 -0
- package/src/__tests__/self-modifying-agent.test.ts +363 -1
- package/src/architecture-evolution/capability-analyzer.ts +56 -40
- package/src/architecture-evolution/index.ts +2 -0
- package/src/architecture-evolution/parameter-optimizer.ts +52 -34
- package/src/architecture-evolution/prompts.ts +179 -41
- package/src/constraints/modification-validator.ts +30 -14
- package/src/index.ts +14 -0
- package/src/meta-reasoning/meta-reasoner.ts +105 -40
- package/src/meta-reasoning/prompts.ts +129 -15
- package/src/self-modifying-agent.ts +764 -489
- package/src/tool-generation/gap-analyzer.ts +19 -18
- package/src/tool-generation/index.ts +13 -3
- package/src/tool-generation/prompts.ts +41 -8
- package/src/tool-generation/tool-generator.ts +59 -33
- package/src/tool-generation/tool-sandbox.ts +306 -175
- package/src/tool-generation/tool-validator.ts +66 -63
- 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
|
|
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
|
-
|
|
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.
|
|
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
|
|
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:
|
|
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:
|
|
63
|
-
|
|
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.
|
|
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.
|
|
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
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
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.
|
|
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
|
|
92
|
-
currentConfig:
|
|
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
|
-
|
|
101
|
-
|
|
102
|
-
|
|
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 (
|
|
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(
|
|
188
|
+
if (selfModification && this.config.architectureEvolution.enabled) {
|
|
189
|
+
optimization = await this.optimizeArchitecture(ctx);
|
|
112
190
|
}
|
|
113
|
-
if (
|
|
114
|
-
|
|
191
|
+
if (selfModification &&
|
|
192
|
+
this.config.toolGeneration.enabled &&
|
|
193
|
+
this.config.toolGeneration.autoGenerate) {
|
|
194
|
+
await this.analyzeAndGenerateTools(ctx);
|
|
115
195
|
}
|
|
116
|
-
const
|
|
117
|
-
|
|
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: [...
|
|
131
|
-
adaptationsMade: [...
|
|
132
|
-
finalConfig: { ...
|
|
199
|
+
output: execution.output,
|
|
200
|
+
toolsGenerated: [...ctx.generatedTools],
|
|
201
|
+
adaptationsMade: [...ctx.adaptations],
|
|
202
|
+
finalConfig: { ...ctx.currentConfig },
|
|
133
203
|
};
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
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
|
-
|
|
148
|
-
|
|
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
|
-
|
|
151
|
-
|
|
152
|
-
|
|
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
|
-
|
|
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
|
|
189
|
-
runId
|
|
190
|
-
|
|
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
|
-
|
|
205
|
-
executionTime,
|
|
235
|
+
data,
|
|
206
236
|
});
|
|
207
237
|
}
|
|
208
|
-
|
|
209
|
-
return
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
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:
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
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
|
-
|
|
362
|
-
return [...(this.agent.tools ?? [])
|
|
316
|
+
getAgentTools() {
|
|
317
|
+
return [...(this.agent.tools ?? [])];
|
|
363
318
|
}
|
|
364
|
-
async
|
|
365
|
-
|
|
366
|
-
|
|
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
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
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
|
-
|
|
395
|
-
|
|
396
|
-
|
|
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
|
|
406
|
-
if (!
|
|
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,
|
|
387
|
+
const analysis = await this.gapAnalyzer.analyze(ctx.input, ctx.tools);
|
|
410
388
|
for (const gap of analysis.gaps) {
|
|
411
|
-
if (
|
|
389
|
+
if (ctx.generatedTools.length >= this.config.toolGeneration.maxToolsPerSession)
|
|
412
390
|
break;
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
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
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
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
|
|
473
|
-
if (
|
|
474
|
-
|
|
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
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
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:
|
|
488
|
-
timeElapsed: Date.now() -
|
|
489
|
-
iterationsRemaining:
|
|
490
|
-
budgetRemaining:
|
|
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
|
-
|
|
493
|
-
if (this.
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
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
|
-
|
|
534
|
-
const
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
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 =
|
|
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: '
|
|
574
|
+
...options.contextAdditions.map((content) => ({ role: 'system', content })),
|
|
575
|
+
{ role: 'user', content: ctx.input },
|
|
546
576
|
];
|
|
547
|
-
|
|
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
|
-
|
|
583
|
+
response = await this.llm.chat({
|
|
550
584
|
model,
|
|
551
585
|
messages,
|
|
552
586
|
tools: toolSchemas.length > 0 ? toolSchemas : undefined,
|
|
553
|
-
temperature:
|
|
554
|
-
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
|
-
|
|
592
|
+
break;
|
|
558
593
|
}
|
|
559
|
-
|
|
594
|
+
const assistantMessage = {
|
|
560
595
|
role: 'assistant',
|
|
561
596
|
content: response.content,
|
|
562
597
|
toolCalls: response.toolCalls,
|
|
563
|
-
}
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
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:
|
|
586
|
-
toolCallId:
|
|
587
|
-
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
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
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
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
629
|
-
|
|
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
|
|
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 =
|
|
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
|