@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
|
@@ -37,10 +37,12 @@ ${contextSection}
|
|
|
37
37
|
|
|
38
38
|
Respond with a JSON object:
|
|
39
39
|
{
|
|
40
|
-
"complexity": "trivial" | "simple" | "moderate" | "complex" | "extreme",
|
|
40
|
+
"complexity": "trivial" | "simple" | "moderate" | "complex" | "expert" | "extreme",
|
|
41
41
|
"domain": "general" | "coding" | "reasoning" | "creative" | "factual" | "conversational",
|
|
42
42
|
"estimatedTokens": number,
|
|
43
43
|
"requiresTools": boolean,
|
|
44
|
+
"requiresReasoning": boolean,
|
|
45
|
+
"requiresCreativity": boolean,
|
|
44
46
|
"toolIntensity": "none" | "light" | "moderate" | "heavy",
|
|
45
47
|
"reasoningDepth": "shallow" | "moderate" | "deep" | "exhaustive",
|
|
46
48
|
"creativityLevel": "low" | "moderate" | "high",
|
|
@@ -58,8 +60,18 @@ export function buildCandidateGenerationPrompt(
|
|
|
58
60
|
config: Partial<ArchitectureConfig>;
|
|
59
61
|
score: number;
|
|
60
62
|
metrics: Record<string, number>;
|
|
61
|
-
}
|
|
63
|
+
}>,
|
|
64
|
+
options: { availableModels?: string[] } = {}
|
|
62
65
|
): string {
|
|
66
|
+
const availableModels = options.availableModels ?? [];
|
|
67
|
+
const modelLine =
|
|
68
|
+
availableModels.length > 0
|
|
69
|
+
? `\n "model": ${availableModels.map((m) => JSON.stringify(m)).join(' | ')} | null,`
|
|
70
|
+
: '';
|
|
71
|
+
const modelRule =
|
|
72
|
+
availableModels.length > 0
|
|
73
|
+
? `Only use models from this list: ${availableModels.join(', ')}.`
|
|
74
|
+
: 'Do not change the model.';
|
|
63
75
|
const historySection = historicalPerformance?.length
|
|
64
76
|
? `
|
|
65
77
|
HISTORICAL PERFORMANCE:
|
|
@@ -83,18 +95,17 @@ ${historySection}
|
|
|
83
95
|
|
|
84
96
|
Generate 3-5 candidate configurations that might improve performance.
|
|
85
97
|
Each candidate should modify 1-3 parameters from current config.
|
|
98
|
+
${modelRule}
|
|
86
99
|
|
|
87
100
|
Respond with a JSON array:
|
|
88
101
|
[
|
|
89
102
|
{
|
|
90
103
|
"id": "candidate_1",
|
|
91
|
-
"config": {
|
|
92
|
-
"
|
|
93
|
-
"temperature": number or null,
|
|
104
|
+
"config": {${modelLine}
|
|
105
|
+
"temperature": number between 0 and 2 or null,
|
|
94
106
|
"maxTokens": number or null,
|
|
95
|
-
"systemPromptAdditions": "additional instructions or null",
|
|
96
107
|
"toolStrategy": "sequential" | "parallel" | "adaptive" | null,
|
|
97
|
-
"reflectionDepth":
|
|
108
|
+
"reflectionDepth": integer between 0 and 5 or null
|
|
98
109
|
},
|
|
99
110
|
"reasoning": "Why this configuration might help",
|
|
100
111
|
"expectedImprovement": 0.0-1.0,
|
|
@@ -140,56 +151,187 @@ Respond with:
|
|
|
140
151
|
}`;
|
|
141
152
|
}
|
|
142
153
|
|
|
154
|
+
const COMPLEXITIES: readonly TaskProfile['complexity'][] = [
|
|
155
|
+
'trivial',
|
|
156
|
+
'simple',
|
|
157
|
+
'moderate',
|
|
158
|
+
'complex',
|
|
159
|
+
'expert',
|
|
160
|
+
'extreme',
|
|
161
|
+
];
|
|
162
|
+
const DOMAINS: readonly TaskProfile['domain'][] = [
|
|
163
|
+
'general',
|
|
164
|
+
'coding',
|
|
165
|
+
'reasoning',
|
|
166
|
+
'creative',
|
|
167
|
+
'factual',
|
|
168
|
+
'conversational',
|
|
169
|
+
];
|
|
170
|
+
const TOOL_INTENSITIES: readonly TaskProfile['toolIntensity'][] = [
|
|
171
|
+
'none',
|
|
172
|
+
'light',
|
|
173
|
+
'moderate',
|
|
174
|
+
'heavy',
|
|
175
|
+
];
|
|
176
|
+
const REASONING_DEPTHS: readonly TaskProfile['reasoningDepth'][] = [
|
|
177
|
+
'shallow',
|
|
178
|
+
'moderate',
|
|
179
|
+
'deep',
|
|
180
|
+
'exhaustive',
|
|
181
|
+
];
|
|
182
|
+
const CREATIVITY_LEVELS: readonly TaskProfile['creativityLevel'][] = ['low', 'moderate', 'high'];
|
|
183
|
+
const ACCURACY_LEVELS: readonly TaskProfile['accuracyRequirement'][] = [
|
|
184
|
+
'approximate',
|
|
185
|
+
'moderate',
|
|
186
|
+
'high',
|
|
187
|
+
'critical',
|
|
188
|
+
];
|
|
189
|
+
const TIME_CONSTRAINTS: readonly TaskProfile['timeConstraint'][] = [
|
|
190
|
+
'none',
|
|
191
|
+
'relaxed',
|
|
192
|
+
'moderate',
|
|
193
|
+
'strict',
|
|
194
|
+
];
|
|
195
|
+
const TOOL_STRATEGIES: readonly ArchitectureConfig['toolStrategy'][] = [
|
|
196
|
+
'sequential',
|
|
197
|
+
'parallel',
|
|
198
|
+
'adaptive',
|
|
199
|
+
];
|
|
200
|
+
const RISKS: readonly EvolutionCandidate['risk'][] = ['low', 'medium', 'high'];
|
|
201
|
+
|
|
202
|
+
export const MAX_TOKENS_RANGE = { min: 100, max: 32000 } as const;
|
|
203
|
+
export const REFLECTION_DEPTH_RANGE = { min: 0, max: 5 } as const;
|
|
204
|
+
export const TEMPERATURE_RANGE = { min: 0, max: 2 } as const;
|
|
205
|
+
|
|
206
|
+
function pickEnum<T extends string>(value: unknown, allowed: readonly T[], fallback: T): T {
|
|
207
|
+
return typeof value === 'string' && (allowed as readonly string[]).includes(value)
|
|
208
|
+
? (value as T)
|
|
209
|
+
: fallback;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
function finiteNumber(value: unknown): number | undefined {
|
|
213
|
+
return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
function clamp(value: number, range: { min: number; max: number }): number {
|
|
217
|
+
return Math.min(range.max, Math.max(range.min, value));
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
221
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
222
|
+
}
|
|
223
|
+
|
|
143
224
|
export function parseTaskProfileResponse(response: string): TaskProfile | null {
|
|
144
225
|
const json = extractJson(response);
|
|
145
226
|
if (!json) return null;
|
|
146
227
|
|
|
228
|
+
let parsed: unknown;
|
|
147
229
|
try {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
return {
|
|
151
|
-
complexity: parsed.complexity || 'moderate',
|
|
152
|
-
domain: parsed.domain || 'general',
|
|
153
|
-
estimatedTokens: parsed.estimatedTokens || 1000,
|
|
154
|
-
requiresTools: Boolean(parsed.requiresTools),
|
|
155
|
-
toolIntensity: parsed.toolIntensity || 'none',
|
|
156
|
-
reasoningDepth: parsed.reasoningDepth || 'moderate',
|
|
157
|
-
creativityLevel: parsed.creativityLevel || 'moderate',
|
|
158
|
-
accuracyRequirement: parsed.accuracyRequirement || 'moderate',
|
|
159
|
-
timeConstraint: parsed.timeConstraint || 'none',
|
|
160
|
-
};
|
|
230
|
+
parsed = JSON.parse(json);
|
|
161
231
|
} catch {
|
|
162
232
|
return null;
|
|
163
233
|
}
|
|
234
|
+
if (!isRecord(parsed)) return null;
|
|
235
|
+
|
|
236
|
+
const estimatedTokens = finiteNumber(parsed.estimatedTokens);
|
|
237
|
+
|
|
238
|
+
return {
|
|
239
|
+
complexity: pickEnum(parsed.complexity, COMPLEXITIES, 'moderate'),
|
|
240
|
+
domain: pickEnum(parsed.domain, DOMAINS, 'general'),
|
|
241
|
+
estimatedTokens:
|
|
242
|
+
estimatedTokens !== undefined && estimatedTokens > 0 ? Math.round(estimatedTokens) : 1000,
|
|
243
|
+
requiresTools: Boolean(parsed.requiresTools),
|
|
244
|
+
requiresReasoning: Boolean(parsed.requiresReasoning),
|
|
245
|
+
requiresCreativity: Boolean(parsed.requiresCreativity),
|
|
246
|
+
toolIntensity: pickEnum(parsed.toolIntensity, TOOL_INTENSITIES, 'none'),
|
|
247
|
+
reasoningDepth: pickEnum(parsed.reasoningDepth, REASONING_DEPTHS, 'moderate'),
|
|
248
|
+
creativityLevel: pickEnum(parsed.creativityLevel, CREATIVITY_LEVELS, 'moderate'),
|
|
249
|
+
accuracyRequirement: pickEnum(parsed.accuracyRequirement, ACCURACY_LEVELS, 'moderate'),
|
|
250
|
+
timeConstraint: pickEnum(parsed.timeConstraint, TIME_CONSTRAINTS, 'none'),
|
|
251
|
+
};
|
|
164
252
|
}
|
|
165
253
|
|
|
166
|
-
export function
|
|
167
|
-
|
|
168
|
-
|
|
254
|
+
export function sanitizeCandidateConfig(
|
|
255
|
+
raw: unknown,
|
|
256
|
+
options: { availableModels?: string[] } = {}
|
|
257
|
+
): Partial<ArchitectureConfig> {
|
|
258
|
+
if (!isRecord(raw)) return {};
|
|
259
|
+
const config: Partial<ArchitectureConfig> = {};
|
|
260
|
+
|
|
261
|
+
if (typeof raw.model === 'string' && options.availableModels?.includes(raw.model)) {
|
|
262
|
+
config.model = raw.model;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
const temperature = finiteNumber(raw.temperature);
|
|
266
|
+
if (temperature !== undefined) {
|
|
267
|
+
config.temperature = clamp(temperature, TEMPERATURE_RANGE);
|
|
268
|
+
}
|
|
169
269
|
|
|
270
|
+
const maxTokens = finiteNumber(raw.maxTokens);
|
|
271
|
+
if (maxTokens !== undefined) {
|
|
272
|
+
config.maxTokens = clamp(Math.round(maxTokens), MAX_TOKENS_RANGE);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
if (
|
|
276
|
+
typeof raw.toolStrategy === 'string' &&
|
|
277
|
+
(TOOL_STRATEGIES as readonly string[]).includes(raw.toolStrategy)
|
|
278
|
+
) {
|
|
279
|
+
config.toolStrategy = raw.toolStrategy as ArchitectureConfig['toolStrategy'];
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
const reflectionDepth = finiteNumber(raw.reflectionDepth);
|
|
283
|
+
if (reflectionDepth !== undefined) {
|
|
284
|
+
config.reflectionDepth = clamp(Math.round(reflectionDepth), REFLECTION_DEPTH_RANGE);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
return config;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
export function parseCandidateGenerationResponse(
|
|
291
|
+
response: string,
|
|
292
|
+
options: { availableModels?: string[] } = {}
|
|
293
|
+
): EvolutionCandidate[] {
|
|
294
|
+
const json = extractJsonArray(response);
|
|
295
|
+
if (!json) return [];
|
|
296
|
+
|
|
297
|
+
let parsed: unknown;
|
|
170
298
|
try {
|
|
171
|
-
|
|
172
|
-
if (!Array.isArray(parsed)) return [];
|
|
173
|
-
|
|
174
|
-
return parsed
|
|
175
|
-
.filter((c: Record<string, unknown>) => c && typeof c === 'object' && c.config)
|
|
176
|
-
.map((c: Record<string, unknown>, idx: number) => ({
|
|
177
|
-
id: String(c.id || `candidate_${idx}`),
|
|
178
|
-
config: c.config as Partial<ArchitectureConfig>,
|
|
179
|
-
reasoning: String(c.reasoning || ''),
|
|
180
|
-
expectedImprovement:
|
|
181
|
-
typeof c.expectedImprovement === 'number' ? c.expectedImprovement : 0.5,
|
|
182
|
-
risk: (['low', 'medium', 'high'].includes(String(c.risk)) ? c.risk : 'medium') as
|
|
183
|
-
| 'low'
|
|
184
|
-
| 'medium'
|
|
185
|
-
| 'high',
|
|
186
|
-
generation: 0,
|
|
187
|
-
score: 0,
|
|
188
|
-
evaluationCount: 0,
|
|
189
|
-
}));
|
|
299
|
+
parsed = JSON.parse(json);
|
|
190
300
|
} catch {
|
|
191
301
|
return [];
|
|
192
302
|
}
|
|
303
|
+
if (!Array.isArray(parsed)) return [];
|
|
304
|
+
|
|
305
|
+
const usedIds = new Set<string>(['baseline']);
|
|
306
|
+
const candidates: EvolutionCandidate[] = [];
|
|
307
|
+
|
|
308
|
+
parsed.forEach((raw: unknown, idx: number) => {
|
|
309
|
+
if (!isRecord(raw)) return;
|
|
310
|
+
const config = sanitizeCandidateConfig(raw.config, options);
|
|
311
|
+
if (Object.keys(config).length === 0) return;
|
|
312
|
+
|
|
313
|
+
let id = typeof raw.id === 'string' && raw.id.trim() ? raw.id.trim() : `candidate_${idx}`;
|
|
314
|
+
while (usedIds.has(id)) {
|
|
315
|
+
id = `${id}_${idx}`;
|
|
316
|
+
}
|
|
317
|
+
usedIds.add(id);
|
|
318
|
+
|
|
319
|
+
const expectedImprovement = finiteNumber(raw.expectedImprovement);
|
|
320
|
+
|
|
321
|
+
candidates.push({
|
|
322
|
+
id,
|
|
323
|
+
config,
|
|
324
|
+
reasoning: typeof raw.reasoning === 'string' ? raw.reasoning : '',
|
|
325
|
+
expectedImprovement:
|
|
326
|
+
expectedImprovement !== undefined ? clamp(expectedImprovement, { min: 0, max: 1 }) : 0.5,
|
|
327
|
+
risk: pickEnum(raw.risk, RISKS, 'medium'),
|
|
328
|
+
generation: 0,
|
|
329
|
+
score: 0,
|
|
330
|
+
evaluationCount: 0,
|
|
331
|
+
});
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
return candidates;
|
|
193
335
|
}
|
|
194
336
|
|
|
195
337
|
export function parsePerformanceAnalysisResponse(response: string): {
|
|
@@ -214,3 +356,43 @@ export function parsePerformanceAnalysisResponse(response: string): {
|
|
|
214
356
|
return null;
|
|
215
357
|
}
|
|
216
358
|
}
|
|
359
|
+
|
|
360
|
+
function extractJsonArray(text: string): string | null {
|
|
361
|
+
const start = text.indexOf('[');
|
|
362
|
+
if (start === -1) return null;
|
|
363
|
+
|
|
364
|
+
let depth = 0;
|
|
365
|
+
let inString = false;
|
|
366
|
+
let escape = false;
|
|
367
|
+
|
|
368
|
+
for (let i = start; i < text.length; i++) {
|
|
369
|
+
const ch = text[i];
|
|
370
|
+
|
|
371
|
+
if (escape) {
|
|
372
|
+
escape = false;
|
|
373
|
+
continue;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
if (ch === '\\' && inString) {
|
|
377
|
+
escape = true;
|
|
378
|
+
continue;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
if (ch === '"') {
|
|
382
|
+
inString = !inString;
|
|
383
|
+
continue;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
if (inString) continue;
|
|
387
|
+
|
|
388
|
+
if (ch === '[' || ch === '{') depth++;
|
|
389
|
+
else if (ch === ']' || ch === '}') {
|
|
390
|
+
depth--;
|
|
391
|
+
if (depth === 0) {
|
|
392
|
+
return text.slice(start, i + 1);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
return null;
|
|
398
|
+
}
|
|
@@ -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,14 +91,26 @@ 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);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const checks: boolean[] = [];
|
|
101
|
+
|
|
102
|
+
if (rule.expression) {
|
|
103
|
+
checks.push(this.evaluateExpression(rule.expression, context));
|
|
93
104
|
}
|
|
94
105
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
106
|
+
if (rule.pattern) {
|
|
107
|
+
const subject = JSON.stringify(request.changes ?? request.payload ?? '');
|
|
108
|
+
checks.push(rule.pattern.test(subject));
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (checks.length === 0) return false;
|
|
112
|
+
|
|
113
|
+
return checks.every(Boolean);
|
|
99
114
|
}
|
|
100
115
|
|
|
101
116
|
private evaluateExpression(expression: string, context: Record<string, unknown>): boolean {
|
|
@@ -159,10 +174,20 @@ export class ModificationValidator {
|
|
|
159
174
|
return Boolean(value);
|
|
160
175
|
}
|
|
161
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
|
+
|
|
162
184
|
private resolveValue(expr: string, context: Record<string, unknown>): unknown {
|
|
163
185
|
if (expr === 'true') return true;
|
|
164
186
|
if (expr === 'false') return false;
|
|
165
|
-
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];
|
|
166
191
|
|
|
167
192
|
const keys = expr.split('.');
|
|
168
193
|
let current: unknown = context;
|
|
@@ -181,34 +206,36 @@ export class ModificationValidator {
|
|
|
181
206
|
): Promise<ConstraintCheckResult[]> {
|
|
182
207
|
const results: ConstraintCheckResult[] = [];
|
|
183
208
|
|
|
184
|
-
if (request.type !== 'tool_generation') {
|
|
209
|
+
if (request.type !== 'tool_generation' && request.type !== 'tool_creation') {
|
|
185
210
|
return results;
|
|
186
211
|
}
|
|
187
212
|
|
|
188
|
-
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;
|
|
189
216
|
|
|
190
217
|
for (const constraint of this.constraints.capability) {
|
|
191
218
|
let satisfied = true;
|
|
192
219
|
let message: string | undefined;
|
|
193
220
|
|
|
194
|
-
if (
|
|
195
|
-
if (constraint.forbidden?.includes(
|
|
221
|
+
if (category) {
|
|
222
|
+
if (constraint.forbidden?.includes(category)) {
|
|
196
223
|
satisfied = false;
|
|
197
|
-
message = `Category '${
|
|
198
|
-
} else if (constraint.allowed?.length && !constraint.allowed.includes(
|
|
224
|
+
message = `Category '${category}' is forbidden`;
|
|
225
|
+
} else if (constraint.allowed?.length && !constraint.allowed.includes(category)) {
|
|
199
226
|
satisfied = false;
|
|
200
|
-
message = `Category '${
|
|
227
|
+
message = `Category '${category}' is not in allowed list`;
|
|
201
228
|
}
|
|
202
229
|
}
|
|
203
230
|
|
|
204
231
|
if (
|
|
205
232
|
satisfied &&
|
|
206
|
-
constraint.maxComplexity &&
|
|
207
|
-
|
|
208
|
-
|
|
233
|
+
constraint.maxComplexity !== undefined &&
|
|
234
|
+
complexity !== undefined &&
|
|
235
|
+
complexity > constraint.maxComplexity
|
|
209
236
|
) {
|
|
210
237
|
satisfied = false;
|
|
211
|
-
message = `Complexity ${
|
|
238
|
+
message = `Complexity ${complexity} exceeds max ${constraint.maxComplexity}`;
|
|
212
239
|
}
|
|
213
240
|
|
|
214
241
|
results.push({
|
|
@@ -227,7 +254,7 @@ export class ModificationValidator {
|
|
|
227
254
|
request: ModificationRequest
|
|
228
255
|
): Promise<ConstraintCheckResult[]> {
|
|
229
256
|
const results: ConstraintCheckResult[] = [];
|
|
230
|
-
const payload = (request
|
|
257
|
+
const payload = this.payloadOf(request) as {
|
|
231
258
|
tokensUsed?: number;
|
|
232
259
|
cost?: number;
|
|
233
260
|
activeTools?: number;
|
|
@@ -239,7 +266,7 @@ export class ModificationValidator {
|
|
|
239
266
|
|
|
240
267
|
if (
|
|
241
268
|
constraint.maxTokensPerRun &&
|
|
242
|
-
payload.tokensUsed &&
|
|
269
|
+
payload.tokensUsed != null &&
|
|
243
270
|
payload.tokensUsed > constraint.maxTokensPerRun
|
|
244
271
|
) {
|
|
245
272
|
satisfied = false;
|
|
@@ -249,7 +276,7 @@ export class ModificationValidator {
|
|
|
249
276
|
if (
|
|
250
277
|
satisfied &&
|
|
251
278
|
constraint.maxCostPerRun &&
|
|
252
|
-
payload.cost &&
|
|
279
|
+
payload.cost != null &&
|
|
253
280
|
payload.cost > constraint.maxCostPerRun
|
|
254
281
|
) {
|
|
255
282
|
satisfied = false;
|
|
@@ -259,7 +286,7 @@ export class ModificationValidator {
|
|
|
259
286
|
if (
|
|
260
287
|
satisfied &&
|
|
261
288
|
constraint.maxToolsActive &&
|
|
262
|
-
payload.activeTools &&
|
|
289
|
+
payload.activeTools != null &&
|
|
263
290
|
payload.activeTools > constraint.maxToolsActive
|
|
264
291
|
) {
|
|
265
292
|
satisfied = false;
|
|
@@ -119,11 +119,30 @@ export class RollbackManager {
|
|
|
119
119
|
if (!checkpoint) return null;
|
|
120
120
|
|
|
121
121
|
return {
|
|
122
|
-
agentConfig: checkpoint.agentConfig
|
|
122
|
+
agentConfig: this.toAgentConfig(checkpoint.agentConfig),
|
|
123
123
|
tools: checkpoint.tools.map((t) => ({ ...t })),
|
|
124
124
|
};
|
|
125
125
|
}
|
|
126
126
|
|
|
127
|
+
private toAgentConfig(record: Record<string, unknown>): AgentConfig {
|
|
128
|
+
const config: AgentConfig = {
|
|
129
|
+
name: typeof record.name === 'string' ? record.name : 'agent',
|
|
130
|
+
model: typeof record.model === 'string' ? record.model : 'default',
|
|
131
|
+
instructions: typeof record.instructions === 'string' ? record.instructions : '',
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
if (typeof record.id === 'string') config.id = record.id;
|
|
135
|
+
if (typeof record.description === 'string') config.description = record.description;
|
|
136
|
+
if (typeof record.provider === 'string') config.provider = record.provider;
|
|
137
|
+
if (typeof record.temperature === 'number') config.temperature = record.temperature;
|
|
138
|
+
if (typeof record.topP === 'number') config.topP = record.topP;
|
|
139
|
+
if (typeof record.maxTokens === 'number') config.maxTokens = record.maxTokens;
|
|
140
|
+
if (typeof record.maxIterations === 'number') config.maxIterations = record.maxIterations;
|
|
141
|
+
if (typeof record.timeout === 'number') config.timeout = record.timeout;
|
|
142
|
+
|
|
143
|
+
return config;
|
|
144
|
+
}
|
|
145
|
+
|
|
127
146
|
async rollbackToLatest(
|
|
128
147
|
agentId: string
|
|
129
148
|
): Promise<{ agentConfig: AgentConfig; tools: Tool[] } | null> {
|
|
@@ -30,7 +30,7 @@ export class SelfModifyingEventEmitter {
|
|
|
30
30
|
...(wildcardHandlers ? [...wildcardHandlers] : []),
|
|
31
31
|
];
|
|
32
32
|
|
|
33
|
-
await Promise.allSettled(
|
|
33
|
+
const results = await Promise.allSettled(
|
|
34
34
|
allHandlers.map((h) => {
|
|
35
35
|
try {
|
|
36
36
|
return Promise.resolve(h(event));
|
|
@@ -39,21 +39,12 @@ export class SelfModifyingEventEmitter {
|
|
|
39
39
|
}
|
|
40
40
|
})
|
|
41
41
|
);
|
|
42
|
-
}
|
|
43
42
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
): SelfModifyingEvent {
|
|
50
|
-
return {
|
|
51
|
-
type,
|
|
52
|
-
runId,
|
|
53
|
-
agentId,
|
|
54
|
-
timestamp: new Date(),
|
|
55
|
-
data,
|
|
56
|
-
};
|
|
43
|
+
for (const result of results) {
|
|
44
|
+
if (result.status === 'rejected') {
|
|
45
|
+
console.error(`[self-modifying] event handler for "${event.type}" failed:`, result.reason);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
57
48
|
}
|
|
58
49
|
|
|
59
50
|
removeAllListeners(event?: SelfModifyingEventType | '*'): void {
|
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,
|