@cogitator-ai/self-modifying 0.1.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/LICENSE +21 -0
- package/README.md +714 -0
- package/dist/architecture-evolution/capability-analyzer.d.ts +32 -0
- package/dist/architecture-evolution/capability-analyzer.d.ts.map +1 -0
- package/dist/architecture-evolution/capability-analyzer.js +264 -0
- package/dist/architecture-evolution/capability-analyzer.js.map +1 -0
- package/dist/architecture-evolution/evolution-strategy.d.ts +29 -0
- package/dist/architecture-evolution/evolution-strategy.d.ts.map +1 -0
- package/dist/architecture-evolution/evolution-strategy.js +176 -0
- package/dist/architecture-evolution/evolution-strategy.js.map +1 -0
- package/dist/architecture-evolution/index.d.ts +5 -0
- package/dist/architecture-evolution/index.d.ts.map +1 -0
- package/dist/architecture-evolution/index.js +5 -0
- package/dist/architecture-evolution/index.js.map +1 -0
- package/dist/architecture-evolution/parameter-optimizer.d.ts +67 -0
- package/dist/architecture-evolution/parameter-optimizer.d.ts.map +1 -0
- package/dist/architecture-evolution/parameter-optimizer.js +341 -0
- package/dist/architecture-evolution/parameter-optimizer.js.map +1 -0
- package/dist/architecture-evolution/prompts.d.ts +33 -0
- package/dist/architecture-evolution/prompts.d.ts.map +1 -0
- package/dist/architecture-evolution/prompts.js +169 -0
- package/dist/architecture-evolution/prompts.js.map +1 -0
- package/dist/constraints/index.d.ts +4 -0
- package/dist/constraints/index.d.ts.map +1 -0
- package/dist/constraints/index.js +4 -0
- package/dist/constraints/index.js.map +1 -0
- package/dist/constraints/modification-validator.d.ts +26 -0
- package/dist/constraints/modification-validator.d.ts.map +1 -0
- package/dist/constraints/modification-validator.js +313 -0
- package/dist/constraints/modification-validator.js.map +1 -0
- package/dist/constraints/rollback-manager.d.ts +52 -0
- package/dist/constraints/rollback-manager.d.ts.map +1 -0
- package/dist/constraints/rollback-manager.js +113 -0
- package/dist/constraints/rollback-manager.js.map +1 -0
- package/dist/constraints/safety-constraints.d.ts +11 -0
- package/dist/constraints/safety-constraints.d.ts.map +1 -0
- package/dist/constraints/safety-constraints.js +78 -0
- package/dist/constraints/safety-constraints.js.map +1 -0
- package/dist/events/event-emitter.d.ts +12 -0
- package/dist/events/event-emitter.d.ts.map +1 -0
- package/dist/events/event-emitter.js +43 -0
- package/dist/events/event-emitter.js.map +1 -0
- package/dist/events/index.d.ts +2 -0
- package/dist/events/index.d.ts.map +1 -0
- package/dist/events/index.js +2 -0
- package/dist/events/index.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/meta-reasoning/index.d.ts +5 -0
- package/dist/meta-reasoning/index.d.ts.map +1 -0
- package/dist/meta-reasoning/index.js +5 -0
- package/dist/meta-reasoning/index.js.map +1 -0
- package/dist/meta-reasoning/meta-reasoner.d.ts +53 -0
- package/dist/meta-reasoning/meta-reasoner.d.ts.map +1 -0
- package/dist/meta-reasoning/meta-reasoner.js +261 -0
- package/dist/meta-reasoning/meta-reasoner.js.map +1 -0
- package/dist/meta-reasoning/observation-collector.d.ts +37 -0
- package/dist/meta-reasoning/observation-collector.d.ts.map +1 -0
- package/dist/meta-reasoning/observation-collector.js +123 -0
- package/dist/meta-reasoning/observation-collector.js.map +1 -0
- package/dist/meta-reasoning/prompts.d.ts +31 -0
- package/dist/meta-reasoning/prompts.d.ts.map +1 -0
- package/dist/meta-reasoning/prompts.js +96 -0
- package/dist/meta-reasoning/prompts.js.map +1 -0
- package/dist/meta-reasoning/strategy-selector.d.ts +27 -0
- package/dist/meta-reasoning/strategy-selector.d.ts.map +1 -0
- package/dist/meta-reasoning/strategy-selector.js +138 -0
- package/dist/meta-reasoning/strategy-selector.js.map +1 -0
- package/dist/self-modifying-agent.d.ts +61 -0
- package/dist/self-modifying-agent.d.ts.map +1 -0
- package/dist/self-modifying-agent.js +449 -0
- package/dist/self-modifying-agent.js.map +1 -0
- package/dist/tool-generation/gap-analyzer.d.ts +25 -0
- package/dist/tool-generation/gap-analyzer.d.ts.map +1 -0
- package/dist/tool-generation/gap-analyzer.js +153 -0
- package/dist/tool-generation/gap-analyzer.js.map +1 -0
- package/dist/tool-generation/generated-tool-store.d.ts +51 -0
- package/dist/tool-generation/generated-tool-store.d.ts.map +1 -0
- package/dist/tool-generation/generated-tool-store.js +195 -0
- package/dist/tool-generation/generated-tool-store.js.map +1 -0
- package/dist/tool-generation/index.d.ts +7 -0
- package/dist/tool-generation/index.d.ts.map +1 -0
- package/dist/tool-generation/index.js +7 -0
- package/dist/tool-generation/index.js.map +1 -0
- package/dist/tool-generation/prompts.d.ts +28 -0
- package/dist/tool-generation/prompts.d.ts.map +1 -0
- package/dist/tool-generation/prompts.js +269 -0
- package/dist/tool-generation/prompts.js.map +1 -0
- package/dist/tool-generation/tool-generator.d.ts +29 -0
- package/dist/tool-generation/tool-generator.d.ts.map +1 -0
- package/dist/tool-generation/tool-generator.js +169 -0
- package/dist/tool-generation/tool-generator.js.map +1 -0
- package/dist/tool-generation/tool-sandbox.d.ts +31 -0
- package/dist/tool-generation/tool-sandbox.d.ts.map +1 -0
- package/dist/tool-generation/tool-sandbox.js +240 -0
- package/dist/tool-generation/tool-sandbox.js.map +1 -0
- package/dist/tool-generation/tool-validator.d.ts +32 -0
- package/dist/tool-generation/tool-validator.d.ts.map +1 -0
- package/dist/tool-generation/tool-validator.js +304 -0
- package/dist/tool-generation/tool-validator.js.map +1 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +2 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/llm-helper.d.ts +6 -0
- package/dist/utils/llm-helper.d.ts.map +1 -0
- package/dist/utils/llm-helper.js +18 -0
- package/dist/utils/llm-helper.js.map +1 -0
- package/package.json +61 -0
- package/src/__tests__/architecture-evolution.test.ts +368 -0
- package/src/__tests__/constraints.test.ts +266 -0
- package/src/__tests__/index.test.ts +99 -0
- package/src/__tests__/meta-reasoning.test.ts +343 -0
- package/src/__tests__/tool-generation.test.ts +455 -0
- package/src/architecture-evolution/capability-analyzer.ts +337 -0
- package/src/architecture-evolution/evolution-strategy.ts +224 -0
- package/src/architecture-evolution/index.ts +26 -0
- package/src/architecture-evolution/parameter-optimizer.ts +489 -0
- package/src/architecture-evolution/prompts.ts +216 -0
- package/src/constraints/index.ts +23 -0
- package/src/constraints/modification-validator.ts +402 -0
- package/src/constraints/rollback-manager.ts +173 -0
- package/src/constraints/safety-constraints.ts +103 -0
- package/src/events/event-emitter.ts +62 -0
- package/src/events/index.ts +1 -0
- package/src/index.ts +112 -0
- package/src/meta-reasoning/index.ts +24 -0
- package/src/meta-reasoning/meta-reasoner.ts +381 -0
- package/src/meta-reasoning/observation-collector.ts +161 -0
- package/src/meta-reasoning/prompts.ts +131 -0
- package/src/meta-reasoning/strategy-selector.ts +179 -0
- package/src/self-modifying-agent.ts +585 -0
- package/src/tool-generation/gap-analyzer.ts +234 -0
- package/src/tool-generation/generated-tool-store.ts +268 -0
- package/src/tool-generation/index.ts +19 -0
- package/src/tool-generation/prompts.ts +308 -0
- package/src/tool-generation/tool-generator.ts +243 -0
- package/src/tool-generation/tool-sandbox.ts +332 -0
- package/src/tool-generation/tool-validator.ts +365 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/llm-helper.ts +24 -0
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
import type { Tool, LLMBackend, TaskProfile } from '@cogitator-ai/types';
|
|
2
|
+
import { buildTaskProfilePrompt, parseTaskProfileResponse } from './prompts';
|
|
3
|
+
|
|
4
|
+
export interface CapabilityAnalyzerOptions {
|
|
5
|
+
llm?: LLMBackend;
|
|
6
|
+
enableLLMAnalysis?: boolean;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
interface DomainKeywords {
|
|
10
|
+
coding: string[];
|
|
11
|
+
reasoning: string[];
|
|
12
|
+
creative: string[];
|
|
13
|
+
factual: string[];
|
|
14
|
+
conversational: string[];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const DOMAIN_KEYWORDS: DomainKeywords = {
|
|
18
|
+
coding: [
|
|
19
|
+
'code', 'program', 'function', 'class', 'debug', 'implement', 'refactor',
|
|
20
|
+
'typescript', 'javascript', 'python', 'api', 'database', 'sql', 'algorithm',
|
|
21
|
+
'data structure', 'compile', 'syntax', 'bug', 'error', 'test', 'unit test',
|
|
22
|
+
],
|
|
23
|
+
reasoning: [
|
|
24
|
+
'analyze', 'reason', 'logic', 'deduce', 'infer', 'solve', 'problem',
|
|
25
|
+
'strategy', 'plan', 'decision', 'evaluate', 'compare', 'trade-off',
|
|
26
|
+
'optimize', 'proof', 'argument', 'conclusion', 'hypothesis',
|
|
27
|
+
],
|
|
28
|
+
creative: [
|
|
29
|
+
'create', 'imagine', 'story', 'poem', 'write', 'design', 'brainstorm',
|
|
30
|
+
'innovative', 'novel', 'artistic', 'compose', 'invent', 'original',
|
|
31
|
+
'creative', 'fiction', 'narrative', 'metaphor', 'style',
|
|
32
|
+
],
|
|
33
|
+
factual: [
|
|
34
|
+
'what is', 'define', 'explain', 'describe', 'list', 'fact', 'information',
|
|
35
|
+
'history', 'science', 'data', 'statistic', 'research', 'study', 'source',
|
|
36
|
+
'reference', 'accurate', 'true', 'correct',
|
|
37
|
+
],
|
|
38
|
+
conversational: [
|
|
39
|
+
'chat', 'talk', 'hello', 'hi', 'thanks', 'please', 'help', 'assist',
|
|
40
|
+
'question', 'answer', 'discuss', 'conversation', 'opinion',
|
|
41
|
+
],
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const COMPLEXITY_INDICATORS = {
|
|
45
|
+
trivial: ['simple', 'quick', 'easy', 'basic', 'straightforward'],
|
|
46
|
+
simple: ['explain', 'define', 'list', 'describe', 'show'],
|
|
47
|
+
moderate: ['compare', 'analyze', 'summarize', 'evaluate', 'implement'],
|
|
48
|
+
complex: ['design', 'architect', 'optimize', 'comprehensive', 'detailed'],
|
|
49
|
+
extreme: ['novel', 'research', 'breakthrough', 'state-of-the-art', 'cutting-edge'],
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export class CapabilityAnalyzer {
|
|
53
|
+
private readonly llm?: LLMBackend;
|
|
54
|
+
private readonly enableLLMAnalysis: boolean;
|
|
55
|
+
private readonly profileCache = new Map<string, { profile: TaskProfile; timestamp: number }>();
|
|
56
|
+
private readonly cacheTTL = 60000;
|
|
57
|
+
|
|
58
|
+
constructor(options: CapabilityAnalyzerOptions = {}) {
|
|
59
|
+
this.llm = options.llm;
|
|
60
|
+
this.enableLLMAnalysis = options.enableLLMAnalysis ?? false;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async analyzeTask(
|
|
64
|
+
taskDescription: string,
|
|
65
|
+
context?: {
|
|
66
|
+
availableTools?: Tool[];
|
|
67
|
+
previousTasks?: string[];
|
|
68
|
+
constraints?: { maxCost?: number; maxLatency?: number };
|
|
69
|
+
}
|
|
70
|
+
): Promise<TaskProfile> {
|
|
71
|
+
const cacheKey = this.buildCacheKey(taskDescription);
|
|
72
|
+
const cached = this.profileCache.get(cacheKey);
|
|
73
|
+
if (cached && Date.now() - cached.timestamp < this.cacheTTL) {
|
|
74
|
+
return cached.profile;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
let profile: TaskProfile;
|
|
78
|
+
|
|
79
|
+
if (this.llm && this.enableLLMAnalysis) {
|
|
80
|
+
profile = await this.analyzWithLLM(taskDescription, context);
|
|
81
|
+
} else {
|
|
82
|
+
profile = this.analyzeHeuristically(taskDescription, context?.availableTools);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
this.profileCache.set(cacheKey, { profile, timestamp: Date.now() });
|
|
86
|
+
|
|
87
|
+
if (this.profileCache.size > 100) {
|
|
88
|
+
const entries = Array.from(this.profileCache.entries());
|
|
89
|
+
entries.sort((a, b) => a[1].timestamp - b[1].timestamp);
|
|
90
|
+
entries.slice(0, 20).forEach(([key]) => this.profileCache.delete(key));
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return profile;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
private async analyzWithLLM(
|
|
97
|
+
taskDescription: string,
|
|
98
|
+
context?: {
|
|
99
|
+
availableTools?: Tool[];
|
|
100
|
+
previousTasks?: string[];
|
|
101
|
+
constraints?: { maxCost?: number; maxLatency?: number };
|
|
102
|
+
}
|
|
103
|
+
): Promise<TaskProfile> {
|
|
104
|
+
const llm = this.llm;
|
|
105
|
+
if (!llm) {
|
|
106
|
+
return this.analyzeHeuristically(taskDescription, context?.availableTools);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
try {
|
|
110
|
+
const prompt = buildTaskProfilePrompt(taskDescription, {
|
|
111
|
+
previousTasks: context?.previousTasks,
|
|
112
|
+
constraints: context?.constraints,
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
const response = llm.complete
|
|
116
|
+
? await llm.complete({
|
|
117
|
+
messages: [
|
|
118
|
+
{
|
|
119
|
+
role: 'system',
|
|
120
|
+
content: 'You are a task analysis expert. Analyze tasks and determine their characteristics.',
|
|
121
|
+
},
|
|
122
|
+
{ role: 'user', content: prompt },
|
|
123
|
+
],
|
|
124
|
+
temperature: 0.2,
|
|
125
|
+
})
|
|
126
|
+
: await llm.chat({
|
|
127
|
+
model: 'default',
|
|
128
|
+
messages: [
|
|
129
|
+
{
|
|
130
|
+
role: 'system',
|
|
131
|
+
content: 'You are a task analysis expert. Analyze tasks and determine their characteristics.',
|
|
132
|
+
},
|
|
133
|
+
{ role: 'user', content: prompt },
|
|
134
|
+
],
|
|
135
|
+
temperature: 0.2,
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
const parsed = parseTaskProfileResponse(response.content);
|
|
139
|
+
if (parsed) {
|
|
140
|
+
return parsed;
|
|
141
|
+
}
|
|
142
|
+
} catch {
|
|
143
|
+
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return this.analyzeHeuristically(taskDescription, context?.availableTools);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
private analyzeHeuristically(
|
|
150
|
+
taskDescription: string,
|
|
151
|
+
availableTools?: Tool[]
|
|
152
|
+
): TaskProfile {
|
|
153
|
+
const lowerTask = taskDescription.toLowerCase();
|
|
154
|
+
const words = lowerTask.split(/\s+/);
|
|
155
|
+
const wordCount = words.length;
|
|
156
|
+
|
|
157
|
+
const domain = this.detectDomain(lowerTask);
|
|
158
|
+
const complexity = this.detectComplexity(lowerTask, wordCount);
|
|
159
|
+
const toolAnalysis = this.analyzeToolRequirements(lowerTask, availableTools);
|
|
160
|
+
|
|
161
|
+
return {
|
|
162
|
+
complexity,
|
|
163
|
+
domain,
|
|
164
|
+
estimatedTokens: this.estimateTokens(wordCount, complexity),
|
|
165
|
+
requiresTools: toolAnalysis.requiresTools,
|
|
166
|
+
toolIntensity: toolAnalysis.intensity,
|
|
167
|
+
reasoningDepth: this.estimateReasoningDepth(complexity, domain),
|
|
168
|
+
creativityLevel: domain === 'creative' ? 'high' : complexity === 'trivial' ? 'low' : 'moderate',
|
|
169
|
+
accuracyRequirement: this.estimateAccuracyRequirement(domain, lowerTask),
|
|
170
|
+
timeConstraint: this.detectTimeConstraint(lowerTask),
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
private detectDomain(task: string): TaskProfile['domain'] {
|
|
175
|
+
const scores: Record<string, number> = {
|
|
176
|
+
coding: 0,
|
|
177
|
+
reasoning: 0,
|
|
178
|
+
creative: 0,
|
|
179
|
+
factual: 0,
|
|
180
|
+
conversational: 0,
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
for (const [domain, keywords] of Object.entries(DOMAIN_KEYWORDS)) {
|
|
184
|
+
for (const keyword of keywords) {
|
|
185
|
+
if (task.includes(keyword)) {
|
|
186
|
+
scores[domain] += keyword.length > 5 ? 2 : 1;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
const maxDomain = Object.entries(scores).reduce((a, b) => (b[1] > a[1] ? b : a));
|
|
192
|
+
if (maxDomain[1] === 0) return 'general';
|
|
193
|
+
return maxDomain[0] as TaskProfile['domain'];
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
private detectComplexity(task: string, wordCount: number): TaskProfile['complexity'] {
|
|
197
|
+
for (const [level, indicators] of Object.entries(COMPLEXITY_INDICATORS).reverse()) {
|
|
198
|
+
for (const indicator of indicators) {
|
|
199
|
+
if (task.includes(indicator)) {
|
|
200
|
+
return level as TaskProfile['complexity'];
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
if (wordCount < 10) return 'trivial';
|
|
206
|
+
if (wordCount < 30) return 'simple';
|
|
207
|
+
if (wordCount < 100) return 'moderate';
|
|
208
|
+
if (wordCount < 300) return 'complex';
|
|
209
|
+
return 'extreme';
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
private analyzeToolRequirements(
|
|
213
|
+
task: string,
|
|
214
|
+
availableTools?: Tool[]
|
|
215
|
+
): { requiresTools: boolean; intensity: TaskProfile['toolIntensity'] } {
|
|
216
|
+
const toolIndicators = [
|
|
217
|
+
'calculate', 'search', 'fetch', 'query', 'lookup', 'find',
|
|
218
|
+
'execute', 'run', 'call', 'invoke', 'use tool',
|
|
219
|
+
];
|
|
220
|
+
|
|
221
|
+
let toolMentions = 0;
|
|
222
|
+
for (const indicator of toolIndicators) {
|
|
223
|
+
if (task.includes(indicator)) {
|
|
224
|
+
toolMentions++;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
if (availableTools?.length) {
|
|
229
|
+
for (const tool of availableTools) {
|
|
230
|
+
if (task.includes(tool.name.toLowerCase())) {
|
|
231
|
+
toolMentions += 2;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
if (toolMentions === 0) {
|
|
237
|
+
return { requiresTools: false, intensity: 'none' };
|
|
238
|
+
}
|
|
239
|
+
if (toolMentions <= 2) {
|
|
240
|
+
return { requiresTools: true, intensity: 'light' };
|
|
241
|
+
}
|
|
242
|
+
if (toolMentions <= 5) {
|
|
243
|
+
return { requiresTools: true, intensity: 'moderate' };
|
|
244
|
+
}
|
|
245
|
+
return { requiresTools: true, intensity: 'heavy' };
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
private estimateTokens(wordCount: number, complexity: TaskProfile['complexity']): number {
|
|
249
|
+
const baseMultiplier: Record<TaskProfile['complexity'], number> = {
|
|
250
|
+
trivial: 2,
|
|
251
|
+
simple: 3,
|
|
252
|
+
moderate: 5,
|
|
253
|
+
complex: 8,
|
|
254
|
+
extreme: 12,
|
|
255
|
+
expert: 15,
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
return Math.min(
|
|
259
|
+
wordCount * baseMultiplier[complexity] + 200,
|
|
260
|
+
32000
|
|
261
|
+
);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
private estimateReasoningDepth(
|
|
265
|
+
complexity: TaskProfile['complexity'],
|
|
266
|
+
domain: TaskProfile['domain']
|
|
267
|
+
): TaskProfile['reasoningDepth'] {
|
|
268
|
+
if (domain === 'reasoning') {
|
|
269
|
+
return complexity === 'trivial' ? 'moderate' : complexity === 'simple' ? 'deep' : 'exhaustive';
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
switch (complexity) {
|
|
273
|
+
case 'trivial':
|
|
274
|
+
return 'shallow';
|
|
275
|
+
case 'simple':
|
|
276
|
+
return 'shallow';
|
|
277
|
+
case 'moderate':
|
|
278
|
+
return 'moderate';
|
|
279
|
+
case 'complex':
|
|
280
|
+
return 'deep';
|
|
281
|
+
case 'extreme':
|
|
282
|
+
case 'expert':
|
|
283
|
+
return 'exhaustive';
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
private estimateAccuracyRequirement(
|
|
288
|
+
domain: TaskProfile['domain'],
|
|
289
|
+
task: string
|
|
290
|
+
): TaskProfile['accuracyRequirement'] {
|
|
291
|
+
if (domain === 'coding' || domain === 'factual') {
|
|
292
|
+
return 'high';
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
const criticalIndicators = ['critical', 'exact', 'precise', 'must be correct', 'no errors'];
|
|
296
|
+
for (const indicator of criticalIndicators) {
|
|
297
|
+
if (task.includes(indicator)) {
|
|
298
|
+
return 'critical';
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
const approximateIndicators = ['rough', 'approximate', 'estimate', 'about', 'roughly'];
|
|
303
|
+
for (const indicator of approximateIndicators) {
|
|
304
|
+
if (task.includes(indicator)) {
|
|
305
|
+
return 'approximate';
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
return 'moderate';
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
private detectTimeConstraint(task: string): TaskProfile['timeConstraint'] {
|
|
313
|
+
const strictIndicators = ['urgent', 'asap', 'immediately', 'right now', 'hurry'];
|
|
314
|
+
const moderateIndicators = ['soon', 'quickly', 'fast', 'today'];
|
|
315
|
+
const relaxedIndicators = ['when possible', 'eventually', 'no rush'];
|
|
316
|
+
|
|
317
|
+
for (const indicator of strictIndicators) {
|
|
318
|
+
if (task.includes(indicator)) return 'strict';
|
|
319
|
+
}
|
|
320
|
+
for (const indicator of moderateIndicators) {
|
|
321
|
+
if (task.includes(indicator)) return 'moderate';
|
|
322
|
+
}
|
|
323
|
+
for (const indicator of relaxedIndicators) {
|
|
324
|
+
if (task.includes(indicator)) return 'relaxed';
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
return 'none';
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
private buildCacheKey(task: string): string {
|
|
331
|
+
return task.slice(0, 200).toLowerCase().replace(/\s+/g, ' ').trim();
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
clearCache(): void {
|
|
335
|
+
this.profileCache.clear();
|
|
336
|
+
}
|
|
337
|
+
}
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import type { EvolutionCandidate, EvolutionStrategy as IEvolutionStrategy } from '@cogitator-ai/types';
|
|
2
|
+
|
|
3
|
+
export interface EvolutionStrategyOptions {
|
|
4
|
+
strategy: IEvolutionStrategy;
|
|
5
|
+
explorationBonus?: number;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface SelectionResult {
|
|
9
|
+
candidate: EvolutionCandidate;
|
|
10
|
+
score: number;
|
|
11
|
+
isExploration: boolean;
|
|
12
|
+
reasoning: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export class EvolutionStrategy {
|
|
16
|
+
private readonly strategy: IEvolutionStrategy;
|
|
17
|
+
private readonly explorationBonus: number;
|
|
18
|
+
private totalSelections = 0;
|
|
19
|
+
|
|
20
|
+
constructor(options: EvolutionStrategyOptions) {
|
|
21
|
+
this.strategy = options.strategy;
|
|
22
|
+
this.explorationBonus = options.explorationBonus ?? 2.0;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
select(candidates: EvolutionCandidate[]): SelectionResult {
|
|
26
|
+
if (candidates.length === 0) {
|
|
27
|
+
throw new Error('No candidates to select from');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (candidates.length === 1) {
|
|
31
|
+
return {
|
|
32
|
+
candidate: candidates[0],
|
|
33
|
+
score: candidates[0].score,
|
|
34
|
+
isExploration: false,
|
|
35
|
+
reasoning: 'Only one candidate available',
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
this.totalSelections++;
|
|
40
|
+
|
|
41
|
+
switch (this.strategy.type) {
|
|
42
|
+
case 'epsilon_greedy':
|
|
43
|
+
return this.epsilonGreedy(candidates);
|
|
44
|
+
case 'ucb':
|
|
45
|
+
return this.upperConfidenceBound(candidates);
|
|
46
|
+
case 'thompson_sampling':
|
|
47
|
+
return this.thompsonSampling(candidates);
|
|
48
|
+
default:
|
|
49
|
+
return this.epsilonGreedy(candidates);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
private epsilonGreedy(candidates: EvolutionCandidate[]): SelectionResult {
|
|
54
|
+
const epsilon = this.strategy.epsilon ?? 0.1;
|
|
55
|
+
const isExploration = Math.random() < epsilon;
|
|
56
|
+
|
|
57
|
+
if (isExploration) {
|
|
58
|
+
const unexplored = candidates.filter((c) => c.evaluationCount === 0);
|
|
59
|
+
if (unexplored.length > 0) {
|
|
60
|
+
const candidate = unexplored[Math.floor(Math.random() * unexplored.length)];
|
|
61
|
+
return {
|
|
62
|
+
candidate,
|
|
63
|
+
score: 0,
|
|
64
|
+
isExploration: true,
|
|
65
|
+
reasoning: `Epsilon-greedy exploration: selected unexplored candidate ${candidate.id}`,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const candidate = candidates[Math.floor(Math.random() * candidates.length)];
|
|
70
|
+
return {
|
|
71
|
+
candidate,
|
|
72
|
+
score: candidate.score,
|
|
73
|
+
isExploration: true,
|
|
74
|
+
reasoning: `Epsilon-greedy exploration: randomly selected ${candidate.id}`,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const best = candidates.reduce((a, b) => (b.score > a.score ? b : a));
|
|
79
|
+
return {
|
|
80
|
+
candidate: best,
|
|
81
|
+
score: best.score,
|
|
82
|
+
isExploration: false,
|
|
83
|
+
reasoning: `Epsilon-greedy exploitation: selected best scoring ${best.id} (score: ${best.score.toFixed(3)})`,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
private upperConfidenceBound(candidates: EvolutionCandidate[]): SelectionResult {
|
|
88
|
+
const c = this.strategy.explorationConstant ?? this.explorationBonus;
|
|
89
|
+
|
|
90
|
+
const ucbScores = candidates.map((candidate) => {
|
|
91
|
+
if (candidate.evaluationCount === 0) {
|
|
92
|
+
return { candidate, ucb: Infinity, isExploration: true };
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const exploitation = candidate.score;
|
|
96
|
+
const exploration = c * Math.sqrt(Math.log(this.totalSelections + 1) / candidate.evaluationCount);
|
|
97
|
+
const ucb = exploitation + exploration;
|
|
98
|
+
|
|
99
|
+
return { candidate, ucb, isExploration: exploration > exploitation };
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
const best = ucbScores.reduce((a, b) => (b.ucb > a.ucb ? b : a));
|
|
103
|
+
|
|
104
|
+
return {
|
|
105
|
+
candidate: best.candidate,
|
|
106
|
+
score: best.ucb === Infinity ? 0 : best.ucb,
|
|
107
|
+
isExploration: best.isExploration,
|
|
108
|
+
reasoning: best.ucb === Infinity
|
|
109
|
+
? `UCB: selected unexplored candidate ${best.candidate.id}`
|
|
110
|
+
: `UCB: selected ${best.candidate.id} with UCB score ${best.ucb.toFixed(3)} (base: ${best.candidate.score.toFixed(3)}, exploration bonus)`,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
private thompsonSampling(candidates: EvolutionCandidate[]): SelectionResult {
|
|
115
|
+
const samples = candidates.map((candidate) => {
|
|
116
|
+
const alpha = candidate.evaluationCount > 0
|
|
117
|
+
? candidate.score * candidate.evaluationCount + 1
|
|
118
|
+
: 1;
|
|
119
|
+
const beta = candidate.evaluationCount > 0
|
|
120
|
+
? (1 - candidate.score) * candidate.evaluationCount + 1
|
|
121
|
+
: 1;
|
|
122
|
+
|
|
123
|
+
const sample = this.sampleBeta(alpha, beta);
|
|
124
|
+
|
|
125
|
+
return { candidate, sample };
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
const best = samples.reduce((a, b) => (b.sample > a.sample ? b : a));
|
|
129
|
+
const isExploration = best.candidate.evaluationCount < 3;
|
|
130
|
+
|
|
131
|
+
return {
|
|
132
|
+
candidate: best.candidate,
|
|
133
|
+
score: best.sample,
|
|
134
|
+
isExploration,
|
|
135
|
+
reasoning: `Thompson sampling: selected ${best.candidate.id} with sample ${best.sample.toFixed(3)} (evals: ${best.candidate.evaluationCount})`,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
private sampleBeta(alpha: number, beta: number): number {
|
|
140
|
+
const gammaA = this.sampleGamma(alpha);
|
|
141
|
+
const gammaB = this.sampleGamma(beta);
|
|
142
|
+
return gammaA / (gammaA + gammaB);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
private sampleGamma(shape: number): number {
|
|
146
|
+
if (shape < 1) {
|
|
147
|
+
return this.sampleGamma(shape + 1) * Math.pow(Math.random(), 1 / shape);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const d = shape - 1 / 3;
|
|
151
|
+
const c = 1 / Math.sqrt(9 * d);
|
|
152
|
+
|
|
153
|
+
while (true) {
|
|
154
|
+
let x: number;
|
|
155
|
+
let v: number;
|
|
156
|
+
|
|
157
|
+
do {
|
|
158
|
+
x = this.sampleNormal();
|
|
159
|
+
v = 1 + c * x;
|
|
160
|
+
} while (v <= 0);
|
|
161
|
+
|
|
162
|
+
v = v * v * v;
|
|
163
|
+
const u = Math.random();
|
|
164
|
+
|
|
165
|
+
if (u < 1 - 0.0331 * (x * x) * (x * x)) {
|
|
166
|
+
return d * v;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (Math.log(u) < 0.5 * x * x + d * (1 - v + Math.log(v))) {
|
|
170
|
+
return d * v;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
private sampleNormal(): number {
|
|
176
|
+
const u1 = Math.random();
|
|
177
|
+
const u2 = Math.random();
|
|
178
|
+
return Math.sqrt(-2 * Math.log(u1)) * Math.cos(2 * Math.PI * u2);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
updateCandidate(candidate: EvolutionCandidate, reward: number): void {
|
|
182
|
+
const oldScore = candidate.score;
|
|
183
|
+
const oldCount = candidate.evaluationCount;
|
|
184
|
+
|
|
185
|
+
candidate.evaluationCount++;
|
|
186
|
+
candidate.score = (oldScore * oldCount + reward) / candidate.evaluationCount;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
getExplorationRate(): number {
|
|
190
|
+
if (this.totalSelections === 0) return 1;
|
|
191
|
+
|
|
192
|
+
switch (this.strategy.type) {
|
|
193
|
+
case 'epsilon_greedy':
|
|
194
|
+
return this.strategy.epsilon ?? 0.1;
|
|
195
|
+
case 'ucb':
|
|
196
|
+
return Math.min(1, (this.strategy.explorationConstant ?? 2) / Math.sqrt(this.totalSelections));
|
|
197
|
+
case 'thompson_sampling':
|
|
198
|
+
return 0.5;
|
|
199
|
+
default:
|
|
200
|
+
return 0.1;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
shouldExploreMore(candidates: EvolutionCandidate[]): boolean {
|
|
205
|
+
const unexploredCount = candidates.filter((c) => c.evaluationCount === 0).length;
|
|
206
|
+
if (unexploredCount > 0) return true;
|
|
207
|
+
|
|
208
|
+
const avgEvaluations = candidates.reduce((sum, c) => sum + c.evaluationCount, 0) / candidates.length;
|
|
209
|
+
if (avgEvaluations < 5) return true;
|
|
210
|
+
|
|
211
|
+
const scores = candidates.map((c) => c.score);
|
|
212
|
+
const maxScore = Math.max(...scores);
|
|
213
|
+
const minScore = Math.min(...scores);
|
|
214
|
+
const scoreRange = maxScore - minScore;
|
|
215
|
+
|
|
216
|
+
if (scoreRange > 0.3) return true;
|
|
217
|
+
|
|
218
|
+
return false;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
reset(): void {
|
|
222
|
+
this.totalSelections = 0;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export {
|
|
2
|
+
CapabilityAnalyzer,
|
|
3
|
+
type CapabilityAnalyzerOptions,
|
|
4
|
+
} from './capability-analyzer';
|
|
5
|
+
|
|
6
|
+
export {
|
|
7
|
+
EvolutionStrategy,
|
|
8
|
+
type EvolutionStrategyOptions,
|
|
9
|
+
type SelectionResult,
|
|
10
|
+
} from './evolution-strategy';
|
|
11
|
+
|
|
12
|
+
export {
|
|
13
|
+
ParameterOptimizer,
|
|
14
|
+
type ParameterOptimizerOptions,
|
|
15
|
+
type OptimizationResult,
|
|
16
|
+
} from './parameter-optimizer';
|
|
17
|
+
|
|
18
|
+
export {
|
|
19
|
+
buildTaskProfilePrompt,
|
|
20
|
+
buildCandidateGenerationPrompt,
|
|
21
|
+
buildPerformanceAnalysisPrompt,
|
|
22
|
+
parseTaskProfileResponse,
|
|
23
|
+
parseCandidateGenerationResponse,
|
|
24
|
+
parsePerformanceAnalysisResponse,
|
|
25
|
+
ARCHITECTURE_ANALYSIS_SYSTEM_PROMPT,
|
|
26
|
+
} from './prompts';
|