@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
|
@@ -3,26 +3,41 @@ import type {
|
|
|
3
3
|
Agent,
|
|
4
4
|
AgentConfig,
|
|
5
5
|
Tool,
|
|
6
|
+
ToolCall,
|
|
7
|
+
ToolCallMessage,
|
|
6
8
|
LLMBackend,
|
|
9
|
+
ChatResponse,
|
|
7
10
|
SelfModifyingConfig,
|
|
11
|
+
ToolSelfGenerationConfig,
|
|
12
|
+
ToolSandboxConfig,
|
|
13
|
+
MetaReasoningConfig,
|
|
14
|
+
ArchitectureEvolutionConfig,
|
|
15
|
+
ModificationConstraintsConfig,
|
|
16
|
+
ModificationConstraints,
|
|
8
17
|
ArchitectureConfig,
|
|
9
18
|
GeneratedTool,
|
|
10
19
|
MetaObservation,
|
|
20
|
+
MetaAssessment,
|
|
11
21
|
MetaAdaptation,
|
|
22
|
+
MetaTrigger,
|
|
12
23
|
ModificationCheckpoint,
|
|
13
24
|
AppliedModification,
|
|
14
25
|
ModificationRequest,
|
|
15
26
|
SelfModifyingEvent,
|
|
27
|
+
SelfModifyingEventType,
|
|
16
28
|
CapabilityGap,
|
|
29
|
+
EvolutionMetrics,
|
|
30
|
+
ReasoningMode,
|
|
17
31
|
Message,
|
|
18
32
|
ToolSchema,
|
|
19
33
|
ToolContext,
|
|
20
34
|
} from '@cogitator-ai/types';
|
|
35
|
+
import { DEFAULT_META_REASONING_CONFIG } from '@cogitator-ai/types';
|
|
21
36
|
|
|
22
37
|
import { SelfModifyingEventEmitter } from './events';
|
|
23
38
|
import { GapAnalyzer, ToolGenerator, InMemoryGeneratedToolStore } from './tool-generation';
|
|
24
39
|
import { MetaReasoner } from './meta-reasoning';
|
|
25
|
-
import { ParameterOptimizer,
|
|
40
|
+
import { ParameterOptimizer, type OptimizationResult } from './architecture-evolution';
|
|
26
41
|
import {
|
|
27
42
|
ModificationValidator,
|
|
28
43
|
RollbackManager,
|
|
@@ -31,12 +46,63 @@ import {
|
|
|
31
46
|
DEFAULT_RESOURCE_CONSTRAINTS,
|
|
32
47
|
} from './constraints';
|
|
33
48
|
|
|
49
|
+
export interface SelfModifyingAgentConfig {
|
|
50
|
+
enabled?: boolean;
|
|
51
|
+
toolGeneration?: Partial<Omit<ToolSelfGenerationConfig, 'sandboxConfig'>> & {
|
|
52
|
+
sandboxConfig?: Partial<ToolSandboxConfig>;
|
|
53
|
+
};
|
|
54
|
+
metaReasoning?: Partial<MetaReasoningConfig>;
|
|
55
|
+
architectureEvolution?: Partial<ArchitectureEvolutionConfig>;
|
|
56
|
+
constraints?: Partial<ModificationConstraintsConfig>;
|
|
57
|
+
}
|
|
58
|
+
|
|
34
59
|
export interface SelfModifyingAgentOptions {
|
|
35
60
|
agent: Agent;
|
|
36
61
|
llm: LLMBackend;
|
|
37
|
-
config?:
|
|
62
|
+
config?: SelfModifyingAgentConfig;
|
|
63
|
+
/** Additional or overriding constraint sets used to validate every self-modification. */
|
|
64
|
+
modificationConstraints?: Partial<ModificationConstraints>;
|
|
65
|
+
/** Models architecture evolution may switch to. Model changes are never proposed when empty. */
|
|
66
|
+
availableModels?: string[];
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface SelfModifyingEventDataMap {
|
|
70
|
+
run_started: { input: string };
|
|
71
|
+
run_completed: {
|
|
72
|
+
success: boolean;
|
|
73
|
+
toolsGenerated?: number;
|
|
74
|
+
adaptationsMade?: number;
|
|
75
|
+
error?: string;
|
|
76
|
+
};
|
|
77
|
+
tool_generation_started: { gap: CapabilityGap };
|
|
78
|
+
tool_generation_completed: {
|
|
79
|
+
toolId: string;
|
|
80
|
+
name: string;
|
|
81
|
+
success: boolean;
|
|
82
|
+
iterations?: number;
|
|
83
|
+
error?: string;
|
|
84
|
+
};
|
|
85
|
+
meta_assessment: { observation: MetaObservation; assessment: MetaAssessment };
|
|
86
|
+
strategy_changed: { previousMode: ReasoningMode; newMode: ReasoningMode; reason: string };
|
|
87
|
+
architecture_evolved: {
|
|
88
|
+
success: boolean;
|
|
89
|
+
candidateId?: string;
|
|
90
|
+
changes?: ArchitectureConfig;
|
|
91
|
+
metrics?: EvolutionMetrics;
|
|
92
|
+
error?: string;
|
|
93
|
+
};
|
|
94
|
+
checkpoint_created: { checkpointId: string };
|
|
95
|
+
rollback_performed: { checkpointId: string; reason: string };
|
|
38
96
|
}
|
|
39
97
|
|
|
98
|
+
export type TypedSelfModifyingEvent<K extends SelfModifyingEventType> = Omit<
|
|
99
|
+
SelfModifyingEvent,
|
|
100
|
+
'type' | 'data'
|
|
101
|
+
> & {
|
|
102
|
+
type: K;
|
|
103
|
+
data: SelfModifyingEventDataMap[K];
|
|
104
|
+
};
|
|
105
|
+
|
|
40
106
|
export interface RunContext {
|
|
41
107
|
runId: string;
|
|
42
108
|
input: string;
|
|
@@ -49,34 +115,73 @@ export interface RunContext {
|
|
|
49
115
|
checkpoints: ModificationCheckpoint[];
|
|
50
116
|
modificationsCount: number;
|
|
51
117
|
appliedModifications: AppliedModification[];
|
|
118
|
+
tokensUsed: number;
|
|
52
119
|
}
|
|
53
120
|
|
|
121
|
+
interface StepOptions {
|
|
122
|
+
temperature: number;
|
|
123
|
+
contextAdditions: string[];
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
interface StepResult {
|
|
127
|
+
content: string;
|
|
128
|
+
finishReason: ChatResponse['finishReason'];
|
|
129
|
+
tokensUsed: number;
|
|
130
|
+
toolCalls: number;
|
|
131
|
+
toolErrors: number;
|
|
132
|
+
complete: boolean;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
interface ExecutionResult {
|
|
136
|
+
output: string;
|
|
137
|
+
confidence: number;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
interface ToolCallOutcome {
|
|
141
|
+
call: ToolCall;
|
|
142
|
+
content: string;
|
|
143
|
+
failed: boolean;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const DEFAULT_TOOL_TIMEOUT_MS = 30_000;
|
|
147
|
+
|
|
148
|
+
function resolveModelName(model: string | undefined, provider: string): string {
|
|
149
|
+
if (!model) return 'default';
|
|
150
|
+
const prefix = `${provider}/`;
|
|
151
|
+
return model.startsWith(prefix) ? model.slice(prefix.length) : model;
|
|
152
|
+
}
|
|
153
|
+
const DEFAULT_MAX_TOOL_ROUNDS = 10;
|
|
154
|
+
|
|
54
155
|
export class SelfModifyingAgent {
|
|
55
156
|
private readonly agent: Agent;
|
|
56
157
|
private readonly llm: LLMBackend;
|
|
158
|
+
private readonly modelName: string;
|
|
57
159
|
private readonly config: SelfModifyingConfig;
|
|
58
160
|
private readonly emitter = new SelfModifyingEventEmitter();
|
|
161
|
+
private readonly listenerWrappers = new Map<
|
|
162
|
+
SelfModifyingEventType,
|
|
163
|
+
Map<(event: never) => void, (event: SelfModifyingEvent) => void>
|
|
164
|
+
>();
|
|
59
165
|
|
|
60
166
|
private readonly gapAnalyzer: GapAnalyzer;
|
|
61
167
|
private readonly toolGenerator: ToolGenerator;
|
|
62
168
|
private readonly toolStore: InMemoryGeneratedToolStore;
|
|
63
169
|
private readonly metaReasoner: MetaReasoner;
|
|
64
170
|
private readonly parameterOptimizer: ParameterOptimizer;
|
|
65
|
-
private readonly capabilityAnalyzer: CapabilityAnalyzer;
|
|
66
171
|
private readonly modificationValidator: ModificationValidator;
|
|
67
172
|
private readonly rollbackManager: RollbackManager;
|
|
68
173
|
|
|
69
174
|
private currentContext: RunContext | null = null;
|
|
70
|
-
private
|
|
71
|
-
private storedExecutableTools: Tool[] = [];
|
|
175
|
+
private runQueue: Promise<unknown> = Promise.resolve();
|
|
72
176
|
|
|
73
177
|
constructor(options: SelfModifyingAgentOptions) {
|
|
74
178
|
this.agent = options.agent;
|
|
75
179
|
this.llm = options.llm;
|
|
180
|
+
this.modelName = resolveModelName(options.agent.model, options.llm.provider);
|
|
76
181
|
this.config = this.mergeConfig(options.config);
|
|
77
182
|
|
|
78
183
|
const toolGenConfig = this.config.toolGeneration;
|
|
79
|
-
const agentModel = this.
|
|
184
|
+
const agentModel = this.modelName;
|
|
80
185
|
this.gapAnalyzer = new GapAnalyzer({ llm: this.llm, config: toolGenConfig, model: agentModel });
|
|
81
186
|
this.toolGenerator = new ToolGenerator({
|
|
82
187
|
llm: this.llm,
|
|
@@ -87,36 +192,30 @@ export class SelfModifyingAgent {
|
|
|
87
192
|
|
|
88
193
|
this.metaReasoner = new MetaReasoner({
|
|
89
194
|
llm: this.llm,
|
|
90
|
-
model: agentModel
|
|
195
|
+
model: agentModel,
|
|
91
196
|
config: this.config.metaReasoning,
|
|
92
197
|
});
|
|
93
198
|
|
|
94
|
-
const baseArchConfig: ArchitectureConfig = {
|
|
95
|
-
model: agentModel ?? 'default',
|
|
96
|
-
temperature: 0.7,
|
|
97
|
-
maxTokens: 4096,
|
|
98
|
-
toolStrategy: 'sequential',
|
|
99
|
-
reflectionDepth: 1,
|
|
100
|
-
};
|
|
101
|
-
|
|
102
199
|
this.parameterOptimizer = new ParameterOptimizer({
|
|
103
200
|
llm: this.llm,
|
|
104
201
|
config: this.config.architectureEvolution,
|
|
105
|
-
baseConfig:
|
|
106
|
-
model: agentModel,
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
this.capabilityAnalyzer = new CapabilityAnalyzer({
|
|
110
|
-
llm: this.llm,
|
|
111
|
-
enableLLMAnalysis: true,
|
|
202
|
+
baseConfig: this.createBaseArchitectureConfig(),
|
|
112
203
|
model: agentModel,
|
|
204
|
+
availableModels: options.availableModels,
|
|
113
205
|
});
|
|
114
206
|
|
|
115
207
|
this.modificationValidator = new ModificationValidator({
|
|
116
208
|
constraints: {
|
|
117
|
-
safety: DEFAULT_SAFETY_CONSTRAINTS,
|
|
118
|
-
capability:
|
|
119
|
-
|
|
209
|
+
safety: [...DEFAULT_SAFETY_CONSTRAINTS, ...(options.modificationConstraints?.safety ?? [])],
|
|
210
|
+
capability: [
|
|
211
|
+
...DEFAULT_CAPABILITY_CONSTRAINTS,
|
|
212
|
+
...(options.modificationConstraints?.capability ?? []),
|
|
213
|
+
],
|
|
214
|
+
resource: [
|
|
215
|
+
...DEFAULT_RESOURCE_CONSTRAINTS,
|
|
216
|
+
...(options.modificationConstraints?.resource ?? []),
|
|
217
|
+
],
|
|
218
|
+
custom: options.modificationConstraints?.custom,
|
|
120
219
|
},
|
|
121
220
|
});
|
|
122
221
|
|
|
@@ -125,120 +224,204 @@ export class SelfModifyingAgent {
|
|
|
125
224
|
});
|
|
126
225
|
}
|
|
127
226
|
|
|
128
|
-
on<K extends
|
|
227
|
+
on<K extends SelfModifyingEventType>(
|
|
129
228
|
event: K,
|
|
130
|
-
handler: (event:
|
|
131
|
-
): void {
|
|
132
|
-
this.
|
|
229
|
+
handler: (event: TypedSelfModifyingEvent<K>) => void
|
|
230
|
+
): () => void {
|
|
231
|
+
let wrappers = this.listenerWrappers.get(event);
|
|
232
|
+
if (!wrappers) {
|
|
233
|
+
wrappers = new Map();
|
|
234
|
+
this.listenerWrappers.set(event, wrappers);
|
|
235
|
+
}
|
|
236
|
+
const existing = wrappers.get(handler);
|
|
237
|
+
if (existing) this.emitter.off(event, existing);
|
|
238
|
+
|
|
239
|
+
const wrapped = (e: SelfModifyingEvent) => handler(e as TypedSelfModifyingEvent<K>);
|
|
240
|
+
wrappers.set(handler, wrapped);
|
|
241
|
+
this.emitter.on(event, wrapped);
|
|
242
|
+
return () => this.off(event, handler);
|
|
133
243
|
}
|
|
134
244
|
|
|
135
|
-
off<K extends
|
|
245
|
+
off<K extends SelfModifyingEventType>(
|
|
136
246
|
event: K,
|
|
137
|
-
handler: (event:
|
|
247
|
+
handler: (event: TypedSelfModifyingEvent<K>) => void
|
|
138
248
|
): void {
|
|
139
|
-
this.
|
|
249
|
+
const wrappers = this.listenerWrappers.get(event);
|
|
250
|
+
const wrapped = wrappers?.get(handler);
|
|
251
|
+
if (!wrappers || !wrapped) return;
|
|
252
|
+
this.emitter.off(event, wrapped);
|
|
253
|
+
wrappers.delete(handler);
|
|
140
254
|
}
|
|
141
255
|
|
|
142
|
-
|
|
256
|
+
run(input: string): Promise<{
|
|
143
257
|
output: string;
|
|
144
258
|
toolsGenerated: GeneratedTool[];
|
|
145
259
|
adaptationsMade: MetaAdaptation[];
|
|
146
260
|
finalConfig: ArchitectureConfig;
|
|
147
261
|
}> {
|
|
148
|
-
|
|
262
|
+
const result = this.runQueue.then(() => this.executeRun(input));
|
|
263
|
+
this.runQueue = result.catch(() => undefined);
|
|
264
|
+
return result;
|
|
265
|
+
}
|
|
149
266
|
|
|
150
|
-
|
|
151
|
-
|
|
267
|
+
async generateTool(gap: CapabilityGap): Promise<GeneratedTool | null> {
|
|
268
|
+
if (!this.config.toolGeneration.enabled) {
|
|
269
|
+
return null;
|
|
270
|
+
}
|
|
152
271
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
272
|
+
return this.generateAndRegisterTool(gap, this.currentContext?.tools ?? this.getAgentTools());
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
async recordToolUsage(toolId: string, success: boolean, executionTime: number): Promise<void> {
|
|
276
|
+
await this.toolStore.recordUsage({
|
|
277
|
+
toolId,
|
|
278
|
+
timestamp: new Date(),
|
|
279
|
+
success,
|
|
280
|
+
executionTime,
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
getGeneratedTools(): Promise<GeneratedTool[]> {
|
|
285
|
+
return this.toolStore.list({ status: 'active' });
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
async createCheckpoint(): Promise<ModificationCheckpoint | null> {
|
|
289
|
+
const ctx = this.currentContext;
|
|
290
|
+
if (!ctx) return null;
|
|
291
|
+
|
|
292
|
+
const agentConfig: AgentConfig = {
|
|
293
|
+
name: this.agent.name || 'agent',
|
|
294
|
+
model: ctx.currentConfig.model,
|
|
295
|
+
instructions: this.agent.instructions || '',
|
|
296
|
+
temperature: ctx.currentConfig.temperature,
|
|
297
|
+
maxTokens: ctx.currentConfig.maxTokens,
|
|
159
298
|
};
|
|
160
299
|
|
|
161
|
-
|
|
300
|
+
const checkpoint = await this.rollbackManager.createCheckpoint(
|
|
301
|
+
this.agent.name || 'agent',
|
|
302
|
+
agentConfig,
|
|
303
|
+
ctx.tools,
|
|
304
|
+
[...ctx.appliedModifications]
|
|
305
|
+
);
|
|
306
|
+
|
|
307
|
+
ctx.checkpoints.push(checkpoint);
|
|
308
|
+
this.emit('checkpoint_created', ctx.runId, { checkpointId: checkpoint.id });
|
|
309
|
+
|
|
310
|
+
return checkpoint;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
async rollbackToCheckpoint(checkpointId: string, reason = 'Manual rollback'): Promise<boolean> {
|
|
314
|
+
const checkpoint = await this.rollbackManager.getCheckpoint(checkpointId);
|
|
315
|
+
const restored = await this.rollbackManager.rollbackTo(checkpointId);
|
|
316
|
+
if (!checkpoint || !restored) return false;
|
|
317
|
+
|
|
318
|
+
const ctx = this.currentContext;
|
|
319
|
+
if (ctx) {
|
|
320
|
+
ctx.tools = restored.tools;
|
|
321
|
+
ctx.currentConfig = {
|
|
322
|
+
...ctx.currentConfig,
|
|
323
|
+
model: restored.agentConfig.model ?? ctx.currentConfig.model,
|
|
324
|
+
temperature: restored.agentConfig.temperature ?? ctx.currentConfig.temperature,
|
|
325
|
+
maxTokens: restored.agentConfig.maxTokens ?? ctx.currentConfig.maxTokens,
|
|
326
|
+
};
|
|
327
|
+
ctx.appliedModifications = [...checkpoint.modifications];
|
|
328
|
+
|
|
329
|
+
const restoredNames = new Set(restored.tools.map((t) => t.name));
|
|
330
|
+
const discarded = ctx.generatedTools.filter((t) => !restoredNames.has(t.name));
|
|
331
|
+
for (const tool of discarded) {
|
|
332
|
+
await this.toolStore.deprecate(tool.id, `Rolled back to checkpoint ${checkpointId}`);
|
|
333
|
+
}
|
|
334
|
+
ctx.generatedTools = ctx.generatedTools.filter((t) => restoredNames.has(t.name));
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
this.emit('rollback_performed', ctx?.runId ?? 'manual', { checkpointId, reason });
|
|
338
|
+
|
|
339
|
+
return true;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
private async executeRun(input: string): Promise<{
|
|
343
|
+
output: string;
|
|
344
|
+
toolsGenerated: GeneratedTool[];
|
|
345
|
+
adaptationsMade: MetaAdaptation[];
|
|
346
|
+
finalConfig: ArchitectureConfig;
|
|
347
|
+
}> {
|
|
348
|
+
const runId = `run_${nanoid(12)}`;
|
|
349
|
+
const selfModification = this.config.enabled;
|
|
350
|
+
const tools = selfModification ? await this.loadAvailableTools() : this.getAgentTools();
|
|
351
|
+
|
|
352
|
+
const ctx: RunContext = {
|
|
162
353
|
runId,
|
|
163
354
|
input,
|
|
164
355
|
startTime: Date.now(),
|
|
165
|
-
tools
|
|
166
|
-
currentConfig:
|
|
356
|
+
tools,
|
|
357
|
+
currentConfig: this.createBaseArchitectureConfig(),
|
|
167
358
|
generatedTools: [],
|
|
168
359
|
observations: [],
|
|
169
360
|
adaptations: [],
|
|
170
361
|
checkpoints: [],
|
|
171
362
|
modificationsCount: 0,
|
|
172
363
|
appliedModifications: [],
|
|
364
|
+
tokensUsed: 0,
|
|
173
365
|
};
|
|
366
|
+
this.currentContext = ctx;
|
|
174
367
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
timestamp: new Date(),
|
|
179
|
-
data: { input },
|
|
180
|
-
});
|
|
368
|
+
this.emit('run_started', runId, { input });
|
|
369
|
+
|
|
370
|
+
let optimization: { result: OptimizationResult; candidateId: string } | null = null;
|
|
181
371
|
|
|
182
372
|
try {
|
|
183
|
-
if (
|
|
373
|
+
if (
|
|
374
|
+
selfModification &&
|
|
375
|
+
this.config.constraints.enabled &&
|
|
376
|
+
this.config.constraints.autoRollback
|
|
377
|
+
) {
|
|
184
378
|
await this.createCheckpoint();
|
|
185
379
|
}
|
|
186
380
|
|
|
187
|
-
if (this.config.architectureEvolution.enabled) {
|
|
188
|
-
await this.optimizeArchitecture(
|
|
381
|
+
if (selfModification && this.config.architectureEvolution.enabled) {
|
|
382
|
+
optimization = await this.optimizeArchitecture(ctx);
|
|
189
383
|
}
|
|
190
384
|
|
|
191
|
-
if (
|
|
192
|
-
|
|
385
|
+
if (
|
|
386
|
+
selfModification &&
|
|
387
|
+
this.config.toolGeneration.enabled &&
|
|
388
|
+
this.config.toolGeneration.autoGenerate
|
|
389
|
+
) {
|
|
390
|
+
await this.analyzeAndGenerateTools(ctx);
|
|
193
391
|
}
|
|
194
392
|
|
|
195
|
-
const
|
|
196
|
-
|
|
197
|
-
void this.emitter.emit({
|
|
198
|
-
type: 'strategy_changed',
|
|
199
|
-
runId,
|
|
200
|
-
timestamp: new Date(),
|
|
201
|
-
data: {
|
|
202
|
-
previousMode: 'analytical',
|
|
203
|
-
newMode: modeConfig.mode,
|
|
204
|
-
reason: 'Initial mode selection',
|
|
205
|
-
},
|
|
206
|
-
});
|
|
393
|
+
const execution = await this.executeWithMetaReasoning(ctx, selfModification);
|
|
207
394
|
|
|
208
|
-
|
|
395
|
+
await this.recordArchitectureOutcome(ctx, optimization, true, execution.confidence);
|
|
209
396
|
|
|
210
397
|
const result = {
|
|
211
|
-
output,
|
|
212
|
-
toolsGenerated: [...
|
|
213
|
-
adaptationsMade: [...
|
|
214
|
-
finalConfig: { ...
|
|
398
|
+
output: execution.output,
|
|
399
|
+
toolsGenerated: [...ctx.generatedTools],
|
|
400
|
+
adaptationsMade: [...ctx.adaptations],
|
|
401
|
+
finalConfig: { ...ctx.currentConfig },
|
|
215
402
|
};
|
|
216
403
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
data: {
|
|
222
|
-
success: true,
|
|
223
|
-
toolsGenerated: result.toolsGenerated.length,
|
|
224
|
-
adaptationsMade: result.adaptationsMade.length,
|
|
225
|
-
},
|
|
404
|
+
this.emit('run_completed', runId, {
|
|
405
|
+
success: true,
|
|
406
|
+
toolsGenerated: result.toolsGenerated.length,
|
|
407
|
+
adaptationsMade: result.adaptationsMade.length,
|
|
226
408
|
});
|
|
227
409
|
|
|
228
410
|
return result;
|
|
229
411
|
} catch (error) {
|
|
230
|
-
|
|
231
|
-
|
|
412
|
+
await this.recordArchitectureOutcome(ctx, optimization, false, 0).catch(() => undefined);
|
|
413
|
+
|
|
414
|
+
if (
|
|
415
|
+
selfModification &&
|
|
416
|
+
this.config.constraints.enabled &&
|
|
417
|
+
this.config.constraints.autoRollback
|
|
418
|
+
) {
|
|
419
|
+
await this.autoRollback(ctx, 'Run failed');
|
|
232
420
|
}
|
|
233
421
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
timestamp: new Date(),
|
|
238
|
-
data: {
|
|
239
|
-
success: false,
|
|
240
|
-
error: error instanceof Error ? error.message : String(error),
|
|
241
|
-
},
|
|
422
|
+
this.emit('run_completed', runId, {
|
|
423
|
+
success: false,
|
|
424
|
+
error: error instanceof Error ? error.message : String(error),
|
|
242
425
|
});
|
|
243
426
|
|
|
244
427
|
throw error;
|
|
@@ -248,128 +431,31 @@ export class SelfModifyingAgent {
|
|
|
248
431
|
}
|
|
249
432
|
}
|
|
250
433
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
const tools = this.getAvailableTools();
|
|
257
|
-
const result = await this.toolGenerator.generate(gap, tools);
|
|
258
|
-
|
|
259
|
-
if (result.success && result.tool) {
|
|
260
|
-
await this.toolStore.save(result.tool);
|
|
261
|
-
|
|
262
|
-
void this.emitter.emit({
|
|
263
|
-
type: 'tool_generation_completed',
|
|
264
|
-
runId: this.currentContext?.runId || 'manual',
|
|
265
|
-
timestamp: new Date(),
|
|
266
|
-
data: {
|
|
267
|
-
toolId: result.tool.id,
|
|
268
|
-
name: result.tool.name,
|
|
269
|
-
success: true,
|
|
270
|
-
iterations: result.iterations,
|
|
271
|
-
},
|
|
272
|
-
});
|
|
273
|
-
|
|
274
|
-
return result.tool;
|
|
275
|
-
}
|
|
276
|
-
|
|
434
|
+
private emit<K extends SelfModifyingEventType>(
|
|
435
|
+
type: K,
|
|
436
|
+
runId: string,
|
|
437
|
+
data: SelfModifyingEventDataMap[K]
|
|
438
|
+
): void {
|
|
277
439
|
void this.emitter.emit({
|
|
278
|
-
type
|
|
279
|
-
runId
|
|
280
|
-
|
|
281
|
-
data: {
|
|
282
|
-
toolId: '',
|
|
283
|
-
name: gap.suggestedToolName,
|
|
284
|
-
success: false,
|
|
285
|
-
error: result.error,
|
|
286
|
-
},
|
|
287
|
-
});
|
|
288
|
-
|
|
289
|
-
return null;
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
async recordToolUsage(toolId: string, success: boolean, executionTime: number): Promise<void> {
|
|
293
|
-
await this.toolStore.recordUsage({
|
|
294
|
-
toolId,
|
|
440
|
+
type,
|
|
441
|
+
runId,
|
|
442
|
+
agentId: this.agent.id,
|
|
295
443
|
timestamp: new Date(),
|
|
296
|
-
|
|
297
|
-
executionTime,
|
|
444
|
+
data,
|
|
298
445
|
});
|
|
299
446
|
}
|
|
300
447
|
|
|
301
|
-
|
|
302
|
-
return
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
const agentConfig: AgentConfig = {
|
|
309
|
-
name: this.agent.name || 'agent',
|
|
310
|
-
model: this.currentContext.currentConfig.model,
|
|
311
|
-
instructions: this.agent.instructions || '',
|
|
312
|
-
temperature: this.currentContext.currentConfig.temperature,
|
|
313
|
-
maxTokens: this.currentContext.currentConfig.maxTokens,
|
|
448
|
+
private createBaseArchitectureConfig(): ArchitectureConfig {
|
|
449
|
+
return {
|
|
450
|
+
model: this.modelName,
|
|
451
|
+
temperature: this.agent.config?.temperature ?? 0.7,
|
|
452
|
+
maxTokens: this.agent.config?.maxTokens ?? 4096,
|
|
453
|
+
toolStrategy: 'sequential',
|
|
454
|
+
reflectionDepth: 0,
|
|
314
455
|
};
|
|
315
|
-
|
|
316
|
-
const checkpoint = await this.rollbackManager.createCheckpoint(
|
|
317
|
-
this.agent.name || 'agent',
|
|
318
|
-
agentConfig,
|
|
319
|
-
this.currentContext.tools,
|
|
320
|
-
[...this.currentContext.appliedModifications]
|
|
321
|
-
);
|
|
322
|
-
|
|
323
|
-
this.currentContext.checkpoints.push(checkpoint);
|
|
324
|
-
|
|
325
|
-
void this.emitter.emit({
|
|
326
|
-
type: 'checkpoint_created',
|
|
327
|
-
runId: this.currentContext.runId,
|
|
328
|
-
timestamp: new Date(),
|
|
329
|
-
data: { checkpointId: checkpoint.id },
|
|
330
|
-
});
|
|
331
|
-
|
|
332
|
-
return checkpoint;
|
|
333
456
|
}
|
|
334
457
|
|
|
335
|
-
|
|
336
|
-
const restored = await this.rollbackManager.rollbackTo(checkpointId);
|
|
337
|
-
if (!restored) return false;
|
|
338
|
-
|
|
339
|
-
if (this.currentContext) {
|
|
340
|
-
this.currentContext.tools = restored.tools;
|
|
341
|
-
this.currentContext.currentConfig = {
|
|
342
|
-
...this.currentContext.currentConfig,
|
|
343
|
-
model: restored.agentConfig.model ?? this.currentContext.currentConfig.model,
|
|
344
|
-
temperature:
|
|
345
|
-
restored.agentConfig.temperature ?? this.currentContext.currentConfig.temperature,
|
|
346
|
-
maxTokens: restored.agentConfig.maxTokens ?? this.currentContext.currentConfig.maxTokens,
|
|
347
|
-
};
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
void this.emitter.emit({
|
|
351
|
-
type: 'rollback_performed',
|
|
352
|
-
runId: this.currentContext?.runId || 'manual',
|
|
353
|
-
timestamp: new Date(),
|
|
354
|
-
data: {
|
|
355
|
-
checkpointId,
|
|
356
|
-
reason: 'Manual rollback',
|
|
357
|
-
},
|
|
358
|
-
});
|
|
359
|
-
|
|
360
|
-
return true;
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
private async ensureInitialized(): Promise<void> {
|
|
364
|
-
if (this.isInitialized) return;
|
|
365
|
-
|
|
366
|
-
const activeTools = await this.toolStore.list({ status: 'active' });
|
|
367
|
-
this.storedExecutableTools = activeTools.map((t) => this.toolGenerator.createExecutableTool(t));
|
|
368
|
-
|
|
369
|
-
this.isInitialized = true;
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
private mergeConfig(partial?: Partial<SelfModifyingConfig>): SelfModifyingConfig {
|
|
458
|
+
private mergeConfig(partial?: SelfModifyingAgentConfig): SelfModifyingConfig {
|
|
373
459
|
const defaults: SelfModifyingConfig = {
|
|
374
460
|
enabled: true,
|
|
375
461
|
toolGeneration: {
|
|
@@ -387,40 +473,7 @@ export class SelfModifyingAgent {
|
|
|
387
473
|
isolationLevel: 'strict',
|
|
388
474
|
},
|
|
389
475
|
},
|
|
390
|
-
metaReasoning: {
|
|
391
|
-
enabled: true,
|
|
392
|
-
defaultMode: 'analytical',
|
|
393
|
-
allowedModes: [
|
|
394
|
-
'analytical',
|
|
395
|
-
'creative',
|
|
396
|
-
'systematic',
|
|
397
|
-
'intuitive',
|
|
398
|
-
'reflective',
|
|
399
|
-
'exploratory',
|
|
400
|
-
],
|
|
401
|
-
modeProfiles: {
|
|
402
|
-
analytical: { mode: 'analytical', temperature: 0.3, depth: 3 },
|
|
403
|
-
creative: { mode: 'creative', temperature: 0.9, depth: 2 },
|
|
404
|
-
systematic: { mode: 'systematic', temperature: 0.2, depth: 4 },
|
|
405
|
-
intuitive: { mode: 'intuitive', temperature: 0.6, depth: 1 },
|
|
406
|
-
reflective: { mode: 'reflective', temperature: 0.4, depth: 3 },
|
|
407
|
-
exploratory: { mode: 'exploratory', temperature: 0.7, depth: 2 },
|
|
408
|
-
},
|
|
409
|
-
maxMetaAssessments: 5,
|
|
410
|
-
maxAdaptations: 3,
|
|
411
|
-
metaAssessmentCooldown: 10000,
|
|
412
|
-
adaptationCooldown: 15000,
|
|
413
|
-
triggers: ['on_failure', 'on_low_confidence', 'periodic'],
|
|
414
|
-
triggerAfterIterations: 3,
|
|
415
|
-
triggerOnConfidenceDrop: 0.3,
|
|
416
|
-
triggerOnProgressStall: 2,
|
|
417
|
-
tokenBudget: 2000,
|
|
418
|
-
maxMetaTokens: 1000,
|
|
419
|
-
minConfidenceToAdapt: 0.6,
|
|
420
|
-
enableRollback: true,
|
|
421
|
-
rollbackWindow: 30000,
|
|
422
|
-
rollbackOnDecline: true,
|
|
423
|
-
},
|
|
476
|
+
metaReasoning: { ...DEFAULT_META_REASONING_CONFIG },
|
|
424
477
|
architectureEvolution: {
|
|
425
478
|
enabled: true,
|
|
426
479
|
strategy: { type: 'ucb', explorationConstant: 2 },
|
|
@@ -439,14 +492,20 @@ export class SelfModifyingAgent {
|
|
|
439
492
|
|
|
440
493
|
if (!partial) return defaults;
|
|
441
494
|
|
|
495
|
+
const defaultSandbox = defaults.toolGeneration.sandboxConfig ?? {
|
|
496
|
+
enabled: true,
|
|
497
|
+
maxExecutionTime: 5000,
|
|
498
|
+
maxMemory: 50 * 1024 * 1024,
|
|
499
|
+
allowedModules: [],
|
|
500
|
+
isolationLevel: 'strict' as const,
|
|
501
|
+
};
|
|
502
|
+
|
|
442
503
|
return {
|
|
443
504
|
enabled: partial.enabled ?? defaults.enabled,
|
|
444
505
|
toolGeneration: {
|
|
445
506
|
...defaults.toolGeneration,
|
|
446
507
|
...partial.toolGeneration,
|
|
447
|
-
sandboxConfig: partial.toolGeneration?.sandboxConfig
|
|
448
|
-
? { ...defaults.toolGeneration.sandboxConfig, ...partial.toolGeneration.sandboxConfig }
|
|
449
|
-
: defaults.toolGeneration.sandboxConfig,
|
|
508
|
+
sandboxConfig: { ...defaultSandbox, ...partial.toolGeneration?.sandboxConfig },
|
|
450
509
|
},
|
|
451
510
|
metaReasoning: {
|
|
452
511
|
...defaults.metaReasoning,
|
|
@@ -459,327 +518,557 @@ export class SelfModifyingAgent {
|
|
|
459
518
|
architectureEvolution: {
|
|
460
519
|
...defaults.architectureEvolution,
|
|
461
520
|
...partial.architectureEvolution,
|
|
462
|
-
strategy:
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
}
|
|
467
|
-
: defaults.architectureEvolution.strategy,
|
|
521
|
+
strategy: {
|
|
522
|
+
...defaults.architectureEvolution.strategy,
|
|
523
|
+
...partial.architectureEvolution?.strategy,
|
|
524
|
+
},
|
|
468
525
|
},
|
|
469
526
|
constraints: { ...defaults.constraints, ...partial.constraints },
|
|
470
527
|
};
|
|
471
528
|
}
|
|
472
529
|
|
|
473
|
-
private
|
|
474
|
-
return [...(this.agent.tools ?? [])
|
|
530
|
+
private getAgentTools(): Tool[] {
|
|
531
|
+
return [...(this.agent.tools ?? [])];
|
|
475
532
|
}
|
|
476
533
|
|
|
477
|
-
private async
|
|
478
|
-
|
|
534
|
+
private async loadAvailableTools(): Promise<Tool[]> {
|
|
535
|
+
const tools = this.getAgentTools();
|
|
536
|
+
const names = new Set(tools.map((t) => t.name));
|
|
537
|
+
const stored = await this.toolStore.list({ status: 'active' });
|
|
538
|
+
|
|
539
|
+
for (const generated of stored) {
|
|
540
|
+
if (names.has(generated.name)) continue;
|
|
541
|
+
names.add(generated.name);
|
|
542
|
+
tools.push(this.toolGenerator.createExecutableTool(generated));
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
return tools;
|
|
546
|
+
}
|
|
479
547
|
|
|
548
|
+
private async optimizeArchitecture(
|
|
549
|
+
ctx: RunContext
|
|
550
|
+
): Promise<{ result: OptimizationResult; candidateId: string } | null> {
|
|
480
551
|
try {
|
|
481
|
-
const result = await this.parameterOptimizer.optimize(input);
|
|
482
|
-
|
|
483
|
-
if (
|
|
484
|
-
const validation = await this.validateModification({
|
|
485
|
-
type: 'config_change',
|
|
486
|
-
target: 'architecture',
|
|
487
|
-
changes: result.recommendedConfig,
|
|
488
|
-
reason: result.reasoning,
|
|
489
|
-
});
|
|
552
|
+
const result = await this.parameterOptimizer.optimize(ctx.input);
|
|
553
|
+
const candidate = result.candidate;
|
|
554
|
+
if (!candidate) return null;
|
|
490
555
|
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
556
|
+
const isNoop = Object.keys(candidate.config).length === 0;
|
|
557
|
+
if (isNoop) {
|
|
558
|
+
return { result, candidateId: candidate.id };
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
if (!result.shouldAdopt || !this.canApplyModification(ctx)) {
|
|
562
|
+
return { result, candidateId: 'baseline' };
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
const valid = await this.validateModification(ctx, {
|
|
566
|
+
type: 'config_change',
|
|
567
|
+
target: 'architecture',
|
|
568
|
+
changes: result.recommendedConfig,
|
|
569
|
+
reason: result.reasoning,
|
|
570
|
+
payload: { candidateId: candidate.id, changedKeys: Object.keys(candidate.config) },
|
|
571
|
+
});
|
|
572
|
+
|
|
573
|
+
if (!valid) {
|
|
574
|
+
return { result, candidateId: 'baseline' };
|
|
507
575
|
}
|
|
576
|
+
|
|
577
|
+
ctx.currentConfig = { ...result.recommendedConfig };
|
|
578
|
+
this.recordModification(ctx, 'config_change', {
|
|
579
|
+
candidateId: candidate.id,
|
|
580
|
+
config: result.recommendedConfig,
|
|
581
|
+
});
|
|
582
|
+
|
|
583
|
+
this.emit('architecture_evolved', ctx.runId, {
|
|
584
|
+
success: true,
|
|
585
|
+
candidateId: candidate.id,
|
|
586
|
+
changes: result.recommendedConfig,
|
|
587
|
+
metrics: result.metrics,
|
|
588
|
+
});
|
|
589
|
+
|
|
590
|
+
return { result, candidateId: candidate.id };
|
|
508
591
|
} catch (error) {
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
timestamp: new Date(),
|
|
513
|
-
data: {
|
|
514
|
-
success: false,
|
|
515
|
-
error: error instanceof Error ? error.message : String(error),
|
|
516
|
-
},
|
|
592
|
+
this.emit('architecture_evolved', ctx.runId, {
|
|
593
|
+
success: false,
|
|
594
|
+
error: error instanceof Error ? error.message : String(error),
|
|
517
595
|
});
|
|
596
|
+
return null;
|
|
518
597
|
}
|
|
519
598
|
}
|
|
520
599
|
|
|
521
|
-
private async
|
|
522
|
-
|
|
600
|
+
private async recordArchitectureOutcome(
|
|
601
|
+
ctx: RunContext,
|
|
602
|
+
optimization: { result: OptimizationResult; candidateId: string } | null,
|
|
603
|
+
success: boolean,
|
|
604
|
+
quality: number
|
|
605
|
+
): Promise<void> {
|
|
606
|
+
if (!optimization) return;
|
|
607
|
+
|
|
608
|
+
await this.parameterOptimizer.recordOutcome(
|
|
609
|
+
optimization.candidateId,
|
|
610
|
+
optimization.result.taskProfile,
|
|
611
|
+
{
|
|
612
|
+
successRate: success ? 1 : 0,
|
|
613
|
+
latency: Date.now() - ctx.startTime,
|
|
614
|
+
tokenUsage: ctx.tokensUsed,
|
|
615
|
+
qualityScore: quality,
|
|
616
|
+
}
|
|
617
|
+
);
|
|
618
|
+
}
|
|
523
619
|
|
|
620
|
+
private async analyzeAndGenerateTools(ctx: RunContext): Promise<void> {
|
|
524
621
|
try {
|
|
525
|
-
const analysis = await this.gapAnalyzer.analyze(input,
|
|
622
|
+
const analysis = await this.gapAnalyzer.analyze(ctx.input, ctx.tools);
|
|
526
623
|
|
|
527
624
|
for (const gap of analysis.gaps) {
|
|
528
|
-
if (
|
|
529
|
-
|
|
530
|
-
)
|
|
531
|
-
break;
|
|
532
|
-
}
|
|
625
|
+
if (ctx.generatedTools.length >= this.config.toolGeneration.maxToolsPerSession) break;
|
|
626
|
+
if (!this.canApplyModification(ctx)) break;
|
|
627
|
+
if (gap.confidence < this.config.toolGeneration.minConfidenceForGeneration) continue;
|
|
533
628
|
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
type: 'tool_generation_started',
|
|
537
|
-
runId: this.currentContext.runId,
|
|
538
|
-
timestamp: new Date(),
|
|
539
|
-
data: { gap },
|
|
540
|
-
});
|
|
541
|
-
|
|
542
|
-
const tool = await this.generateTool(gap);
|
|
543
|
-
|
|
544
|
-
if (!tool) continue;
|
|
545
|
-
|
|
546
|
-
const linesOfCode = tool.implementation.split('\n').length;
|
|
547
|
-
const validated = await this.validateModification({
|
|
548
|
-
type: 'tool_generation',
|
|
549
|
-
target: tool.name,
|
|
550
|
-
changes: { name: tool.name, implementation: tool.implementation },
|
|
551
|
-
reason: `Generated tool for gap: ${gap.suggestedToolName}`,
|
|
552
|
-
payload: {
|
|
553
|
-
sandboxExecution: this.config.toolGeneration.sandboxConfig?.enabled ?? false,
|
|
554
|
-
linesOfCode,
|
|
555
|
-
complexity: linesOfCode,
|
|
556
|
-
modificationDepth: 1,
|
|
557
|
-
},
|
|
558
|
-
});
|
|
559
|
-
|
|
560
|
-
if (!validated || !this.canApplyModification()) {
|
|
561
|
-
void this.emitter.emit({
|
|
562
|
-
type: 'tool_generation_completed',
|
|
563
|
-
runId: this.currentContext.runId,
|
|
564
|
-
timestamp: new Date(),
|
|
565
|
-
data: {
|
|
566
|
-
toolId: tool.id,
|
|
567
|
-
name: tool.name,
|
|
568
|
-
success: false,
|
|
569
|
-
error: 'Rejected by safety constraints or modification limit',
|
|
570
|
-
},
|
|
571
|
-
});
|
|
572
|
-
continue;
|
|
573
|
-
}
|
|
629
|
+
const tool = await this.generateAndRegisterTool(gap, ctx.tools);
|
|
630
|
+
if (!tool) continue;
|
|
574
631
|
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
this.recordModification('tool_generation', { toolId: tool.id, name: tool.name });
|
|
579
|
-
}
|
|
632
|
+
ctx.generatedTools.push(tool);
|
|
633
|
+
ctx.tools.push(this.toolGenerator.createExecutableTool(tool));
|
|
634
|
+
this.recordModification(ctx, 'tool_generation', { toolId: tool.id, name: tool.name });
|
|
580
635
|
}
|
|
581
636
|
} catch (error) {
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
637
|
+
this.emit('tool_generation_completed', ctx.runId, {
|
|
638
|
+
toolId: '',
|
|
639
|
+
name: '',
|
|
640
|
+
success: false,
|
|
641
|
+
error: error instanceof Error ? error.message : String(error),
|
|
642
|
+
});
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
private async generateAndRegisterTool(
|
|
647
|
+
gap: CapabilityGap,
|
|
648
|
+
existingTools: Tool[]
|
|
649
|
+
): Promise<GeneratedTool | null> {
|
|
650
|
+
const ctx = this.currentContext;
|
|
651
|
+
const runId = ctx?.runId ?? 'manual';
|
|
652
|
+
|
|
653
|
+
this.emit('tool_generation_started', runId, { gap });
|
|
654
|
+
|
|
655
|
+
const result = await this.toolGenerator.generate(gap, existingTools);
|
|
656
|
+
const generated = result.tool;
|
|
657
|
+
|
|
658
|
+
if (!result.success || !generated) {
|
|
659
|
+
this.emit('tool_generation_completed', runId, {
|
|
660
|
+
toolId: generated?.id ?? '',
|
|
661
|
+
name: generated?.name ?? gap.suggestedToolName,
|
|
662
|
+
success: false,
|
|
663
|
+
iterations: result.iterations,
|
|
664
|
+
error: result.error,
|
|
665
|
+
});
|
|
666
|
+
return null;
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
const rejection = await this.checkGeneratedTool(generated, existingTools);
|
|
670
|
+
if (rejection) {
|
|
671
|
+
this.emit('tool_generation_completed', runId, {
|
|
672
|
+
toolId: generated.id,
|
|
673
|
+
name: generated.name,
|
|
674
|
+
success: false,
|
|
675
|
+
iterations: result.iterations,
|
|
676
|
+
error: rejection,
|
|
592
677
|
});
|
|
678
|
+
return null;
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
const activeTool: GeneratedTool = { ...generated, status: 'active' };
|
|
682
|
+
await this.toolStore.save(activeTool);
|
|
683
|
+
const saved = (await this.toolStore.get(activeTool.id)) ?? activeTool;
|
|
684
|
+
|
|
685
|
+
this.emit('tool_generation_completed', runId, {
|
|
686
|
+
toolId: saved.id,
|
|
687
|
+
name: saved.name,
|
|
688
|
+
success: true,
|
|
689
|
+
iterations: result.iterations,
|
|
690
|
+
});
|
|
691
|
+
|
|
692
|
+
return saved;
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
private async checkGeneratedTool(
|
|
696
|
+
tool: GeneratedTool,
|
|
697
|
+
existingTools: Tool[]
|
|
698
|
+
): Promise<string | null> {
|
|
699
|
+
if (existingTools.some((t) => t.name === tool.name)) {
|
|
700
|
+
return `A tool named "${tool.name}" already exists`;
|
|
593
701
|
}
|
|
702
|
+
|
|
703
|
+
const linesOfCode = tool.implementation.split('\n').length;
|
|
704
|
+
const valid = await this.validateModification(this.currentContext, {
|
|
705
|
+
type: 'tool_generation',
|
|
706
|
+
target: tool.name,
|
|
707
|
+
changes: { name: tool.name, implementation: tool.implementation },
|
|
708
|
+
reason: `Generated tool for capability gap: ${tool.name}`,
|
|
709
|
+
payload: {
|
|
710
|
+
sandboxExecution: this.config.toolGeneration.sandboxConfig?.enabled ?? false,
|
|
711
|
+
linesOfCode,
|
|
712
|
+
complexity: linesOfCode,
|
|
713
|
+
modificationDepth: 1,
|
|
714
|
+
},
|
|
715
|
+
});
|
|
716
|
+
|
|
717
|
+
return valid ? null : 'Rejected by modification constraints';
|
|
594
718
|
}
|
|
595
719
|
|
|
596
|
-
private async executeWithMetaReasoning(
|
|
597
|
-
|
|
598
|
-
|
|
720
|
+
private async executeWithMetaReasoning(
|
|
721
|
+
ctx: RunContext,
|
|
722
|
+
selfModification: boolean
|
|
723
|
+
): Promise<ExecutionResult> {
|
|
724
|
+
const runId = ctx.runId;
|
|
725
|
+
const metaEnabled = selfModification && this.config.metaReasoning.enabled;
|
|
726
|
+
const maxAttempts = metaEnabled ? Math.max(1, this.config.metaReasoning.maxAdaptations + 1) : 1;
|
|
727
|
+
const contextAdditions: string[] = [];
|
|
728
|
+
let modeAdapted = false;
|
|
729
|
+
let pendingAdaptation: { adaptation: MetaAdaptation; confidence: number } | null = null;
|
|
730
|
+
|
|
731
|
+
if (metaEnabled) {
|
|
732
|
+
const modeConfig = this.metaReasoner.initializeRun(runId);
|
|
733
|
+
this.emit('strategy_changed', runId, {
|
|
734
|
+
previousMode: this.config.metaReasoning.defaultMode,
|
|
735
|
+
newMode: modeConfig.mode,
|
|
736
|
+
reason: 'Initial mode selection',
|
|
737
|
+
});
|
|
599
738
|
}
|
|
600
739
|
|
|
601
|
-
let
|
|
602
|
-
let
|
|
603
|
-
|
|
740
|
+
let step: StepResult | null = null;
|
|
741
|
+
let confidence = 0;
|
|
742
|
+
|
|
743
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
744
|
+
const temperature = modeAdapted
|
|
745
|
+
? this.metaReasoner.getCurrentConfig(runId).temperature
|
|
746
|
+
: ctx.currentConfig.temperature;
|
|
747
|
+
|
|
748
|
+
step = await this.executeAgentStep(ctx, { temperature, contextAdditions });
|
|
749
|
+
ctx.tokensUsed += step.tokensUsed;
|
|
750
|
+
confidence = this.stepConfidence(step);
|
|
751
|
+
|
|
752
|
+
if (!metaEnabled) break;
|
|
604
753
|
|
|
605
|
-
|
|
606
|
-
|
|
754
|
+
this.metaReasoner.recordConfidence(runId, confidence);
|
|
755
|
+
|
|
756
|
+
if (pendingAdaptation) {
|
|
757
|
+
this.metaReasoner.recordOutcome(runId, pendingAdaptation.adaptation.id, {
|
|
758
|
+
improved: step.complete || confidence > pendingAdaptation.confidence,
|
|
759
|
+
progressDelta: step.complete ? 1 : 0,
|
|
760
|
+
confidenceDelta: confidence - pendingAdaptation.confidence,
|
|
761
|
+
});
|
|
762
|
+
pendingAdaptation = null;
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
if (step.complete || attempt === maxAttempts) break;
|
|
607
766
|
|
|
608
|
-
const currentMode = this.metaReasoner.getCurrentMode(runId);
|
|
609
767
|
const observation = this.metaReasoner.observe(
|
|
610
768
|
{
|
|
611
769
|
runId,
|
|
612
|
-
iteration,
|
|
613
|
-
goal: input,
|
|
614
|
-
currentMode,
|
|
615
|
-
tokensUsed:
|
|
616
|
-
timeElapsed: Date.now() -
|
|
617
|
-
iterationsRemaining:
|
|
618
|
-
budgetRemaining:
|
|
770
|
+
iteration: attempt,
|
|
771
|
+
goal: ctx.input,
|
|
772
|
+
currentMode: this.metaReasoner.getCurrentMode(runId),
|
|
773
|
+
tokensUsed: ctx.tokensUsed,
|
|
774
|
+
timeElapsed: Date.now() - ctx.startTime,
|
|
775
|
+
iterationsRemaining: maxAttempts - attempt,
|
|
776
|
+
budgetRemaining: (maxAttempts - attempt) / maxAttempts,
|
|
619
777
|
},
|
|
620
778
|
[]
|
|
621
779
|
);
|
|
780
|
+
ctx.observations.push(observation);
|
|
622
781
|
|
|
623
|
-
this.
|
|
782
|
+
if (!this.selectTrigger(runId, attempt, confidence, observation)) continue;
|
|
624
783
|
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
iteration,
|
|
628
|
-
confidence: this.estimateConfidence(output),
|
|
629
|
-
progressDelta: output.length > 0 ? 0.1 : 0,
|
|
630
|
-
stagnationCount: 0,
|
|
631
|
-
})
|
|
632
|
-
) {
|
|
633
|
-
const assessment = await this.metaReasoner.assess(observation);
|
|
784
|
+
const assessment = await this.metaReasoner.assess(observation);
|
|
785
|
+
this.emit('meta_assessment', runId, { observation, assessment });
|
|
634
786
|
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
runId,
|
|
638
|
-
timestamp: new Date(),
|
|
639
|
-
data: {
|
|
640
|
-
observation,
|
|
641
|
-
assessment,
|
|
642
|
-
},
|
|
643
|
-
});
|
|
787
|
+
if (!assessment.requiresAdaptation) continue;
|
|
788
|
+
if (assessment.recommendation.action === 'abort') break;
|
|
644
789
|
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
if (adaptation) {
|
|
649
|
-
this.currentContext.adaptations.push(adaptation);
|
|
650
|
-
|
|
651
|
-
void this.emitter.emit({
|
|
652
|
-
type: 'strategy_changed',
|
|
653
|
-
runId,
|
|
654
|
-
timestamp: new Date(),
|
|
655
|
-
data: {
|
|
656
|
-
previousMode: adaptation.before?.mode || 'analytical',
|
|
657
|
-
newMode: adaptation.after?.mode || 'analytical',
|
|
658
|
-
reason: adaptation.type,
|
|
659
|
-
},
|
|
660
|
-
});
|
|
661
|
-
}
|
|
662
|
-
}
|
|
663
|
-
}
|
|
790
|
+
const adaptation = await this.metaReasoner.adapt(runId, assessment);
|
|
791
|
+
if (!adaptation) continue;
|
|
664
792
|
|
|
665
|
-
|
|
793
|
+
ctx.adaptations.push(adaptation);
|
|
794
|
+
pendingAdaptation = { adaptation, confidence };
|
|
666
795
|
|
|
667
|
-
if (
|
|
668
|
-
|
|
796
|
+
if (adaptation.type === 'context_injection' && assessment.recommendation.contextAddition) {
|
|
797
|
+
contextAdditions.push(assessment.recommendation.contextAddition);
|
|
798
|
+
} else {
|
|
799
|
+
modeAdapted = true;
|
|
669
800
|
}
|
|
801
|
+
|
|
802
|
+
this.emit('strategy_changed', runId, {
|
|
803
|
+
previousMode: adaptation.previousMode ?? this.metaReasoner.getCurrentMode(runId),
|
|
804
|
+
newMode: adaptation.newMode ?? this.metaReasoner.getCurrentMode(runId),
|
|
805
|
+
reason: adaptation.reason ?? adaptation.type,
|
|
806
|
+
});
|
|
670
807
|
}
|
|
671
808
|
|
|
672
|
-
return output;
|
|
809
|
+
return { output: step?.content ?? '', confidence };
|
|
673
810
|
}
|
|
674
811
|
|
|
675
|
-
private
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
812
|
+
private selectTrigger(
|
|
813
|
+
runId: string,
|
|
814
|
+
iteration: number,
|
|
815
|
+
confidence: number,
|
|
816
|
+
observation: MetaObservation
|
|
817
|
+
): MetaTrigger | null {
|
|
818
|
+
const context = {
|
|
819
|
+
iteration,
|
|
820
|
+
confidence,
|
|
821
|
+
progressDelta: observation.progressDelta,
|
|
822
|
+
stagnationCount: observation.stagnationCount,
|
|
823
|
+
};
|
|
824
|
+
const candidates: MetaTrigger[] = [
|
|
825
|
+
'on_failure',
|
|
826
|
+
'on_low_confidence',
|
|
827
|
+
'on_stagnation',
|
|
828
|
+
'iteration_complete',
|
|
829
|
+
'periodic',
|
|
830
|
+
];
|
|
831
|
+
return candidates.find((t) => this.metaReasoner.shouldTrigger(runId, t, context)) ?? null;
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
private async executeAgentStep(ctx: RunContext, options: StepOptions): Promise<StepResult> {
|
|
835
|
+
const toolMap = new Map<string, Tool>(ctx.tools.map((t) => [t.name, t]));
|
|
836
|
+
const toolSchemas = this.buildToolSchemas(ctx.tools);
|
|
837
|
+
const generatedIds = new Map(ctx.generatedTools.map((t) => [t.name, t.id]));
|
|
838
|
+
for (const stored of await this.toolStore.list({ status: 'active' })) {
|
|
839
|
+
if (!generatedIds.has(stored.name)) generatedIds.set(stored.name, stored.id);
|
|
681
840
|
}
|
|
682
841
|
|
|
683
|
-
const model =
|
|
842
|
+
const model = ctx.currentConfig.model;
|
|
843
|
+
const maxTokens = ctx.currentConfig.maxTokens;
|
|
684
844
|
const messages: Message[] = [
|
|
685
845
|
...(this.agent.instructions
|
|
686
846
|
? [{ role: 'system' as const, content: this.agent.instructions }]
|
|
687
847
|
: []),
|
|
688
|
-
{ role: '
|
|
848
|
+
...options.contextAdditions.map((content) => ({ role: 'system' as const, content })),
|
|
849
|
+
{ role: 'user' as const, content: ctx.input },
|
|
689
850
|
];
|
|
690
851
|
|
|
691
|
-
|
|
852
|
+
let tokensUsed = 0;
|
|
853
|
+
let toolCalls = 0;
|
|
854
|
+
let toolErrors = 0;
|
|
855
|
+
let response: ChatResponse | null = null;
|
|
856
|
+
|
|
857
|
+
const maxToolRounds = this.agent.config?.maxIterations ?? DEFAULT_MAX_TOOL_ROUNDS;
|
|
692
858
|
for (let round = 0; round < maxToolRounds; round++) {
|
|
693
|
-
|
|
859
|
+
response = await this.llm.chat({
|
|
694
860
|
model,
|
|
695
861
|
messages,
|
|
696
862
|
tools: toolSchemas.length > 0 ? toolSchemas : undefined,
|
|
697
|
-
temperature:
|
|
698
|
-
maxTokens
|
|
863
|
+
temperature: options.temperature,
|
|
864
|
+
maxTokens,
|
|
699
865
|
});
|
|
866
|
+
tokensUsed += response.usage?.totalTokens ?? 0;
|
|
700
867
|
|
|
701
868
|
if (response.finishReason !== 'tool_calls' || !response.toolCalls?.length) {
|
|
702
|
-
|
|
869
|
+
break;
|
|
703
870
|
}
|
|
704
871
|
|
|
705
|
-
|
|
872
|
+
const assistantMessage: ToolCallMessage = {
|
|
706
873
|
role: 'assistant',
|
|
707
874
|
content: response.content,
|
|
708
875
|
toolCalls: response.toolCalls,
|
|
709
|
-
}
|
|
710
|
-
|
|
711
|
-
for (const toolCall of response.toolCalls) {
|
|
712
|
-
const t = toolMap.get(toolCall.name);
|
|
713
|
-
let result: unknown;
|
|
714
|
-
|
|
715
|
-
if (!t) {
|
|
716
|
-
result = { error: `Tool "${toolCall.name}" not found` };
|
|
717
|
-
} else {
|
|
718
|
-
try {
|
|
719
|
-
const ctx: ToolContext = {
|
|
720
|
-
agentId: this.agent.name || 'self-modifying',
|
|
721
|
-
runId: this.currentContext?.runId || 'unknown',
|
|
722
|
-
signal: AbortSignal.timeout(30_000),
|
|
723
|
-
};
|
|
724
|
-
result = await t.execute(toolCall.arguments, ctx);
|
|
725
|
-
} catch (err) {
|
|
726
|
-
result = { error: err instanceof Error ? err.message : String(err) };
|
|
727
|
-
}
|
|
728
|
-
}
|
|
876
|
+
};
|
|
877
|
+
messages.push(assistantMessage);
|
|
729
878
|
|
|
879
|
+
const outcomes = await this.executeToolCalls(ctx, response.toolCalls, toolMap, generatedIds);
|
|
880
|
+
for (const outcome of outcomes) {
|
|
881
|
+
toolCalls++;
|
|
882
|
+
if (outcome.failed) toolErrors++;
|
|
730
883
|
messages.push({
|
|
731
|
-
role: 'tool'
|
|
732
|
-
content:
|
|
733
|
-
toolCallId:
|
|
734
|
-
name:
|
|
884
|
+
role: 'tool',
|
|
885
|
+
content: outcome.content,
|
|
886
|
+
toolCallId: outcome.call.id,
|
|
887
|
+
name: outcome.call.name,
|
|
735
888
|
});
|
|
736
889
|
}
|
|
890
|
+
response = null;
|
|
737
891
|
}
|
|
738
892
|
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
893
|
+
if (!response) {
|
|
894
|
+
response = await this.llm.chat({
|
|
895
|
+
model,
|
|
896
|
+
messages,
|
|
897
|
+
temperature: options.temperature,
|
|
898
|
+
maxTokens,
|
|
899
|
+
});
|
|
900
|
+
tokensUsed += response.usage?.totalTokens ?? 0;
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
let content = response.content;
|
|
904
|
+
let finishReason = response.finishReason;
|
|
905
|
+
|
|
906
|
+
for (let depth = 0; depth < ctx.currentConfig.reflectionDepth && content.trim(); depth++) {
|
|
907
|
+
const reflection = await this.llm.chat({
|
|
908
|
+
model,
|
|
909
|
+
messages: [
|
|
910
|
+
...messages,
|
|
911
|
+
{ role: 'assistant', content },
|
|
912
|
+
{
|
|
913
|
+
role: 'user',
|
|
914
|
+
content:
|
|
915
|
+
'Review your previous answer for mistakes or omissions. Reply with the final, corrected answer only. If it is already correct, repeat it unchanged.',
|
|
916
|
+
},
|
|
917
|
+
],
|
|
918
|
+
temperature: options.temperature,
|
|
919
|
+
maxTokens,
|
|
920
|
+
});
|
|
921
|
+
tokensUsed += reflection.usage?.totalTokens ?? 0;
|
|
922
|
+
if (!reflection.content.trim() || reflection.finishReason === 'error') break;
|
|
923
|
+
content = reflection.content;
|
|
924
|
+
finishReason = reflection.finishReason;
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
return {
|
|
928
|
+
content,
|
|
929
|
+
finishReason,
|
|
930
|
+
tokensUsed,
|
|
931
|
+
toolCalls,
|
|
932
|
+
toolErrors,
|
|
933
|
+
complete: content.trim().length > 0 && finishReason !== 'length' && finishReason !== 'error',
|
|
934
|
+
};
|
|
746
935
|
}
|
|
747
936
|
|
|
748
|
-
private
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
937
|
+
private async executeToolCalls(
|
|
938
|
+
ctx: RunContext,
|
|
939
|
+
calls: ToolCall[],
|
|
940
|
+
toolMap: Map<string, Tool>,
|
|
941
|
+
generatedIds: Map<string, string>
|
|
942
|
+
): Promise<ToolCallOutcome[]> {
|
|
943
|
+
const strategy = ctx.currentConfig.toolStrategy;
|
|
944
|
+
const parallel =
|
|
945
|
+
strategy === 'parallel' ||
|
|
946
|
+
(strategy === 'adaptive' && new Set(calls.map((c) => c.name)).size === calls.length);
|
|
947
|
+
|
|
948
|
+
if (parallel) {
|
|
949
|
+
return Promise.all(
|
|
950
|
+
calls.map((call) => this.executeToolCall(ctx, call, toolMap, generatedIds))
|
|
951
|
+
);
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
const outcomes: ToolCallOutcome[] = [];
|
|
955
|
+
for (const call of calls) {
|
|
956
|
+
outcomes.push(await this.executeToolCall(ctx, call, toolMap, generatedIds));
|
|
957
|
+
}
|
|
958
|
+
return outcomes;
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
private async executeToolCall(
|
|
962
|
+
ctx: RunContext,
|
|
963
|
+
call: ToolCall,
|
|
964
|
+
toolMap: Map<string, Tool>,
|
|
965
|
+
generatedIds: Map<string, string>
|
|
966
|
+
): Promise<ToolCallOutcome> {
|
|
967
|
+
const t = toolMap.get(call.name);
|
|
968
|
+
const startedAt = Date.now();
|
|
969
|
+
let result: unknown;
|
|
970
|
+
let error: string | undefined;
|
|
971
|
+
|
|
972
|
+
if (!t) {
|
|
973
|
+
error = `Tool "${call.name}" not found`;
|
|
974
|
+
} else {
|
|
975
|
+
const parsed = t.parameters.safeParse(call.arguments);
|
|
976
|
+
if (!parsed.success) {
|
|
977
|
+
error = `Invalid arguments for "${call.name}": ${parsed.error.issues
|
|
978
|
+
.map((i) => `${i.path.join('.') || '(root)'}: ${i.message}`)
|
|
979
|
+
.join('; ')}`;
|
|
980
|
+
} else {
|
|
981
|
+
try {
|
|
982
|
+
const toolContext: ToolContext = {
|
|
983
|
+
agentId: this.agent.id ?? this.agent.name ?? 'self-modifying',
|
|
984
|
+
runId: ctx.runId,
|
|
985
|
+
signal: AbortSignal.timeout(t.timeout ?? DEFAULT_TOOL_TIMEOUT_MS),
|
|
986
|
+
};
|
|
987
|
+
result = await t.execute(parsed.data, toolContext);
|
|
988
|
+
} catch (err) {
|
|
989
|
+
error = err instanceof Error ? err.message : String(err);
|
|
990
|
+
}
|
|
752
991
|
}
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
992
|
+
}
|
|
993
|
+
|
|
994
|
+
const duration = Date.now() - startedAt;
|
|
995
|
+
const generatedId = generatedIds.get(call.name);
|
|
996
|
+
if (generatedId) {
|
|
997
|
+
await this.toolStore.recordUsage({
|
|
998
|
+
toolId: generatedId,
|
|
999
|
+
timestamp: new Date(),
|
|
1000
|
+
success: error === undefined,
|
|
1001
|
+
executionTime: duration,
|
|
1002
|
+
error,
|
|
1003
|
+
});
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
if (this.config.enabled && this.config.metaReasoning.enabled) {
|
|
1007
|
+
this.metaReasoner.recordAction(ctx.runId, {
|
|
1008
|
+
type: 'tool_call',
|
|
1009
|
+
toolName: call.name,
|
|
1010
|
+
input: call.arguments,
|
|
1011
|
+
output: error === undefined ? result : undefined,
|
|
1012
|
+
error,
|
|
1013
|
+
duration,
|
|
1014
|
+
timestamp: startedAt,
|
|
1015
|
+
});
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
if (error !== undefined) {
|
|
1019
|
+
return { call, content: JSON.stringify({ error }), failed: true };
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
return {
|
|
1023
|
+
call,
|
|
1024
|
+
content: typeof result === 'string' ? result : (JSON.stringify(result) ?? 'null'),
|
|
1025
|
+
failed: false,
|
|
1026
|
+
};
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
private buildToolSchemas(tools: Tool[]): ToolSchema[] {
|
|
1030
|
+
return tools.map((t) =>
|
|
1031
|
+
typeof t.toJSON === 'function'
|
|
1032
|
+
? t.toJSON()
|
|
1033
|
+
: {
|
|
1034
|
+
name: t.name,
|
|
1035
|
+
description: t.description,
|
|
1036
|
+
parameters: { type: 'object' as const, properties: {} },
|
|
1037
|
+
}
|
|
1038
|
+
);
|
|
1039
|
+
}
|
|
1040
|
+
|
|
1041
|
+
private stepConfidence(step: StepResult): number {
|
|
1042
|
+
if (!step.complete) return 0.2;
|
|
1043
|
+
if (step.toolCalls > 0 && step.toolErrors > 0) {
|
|
1044
|
+
return step.toolErrors >= step.toolCalls ? 0.4 : 0.6;
|
|
1045
|
+
}
|
|
1046
|
+
return 0.9;
|
|
759
1047
|
}
|
|
760
1048
|
|
|
761
|
-
private async validateModification(
|
|
1049
|
+
private async validateModification(
|
|
1050
|
+
ctx: RunContext | null,
|
|
1051
|
+
request: ModificationRequest
|
|
1052
|
+
): Promise<boolean> {
|
|
762
1053
|
if (!this.config.constraints.enabled) return true;
|
|
763
1054
|
|
|
764
1055
|
const validation = await this.modificationValidator.validate(request);
|
|
765
1056
|
|
|
766
|
-
if (validation.rollbackRequired && this.config.constraints.autoRollback) {
|
|
767
|
-
await this.
|
|
1057
|
+
if (validation.rollbackRequired && this.config.constraints.autoRollback && ctx) {
|
|
1058
|
+
await this.autoRollback(ctx, `Critical constraint violation: ${request.type}`);
|
|
768
1059
|
}
|
|
769
1060
|
|
|
770
1061
|
return validation.valid;
|
|
771
1062
|
}
|
|
772
1063
|
|
|
773
|
-
private canApplyModification(): boolean {
|
|
1064
|
+
private canApplyModification(ctx: RunContext): boolean {
|
|
774
1065
|
if (!this.config.constraints.enabled) return true;
|
|
775
|
-
|
|
776
|
-
return this.currentContext.modificationsCount < this.config.constraints.maxModificationsPerRun;
|
|
1066
|
+
return ctx.modificationsCount < this.config.constraints.maxModificationsPerRun;
|
|
777
1067
|
}
|
|
778
1068
|
|
|
779
|
-
private recordModification(type: string, data: unknown): void {
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
this.currentContext.appliedModifications.push({
|
|
1069
|
+
private recordModification(ctx: RunContext, type: string, data: unknown): void {
|
|
1070
|
+
ctx.modificationsCount++;
|
|
1071
|
+
ctx.appliedModifications.push({
|
|
783
1072
|
id: `mod_${nanoid(8)}`,
|
|
784
1073
|
type,
|
|
785
1074
|
appliedAt: new Date(),
|
|
@@ -787,29 +1076,15 @@ export class SelfModifyingAgent {
|
|
|
787
1076
|
});
|
|
788
1077
|
}
|
|
789
1078
|
|
|
790
|
-
private async
|
|
791
|
-
if (!this.currentContext) return;
|
|
792
|
-
|
|
1079
|
+
private async autoRollback(ctx: RunContext, reason: string): Promise<void> {
|
|
793
1080
|
const now = Date.now();
|
|
794
1081
|
const window = this.config.constraints.rollbackWindow;
|
|
795
|
-
const target =
|
|
1082
|
+
const target = ctx.checkpoints
|
|
796
1083
|
.filter((c) => now - c.timestamp.getTime() <= window)
|
|
797
1084
|
.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime())[0];
|
|
798
1085
|
|
|
799
1086
|
if (target) {
|
|
800
|
-
await this.rollbackToCheckpoint(target.id);
|
|
1087
|
+
await this.rollbackToCheckpoint(target.id, reason);
|
|
801
1088
|
}
|
|
802
1089
|
}
|
|
803
|
-
|
|
804
|
-
private estimateConfidence(output: string): number {
|
|
805
|
-
if (!output) return 0.3;
|
|
806
|
-
if (output.length < 50) return 0.4;
|
|
807
|
-
if (output.length < 200) return 0.6;
|
|
808
|
-
return 0.8;
|
|
809
|
-
}
|
|
810
|
-
|
|
811
|
-
private isTaskComplete(output: string): boolean {
|
|
812
|
-
if (!output.trim()) return false;
|
|
813
|
-
return this.estimateConfidence(output) >= 0.6;
|
|
814
|
-
}
|
|
815
1090
|
}
|