@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,5 +1,21 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
1
2
|
import type { Tool, LLMBackend, TaskProfile } from '@cogitator-ai/types';
|
|
2
3
|
import { buildTaskProfilePrompt, parseTaskProfileResponse } from './prompts';
|
|
4
|
+
import { llmChat } from '../utils/llm-helper';
|
|
5
|
+
|
|
6
|
+
function escapeRegExp(value: string): string {
|
|
7
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function containsPhrase(text: string, phrase: string): boolean {
|
|
11
|
+
return new RegExp(`(?:^|[^a-z0-9])${escapeRegExp(phrase)}(?:s|es|ed|ing)?(?:$|[^a-z0-9])`).test(
|
|
12
|
+
text
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function tokenize(text: string): string[] {
|
|
17
|
+
return text.split(/[^a-z0-9-]+/).filter(Boolean);
|
|
18
|
+
}
|
|
3
19
|
|
|
4
20
|
export interface CapabilityAnalyzerOptions {
|
|
5
21
|
llm?: LLMBackend;
|
|
@@ -121,6 +137,7 @@ const COMPLEXITY_INDICATORS = {
|
|
|
121
137
|
simple: ['explain', 'define', 'list', 'describe', 'show'],
|
|
122
138
|
moderate: ['compare', 'analyze', 'summarize', 'evaluate', 'implement'],
|
|
123
139
|
complex: ['design', 'architect', 'optimize', 'comprehensive', 'detailed'],
|
|
140
|
+
expert: ['expert', 'advanced', 'specialized', 'intricate', 'sophisticated'],
|
|
124
141
|
extreme: ['novel', 'research', 'breakthrough', 'state-of-the-art', 'cutting-edge'],
|
|
125
142
|
};
|
|
126
143
|
|
|
@@ -145,7 +162,7 @@ export class CapabilityAnalyzer {
|
|
|
145
162
|
constraints?: { maxCost?: number; maxLatency?: number };
|
|
146
163
|
}
|
|
147
164
|
): Promise<TaskProfile> {
|
|
148
|
-
const cacheKey = this.buildCacheKey(taskDescription);
|
|
165
|
+
const cacheKey = this.buildCacheKey(taskDescription, context);
|
|
149
166
|
const cached = this.profileCache.get(cacheKey);
|
|
150
167
|
if (cached && Date.now() - cached.timestamp < this.cacheTTL) {
|
|
151
168
|
return cached.profile;
|
|
@@ -189,32 +206,20 @@ export class CapabilityAnalyzer {
|
|
|
189
206
|
constraints: context?.constraints,
|
|
190
207
|
});
|
|
191
208
|
|
|
192
|
-
const
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
messages: [
|
|
207
|
-
{
|
|
208
|
-
role: 'system',
|
|
209
|
-
content:
|
|
210
|
-
'You are a task analysis expert. Analyze tasks and determine their characteristics.',
|
|
211
|
-
},
|
|
212
|
-
{ role: 'user', content: prompt },
|
|
213
|
-
],
|
|
214
|
-
temperature: 0.2,
|
|
215
|
-
});
|
|
216
|
-
|
|
217
|
-
const parsed = parseTaskProfileResponse(response.content);
|
|
209
|
+
const content = await llmChat(
|
|
210
|
+
llm,
|
|
211
|
+
[
|
|
212
|
+
{
|
|
213
|
+
role: 'system',
|
|
214
|
+
content:
|
|
215
|
+
'You are a task analysis expert. Analyze tasks and determine their characteristics.',
|
|
216
|
+
},
|
|
217
|
+
{ role: 'user', content: prompt },
|
|
218
|
+
],
|
|
219
|
+
{ model: this.model, temperature: 0.2 }
|
|
220
|
+
);
|
|
221
|
+
|
|
222
|
+
const parsed = parseTaskProfileResponse(content);
|
|
218
223
|
if (parsed) {
|
|
219
224
|
return parsed;
|
|
220
225
|
}
|
|
@@ -225,8 +230,7 @@ export class CapabilityAnalyzer {
|
|
|
225
230
|
|
|
226
231
|
private analyzeHeuristically(taskDescription: string, availableTools?: Tool[]): TaskProfile {
|
|
227
232
|
const lowerTask = taskDescription.toLowerCase();
|
|
228
|
-
const
|
|
229
|
-
const wordCount = words.length;
|
|
233
|
+
const wordCount = tokenize(lowerTask).length;
|
|
230
234
|
|
|
231
235
|
const domain = this.detectDomain(lowerTask);
|
|
232
236
|
const complexity = this.detectComplexity(lowerTask, wordCount);
|
|
@@ -237,6 +241,8 @@ export class CapabilityAnalyzer {
|
|
|
237
241
|
domain,
|
|
238
242
|
estimatedTokens: this.estimateTokens(wordCount, complexity),
|
|
239
243
|
requiresTools: toolAnalysis.requiresTools,
|
|
244
|
+
requiresReasoning: domain === 'reasoning' || domain === 'coding',
|
|
245
|
+
requiresCreativity: domain === 'creative',
|
|
240
246
|
toolIntensity: toolAnalysis.intensity,
|
|
241
247
|
reasoningDepth: this.estimateReasoningDepth(complexity, domain),
|
|
242
248
|
creativityLevel:
|
|
@@ -257,7 +263,7 @@ export class CapabilityAnalyzer {
|
|
|
257
263
|
|
|
258
264
|
for (const [domain, keywords] of Object.entries(DOMAIN_KEYWORDS)) {
|
|
259
265
|
for (const keyword of keywords) {
|
|
260
|
-
if (task
|
|
266
|
+
if (containsPhrase(task, keyword)) {
|
|
261
267
|
scores[domain] += keyword.length > 5 ? 2 : 1;
|
|
262
268
|
}
|
|
263
269
|
}
|
|
@@ -269,7 +275,7 @@ export class CapabilityAnalyzer {
|
|
|
269
275
|
}
|
|
270
276
|
|
|
271
277
|
private detectComplexity(task: string, wordCount: number): TaskProfile['complexity'] {
|
|
272
|
-
const taskWords = new Set(task
|
|
278
|
+
const taskWords = new Set(tokenize(task));
|
|
273
279
|
|
|
274
280
|
for (const [level, indicators] of Object.entries(COMPLEXITY_INDICATORS).reverse()) {
|
|
275
281
|
for (const indicator of indicators) {
|
|
@@ -306,14 +312,14 @@ export class CapabilityAnalyzer {
|
|
|
306
312
|
|
|
307
313
|
let toolMentions = 0;
|
|
308
314
|
for (const indicator of toolIndicators) {
|
|
309
|
-
if (task
|
|
315
|
+
if (containsPhrase(task, indicator)) {
|
|
310
316
|
toolMentions++;
|
|
311
317
|
}
|
|
312
318
|
}
|
|
313
319
|
|
|
314
320
|
if (availableTools?.length) {
|
|
315
321
|
for (const tool of availableTools) {
|
|
316
|
-
if (task
|
|
322
|
+
if (containsPhrase(task, tool.name.toLowerCase())) {
|
|
317
323
|
toolMentions += 2;
|
|
318
324
|
}
|
|
319
325
|
}
|
|
@@ -375,20 +381,20 @@ export class CapabilityAnalyzer {
|
|
|
375
381
|
domain: TaskProfile['domain'],
|
|
376
382
|
task: string
|
|
377
383
|
): TaskProfile['accuracyRequirement'] {
|
|
378
|
-
if (domain === 'coding' || domain === 'factual') {
|
|
379
|
-
return 'high';
|
|
380
|
-
}
|
|
381
|
-
|
|
382
384
|
const criticalIndicators = ['critical', 'exact', 'precise', 'must be correct', 'no errors'];
|
|
383
385
|
for (const indicator of criticalIndicators) {
|
|
384
|
-
if (task
|
|
386
|
+
if (containsPhrase(task, indicator)) {
|
|
385
387
|
return 'critical';
|
|
386
388
|
}
|
|
387
389
|
}
|
|
388
390
|
|
|
391
|
+
if (domain === 'coding' || domain === 'factual') {
|
|
392
|
+
return 'high';
|
|
393
|
+
}
|
|
394
|
+
|
|
389
395
|
const approximateIndicators = ['rough', 'approximate', 'estimate', 'about', 'roughly'];
|
|
390
396
|
for (const indicator of approximateIndicators) {
|
|
391
|
-
if (task
|
|
397
|
+
if (containsPhrase(task, indicator)) {
|
|
392
398
|
return 'approximate';
|
|
393
399
|
}
|
|
394
400
|
}
|
|
@@ -402,20 +408,33 @@ export class CapabilityAnalyzer {
|
|
|
402
408
|
const relaxedIndicators = ['when possible', 'eventually', 'no rush'];
|
|
403
409
|
|
|
404
410
|
for (const indicator of strictIndicators) {
|
|
405
|
-
if (task
|
|
411
|
+
if (containsPhrase(task, indicator)) return 'strict';
|
|
406
412
|
}
|
|
407
413
|
for (const indicator of moderateIndicators) {
|
|
408
|
-
if (task
|
|
414
|
+
if (containsPhrase(task, indicator)) return 'moderate';
|
|
409
415
|
}
|
|
410
416
|
for (const indicator of relaxedIndicators) {
|
|
411
|
-
if (task
|
|
417
|
+
if (containsPhrase(task, indicator)) return 'relaxed';
|
|
412
418
|
}
|
|
413
419
|
|
|
414
420
|
return 'none';
|
|
415
421
|
}
|
|
416
422
|
|
|
417
|
-
private buildCacheKey(
|
|
418
|
-
|
|
423
|
+
private buildCacheKey(
|
|
424
|
+
task: string,
|
|
425
|
+
context?: {
|
|
426
|
+
availableTools?: Tool[];
|
|
427
|
+
previousTasks?: string[];
|
|
428
|
+
constraints?: { maxCost?: number; maxLatency?: number };
|
|
429
|
+
}
|
|
430
|
+
): string {
|
|
431
|
+
const raw = JSON.stringify([
|
|
432
|
+
task.toLowerCase().replace(/\s+/g, ' ').trim(),
|
|
433
|
+
(context?.availableTools ?? []).map((t) => t.name).sort(),
|
|
434
|
+
context?.previousTasks ?? [],
|
|
435
|
+
context?.constraints ?? {},
|
|
436
|
+
]);
|
|
437
|
+
return createHash('sha256').update(raw).digest('hex');
|
|
419
438
|
}
|
|
420
439
|
|
|
421
440
|
clearCache(): void {
|
|
@@ -152,8 +152,9 @@ export class EvolutionStrategy {
|
|
|
152
152
|
|
|
153
153
|
const d = shape - 1 / 3;
|
|
154
154
|
const c = 1 / Math.sqrt(9 * d);
|
|
155
|
+
const maxIterations = 1000;
|
|
155
156
|
|
|
156
|
-
|
|
157
|
+
for (let i = 0; i < maxIterations; i++) {
|
|
157
158
|
let x: number;
|
|
158
159
|
let v: number;
|
|
159
160
|
|
|
@@ -173,6 +174,8 @@ export class EvolutionStrategy {
|
|
|
173
174
|
return d * v;
|
|
174
175
|
}
|
|
175
176
|
}
|
|
177
|
+
|
|
178
|
+
return d;
|
|
176
179
|
}
|
|
177
180
|
|
|
178
181
|
private sampleNormal(): number {
|
|
@@ -202,7 +205,7 @@ export class EvolutionStrategy {
|
|
|
202
205
|
(this.strategy.explorationConstant ?? 2) / Math.sqrt(this.totalSelections)
|
|
203
206
|
);
|
|
204
207
|
case 'thompson_sampling':
|
|
205
|
-
return 0.
|
|
208
|
+
return Math.max(0.05, 1 / Math.sqrt(this.totalSelections + 1));
|
|
206
209
|
default:
|
|
207
210
|
return 0.1;
|
|
208
211
|
}
|
|
@@ -10,6 +10,7 @@ export {
|
|
|
10
10
|
ParameterOptimizer,
|
|
11
11
|
type ParameterOptimizerOptions,
|
|
12
12
|
type OptimizationResult,
|
|
13
|
+
type HistoricalRecord,
|
|
13
14
|
} from './parameter-optimizer';
|
|
14
15
|
|
|
15
16
|
export {
|
|
@@ -19,5 +20,6 @@ export {
|
|
|
19
20
|
parseTaskProfileResponse,
|
|
20
21
|
parseCandidateGenerationResponse,
|
|
21
22
|
parsePerformanceAnalysisResponse,
|
|
23
|
+
sanitizeCandidateConfig,
|
|
22
24
|
ARCHITECTURE_ANALYSIS_SYSTEM_PROMPT,
|
|
23
25
|
} from './prompts';
|
|
@@ -13,17 +13,23 @@ import {
|
|
|
13
13
|
buildPerformanceAnalysisPrompt,
|
|
14
14
|
parseCandidateGenerationResponse,
|
|
15
15
|
parsePerformanceAnalysisResponse,
|
|
16
|
+
MAX_TOKENS_RANGE,
|
|
17
|
+
REFLECTION_DEPTH_RANGE,
|
|
18
|
+
TEMPERATURE_RANGE,
|
|
16
19
|
} from './prompts';
|
|
20
|
+
import { llmChat } from '../utils/llm-helper';
|
|
17
21
|
|
|
18
22
|
export interface ParameterOptimizerOptions {
|
|
19
23
|
llm: LLMBackend;
|
|
20
24
|
config: ArchitectureEvolutionConfig;
|
|
21
25
|
baseConfig: ArchitectureConfig;
|
|
22
26
|
model?: string;
|
|
27
|
+
availableModels?: string[];
|
|
23
28
|
}
|
|
24
29
|
|
|
25
30
|
export interface OptimizationResult {
|
|
26
31
|
recommendedConfig: ArchitectureConfig;
|
|
32
|
+
taskProfile: TaskProfile;
|
|
27
33
|
candidate: EvolutionCandidate | null;
|
|
28
34
|
metrics: EvolutionMetrics;
|
|
29
35
|
shouldAdopt: boolean;
|
|
@@ -31,7 +37,7 @@ export interface OptimizationResult {
|
|
|
31
37
|
reasoning: string;
|
|
32
38
|
}
|
|
33
39
|
|
|
34
|
-
interface HistoricalRecord {
|
|
40
|
+
export interface HistoricalRecord {
|
|
35
41
|
taskProfile: TaskProfile;
|
|
36
42
|
config: Partial<ArchitectureConfig>;
|
|
37
43
|
score: number;
|
|
@@ -44,6 +50,7 @@ export class ParameterOptimizer {
|
|
|
44
50
|
private readonly config: ArchitectureEvolutionConfig;
|
|
45
51
|
private readonly model: string;
|
|
46
52
|
private readonly baseConfig: ArchitectureConfig;
|
|
53
|
+
private readonly availableModels: string[];
|
|
47
54
|
private readonly capabilityAnalyzer: CapabilityAnalyzer;
|
|
48
55
|
private readonly evolutionStrategy: EvolutionStrategy;
|
|
49
56
|
|
|
@@ -58,6 +65,7 @@ export class ParameterOptimizer {
|
|
|
58
65
|
this.config = options.config;
|
|
59
66
|
this.model = options.model ?? 'default';
|
|
60
67
|
this.baseConfig = options.baseConfig;
|
|
68
|
+
this.availableModels = options.availableModels ?? [];
|
|
61
69
|
|
|
62
70
|
this.capabilityAnalyzer = new CapabilityAnalyzer({
|
|
63
71
|
llm: options.llm,
|
|
@@ -79,15 +87,28 @@ export class ParameterOptimizer {
|
|
|
79
87
|
}
|
|
80
88
|
|
|
81
89
|
const selection = this.evolutionStrategy.select(this.candidates);
|
|
90
|
+
const candidate = selection.candidate;
|
|
91
|
+
|
|
92
|
+
const mergedConfig = this.mergeConfigs(this.baseConfig, candidate.config);
|
|
82
93
|
|
|
83
|
-
const
|
|
94
|
+
const bestEvaluated = this.candidates
|
|
95
|
+
.filter((c) => c.evaluationCount > 0)
|
|
96
|
+
.sort((a, b) => b.score - a.score)[0];
|
|
97
|
+
|
|
98
|
+
const threshold = this.config.adaptationThreshold ?? 0.1;
|
|
99
|
+
const shouldAdopt =
|
|
100
|
+
candidate.evaluationCount === 0 ||
|
|
101
|
+
!bestEvaluated ||
|
|
102
|
+
candidate.id === bestEvaluated.id ||
|
|
103
|
+
candidate.score >= bestEvaluated.score - threshold;
|
|
84
104
|
|
|
85
105
|
return {
|
|
86
106
|
recommendedConfig: mergedConfig,
|
|
87
|
-
|
|
107
|
+
taskProfile: profile,
|
|
108
|
+
candidate,
|
|
88
109
|
metrics: this.calculateMetrics(),
|
|
89
|
-
shouldAdopt
|
|
90
|
-
confidence:
|
|
110
|
+
shouldAdopt,
|
|
111
|
+
confidence: candidate.evaluationCount > 0 ? candidate.score : 0.5,
|
|
91
112
|
reasoning: selection.reasoning,
|
|
92
113
|
};
|
|
93
114
|
}
|
|
@@ -134,11 +155,13 @@ export class ParameterOptimizer {
|
|
|
134
155
|
const prompt = buildCandidateGenerationPrompt(
|
|
135
156
|
profile,
|
|
136
157
|
this.baseConfig,
|
|
137
|
-
this.getRelevantHistory(profile)
|
|
158
|
+
this.getRelevantHistory(profile),
|
|
159
|
+
{ availableModels: this.availableModels }
|
|
138
160
|
);
|
|
139
161
|
|
|
140
162
|
try {
|
|
141
|
-
const
|
|
163
|
+
const content = await llmChat(
|
|
164
|
+
this.llm,
|
|
142
165
|
[
|
|
143
166
|
{
|
|
144
167
|
role: 'system',
|
|
@@ -146,14 +169,17 @@ export class ParameterOptimizer {
|
|
|
146
169
|
},
|
|
147
170
|
{ role: 'user', content: prompt },
|
|
148
171
|
],
|
|
149
|
-
0.5
|
|
172
|
+
{ model: this.model, temperature: 0.5 }
|
|
150
173
|
);
|
|
151
174
|
|
|
152
|
-
const generated = parseCandidateGenerationResponse(
|
|
175
|
+
const generated = parseCandidateGenerationResponse(content, {
|
|
176
|
+
availableModels: this.availableModels,
|
|
177
|
+
}).filter((c) => c.risk !== 'high');
|
|
153
178
|
|
|
179
|
+
const maxCandidates = this.config.maxCandidates ?? 10;
|
|
154
180
|
this.candidates = [
|
|
155
181
|
this.createBaselineCandidate(),
|
|
156
|
-
...generated.map((c) => ({
|
|
182
|
+
...generated.slice(0, Math.max(0, maxCandidates - 1)).map((c) => ({
|
|
157
183
|
...c,
|
|
158
184
|
generation: this.currentGeneration,
|
|
159
185
|
})),
|
|
@@ -247,22 +273,28 @@ export class ParameterOptimizer {
|
|
|
247
273
|
const mutated = { ...config };
|
|
248
274
|
const mutationRate = 0.3;
|
|
249
275
|
|
|
250
|
-
if (Math.random() < mutationRate
|
|
276
|
+
if (Math.random() < mutationRate) {
|
|
277
|
+
const base = mutated.temperature ?? this.baseConfig.temperature;
|
|
251
278
|
mutated.temperature = Math.max(
|
|
252
|
-
|
|
253
|
-
Math.min(
|
|
279
|
+
TEMPERATURE_RANGE.min,
|
|
280
|
+
Math.min(TEMPERATURE_RANGE.max, base + (Math.random() - 0.5) * 0.3)
|
|
254
281
|
);
|
|
255
282
|
}
|
|
256
283
|
|
|
257
|
-
if (Math.random() < mutationRate
|
|
284
|
+
if (Math.random() < mutationRate) {
|
|
285
|
+
const base = mutated.maxTokens ?? this.baseConfig.maxTokens;
|
|
258
286
|
const delta = Math.floor((Math.random() - 0.5) * 1000);
|
|
259
|
-
mutated.maxTokens = Math.max(
|
|
287
|
+
mutated.maxTokens = Math.max(
|
|
288
|
+
MAX_TOKENS_RANGE.min,
|
|
289
|
+
Math.min(MAX_TOKENS_RANGE.max, base + delta)
|
|
290
|
+
);
|
|
260
291
|
}
|
|
261
292
|
|
|
262
|
-
if (Math.random() < mutationRate
|
|
293
|
+
if (Math.random() < mutationRate) {
|
|
294
|
+
const base = mutated.reflectionDepth ?? this.baseConfig.reflectionDepth;
|
|
263
295
|
mutated.reflectionDepth = Math.max(
|
|
264
|
-
|
|
265
|
-
Math.min(
|
|
296
|
+
REFLECTION_DEPTH_RANGE.min,
|
|
297
|
+
Math.min(REFLECTION_DEPTH_RANGE.max, base + Math.round(Math.random() * 2 - 1))
|
|
266
298
|
);
|
|
267
299
|
}
|
|
268
300
|
|
|
@@ -316,22 +348,26 @@ export class ParameterOptimizer {
|
|
|
316
348
|
}
|
|
317
349
|
|
|
318
350
|
private shouldEvolve(): boolean {
|
|
319
|
-
const
|
|
351
|
+
const evaluatedCandidates = this.candidates.filter((c) => c.evaluationCount > 0);
|
|
352
|
+
if (evaluatedCandidates.length === 0) return false;
|
|
353
|
+
|
|
354
|
+
const minEvaluations = evaluatedCandidates.reduce(
|
|
320
355
|
(min, c) => Math.min(min, c.evaluationCount),
|
|
321
356
|
Infinity
|
|
322
357
|
);
|
|
323
358
|
|
|
324
|
-
|
|
359
|
+
const minRequired = this.config.minEvaluationsBeforeEvolution ?? 3;
|
|
360
|
+
if (minEvaluations < minRequired) return false;
|
|
325
361
|
|
|
326
362
|
const evaluationsSinceEvolution = this.history.filter(
|
|
327
|
-
(h) => h.timestamp > this.
|
|
363
|
+
(h) => h.timestamp > this.lastEvolutionTimestamp
|
|
328
364
|
).length;
|
|
329
365
|
|
|
330
|
-
return evaluationsSinceEvolution >=
|
|
366
|
+
return evaluationsSinceEvolution >= this.getEvaluationWindow();
|
|
331
367
|
}
|
|
332
368
|
|
|
333
|
-
private
|
|
334
|
-
return this.
|
|
369
|
+
private getEvaluationWindow(): number {
|
|
370
|
+
return Math.max(1, this.config.evaluationWindow ?? 10);
|
|
335
371
|
}
|
|
336
372
|
|
|
337
373
|
private getRelevantHistory(profile: TaskProfile): HistoricalRecord[] {
|
|
@@ -340,7 +376,7 @@ export class ParameterOptimizer {
|
|
|
340
376
|
(h) =>
|
|
341
377
|
h.taskProfile.domain === profile.domain || h.taskProfile.complexity === profile.complexity
|
|
342
378
|
)
|
|
343
|
-
.slice(-
|
|
379
|
+
.slice(-this.getEvaluationWindow());
|
|
344
380
|
}
|
|
345
381
|
|
|
346
382
|
private mergeConfigs(
|
|
@@ -418,13 +454,28 @@ export class ParameterOptimizer {
|
|
|
418
454
|
fields++;
|
|
419
455
|
}
|
|
420
456
|
|
|
457
|
+
if (
|
|
458
|
+
a.toolStrategy !== undefined &&
|
|
459
|
+
b.toolStrategy !== undefined &&
|
|
460
|
+
a.toolStrategy !== b.toolStrategy
|
|
461
|
+
) {
|
|
462
|
+
distance += 1;
|
|
463
|
+
fields++;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
if (a.reflectionDepth !== undefined && b.reflectionDepth !== undefined) {
|
|
467
|
+
distance += Math.abs(a.reflectionDepth - b.reflectionDepth) / 5;
|
|
468
|
+
fields++;
|
|
469
|
+
}
|
|
470
|
+
|
|
421
471
|
return fields > 0 ? distance / fields : 0;
|
|
422
472
|
}
|
|
423
473
|
|
|
424
474
|
private calculateConvergenceRate(): number {
|
|
425
|
-
|
|
475
|
+
const window = this.getEvaluationWindow();
|
|
476
|
+
if (this.history.length < window) return 0;
|
|
426
477
|
|
|
427
|
-
const recentScores = this.history.slice(-
|
|
478
|
+
const recentScores = this.history.slice(-window).map((h) => h.score);
|
|
428
479
|
const variance = this.calculateVariance(recentScores);
|
|
429
480
|
|
|
430
481
|
return Math.max(0, 1 - variance * 4);
|
|
@@ -471,30 +522,21 @@ export class ParameterOptimizer {
|
|
|
471
522
|
const prompt = buildPerformanceAnalysisPrompt(evaluatedCandidates, results);
|
|
472
523
|
|
|
473
524
|
try {
|
|
474
|
-
const
|
|
525
|
+
const content = await llmChat(
|
|
526
|
+
this.llm,
|
|
475
527
|
[
|
|
476
528
|
{ role: 'system', content: 'You are an AI performance analyst.' },
|
|
477
529
|
{ role: 'user', content: prompt },
|
|
478
530
|
],
|
|
479
|
-
0.2
|
|
531
|
+
{ model: this.model, temperature: 0.2 }
|
|
480
532
|
);
|
|
481
533
|
|
|
482
|
-
return parsePerformanceAnalysisResponse(
|
|
534
|
+
return parsePerformanceAnalysisResponse(content);
|
|
483
535
|
} catch {
|
|
484
536
|
return null;
|
|
485
537
|
}
|
|
486
538
|
}
|
|
487
539
|
|
|
488
|
-
private async callLLM(
|
|
489
|
-
messages: Array<{ role: 'system' | 'user' | 'assistant'; content: string }>,
|
|
490
|
-
temperature: number
|
|
491
|
-
) {
|
|
492
|
-
if (this.llm.complete) {
|
|
493
|
-
return this.llm.complete({ messages, temperature });
|
|
494
|
-
}
|
|
495
|
-
return this.llm.chat({ model: this.model, messages, temperature });
|
|
496
|
-
}
|
|
497
|
-
|
|
498
540
|
getCandidates(): EvolutionCandidate[] {
|
|
499
541
|
return [...this.candidates];
|
|
500
542
|
}
|