@cogitator-ai/self-modifying 17.0.18 → 19.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +114 -50
- 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 +11 -18
- 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
|
@@ -74,6 +74,9 @@ export class ModificationValidator {
|
|
|
74
74
|
const results: ConstraintCheckResult[] = [];
|
|
75
75
|
|
|
76
76
|
for (const constraint of this.constraints.safety) {
|
|
77
|
+
if (constraint.appliesTo && !constraint.appliesTo.includes(request.type)) {
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
77
80
|
const satisfied = this.evaluateSafetyRule(constraint.rule, request);
|
|
78
81
|
results.push({
|
|
79
82
|
constraintId: constraint.id,
|
|
@@ -88,11 +91,12 @@ export class ModificationValidator {
|
|
|
88
91
|
}
|
|
89
92
|
|
|
90
93
|
private evaluateSafetyRule(rule: ConstraintRule, request: ModificationRequest): boolean {
|
|
94
|
+
const context = this.payloadOf(request);
|
|
95
|
+
|
|
91
96
|
if (typeof rule === 'string') {
|
|
92
|
-
return this.evaluateExpression(rule,
|
|
97
|
+
return this.evaluateExpression(rule, context);
|
|
93
98
|
}
|
|
94
99
|
|
|
95
|
-
const context = request.payload as Record<string, unknown>;
|
|
96
100
|
const checks: boolean[] = [];
|
|
97
101
|
|
|
98
102
|
if (rule.expression) {
|
|
@@ -170,10 +174,20 @@ export class ModificationValidator {
|
|
|
170
174
|
return Boolean(value);
|
|
171
175
|
}
|
|
172
176
|
|
|
177
|
+
private payloadOf(request: ModificationRequest): Record<string, unknown> {
|
|
178
|
+
const payload = request.payload;
|
|
179
|
+
return payload && typeof payload === 'object' && !Array.isArray(payload)
|
|
180
|
+
? (payload as Record<string, unknown>)
|
|
181
|
+
: {};
|
|
182
|
+
}
|
|
183
|
+
|
|
173
184
|
private resolveValue(expr: string, context: Record<string, unknown>): unknown {
|
|
174
185
|
if (expr === 'true') return true;
|
|
175
186
|
if (expr === 'false') return false;
|
|
176
|
-
if (
|
|
187
|
+
if (expr === 'null') return null;
|
|
188
|
+
if (/^-?\d+(\.\d+)?$/.test(expr)) return parseFloat(expr);
|
|
189
|
+
const quoted = /^(['"])(.*)\1$/.exec(expr);
|
|
190
|
+
if (quoted) return quoted[2];
|
|
177
191
|
|
|
178
192
|
const keys = expr.split('.');
|
|
179
193
|
let current: unknown = context;
|
|
@@ -196,30 +210,32 @@ export class ModificationValidator {
|
|
|
196
210
|
return results;
|
|
197
211
|
}
|
|
198
212
|
|
|
199
|
-
const payload = request
|
|
213
|
+
const payload = this.payloadOf(request) as { category?: unknown; complexity?: unknown };
|
|
214
|
+
const category = typeof payload.category === 'string' ? payload.category : undefined;
|
|
215
|
+
const complexity = typeof payload.complexity === 'number' ? payload.complexity : undefined;
|
|
200
216
|
|
|
201
217
|
for (const constraint of this.constraints.capability) {
|
|
202
218
|
let satisfied = true;
|
|
203
219
|
let message: string | undefined;
|
|
204
220
|
|
|
205
|
-
if (
|
|
206
|
-
if (constraint.forbidden?.includes(
|
|
221
|
+
if (category) {
|
|
222
|
+
if (constraint.forbidden?.includes(category)) {
|
|
207
223
|
satisfied = false;
|
|
208
|
-
message = `Category '${
|
|
209
|
-
} else if (constraint.allowed?.length && !constraint.allowed.includes(
|
|
224
|
+
message = `Category '${category}' is forbidden`;
|
|
225
|
+
} else if (constraint.allowed?.length && !constraint.allowed.includes(category)) {
|
|
210
226
|
satisfied = false;
|
|
211
|
-
message = `Category '${
|
|
227
|
+
message = `Category '${category}' is not in allowed list`;
|
|
212
228
|
}
|
|
213
229
|
}
|
|
214
230
|
|
|
215
231
|
if (
|
|
216
232
|
satisfied &&
|
|
217
|
-
constraint.maxComplexity &&
|
|
218
|
-
|
|
219
|
-
|
|
233
|
+
constraint.maxComplexity !== undefined &&
|
|
234
|
+
complexity !== undefined &&
|
|
235
|
+
complexity > constraint.maxComplexity
|
|
220
236
|
) {
|
|
221
237
|
satisfied = false;
|
|
222
|
-
message = `Complexity ${
|
|
238
|
+
message = `Complexity ${complexity} exceeds max ${constraint.maxComplexity}`;
|
|
223
239
|
}
|
|
224
240
|
|
|
225
241
|
results.push({
|
|
@@ -238,7 +254,7 @@ export class ModificationValidator {
|
|
|
238
254
|
request: ModificationRequest
|
|
239
255
|
): Promise<ConstraintCheckResult[]> {
|
|
240
256
|
const results: ConstraintCheckResult[] = [];
|
|
241
|
-
const payload = (request
|
|
257
|
+
const payload = this.payloadOf(request) as {
|
|
242
258
|
tokensUsed?: number;
|
|
243
259
|
cost?: number;
|
|
244
260
|
activeTools?: number;
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
export {
|
|
2
2
|
SelfModifyingAgent,
|
|
3
3
|
type SelfModifyingAgentOptions,
|
|
4
|
+
type SelfModifyingAgentConfig,
|
|
5
|
+
type SelfModifyingEventDataMap,
|
|
6
|
+
type TypedSelfModifyingEvent,
|
|
4
7
|
type RunContext,
|
|
5
8
|
} from './self-modifying-agent';
|
|
6
9
|
|
|
@@ -15,11 +18,16 @@ export {
|
|
|
15
18
|
buildGapAnalysisPrompt,
|
|
16
19
|
buildToolGenerationPrompt,
|
|
17
20
|
buildToolValidationPrompt,
|
|
21
|
+
buildToolImprovementPrompt,
|
|
18
22
|
parseGapAnalysisResponse,
|
|
19
23
|
parseToolGenerationResponse,
|
|
24
|
+
parseValidationResponse,
|
|
20
25
|
type GapAnalyzerOptions,
|
|
21
26
|
type ToolGeneratorOptions,
|
|
22
27
|
type ToolValidatorOptions,
|
|
28
|
+
type ValidationRule,
|
|
29
|
+
type SandboxTestCase,
|
|
30
|
+
type GenerateOptions,
|
|
23
31
|
type GenerationResult,
|
|
24
32
|
type ToolUsageRecord,
|
|
25
33
|
type ToolMetrics,
|
|
@@ -48,13 +56,17 @@ export {
|
|
|
48
56
|
ARCHITECTURE_ANALYSIS_SYSTEM_PROMPT,
|
|
49
57
|
buildTaskProfilePrompt,
|
|
50
58
|
buildCandidateGenerationPrompt,
|
|
59
|
+
buildPerformanceAnalysisPrompt,
|
|
51
60
|
parseTaskProfileResponse,
|
|
52
61
|
parseCandidateGenerationResponse,
|
|
62
|
+
parsePerformanceAnalysisResponse,
|
|
63
|
+
sanitizeCandidateConfig,
|
|
53
64
|
type CapabilityAnalyzerOptions,
|
|
54
65
|
type EvolutionStrategyOptions,
|
|
55
66
|
type ParameterOptimizerOptions,
|
|
56
67
|
type SelectionResult,
|
|
57
68
|
type OptimizationResult,
|
|
69
|
+
type HistoricalRecord,
|
|
58
70
|
} from './architecture-evolution';
|
|
59
71
|
|
|
60
72
|
export {
|
|
@@ -64,6 +76,8 @@ export {
|
|
|
64
76
|
DEFAULT_SAFETY_CONSTRAINTS,
|
|
65
77
|
DEFAULT_CAPABILITY_CONSTRAINTS,
|
|
66
78
|
DEFAULT_RESOURCE_CONSTRAINTS,
|
|
79
|
+
createDefaultConstraints,
|
|
80
|
+
mergeConstraints,
|
|
67
81
|
mergeSafetyConstraints,
|
|
68
82
|
mergeCapabilityConstraints,
|
|
69
83
|
mergeResourceConstraints,
|
|
@@ -10,8 +10,6 @@ import type {
|
|
|
10
10
|
ReasoningModeConfig,
|
|
11
11
|
Insight,
|
|
12
12
|
LLMBackend,
|
|
13
|
-
MetaIssue,
|
|
14
|
-
MetaOpportunity,
|
|
15
13
|
} from '@cogitator-ai/types';
|
|
16
14
|
import { DEFAULT_META_REASONING_CONFIG } from '@cogitator-ai/types';
|
|
17
15
|
import {
|
|
@@ -28,6 +26,17 @@ import {
|
|
|
28
26
|
|
|
29
27
|
export { DEFAULT_META_REASONING_CONFIG };
|
|
30
28
|
|
|
29
|
+
const TRIGGER_ALIASES: Partial<Record<MetaTrigger, MetaTrigger>> = {
|
|
30
|
+
confidence_drop: 'on_low_confidence',
|
|
31
|
+
progress_stall: 'on_stagnation',
|
|
32
|
+
tool_call_failed: 'on_failure',
|
|
33
|
+
explicit_request: 'on_request',
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
function canonicalTrigger(trigger: MetaTrigger): MetaTrigger {
|
|
37
|
+
return TRIGGER_ALIASES[trigger] ?? trigger;
|
|
38
|
+
}
|
|
39
|
+
|
|
31
40
|
export interface MetaReasonerOptions {
|
|
32
41
|
llm: LLMBackend;
|
|
33
42
|
model: string;
|
|
@@ -44,6 +53,8 @@ export class MetaReasoner {
|
|
|
44
53
|
private assessments = new Map<string, MetaAssessment[]>();
|
|
45
54
|
private adaptations = new Map<string, MetaAdaptation[]>();
|
|
46
55
|
private currentMode = new Map<string, ReasoningMode>();
|
|
56
|
+
private parameterOverrides = new Map<string, Partial<ReasoningModeConfig>>();
|
|
57
|
+
private overridesBefore = new Map<string, Partial<ReasoningModeConfig>>();
|
|
47
58
|
|
|
48
59
|
private lastAssessmentTime = new Map<string, number>();
|
|
49
60
|
private lastAdaptationTime = new Map<string, number>();
|
|
@@ -51,7 +62,14 @@ export class MetaReasoner {
|
|
|
51
62
|
constructor(options: MetaReasonerOptions) {
|
|
52
63
|
this.llm = options.llm;
|
|
53
64
|
this.model = options.model;
|
|
54
|
-
this.config = {
|
|
65
|
+
this.config = {
|
|
66
|
+
...DEFAULT_META_REASONING_CONFIG,
|
|
67
|
+
...options.config,
|
|
68
|
+
modeProfiles: {
|
|
69
|
+
...DEFAULT_META_REASONING_CONFIG.modeProfiles,
|
|
70
|
+
...options.config?.modeProfiles,
|
|
71
|
+
},
|
|
72
|
+
};
|
|
55
73
|
|
|
56
74
|
this.collector = new ObservationCollector();
|
|
57
75
|
this.selector = new StrategySelector({
|
|
@@ -65,10 +83,17 @@ export class MetaReasoner {
|
|
|
65
83
|
this.assessments.set(runId, []);
|
|
66
84
|
this.adaptations.set(runId, []);
|
|
67
85
|
this.currentMode.set(runId, this.config.defaultMode);
|
|
86
|
+
this.parameterOverrides.delete(runId);
|
|
68
87
|
|
|
69
88
|
return this.getModeConfig(this.config.defaultMode);
|
|
70
89
|
}
|
|
71
90
|
|
|
91
|
+
isTriggerEnabled(trigger: MetaTrigger): boolean {
|
|
92
|
+
const canonical = canonicalTrigger(trigger);
|
|
93
|
+
if (canonical === 'on_request') return true;
|
|
94
|
+
return this.config.triggers.some((t) => canonicalTrigger(t) === canonical);
|
|
95
|
+
}
|
|
96
|
+
|
|
72
97
|
recordAction(runId: string, action: ActionRecord): void {
|
|
73
98
|
this.collector.recordAction(runId, action);
|
|
74
99
|
}
|
|
@@ -88,6 +113,7 @@ export class MetaReasoner {
|
|
|
88
113
|
}
|
|
89
114
|
): boolean {
|
|
90
115
|
if (!this.config.enabled) return false;
|
|
116
|
+
if (!this.isTriggerEnabled(trigger)) return false;
|
|
91
117
|
|
|
92
118
|
const lastAssessment = this.lastAssessmentTime.get(runId) ?? 0;
|
|
93
119
|
if (Date.now() - lastAssessment < this.config.metaAssessmentCooldown) {
|
|
@@ -155,6 +181,7 @@ export class MetaReasoner {
|
|
|
155
181
|
});
|
|
156
182
|
|
|
157
183
|
const parsed = parseMetaAssessmentResponse(response.content);
|
|
184
|
+
const recommendation = this.buildRecommendation(parsed, observation);
|
|
158
185
|
|
|
159
186
|
const assessment: MetaAssessment = {
|
|
160
187
|
id: `meta_${nanoid(10)}`,
|
|
@@ -165,18 +192,16 @@ export class MetaReasoner {
|
|
|
165
192
|
confidence: parsed?.confidence ?? 0.5,
|
|
166
193
|
reasoning: parsed?.reasoning ?? 'Assessment unavailable',
|
|
167
194
|
|
|
168
|
-
issues:
|
|
195
|
+
issues: parsed?.issues ?? [],
|
|
169
196
|
opportunities: (parsed?.opportunities ?? []).map((o) => ({
|
|
170
|
-
type: o.type
|
|
171
|
-
confidence: o.expectedImprovement
|
|
197
|
+
type: o.type,
|
|
198
|
+
confidence: o.expectedImprovement,
|
|
172
199
|
description: o.description,
|
|
173
|
-
}))
|
|
200
|
+
})),
|
|
174
201
|
|
|
175
|
-
recommendation
|
|
202
|
+
recommendation,
|
|
176
203
|
|
|
177
|
-
requiresAdaptation:
|
|
178
|
-
parsed?.recommendation?.action !== undefined &&
|
|
179
|
-
parsed?.recommendation?.action !== 'continue',
|
|
204
|
+
requiresAdaptation: recommendation.action !== 'continue',
|
|
180
205
|
|
|
181
206
|
assessmentDuration: Date.now() - startTime,
|
|
182
207
|
assessmentCost: (response.usage?.outputTokens ?? 0) * 0.00001,
|
|
@@ -211,16 +236,7 @@ export class MetaReasoner {
|
|
|
211
236
|
};
|
|
212
237
|
}
|
|
213
238
|
|
|
214
|
-
return {
|
|
215
|
-
action: parsed.recommendation.action as MetaRecommendation['action'],
|
|
216
|
-
newMode: parsed.recommendation.newMode as ReasoningMode | undefined,
|
|
217
|
-
parameterChanges: parsed.recommendation.parameterChanges as
|
|
218
|
-
| Partial<ReasoningModeConfig>
|
|
219
|
-
| undefined,
|
|
220
|
-
contextAddition: parsed.recommendation.contextAddition,
|
|
221
|
-
confidence: parsed.recommendation.confidence,
|
|
222
|
-
reasoning: parsed.recommendation.reasoning,
|
|
223
|
-
};
|
|
239
|
+
return { ...parsed.recommendation };
|
|
224
240
|
}
|
|
225
241
|
|
|
226
242
|
async adapt(runId: string, assessment: MetaAssessment): Promise<MetaAdaptation | null> {
|
|
@@ -239,38 +255,62 @@ export class MetaReasoner {
|
|
|
239
255
|
return null;
|
|
240
256
|
}
|
|
241
257
|
|
|
242
|
-
const adaptationCount = this.adaptations.get(runId)
|
|
258
|
+
const adaptationCount = (this.adaptations.get(runId) ?? []).filter(
|
|
259
|
+
(a) => a.type !== 'rollback'
|
|
260
|
+
).length;
|
|
243
261
|
if (adaptationCount >= this.config.maxAdaptations) {
|
|
244
262
|
return null;
|
|
245
263
|
}
|
|
246
264
|
|
|
247
265
|
const currentMode = this.currentMode.get(runId) ?? this.config.defaultMode;
|
|
248
|
-
const currentConfig = this.
|
|
266
|
+
const currentConfig = this.getCurrentConfig(runId);
|
|
249
267
|
|
|
250
|
-
let newConfig: Partial<ReasoningModeConfig
|
|
251
|
-
let adaptationType: MetaAdaptation['type']
|
|
268
|
+
let newConfig: Partial<ReasoningModeConfig>;
|
|
269
|
+
let adaptationType: MetaAdaptation['type'];
|
|
270
|
+
let newMode = currentMode;
|
|
271
|
+
const previousOverrides = this.parameterOverrides.get(runId);
|
|
252
272
|
|
|
253
273
|
switch (recommendation.action) {
|
|
254
|
-
case 'switch_mode':
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
this.currentMode.set(runId, recommendation.newMode);
|
|
274
|
+
case 'switch_mode': {
|
|
275
|
+
const target = recommendation.newMode;
|
|
276
|
+
if (!target || target === currentMode || !this.config.allowedModes.includes(target)) {
|
|
277
|
+
return null;
|
|
259
278
|
}
|
|
279
|
+
newConfig = this.getModeConfig(target);
|
|
280
|
+
adaptationType = 'mode_switch';
|
|
281
|
+
newMode = target;
|
|
282
|
+
this.currentMode.set(runId, target);
|
|
283
|
+
this.parameterOverrides.delete(runId);
|
|
260
284
|
break;
|
|
285
|
+
}
|
|
261
286
|
|
|
262
|
-
case 'adjust_parameters':
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
287
|
+
case 'adjust_parameters': {
|
|
288
|
+
const changes = recommendation.parameterChanges;
|
|
289
|
+
if (!changes) return null;
|
|
290
|
+
const effective: Partial<ReasoningModeConfig> = {};
|
|
291
|
+
if (
|
|
292
|
+
changes.temperature !== undefined &&
|
|
293
|
+
changes.temperature !== currentConfig.temperature
|
|
294
|
+
) {
|
|
295
|
+
effective.temperature = changes.temperature;
|
|
296
|
+
}
|
|
297
|
+
if (changes.depth !== undefined && changes.depth !== currentConfig.depth) {
|
|
298
|
+
effective.depth = changes.depth;
|
|
266
299
|
}
|
|
300
|
+
if (Object.keys(effective).length === 0) return null;
|
|
301
|
+
newConfig = { ...currentConfig, ...effective };
|
|
302
|
+
adaptationType = 'parameter_change';
|
|
303
|
+
this.parameterOverrides.set(runId, { ...previousOverrides, ...effective });
|
|
267
304
|
break;
|
|
305
|
+
}
|
|
268
306
|
|
|
269
307
|
case 'inject_context':
|
|
308
|
+
if (!recommendation.contextAddition) return null;
|
|
309
|
+
newConfig = { ...currentConfig };
|
|
270
310
|
adaptationType = 'context_injection';
|
|
271
311
|
break;
|
|
272
312
|
|
|
273
|
-
|
|
313
|
+
default:
|
|
274
314
|
return null;
|
|
275
315
|
}
|
|
276
316
|
|
|
@@ -282,6 +322,9 @@ export class MetaReasoner {
|
|
|
282
322
|
type: adaptationType,
|
|
283
323
|
before: currentConfig,
|
|
284
324
|
after: newConfig,
|
|
325
|
+
previousMode: currentMode,
|
|
326
|
+
newMode,
|
|
327
|
+
reason: recommendation.reasoning || undefined,
|
|
285
328
|
|
|
286
329
|
rollbackable: this.config.enableRollback,
|
|
287
330
|
rollbackDeadline: this.config.enableRollback
|
|
@@ -289,6 +332,10 @@ export class MetaReasoner {
|
|
|
289
332
|
: undefined,
|
|
290
333
|
};
|
|
291
334
|
|
|
335
|
+
if (previousOverrides) {
|
|
336
|
+
this.overridesBefore.set(adaptation.id, previousOverrides);
|
|
337
|
+
}
|
|
338
|
+
|
|
292
339
|
const runAdaptations = this.adaptations.get(runId) ?? [];
|
|
293
340
|
runAdaptations.push(adaptation);
|
|
294
341
|
this.adaptations.set(runId, runAdaptations);
|
|
@@ -301,7 +348,7 @@ export class MetaReasoner {
|
|
|
301
348
|
const runAdaptations = this.adaptations.get(runId) ?? [];
|
|
302
349
|
const target = adaptationId
|
|
303
350
|
? runAdaptations.find((a) => a.id === adaptationId)
|
|
304
|
-
:
|
|
351
|
+
: [...runAdaptations].reverse().find((a) => a.type !== 'rollback');
|
|
305
352
|
|
|
306
353
|
if (!target?.rollbackable) {
|
|
307
354
|
return null;
|
|
@@ -319,15 +366,29 @@ export class MetaReasoner {
|
|
|
319
366
|
type: 'rollback',
|
|
320
367
|
before: target.after,
|
|
321
368
|
after: target.before,
|
|
369
|
+
previousMode: target.newMode,
|
|
370
|
+
newMode: target.previousMode,
|
|
371
|
+
reason: `Rollback of ${target.id}`,
|
|
372
|
+
isRollback: true,
|
|
322
373
|
|
|
323
374
|
rollbackable: false,
|
|
324
375
|
};
|
|
325
376
|
|
|
326
|
-
if (target.type === 'mode_switch'
|
|
327
|
-
|
|
377
|
+
if (target.type === 'mode_switch' || target.type === 'parameter_change') {
|
|
378
|
+
const restoredMode = target.previousMode ?? target.before.mode;
|
|
379
|
+
if (restoredMode) {
|
|
380
|
+
this.currentMode.set(runId, restoredMode);
|
|
381
|
+
}
|
|
382
|
+
const restoredOverrides = this.overridesBefore.get(target.id);
|
|
383
|
+
if (restoredOverrides) {
|
|
384
|
+
this.parameterOverrides.set(runId, restoredOverrides);
|
|
385
|
+
} else {
|
|
386
|
+
this.parameterOverrides.delete(runId);
|
|
387
|
+
}
|
|
328
388
|
}
|
|
329
389
|
|
|
330
390
|
target.rollbackable = false;
|
|
391
|
+
this.overridesBefore.delete(target.id);
|
|
331
392
|
runAdaptations.push(rollback);
|
|
332
393
|
return rollback;
|
|
333
394
|
}
|
|
@@ -351,7 +412,7 @@ export class MetaReasoner {
|
|
|
351
412
|
|
|
352
413
|
getCurrentConfig(runId: string): ReasoningModeConfig {
|
|
353
414
|
const mode = this.currentMode.get(runId) ?? this.config.defaultMode;
|
|
354
|
-
return this.getModeConfig(mode);
|
|
415
|
+
return { ...this.getModeConfig(mode), ...this.parameterOverrides.get(runId) };
|
|
355
416
|
}
|
|
356
417
|
|
|
357
418
|
getCurrentMode(runId: string): ReasoningMode {
|
|
@@ -384,9 +445,13 @@ export class MetaReasoner {
|
|
|
384
445
|
this.collector.cleanupRun(runId);
|
|
385
446
|
this.selector.cleanupRun(runId);
|
|
386
447
|
this.assessments.delete(runId);
|
|
387
|
-
this.adaptations.delete(runId);
|
|
388
448
|
this.currentMode.delete(runId);
|
|
449
|
+
this.parameterOverrides.delete(runId);
|
|
389
450
|
this.lastAssessmentTime.delete(runId);
|
|
390
451
|
this.lastAdaptationTime.delete(runId);
|
|
452
|
+
for (const adaptation of this.adaptations.get(runId) ?? []) {
|
|
453
|
+
this.overridesBefore.delete(adaptation.id);
|
|
454
|
+
}
|
|
455
|
+
this.adaptations.delete(runId);
|
|
391
456
|
}
|
|
392
457
|
}
|
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
MetaIssue,
|
|
3
|
+
MetaObservation,
|
|
4
|
+
MetaOpportunity,
|
|
5
|
+
MetaRecommendation,
|
|
6
|
+
ReasoningMode,
|
|
7
|
+
ReasoningModeConfig,
|
|
8
|
+
} from '@cogitator-ai/types';
|
|
2
9
|
import { extractJson } from '../utils';
|
|
3
10
|
|
|
4
11
|
export function buildMetaAssessmentPrompt(
|
|
@@ -86,38 +93,145 @@ Analyze the agent's reasoning process and respond with a JSON object:
|
|
|
86
93
|
}`;
|
|
87
94
|
}
|
|
88
95
|
|
|
96
|
+
const REASONING_MODES: readonly ReasoningMode[] = [
|
|
97
|
+
'analytical',
|
|
98
|
+
'creative',
|
|
99
|
+
'systematic',
|
|
100
|
+
'intuitive',
|
|
101
|
+
'reflective',
|
|
102
|
+
'exploratory',
|
|
103
|
+
];
|
|
104
|
+
const ISSUE_TYPES: readonly MetaIssue['type'][] = [
|
|
105
|
+
'stagnation',
|
|
106
|
+
'low_confidence',
|
|
107
|
+
'high_cost',
|
|
108
|
+
'repetition',
|
|
109
|
+
'tool_failure',
|
|
110
|
+
];
|
|
111
|
+
const SEVERITIES: readonly MetaIssue['severity'][] = ['low', 'medium', 'high'];
|
|
112
|
+
const OPPORTUNITY_TYPES: readonly MetaOpportunity['type'][] = [
|
|
113
|
+
'mode_switch',
|
|
114
|
+
'parameter_tune',
|
|
115
|
+
'context_add',
|
|
116
|
+
'tool_compose',
|
|
117
|
+
];
|
|
118
|
+
const ACTIONS: readonly MetaRecommendation['action'][] = [
|
|
119
|
+
'continue',
|
|
120
|
+
'switch_mode',
|
|
121
|
+
'adjust_parameters',
|
|
122
|
+
'inject_context',
|
|
123
|
+
'abort',
|
|
124
|
+
];
|
|
125
|
+
|
|
89
126
|
export interface ParsedAssessment {
|
|
90
|
-
onTrack
|
|
91
|
-
confidence
|
|
92
|
-
reasoning
|
|
93
|
-
issues:
|
|
94
|
-
type: string;
|
|
95
|
-
severity: string;
|
|
96
|
-
description: string;
|
|
97
|
-
}>;
|
|
127
|
+
onTrack?: boolean;
|
|
128
|
+
confidence?: number;
|
|
129
|
+
reasoning?: string;
|
|
130
|
+
issues: MetaIssue[];
|
|
98
131
|
opportunities: Array<{
|
|
99
|
-
type:
|
|
132
|
+
type: MetaOpportunity['type'];
|
|
100
133
|
description: string;
|
|
101
134
|
expectedImprovement: number;
|
|
102
135
|
}>;
|
|
103
|
-
recommendation
|
|
104
|
-
action:
|
|
105
|
-
newMode?:
|
|
106
|
-
parameterChanges?:
|
|
136
|
+
recommendation?: {
|
|
137
|
+
action: MetaRecommendation['action'];
|
|
138
|
+
newMode?: ReasoningMode;
|
|
139
|
+
parameterChanges?: Partial<ReasoningModeConfig>;
|
|
107
140
|
contextAddition?: string;
|
|
108
141
|
confidence: number;
|
|
109
142
|
reasoning: string;
|
|
110
143
|
};
|
|
111
144
|
}
|
|
112
145
|
|
|
146
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
147
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function pick<T extends string>(value: unknown, allowed: readonly T[]): T | undefined {
|
|
151
|
+
return typeof value === 'string' && (allowed as readonly string[]).includes(value)
|
|
152
|
+
? (value as T)
|
|
153
|
+
: undefined;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function probability(value: unknown): number | undefined {
|
|
157
|
+
return typeof value === 'number' && Number.isFinite(value)
|
|
158
|
+
? Math.min(1, Math.max(0, value))
|
|
159
|
+
: undefined;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function parseParameterChanges(value: unknown): Partial<ReasoningModeConfig> | undefined {
|
|
163
|
+
if (!isRecord(value)) return undefined;
|
|
164
|
+
const changes: Partial<ReasoningModeConfig> = {};
|
|
165
|
+
if (typeof value.temperature === 'number' && Number.isFinite(value.temperature)) {
|
|
166
|
+
changes.temperature = Math.min(2, Math.max(0, value.temperature));
|
|
167
|
+
}
|
|
168
|
+
if (typeof value.depth === 'number' && Number.isFinite(value.depth)) {
|
|
169
|
+
changes.depth = Math.min(10, Math.max(1, Math.round(value.depth)));
|
|
170
|
+
}
|
|
171
|
+
return Object.keys(changes).length > 0 ? changes : undefined;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function parseRecommendation(value: unknown): ParsedAssessment['recommendation'] {
|
|
175
|
+
if (!isRecord(value)) return undefined;
|
|
176
|
+
const action = pick(value.action, ACTIONS);
|
|
177
|
+
if (!action) return undefined;
|
|
178
|
+
|
|
179
|
+
return {
|
|
180
|
+
action,
|
|
181
|
+
newMode: pick(value.newMode, REASONING_MODES),
|
|
182
|
+
parameterChanges: parseParameterChanges(value.parameterChanges),
|
|
183
|
+
contextAddition:
|
|
184
|
+
typeof value.contextAddition === 'string' && value.contextAddition.trim()
|
|
185
|
+
? value.contextAddition.trim()
|
|
186
|
+
: undefined,
|
|
187
|
+
confidence: probability(value.confidence) ?? 0,
|
|
188
|
+
reasoning: typeof value.reasoning === 'string' ? value.reasoning : '',
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
|
|
113
192
|
export function parseMetaAssessmentResponse(content: string): ParsedAssessment | null {
|
|
193
|
+
let parsed: unknown;
|
|
114
194
|
try {
|
|
115
195
|
const json = extractJson(content);
|
|
116
196
|
if (!json) return null;
|
|
117
|
-
|
|
197
|
+
parsed = JSON.parse(json);
|
|
118
198
|
} catch {
|
|
119
199
|
return null;
|
|
120
200
|
}
|
|
201
|
+
if (!isRecord(parsed)) return null;
|
|
202
|
+
|
|
203
|
+
const issues: MetaIssue[] = [];
|
|
204
|
+
for (const raw of Array.isArray(parsed.issues) ? parsed.issues : []) {
|
|
205
|
+
if (!isRecord(raw)) continue;
|
|
206
|
+
const type = pick(raw.type, ISSUE_TYPES);
|
|
207
|
+
if (!type) continue;
|
|
208
|
+
issues.push({
|
|
209
|
+
type,
|
|
210
|
+
severity: pick(raw.severity, SEVERITIES) ?? 'medium',
|
|
211
|
+
description: typeof raw.description === 'string' ? raw.description : '',
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const opportunities: ParsedAssessment['opportunities'] = [];
|
|
216
|
+
for (const raw of Array.isArray(parsed.opportunities) ? parsed.opportunities : []) {
|
|
217
|
+
if (!isRecord(raw)) continue;
|
|
218
|
+
const type = pick(raw.type, OPPORTUNITY_TYPES);
|
|
219
|
+
if (!type) continue;
|
|
220
|
+
opportunities.push({
|
|
221
|
+
type,
|
|
222
|
+
description: typeof raw.description === 'string' ? raw.description : '',
|
|
223
|
+
expectedImprovement: probability(raw.expectedImprovement) ?? 0.5,
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
return {
|
|
228
|
+
onTrack: typeof parsed.onTrack === 'boolean' ? parsed.onTrack : undefined,
|
|
229
|
+
confidence: probability(parsed.confidence),
|
|
230
|
+
reasoning: typeof parsed.reasoning === 'string' ? parsed.reasoning : undefined,
|
|
231
|
+
issues,
|
|
232
|
+
opportunities,
|
|
233
|
+
recommendation: parseRecommendation(parsed.recommendation),
|
|
234
|
+
};
|
|
121
235
|
}
|
|
122
236
|
|
|
123
237
|
export const META_REASONING_SYSTEM_PROMPT = `You are a meta-reasoning system analyzing an AI agent's reasoning process.
|