@cogitator-ai/self-modifying 17.0.17 → 18.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +112 -48
- package/dist/architecture-evolution/capability-analyzer.d.ts.map +1 -1
- package/dist/architecture-evolution/capability-analyzer.js +44 -40
- package/dist/architecture-evolution/capability-analyzer.js.map +1 -1
- package/dist/architecture-evolution/evolution-strategy.d.ts.map +1 -1
- package/dist/architecture-evolution/evolution-strategy.js +4 -2
- package/dist/architecture-evolution/evolution-strategy.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 +62 -34
- 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 +189 -37
- 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 +45 -18
- package/dist/constraints/modification-validator.js.map +1 -1
- package/dist/constraints/rollback-manager.d.ts +1 -0
- package/dist/constraints/rollback-manager.d.ts.map +1 -1
- package/dist/constraints/rollback-manager.js +25 -1
- package/dist/constraints/rollback-manager.js.map +1 -1
- package/dist/events/event-emitter.d.ts +0 -1
- package/dist/events/event-emitter.d.ts.map +1 -1
- package/dist/events/event-emitter.js +6 -10
- package/dist/events/event-emitter.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 +4 -1
- package/dist/meta-reasoning/meta-reasoner.d.ts.map +1 -1
- package/dist/meta-reasoning/meta-reasoner.js +120 -43
- package/dist/meta-reasoning/meta-reasoner.js.map +1 -1
- package/dist/meta-reasoning/observation-collector.d.ts.map +1 -1
- package/dist/meta-reasoning/observation-collector.js +6 -2
- package/dist/meta-reasoning/observation-collector.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 +108 -33
- package/dist/meta-reasoning/prompts.js.map +1 -1
- package/dist/meta-reasoning/strategy-selector.d.ts.map +1 -1
- package/dist/meta-reasoning/strategy-selector.js +6 -0
- package/dist/meta-reasoning/strategy-selector.js.map +1 -1
- package/dist/self-modifying-agent.d.ts +88 -15
- package/dist/self-modifying-agent.d.ts.map +1 -1
- package/dist/self-modifying-agent.js +583 -376
- 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 +16 -15
- package/dist/tool-generation/gap-analyzer.js.map +1 -1
- package/dist/tool-generation/generated-tool-store.d.ts.map +1 -1
- package/dist/tool-generation/generated-tool-store.js +90 -10
- package/dist/tool-generation/generated-tool-store.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 +4 -3
- package/dist/tool-generation/prompts.d.ts.map +1 -1
- package/dist/tool-generation/prompts.js +96 -18
- package/dist/tool-generation/prompts.js.map +1 -1
- package/dist/tool-generation/tool-generator.d.ts +6 -6
- package/dist/tool-generation/tool-generator.d.ts.map +1 -1
- package/dist/tool-generation/tool-generator.js +88 -23
- package/dist/tool-generation/tool-generator.js.map +1 -1
- package/dist/tool-generation/tool-sandbox.d.ts +10 -11
- package/dist/tool-generation/tool-sandbox.d.ts.map +1 -1
- package/dist/tool-generation/tool-sandbox.js +346 -156
- package/dist/tool-generation/tool-sandbox.js.map +1 -1
- package/dist/tool-generation/tool-validator.d.ts +4 -8
- package/dist/tool-generation/tool-validator.d.ts.map +1 -1
- package/dist/tool-generation/tool-validator.js +74 -28
- package/dist/tool-generation/tool-validator.js.map +1 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +30 -5
- package/dist/utils/index.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 +405 -11
- package/src/architecture-evolution/capability-analyzer.ts +63 -44
- package/src/architecture-evolution/evolution-strategy.ts +5 -2
- package/src/architecture-evolution/index.ts +2 -0
- package/src/architecture-evolution/parameter-optimizer.ts +82 -40
- package/src/architecture-evolution/prompts.ts +224 -42
- package/src/constraints/modification-validator.ts +48 -21
- package/src/constraints/rollback-manager.ts +20 -1
- package/src/events/event-emitter.ts +6 -15
- package/src/index.ts +14 -0
- package/src/meta-reasoning/meta-reasoner.ts +124 -52
- package/src/meta-reasoning/observation-collector.ts +6 -2
- package/src/meta-reasoning/prompts.ts +131 -56
- package/src/meta-reasoning/strategy-selector.ts +6 -0
- package/src/self-modifying-agent.ts +797 -413
- package/src/tool-generation/gap-analyzer.ts +21 -19
- package/src/tool-generation/generated-tool-store.ts +97 -10
- package/src/tool-generation/index.ts +13 -3
- package/src/tool-generation/prompts.ts +120 -18
- package/src/tool-generation/tool-generator.ts +120 -26
- package/src/tool-generation/tool-sandbox.ts +408 -206
- package/src/tool-generation/tool-validator.ts +90 -37
- package/src/utils/index.ts +29 -5
- package/src/utils/llm-helper.ts +1 -0
|
@@ -1,25 +1,43 @@
|
|
|
1
|
+
import { nanoid } from 'nanoid';
|
|
1
2
|
import type {
|
|
2
3
|
Agent,
|
|
3
4
|
AgentConfig,
|
|
4
5
|
Tool,
|
|
6
|
+
ToolCall,
|
|
7
|
+
ToolCallMessage,
|
|
5
8
|
LLMBackend,
|
|
9
|
+
ChatResponse,
|
|
6
10
|
SelfModifyingConfig,
|
|
11
|
+
ToolSelfGenerationConfig,
|
|
12
|
+
ToolSandboxConfig,
|
|
13
|
+
MetaReasoningConfig,
|
|
14
|
+
ArchitectureEvolutionConfig,
|
|
15
|
+
ModificationConstraintsConfig,
|
|
16
|
+
ModificationConstraints,
|
|
7
17
|
ArchitectureConfig,
|
|
8
18
|
GeneratedTool,
|
|
9
19
|
MetaObservation,
|
|
20
|
+
MetaAssessment,
|
|
10
21
|
MetaAdaptation,
|
|
22
|
+
MetaTrigger,
|
|
11
23
|
ModificationCheckpoint,
|
|
24
|
+
AppliedModification,
|
|
25
|
+
ModificationRequest,
|
|
12
26
|
SelfModifyingEvent,
|
|
27
|
+
SelfModifyingEventType,
|
|
13
28
|
CapabilityGap,
|
|
29
|
+
EvolutionMetrics,
|
|
30
|
+
ReasoningMode,
|
|
14
31
|
Message,
|
|
15
32
|
ToolSchema,
|
|
16
33
|
ToolContext,
|
|
17
34
|
} from '@cogitator-ai/types';
|
|
35
|
+
import { DEFAULT_META_REASONING_CONFIG } from '@cogitator-ai/types';
|
|
18
36
|
|
|
19
37
|
import { SelfModifyingEventEmitter } from './events';
|
|
20
38
|
import { GapAnalyzer, ToolGenerator, InMemoryGeneratedToolStore } from './tool-generation';
|
|
21
39
|
import { MetaReasoner } from './meta-reasoning';
|
|
22
|
-
import { ParameterOptimizer,
|
|
40
|
+
import { ParameterOptimizer, type OptimizationResult } from './architecture-evolution';
|
|
23
41
|
import {
|
|
24
42
|
ModificationValidator,
|
|
25
43
|
RollbackManager,
|
|
@@ -28,12 +46,63 @@ import {
|
|
|
28
46
|
DEFAULT_RESOURCE_CONSTRAINTS,
|
|
29
47
|
} from './constraints';
|
|
30
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
|
+
|
|
31
59
|
export interface SelfModifyingAgentOptions {
|
|
32
60
|
agent: Agent;
|
|
33
61
|
llm: LLMBackend;
|
|
34
|
-
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[];
|
|
35
67
|
}
|
|
36
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 };
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export type TypedSelfModifyingEvent<K extends SelfModifyingEventType> = Omit<
|
|
99
|
+
SelfModifyingEvent,
|
|
100
|
+
'type' | 'data'
|
|
101
|
+
> & {
|
|
102
|
+
type: K;
|
|
103
|
+
data: SelfModifyingEventDataMap[K];
|
|
104
|
+
};
|
|
105
|
+
|
|
37
106
|
export interface RunContext {
|
|
38
107
|
runId: string;
|
|
39
108
|
input: string;
|
|
@@ -44,33 +113,75 @@ export interface RunContext {
|
|
|
44
113
|
observations: MetaObservation[];
|
|
45
114
|
adaptations: MetaAdaptation[];
|
|
46
115
|
checkpoints: ModificationCheckpoint[];
|
|
116
|
+
modificationsCount: number;
|
|
117
|
+
appliedModifications: AppliedModification[];
|
|
118
|
+
tokensUsed: number;
|
|
119
|
+
}
|
|
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;
|
|
47
133
|
}
|
|
48
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
|
+
|
|
49
155
|
export class SelfModifyingAgent {
|
|
50
156
|
private readonly agent: Agent;
|
|
51
157
|
private readonly llm: LLMBackend;
|
|
158
|
+
private readonly modelName: string;
|
|
52
159
|
private readonly config: SelfModifyingConfig;
|
|
53
160
|
private readonly emitter = new SelfModifyingEventEmitter();
|
|
161
|
+
private readonly listenerWrappers = new Map<
|
|
162
|
+
SelfModifyingEventType,
|
|
163
|
+
Map<(event: never) => void, (event: SelfModifyingEvent) => void>
|
|
164
|
+
>();
|
|
54
165
|
|
|
55
166
|
private readonly gapAnalyzer: GapAnalyzer;
|
|
56
167
|
private readonly toolGenerator: ToolGenerator;
|
|
57
168
|
private readonly toolStore: InMemoryGeneratedToolStore;
|
|
58
169
|
private readonly metaReasoner: MetaReasoner;
|
|
59
170
|
private readonly parameterOptimizer: ParameterOptimizer;
|
|
60
|
-
private readonly capabilityAnalyzer: CapabilityAnalyzer;
|
|
61
171
|
private readonly modificationValidator: ModificationValidator;
|
|
62
172
|
private readonly rollbackManager: RollbackManager;
|
|
63
173
|
|
|
64
174
|
private currentContext: RunContext | null = null;
|
|
65
|
-
private
|
|
175
|
+
private runQueue: Promise<unknown> = Promise.resolve();
|
|
66
176
|
|
|
67
177
|
constructor(options: SelfModifyingAgentOptions) {
|
|
68
178
|
this.agent = options.agent;
|
|
69
179
|
this.llm = options.llm;
|
|
180
|
+
this.modelName = resolveModelName(options.agent.model, options.llm.provider);
|
|
70
181
|
this.config = this.mergeConfig(options.config);
|
|
71
182
|
|
|
72
183
|
const toolGenConfig = this.config.toolGeneration;
|
|
73
|
-
const agentModel = this.
|
|
184
|
+
const agentModel = this.modelName;
|
|
74
185
|
this.gapAnalyzer = new GapAnalyzer({ llm: this.llm, config: toolGenConfig, model: agentModel });
|
|
75
186
|
this.toolGenerator = new ToolGenerator({
|
|
76
187
|
llm: this.llm,
|
|
@@ -81,36 +192,30 @@ export class SelfModifyingAgent {
|
|
|
81
192
|
|
|
82
193
|
this.metaReasoner = new MetaReasoner({
|
|
83
194
|
llm: this.llm,
|
|
84
|
-
model: agentModel
|
|
195
|
+
model: agentModel,
|
|
85
196
|
config: this.config.metaReasoning,
|
|
86
197
|
});
|
|
87
198
|
|
|
88
|
-
const baseArchConfig: ArchitectureConfig = {
|
|
89
|
-
model: agentModel ?? 'default',
|
|
90
|
-
temperature: 0.7,
|
|
91
|
-
maxTokens: 4096,
|
|
92
|
-
toolStrategy: 'sequential',
|
|
93
|
-
reflectionDepth: 1,
|
|
94
|
-
};
|
|
95
|
-
|
|
96
199
|
this.parameterOptimizer = new ParameterOptimizer({
|
|
97
200
|
llm: this.llm,
|
|
98
201
|
config: this.config.architectureEvolution,
|
|
99
|
-
baseConfig:
|
|
100
|
-
model: agentModel,
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
this.capabilityAnalyzer = new CapabilityAnalyzer({
|
|
104
|
-
llm: this.llm,
|
|
105
|
-
enableLLMAnalysis: true,
|
|
202
|
+
baseConfig: this.createBaseArchitectureConfig(),
|
|
106
203
|
model: agentModel,
|
|
204
|
+
availableModels: options.availableModels,
|
|
107
205
|
});
|
|
108
206
|
|
|
109
207
|
this.modificationValidator = new ModificationValidator({
|
|
110
208
|
constraints: {
|
|
111
|
-
safety: DEFAULT_SAFETY_CONSTRAINTS,
|
|
112
|
-
capability:
|
|
113
|
-
|
|
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,
|
|
114
219
|
},
|
|
115
220
|
});
|
|
116
221
|
|
|
@@ -119,117 +224,44 @@ export class SelfModifyingAgent {
|
|
|
119
224
|
});
|
|
120
225
|
}
|
|
121
226
|
|
|
122
|
-
on<K extends
|
|
227
|
+
on<K extends SelfModifyingEventType>(
|
|
123
228
|
event: K,
|
|
124
|
-
handler: (event:
|
|
125
|
-
): void {
|
|
126
|
-
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);
|
|
127
243
|
}
|
|
128
244
|
|
|
129
|
-
off<K extends
|
|
245
|
+
off<K extends SelfModifyingEventType>(
|
|
130
246
|
event: K,
|
|
131
|
-
handler: (event:
|
|
247
|
+
handler: (event: TypedSelfModifyingEvent<K>) => void
|
|
132
248
|
): void {
|
|
133
|
-
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);
|
|
134
254
|
}
|
|
135
255
|
|
|
136
|
-
|
|
256
|
+
run(input: string): Promise<{
|
|
137
257
|
output: string;
|
|
138
258
|
toolsGenerated: GeneratedTool[];
|
|
139
259
|
adaptationsMade: MetaAdaptation[];
|
|
140
260
|
finalConfig: ArchitectureConfig;
|
|
141
261
|
}> {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
const tools = this.getAvailableTools();
|
|
146
|
-
|
|
147
|
-
const baseConfig: ArchitectureConfig = {
|
|
148
|
-
model: 'default',
|
|
149
|
-
temperature: 0.7,
|
|
150
|
-
maxTokens: 4096,
|
|
151
|
-
toolStrategy: 'sequential',
|
|
152
|
-
reflectionDepth: 1,
|
|
153
|
-
};
|
|
154
|
-
|
|
155
|
-
this.currentContext = {
|
|
156
|
-
runId,
|
|
157
|
-
input,
|
|
158
|
-
startTime: Date.now(),
|
|
159
|
-
tools: [...tools],
|
|
160
|
-
currentConfig: baseConfig,
|
|
161
|
-
generatedTools: [],
|
|
162
|
-
observations: [],
|
|
163
|
-
adaptations: [],
|
|
164
|
-
checkpoints: [],
|
|
165
|
-
};
|
|
166
|
-
|
|
167
|
-
void this.emitter.emit({
|
|
168
|
-
type: 'run_started',
|
|
169
|
-
runId,
|
|
170
|
-
timestamp: new Date(),
|
|
171
|
-
data: { input },
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
try {
|
|
175
|
-
if (this.config.architectureEvolution.enabled) {
|
|
176
|
-
await this.optimizeArchitecture(input);
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
if (this.config.toolGeneration.enabled && this.config.toolGeneration.autoGenerate) {
|
|
180
|
-
await this.analyzeAndGenerateTools(input);
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
const modeConfig = this.metaReasoner.initializeRun(runId);
|
|
184
|
-
|
|
185
|
-
void this.emitter.emit({
|
|
186
|
-
type: 'strategy_changed',
|
|
187
|
-
runId,
|
|
188
|
-
timestamp: new Date(),
|
|
189
|
-
data: {
|
|
190
|
-
previousMode: 'analytical',
|
|
191
|
-
newMode: modeConfig.mode,
|
|
192
|
-
reason: 'Initial mode selection',
|
|
193
|
-
},
|
|
194
|
-
});
|
|
195
|
-
|
|
196
|
-
const output = await this.executeWithMetaReasoning(input, runId);
|
|
197
|
-
|
|
198
|
-
const result = {
|
|
199
|
-
output,
|
|
200
|
-
toolsGenerated: [...this.currentContext.generatedTools],
|
|
201
|
-
adaptationsMade: [...this.currentContext.adaptations],
|
|
202
|
-
finalConfig: { ...this.currentContext.currentConfig },
|
|
203
|
-
};
|
|
204
|
-
|
|
205
|
-
void this.emitter.emit({
|
|
206
|
-
type: 'run_completed',
|
|
207
|
-
runId,
|
|
208
|
-
timestamp: new Date(),
|
|
209
|
-
data: {
|
|
210
|
-
success: true,
|
|
211
|
-
toolsGenerated: result.toolsGenerated.length,
|
|
212
|
-
adaptationsMade: result.adaptationsMade.length,
|
|
213
|
-
},
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
return result;
|
|
217
|
-
} catch (error) {
|
|
218
|
-
void this.emitter.emit({
|
|
219
|
-
type: 'run_completed',
|
|
220
|
-
runId,
|
|
221
|
-
timestamp: new Date(),
|
|
222
|
-
data: {
|
|
223
|
-
success: false,
|
|
224
|
-
error: error instanceof Error ? error.message : String(error),
|
|
225
|
-
},
|
|
226
|
-
});
|
|
227
|
-
|
|
228
|
-
throw error;
|
|
229
|
-
} finally {
|
|
230
|
-
this.metaReasoner.cleanupRun(runId);
|
|
231
|
-
this.currentContext = null;
|
|
232
|
-
}
|
|
262
|
+
const result = this.runQueue.then(() => this.executeRun(input));
|
|
263
|
+
this.runQueue = result.catch(() => undefined);
|
|
264
|
+
return result;
|
|
233
265
|
}
|
|
234
266
|
|
|
235
267
|
async generateTool(gap: CapabilityGap): Promise<GeneratedTool | null> {
|
|
@@ -237,40 +269,7 @@ export class SelfModifyingAgent {
|
|
|
237
269
|
return null;
|
|
238
270
|
}
|
|
239
271
|
|
|
240
|
-
|
|
241
|
-
const result = await this.toolGenerator.generate(gap, tools);
|
|
242
|
-
|
|
243
|
-
if (result.success && result.tool) {
|
|
244
|
-
await this.toolStore.save(result.tool);
|
|
245
|
-
|
|
246
|
-
void this.emitter.emit({
|
|
247
|
-
type: 'tool_generation_completed',
|
|
248
|
-
runId: this.currentContext?.runId || 'manual',
|
|
249
|
-
timestamp: new Date(),
|
|
250
|
-
data: {
|
|
251
|
-
toolId: result.tool.id,
|
|
252
|
-
name: result.tool.name,
|
|
253
|
-
success: true,
|
|
254
|
-
iterations: result.iterations,
|
|
255
|
-
},
|
|
256
|
-
});
|
|
257
|
-
|
|
258
|
-
return result.tool;
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
void this.emitter.emit({
|
|
262
|
-
type: 'tool_generation_completed',
|
|
263
|
-
runId: this.currentContext?.runId || 'manual',
|
|
264
|
-
timestamp: new Date(),
|
|
265
|
-
data: {
|
|
266
|
-
toolId: '',
|
|
267
|
-
name: gap.suggestedToolName,
|
|
268
|
-
success: false,
|
|
269
|
-
error: result.error,
|
|
270
|
-
},
|
|
271
|
-
});
|
|
272
|
-
|
|
273
|
-
return null;
|
|
272
|
+
return this.generateAndRegisterTool(gap, this.currentContext?.tools ?? this.getAgentTools());
|
|
274
273
|
}
|
|
275
274
|
|
|
276
275
|
async recordToolUsage(toolId: string, success: boolean, executionTime: number): Promise<void> {
|
|
@@ -287,65 +286,176 @@ export class SelfModifyingAgent {
|
|
|
287
286
|
}
|
|
288
287
|
|
|
289
288
|
async createCheckpoint(): Promise<ModificationCheckpoint | null> {
|
|
290
|
-
|
|
289
|
+
const ctx = this.currentContext;
|
|
290
|
+
if (!ctx) return null;
|
|
291
291
|
|
|
292
292
|
const agentConfig: AgentConfig = {
|
|
293
293
|
name: this.agent.name || 'agent',
|
|
294
|
-
model:
|
|
294
|
+
model: ctx.currentConfig.model,
|
|
295
295
|
instructions: this.agent.instructions || '',
|
|
296
|
-
temperature:
|
|
297
|
-
maxTokens:
|
|
296
|
+
temperature: ctx.currentConfig.temperature,
|
|
297
|
+
maxTokens: ctx.currentConfig.maxTokens,
|
|
298
298
|
};
|
|
299
299
|
|
|
300
300
|
const checkpoint = await this.rollbackManager.createCheckpoint(
|
|
301
301
|
this.agent.name || 'agent',
|
|
302
302
|
agentConfig,
|
|
303
|
-
|
|
304
|
-
[]
|
|
303
|
+
ctx.tools,
|
|
304
|
+
[...ctx.appliedModifications]
|
|
305
305
|
);
|
|
306
306
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
void this.emitter.emit({
|
|
310
|
-
type: 'checkpoint_created',
|
|
311
|
-
runId: this.currentContext.runId,
|
|
312
|
-
timestamp: new Date(),
|
|
313
|
-
data: { checkpointId: checkpoint.id },
|
|
314
|
-
});
|
|
307
|
+
ctx.checkpoints.push(checkpoint);
|
|
308
|
+
this.emit('checkpoint_created', ctx.runId, { checkpointId: checkpoint.id });
|
|
315
309
|
|
|
316
310
|
return checkpoint;
|
|
317
311
|
}
|
|
318
312
|
|
|
319
|
-
async rollbackToCheckpoint(checkpointId: string): Promise<boolean> {
|
|
313
|
+
async rollbackToCheckpoint(checkpointId: string, reason = 'Manual rollback'): Promise<boolean> {
|
|
314
|
+
const checkpoint = await this.rollbackManager.getCheckpoint(checkpointId);
|
|
320
315
|
const restored = await this.rollbackManager.rollbackTo(checkpointId);
|
|
321
|
-
if (!restored) return false;
|
|
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];
|
|
322
328
|
|
|
323
|
-
|
|
324
|
-
|
|
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));
|
|
325
335
|
}
|
|
326
336
|
|
|
327
|
-
|
|
328
|
-
type: 'rollback_performed',
|
|
329
|
-
runId: this.currentContext?.runId || 'manual',
|
|
330
|
-
timestamp: new Date(),
|
|
331
|
-
data: {
|
|
332
|
-
checkpointId,
|
|
333
|
-
reason: 'Manual rollback',
|
|
334
|
-
},
|
|
335
|
-
});
|
|
337
|
+
this.emit('rollback_performed', ctx?.runId ?? 'manual', { checkpointId, reason });
|
|
336
338
|
|
|
337
339
|
return true;
|
|
338
340
|
}
|
|
339
341
|
|
|
340
|
-
private async
|
|
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 = {
|
|
353
|
+
runId,
|
|
354
|
+
input,
|
|
355
|
+
startTime: Date.now(),
|
|
356
|
+
tools,
|
|
357
|
+
currentConfig: this.createBaseArchitectureConfig(),
|
|
358
|
+
generatedTools: [],
|
|
359
|
+
observations: [],
|
|
360
|
+
adaptations: [],
|
|
361
|
+
checkpoints: [],
|
|
362
|
+
modificationsCount: 0,
|
|
363
|
+
appliedModifications: [],
|
|
364
|
+
tokensUsed: 0,
|
|
365
|
+
};
|
|
366
|
+
this.currentContext = ctx;
|
|
367
|
+
|
|
368
|
+
this.emit('run_started', runId, { input });
|
|
342
369
|
|
|
343
|
-
|
|
370
|
+
let optimization: { result: OptimizationResult; candidateId: string } | null = null;
|
|
371
|
+
|
|
372
|
+
try {
|
|
373
|
+
if (
|
|
374
|
+
selfModification &&
|
|
375
|
+
this.config.constraints.enabled &&
|
|
376
|
+
this.config.constraints.autoRollback
|
|
377
|
+
) {
|
|
378
|
+
await this.createCheckpoint();
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
if (selfModification && this.config.architectureEvolution.enabled) {
|
|
382
|
+
optimization = await this.optimizeArchitecture(ctx);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
if (
|
|
386
|
+
selfModification &&
|
|
387
|
+
this.config.toolGeneration.enabled &&
|
|
388
|
+
this.config.toolGeneration.autoGenerate
|
|
389
|
+
) {
|
|
390
|
+
await this.analyzeAndGenerateTools(ctx);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
const execution = await this.executeWithMetaReasoning(ctx, selfModification);
|
|
394
|
+
|
|
395
|
+
await this.recordArchitectureOutcome(ctx, optimization, true, execution.confidence);
|
|
396
|
+
|
|
397
|
+
const result = {
|
|
398
|
+
output: execution.output,
|
|
399
|
+
toolsGenerated: [...ctx.generatedTools],
|
|
400
|
+
adaptationsMade: [...ctx.adaptations],
|
|
401
|
+
finalConfig: { ...ctx.currentConfig },
|
|
402
|
+
};
|
|
403
|
+
|
|
404
|
+
this.emit('run_completed', runId, {
|
|
405
|
+
success: true,
|
|
406
|
+
toolsGenerated: result.toolsGenerated.length,
|
|
407
|
+
adaptationsMade: result.adaptationsMade.length,
|
|
408
|
+
});
|
|
409
|
+
|
|
410
|
+
return result;
|
|
411
|
+
} catch (error) {
|
|
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');
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
this.emit('run_completed', runId, {
|
|
423
|
+
success: false,
|
|
424
|
+
error: error instanceof Error ? error.message : String(error),
|
|
425
|
+
});
|
|
426
|
+
|
|
427
|
+
throw error;
|
|
428
|
+
} finally {
|
|
429
|
+
this.metaReasoner.cleanupRun(runId);
|
|
430
|
+
this.currentContext = null;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
private emit<K extends SelfModifyingEventType>(
|
|
435
|
+
type: K,
|
|
436
|
+
runId: string,
|
|
437
|
+
data: SelfModifyingEventDataMap[K]
|
|
438
|
+
): void {
|
|
439
|
+
void this.emitter.emit({
|
|
440
|
+
type,
|
|
441
|
+
runId,
|
|
442
|
+
agentId: this.agent.id,
|
|
443
|
+
timestamp: new Date(),
|
|
444
|
+
data,
|
|
445
|
+
});
|
|
446
|
+
}
|
|
344
447
|
|
|
345
|
-
|
|
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,
|
|
455
|
+
};
|
|
346
456
|
}
|
|
347
457
|
|
|
348
|
-
private mergeConfig(partial?:
|
|
458
|
+
private mergeConfig(partial?: SelfModifyingAgentConfig): SelfModifyingConfig {
|
|
349
459
|
const defaults: SelfModifyingConfig = {
|
|
350
460
|
enabled: true,
|
|
351
461
|
toolGeneration: {
|
|
@@ -363,40 +473,7 @@ export class SelfModifyingAgent {
|
|
|
363
473
|
isolationLevel: 'strict',
|
|
364
474
|
},
|
|
365
475
|
},
|
|
366
|
-
metaReasoning: {
|
|
367
|
-
enabled: true,
|
|
368
|
-
defaultMode: 'analytical',
|
|
369
|
-
allowedModes: [
|
|
370
|
-
'analytical',
|
|
371
|
-
'creative',
|
|
372
|
-
'systematic',
|
|
373
|
-
'intuitive',
|
|
374
|
-
'reflective',
|
|
375
|
-
'exploratory',
|
|
376
|
-
],
|
|
377
|
-
modeProfiles: {
|
|
378
|
-
analytical: { mode: 'analytical', temperature: 0.3, depth: 3 },
|
|
379
|
-
creative: { mode: 'creative', temperature: 0.9, depth: 2 },
|
|
380
|
-
systematic: { mode: 'systematic', temperature: 0.2, depth: 4 },
|
|
381
|
-
intuitive: { mode: 'intuitive', temperature: 0.6, depth: 1 },
|
|
382
|
-
reflective: { mode: 'reflective', temperature: 0.4, depth: 3 },
|
|
383
|
-
exploratory: { mode: 'exploratory', temperature: 0.7, depth: 2 },
|
|
384
|
-
},
|
|
385
|
-
maxMetaAssessments: 5,
|
|
386
|
-
maxAdaptations: 3,
|
|
387
|
-
metaAssessmentCooldown: 10000,
|
|
388
|
-
adaptationCooldown: 15000,
|
|
389
|
-
triggers: ['on_failure', 'on_low_confidence', 'periodic'],
|
|
390
|
-
triggerAfterIterations: 3,
|
|
391
|
-
triggerOnConfidenceDrop: 0.3,
|
|
392
|
-
triggerOnProgressStall: 2,
|
|
393
|
-
tokenBudget: 2000,
|
|
394
|
-
maxMetaTokens: 1000,
|
|
395
|
-
minConfidenceToAdapt: 0.6,
|
|
396
|
-
enableRollback: true,
|
|
397
|
-
rollbackWindow: 30000,
|
|
398
|
-
rollbackOnDecline: true,
|
|
399
|
-
},
|
|
476
|
+
metaReasoning: { ...DEFAULT_META_REASONING_CONFIG },
|
|
400
477
|
architectureEvolution: {
|
|
401
478
|
enabled: true,
|
|
402
479
|
strategy: { type: 'ucb', explorationConstant: 2 },
|
|
@@ -415,14 +492,20 @@ export class SelfModifyingAgent {
|
|
|
415
492
|
|
|
416
493
|
if (!partial) return defaults;
|
|
417
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
|
+
|
|
418
503
|
return {
|
|
419
504
|
enabled: partial.enabled ?? defaults.enabled,
|
|
420
505
|
toolGeneration: {
|
|
421
506
|
...defaults.toolGeneration,
|
|
422
507
|
...partial.toolGeneration,
|
|
423
|
-
sandboxConfig: partial.toolGeneration?.sandboxConfig
|
|
424
|
-
? { ...defaults.toolGeneration.sandboxConfig, ...partial.toolGeneration.sandboxConfig }
|
|
425
|
-
: defaults.toolGeneration.sandboxConfig,
|
|
508
|
+
sandboxConfig: { ...defaultSandbox, ...partial.toolGeneration?.sandboxConfig },
|
|
426
509
|
},
|
|
427
510
|
metaReasoning: {
|
|
428
511
|
...defaults.metaReasoning,
|
|
@@ -435,272 +518,573 @@ export class SelfModifyingAgent {
|
|
|
435
518
|
architectureEvolution: {
|
|
436
519
|
...defaults.architectureEvolution,
|
|
437
520
|
...partial.architectureEvolution,
|
|
438
|
-
strategy:
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
}
|
|
443
|
-
: defaults.architectureEvolution.strategy,
|
|
521
|
+
strategy: {
|
|
522
|
+
...defaults.architectureEvolution.strategy,
|
|
523
|
+
...partial.architectureEvolution?.strategy,
|
|
524
|
+
},
|
|
444
525
|
},
|
|
445
526
|
constraints: { ...defaults.constraints, ...partial.constraints },
|
|
446
527
|
};
|
|
447
528
|
}
|
|
448
529
|
|
|
449
|
-
private
|
|
450
|
-
return this.agent.tools ?? [];
|
|
530
|
+
private getAgentTools(): Tool[] {
|
|
531
|
+
return [...(this.agent.tools ?? [])];
|
|
451
532
|
}
|
|
452
533
|
|
|
453
|
-
private async
|
|
454
|
-
|
|
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
|
+
}
|
|
455
547
|
|
|
548
|
+
private async optimizeArchitecture(
|
|
549
|
+
ctx: RunContext
|
|
550
|
+
): Promise<{ result: OptimizationResult; candidateId: string } | null> {
|
|
456
551
|
try {
|
|
457
|
-
const result = await this.parameterOptimizer.optimize(input);
|
|
458
|
-
|
|
459
|
-
if (
|
|
460
|
-
const validation = await this.modificationValidator.validate({
|
|
461
|
-
type: 'config_change',
|
|
462
|
-
target: 'architecture',
|
|
463
|
-
changes: result.recommendedConfig,
|
|
464
|
-
reason: result.reasoning,
|
|
465
|
-
});
|
|
552
|
+
const result = await this.parameterOptimizer.optimize(ctx.input);
|
|
553
|
+
const candidate = result.candidate;
|
|
554
|
+
if (!candidate) return null;
|
|
466
555
|
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
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' };
|
|
481
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 };
|
|
482
591
|
} catch (error) {
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
timestamp: new Date(),
|
|
487
|
-
data: { error: error instanceof Error ? error.message : String(error) },
|
|
592
|
+
this.emit('architecture_evolved', ctx.runId, {
|
|
593
|
+
success: false,
|
|
594
|
+
error: error instanceof Error ? error.message : String(error),
|
|
488
595
|
});
|
|
596
|
+
return null;
|
|
489
597
|
}
|
|
490
598
|
}
|
|
491
599
|
|
|
492
|
-
private async
|
|
493
|
-
|
|
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
|
+
}
|
|
494
619
|
|
|
620
|
+
private async analyzeAndGenerateTools(ctx: RunContext): Promise<void> {
|
|
495
621
|
try {
|
|
496
|
-
const analysis = await this.gapAnalyzer.analyze(input,
|
|
622
|
+
const analysis = await this.gapAnalyzer.analyze(ctx.input, ctx.tools);
|
|
497
623
|
|
|
498
624
|
for (const gap of analysis.gaps) {
|
|
499
|
-
if (
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
if (tool) {
|
|
510
|
-
this.currentContext.generatedTools.push(tool);
|
|
511
|
-
const executableTool = this.toolGenerator.createExecutableTool(tool);
|
|
512
|
-
this.currentContext.tools.push(executableTool);
|
|
513
|
-
}
|
|
514
|
-
}
|
|
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;
|
|
628
|
+
|
|
629
|
+
const tool = await this.generateAndRegisterTool(gap, ctx.tools);
|
|
630
|
+
if (!tool) continue;
|
|
631
|
+
|
|
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 });
|
|
515
635
|
}
|
|
516
636
|
} catch (error) {
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
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,
|
|
527
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`;
|
|
528
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';
|
|
529
718
|
}
|
|
530
719
|
|
|
531
|
-
private async executeWithMetaReasoning(
|
|
532
|
-
|
|
533
|
-
|
|
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
|
+
});
|
|
534
738
|
}
|
|
535
739
|
|
|
536
|
-
let
|
|
537
|
-
let
|
|
538
|
-
|
|
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;
|
|
753
|
+
|
|
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
|
+
}
|
|
539
764
|
|
|
540
|
-
|
|
541
|
-
iteration++;
|
|
765
|
+
if (step.complete || attempt === maxAttempts) break;
|
|
542
766
|
|
|
543
|
-
const currentMode = this.metaReasoner.getCurrentMode(runId);
|
|
544
767
|
const observation = this.metaReasoner.observe(
|
|
545
768
|
{
|
|
546
769
|
runId,
|
|
547
|
-
iteration,
|
|
548
|
-
goal: input,
|
|
549
|
-
currentMode,
|
|
550
|
-
tokensUsed:
|
|
551
|
-
timeElapsed: Date.now() -
|
|
552
|
-
iterationsRemaining:
|
|
553
|
-
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,
|
|
554
777
|
},
|
|
555
778
|
[]
|
|
556
779
|
);
|
|
780
|
+
ctx.observations.push(observation);
|
|
557
781
|
|
|
558
|
-
this.
|
|
782
|
+
if (!this.selectTrigger(runId, attempt, confidence, observation)) continue;
|
|
559
783
|
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
iteration,
|
|
563
|
-
confidence: this.estimateConfidence(output),
|
|
564
|
-
progressDelta: output.length > 0 ? 0.1 : 0,
|
|
565
|
-
stagnationCount: 0,
|
|
566
|
-
})
|
|
567
|
-
) {
|
|
568
|
-
const assessment = await this.metaReasoner.assess(observation);
|
|
784
|
+
const assessment = await this.metaReasoner.assess(observation);
|
|
785
|
+
this.emit('meta_assessment', runId, { observation, assessment });
|
|
569
786
|
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
runId,
|
|
573
|
-
timestamp: new Date(),
|
|
574
|
-
data: {
|
|
575
|
-
observation,
|
|
576
|
-
assessment,
|
|
577
|
-
},
|
|
578
|
-
});
|
|
787
|
+
if (!assessment.requiresAdaptation) continue;
|
|
788
|
+
if (assessment.recommendation.action === 'abort') break;
|
|
579
789
|
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
if (adaptation) {
|
|
584
|
-
this.currentContext.adaptations.push(adaptation);
|
|
585
|
-
|
|
586
|
-
void this.emitter.emit({
|
|
587
|
-
type: 'strategy_changed',
|
|
588
|
-
runId,
|
|
589
|
-
timestamp: new Date(),
|
|
590
|
-
data: {
|
|
591
|
-
previousMode: adaptation.before?.mode || 'analytical',
|
|
592
|
-
newMode: adaptation.after?.mode || 'analytical',
|
|
593
|
-
reason: adaptation.type,
|
|
594
|
-
},
|
|
595
|
-
});
|
|
596
|
-
}
|
|
597
|
-
}
|
|
598
|
-
}
|
|
790
|
+
const adaptation = await this.metaReasoner.adapt(runId, assessment);
|
|
791
|
+
if (!adaptation) continue;
|
|
599
792
|
|
|
600
|
-
|
|
793
|
+
ctx.adaptations.push(adaptation);
|
|
794
|
+
pendingAdaptation = { adaptation, confidence };
|
|
601
795
|
|
|
602
|
-
if (
|
|
603
|
-
|
|
796
|
+
if (adaptation.type === 'context_injection' && assessment.recommendation.contextAddition) {
|
|
797
|
+
contextAdditions.push(assessment.recommendation.contextAddition);
|
|
798
|
+
} else {
|
|
799
|
+
modeAdapted = true;
|
|
604
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
|
+
});
|
|
605
807
|
}
|
|
606
808
|
|
|
607
|
-
return output;
|
|
809
|
+
return { output: step?.content ?? '', confidence };
|
|
810
|
+
}
|
|
811
|
+
|
|
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;
|
|
608
832
|
}
|
|
609
833
|
|
|
610
|
-
private async executeAgentStep(
|
|
611
|
-
const
|
|
612
|
-
const toolSchemas = this.buildToolSchemas(tools);
|
|
613
|
-
const
|
|
614
|
-
for (const
|
|
615
|
-
|
|
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);
|
|
616
840
|
}
|
|
617
841
|
|
|
618
|
-
const model =
|
|
842
|
+
const model = ctx.currentConfig.model;
|
|
843
|
+
const maxTokens = ctx.currentConfig.maxTokens;
|
|
619
844
|
const messages: Message[] = [
|
|
620
845
|
...(this.agent.instructions
|
|
621
846
|
? [{ role: 'system' as const, content: this.agent.instructions }]
|
|
622
847
|
: []),
|
|
623
|
-
{ role: '
|
|
848
|
+
...options.contextAdditions.map((content) => ({ role: 'system' as const, content })),
|
|
849
|
+
{ role: 'user' as const, content: ctx.input },
|
|
624
850
|
];
|
|
625
851
|
|
|
626
|
-
|
|
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;
|
|
627
858
|
for (let round = 0; round < maxToolRounds; round++) {
|
|
628
|
-
|
|
859
|
+
response = await this.llm.chat({
|
|
629
860
|
model,
|
|
630
861
|
messages,
|
|
631
862
|
tools: toolSchemas.length > 0 ? toolSchemas : undefined,
|
|
632
|
-
temperature:
|
|
633
|
-
maxTokens
|
|
863
|
+
temperature: options.temperature,
|
|
864
|
+
maxTokens,
|
|
634
865
|
});
|
|
866
|
+
tokensUsed += response.usage?.totalTokens ?? 0;
|
|
635
867
|
|
|
636
868
|
if (response.finishReason !== 'tool_calls' || !response.toolCalls?.length) {
|
|
637
|
-
|
|
869
|
+
break;
|
|
638
870
|
}
|
|
639
871
|
|
|
640
|
-
|
|
872
|
+
const assistantMessage: ToolCallMessage = {
|
|
641
873
|
role: 'assistant',
|
|
642
874
|
content: response.content,
|
|
643
875
|
toolCalls: response.toolCalls,
|
|
644
|
-
}
|
|
645
|
-
|
|
646
|
-
for (const toolCall of response.toolCalls) {
|
|
647
|
-
const t = toolMap.get(toolCall.name);
|
|
648
|
-
let result: unknown;
|
|
649
|
-
|
|
650
|
-
if (!t) {
|
|
651
|
-
result = { error: `Tool "${toolCall.name}" not found` };
|
|
652
|
-
} else {
|
|
653
|
-
try {
|
|
654
|
-
const ctx: ToolContext = {
|
|
655
|
-
agentId: this.agent.name || 'self-modifying',
|
|
656
|
-
runId: this.currentContext?.runId || 'unknown',
|
|
657
|
-
signal: AbortSignal.timeout(30_000),
|
|
658
|
-
};
|
|
659
|
-
result = await t.execute(toolCall.arguments, ctx);
|
|
660
|
-
} catch (err) {
|
|
661
|
-
result = { error: err instanceof Error ? err.message : String(err) };
|
|
662
|
-
}
|
|
663
|
-
}
|
|
876
|
+
};
|
|
877
|
+
messages.push(assistantMessage);
|
|
664
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++;
|
|
665
883
|
messages.push({
|
|
666
|
-
role: 'tool'
|
|
667
|
-
content:
|
|
668
|
-
toolCallId:
|
|
669
|
-
name:
|
|
884
|
+
role: 'tool',
|
|
885
|
+
content: outcome.content,
|
|
886
|
+
toolCallId: outcome.call.id,
|
|
887
|
+
name: outcome.call.name,
|
|
670
888
|
});
|
|
671
889
|
}
|
|
890
|
+
response = null;
|
|
672
891
|
}
|
|
673
892
|
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
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
|
+
};
|
|
681
935
|
}
|
|
682
936
|
|
|
683
|
-
private
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
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
|
+
}
|
|
687
991
|
}
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
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
|
+
};
|
|
694
1027
|
}
|
|
695
1028
|
|
|
696
|
-
private
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
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
|
+
);
|
|
701
1039
|
}
|
|
702
1040
|
|
|
703
|
-
private
|
|
704
|
-
return
|
|
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;
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
private async validateModification(
|
|
1050
|
+
ctx: RunContext | null,
|
|
1051
|
+
request: ModificationRequest
|
|
1052
|
+
): Promise<boolean> {
|
|
1053
|
+
if (!this.config.constraints.enabled) return true;
|
|
1054
|
+
|
|
1055
|
+
const validation = await this.modificationValidator.validate(request);
|
|
1056
|
+
|
|
1057
|
+
if (validation.rollbackRequired && this.config.constraints.autoRollback && ctx) {
|
|
1058
|
+
await this.autoRollback(ctx, `Critical constraint violation: ${request.type}`);
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
return validation.valid;
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
private canApplyModification(ctx: RunContext): boolean {
|
|
1065
|
+
if (!this.config.constraints.enabled) return true;
|
|
1066
|
+
return ctx.modificationsCount < this.config.constraints.maxModificationsPerRun;
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
private recordModification(ctx: RunContext, type: string, data: unknown): void {
|
|
1070
|
+
ctx.modificationsCount++;
|
|
1071
|
+
ctx.appliedModifications.push({
|
|
1072
|
+
id: `mod_${nanoid(8)}`,
|
|
1073
|
+
type,
|
|
1074
|
+
appliedAt: new Date(),
|
|
1075
|
+
data,
|
|
1076
|
+
});
|
|
1077
|
+
}
|
|
1078
|
+
|
|
1079
|
+
private async autoRollback(ctx: RunContext, reason: string): Promise<void> {
|
|
1080
|
+
const now = Date.now();
|
|
1081
|
+
const window = this.config.constraints.rollbackWindow;
|
|
1082
|
+
const target = ctx.checkpoints
|
|
1083
|
+
.filter((c) => now - c.timestamp.getTime() <= window)
|
|
1084
|
+
.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime())[0];
|
|
1085
|
+
|
|
1086
|
+
if (target) {
|
|
1087
|
+
await this.rollbackToCheckpoint(target.id, reason);
|
|
1088
|
+
}
|
|
705
1089
|
}
|
|
706
1090
|
}
|