@cogitator-ai/self-modifying 17.0.5 → 17.0.10
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 +42 -1
- package/dist/architecture-evolution/capability-analyzer.d.ts +1 -1
- package/dist/architecture-evolution/capability-analyzer.d.ts.map +1 -1
- package/dist/architecture-evolution/capability-analyzer.js +4 -3
- 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 +3 -2
- package/dist/architecture-evolution/evolution-strategy.js.map +1 -1
- package/dist/architecture-evolution/parameter-optimizer.d.ts +1 -0
- package/dist/architecture-evolution/parameter-optimizer.d.ts.map +1 -1
- package/dist/architecture-evolution/parameter-optimizer.js +7 -4
- package/dist/architecture-evolution/parameter-optimizer.js.map +1 -1
- package/dist/architecture-evolution/prompts.d.ts.map +1 -1
- package/dist/architecture-evolution/prompts.js +7 -6
- package/dist/architecture-evolution/prompts.js.map +1 -1
- package/dist/constraints/index.d.ts +1 -1
- package/dist/constraints/index.d.ts.map +1 -1
- package/dist/constraints/index.js +1 -1
- package/dist/constraints/index.js.map +1 -1
- package/dist/constraints/modification-validator.d.ts.map +1 -1
- package/dist/constraints/modification-validator.js +13 -22
- package/dist/constraints/modification-validator.js.map +1 -1
- package/dist/constraints/safety-constraints.d.ts +2 -1
- package/dist/constraints/safety-constraints.d.ts.map +1 -1
- package/dist/constraints/safety-constraints.js +11 -1
- package/dist/constraints/safety-constraints.js.map +1 -1
- package/dist/events/event-emitter.d.ts.map +1 -1
- package/dist/events/event-emitter.js +8 -1
- package/dist/events/event-emitter.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/meta-reasoning/meta-reasoner.d.ts.map +1 -1
- package/dist/meta-reasoning/meta-reasoner.js +6 -0
- package/dist/meta-reasoning/meta-reasoner.js.map +1 -1
- package/dist/meta-reasoning/prompts.d.ts.map +1 -1
- package/dist/meta-reasoning/prompts.js +37 -3
- package/dist/meta-reasoning/prompts.js.map +1 -1
- package/dist/self-modifying-agent.d.ts +1 -1
- package/dist/self-modifying-agent.d.ts.map +1 -1
- package/dist/self-modifying-agent.js +57 -10
- package/dist/self-modifying-agent.js.map +1 -1
- package/dist/tool-generation/generated-tool-store.d.ts.map +1 -1
- package/dist/tool-generation/generated-tool-store.js +2 -4
- package/dist/tool-generation/generated-tool-store.js.map +1 -1
- package/dist/tool-generation/prompts.d.ts.map +1 -1
- package/dist/tool-generation/prompts.js +10 -9
- package/dist/tool-generation/prompts.js.map +1 -1
- package/dist/tool-generation/tool-generator.d.ts +1 -1
- package/dist/tool-generation/tool-generator.d.ts.map +1 -1
- package/dist/tool-generation/tool-generator.js +12 -13
- package/dist/tool-generation/tool-generator.js.map +1 -1
- package/dist/tool-generation/tool-sandbox.d.ts.map +1 -1
- package/dist/tool-generation/tool-sandbox.js +6 -2
- package/dist/tool-generation/tool-sandbox.js.map +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +34 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/llm-helper.d.ts +1 -0
- package/dist/utils/llm-helper.d.ts.map +1 -1
- package/dist/utils/llm-helper.js +1 -1
- package/dist/utils/llm-helper.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/events.test.ts +112 -0
- package/src/__tests__/utils.test.ts +100 -0
- package/src/architecture-evolution/capability-analyzer.ts +5 -3
- package/src/architecture-evolution/evolution-strategy.ts +3 -2
- package/src/architecture-evolution/parameter-optimizer.ts +8 -7
- package/src/architecture-evolution/prompts.ts +7 -6
- package/src/constraints/index.ts +1 -0
- package/src/constraints/modification-validator.ts +14 -23
- package/src/constraints/safety-constraints.ts +16 -1
- package/src/events/event-emitter.ts +9 -1
- package/src/index.ts +3 -0
- package/src/meta-reasoning/meta-reasoner.ts +9 -0
- package/src/meta-reasoning/prompts.ts +43 -3
- package/src/self-modifying-agent.ts +58 -10
- package/src/tool-generation/generated-tool-store.ts +2 -4
- package/src/tool-generation/prompts.ts +10 -9
- package/src/tool-generation/tool-generator.ts +13 -15
- package/src/tool-generation/tool-sandbox.ts +12 -2
- package/src/utils/index.ts +40 -0
- package/src/utils/llm-helper.ts +2 -2
|
@@ -7,7 +7,7 @@ import type {
|
|
|
7
7
|
EvolutionMetrics,
|
|
8
8
|
} from '@cogitator-ai/types';
|
|
9
9
|
import { CapabilityAnalyzer } from './capability-analyzer';
|
|
10
|
-
import { EvolutionStrategy
|
|
10
|
+
import { EvolutionStrategy } from './evolution-strategy';
|
|
11
11
|
import {
|
|
12
12
|
buildCandidateGenerationPrompt,
|
|
13
13
|
buildPerformanceAnalysisPrompt,
|
|
@@ -48,6 +48,7 @@ export class ParameterOptimizer {
|
|
|
48
48
|
private candidates: EvolutionCandidate[] = [];
|
|
49
49
|
private history: HistoricalRecord[] = [];
|
|
50
50
|
private currentGeneration = 0;
|
|
51
|
+
private lastEvolutionTimestamp = 0;
|
|
51
52
|
private readonly maxHistorySize = 100;
|
|
52
53
|
|
|
53
54
|
constructor(options: ParameterOptimizerOptions) {
|
|
@@ -173,6 +174,7 @@ export class ParameterOptimizer {
|
|
|
173
174
|
|
|
174
175
|
private async evolve(currentProfile: TaskProfile): Promise<void> {
|
|
175
176
|
this.currentGeneration++;
|
|
177
|
+
this.lastEvolutionTimestamp = Date.now();
|
|
176
178
|
|
|
177
179
|
const topCandidates = [...this.candidates]
|
|
178
180
|
.filter((c) => c.evaluationCount > 0)
|
|
@@ -325,10 +327,7 @@ export class ParameterOptimizer {
|
|
|
325
327
|
}
|
|
326
328
|
|
|
327
329
|
private getLastEvolutionTime(): number {
|
|
328
|
-
|
|
329
|
-
(c) => c.generation === this.currentGeneration && c.evaluationCount === 0
|
|
330
|
-
);
|
|
331
|
-
return latestGenCandidate ? Date.now() - 300000 : 0;
|
|
330
|
+
return this.lastEvolutionTimestamp;
|
|
332
331
|
}
|
|
333
332
|
|
|
334
333
|
private getRelevantHistory(profile: TaskProfile): HistoricalRecord[] {
|
|
@@ -410,7 +409,7 @@ export class ParameterOptimizer {
|
|
|
410
409
|
fields++;
|
|
411
410
|
}
|
|
412
411
|
|
|
413
|
-
if (a.model !== b.model) {
|
|
412
|
+
if (a.model !== undefined && b.model !== undefined && a.model !== b.model) {
|
|
414
413
|
distance += 1;
|
|
415
414
|
fields++;
|
|
416
415
|
}
|
|
@@ -447,8 +446,9 @@ export class ParameterOptimizer {
|
|
|
447
446
|
if (evaluatedCandidates.length === 0) return null;
|
|
448
447
|
|
|
449
448
|
const results = evaluatedCandidates.map((c) => {
|
|
449
|
+
const configKey = JSON.stringify(c.config, Object.keys(c.config).sort());
|
|
450
450
|
const records = this.history.filter(
|
|
451
|
-
(h) => JSON.stringify(h.config
|
|
451
|
+
(h) => JSON.stringify(h.config, Object.keys(h.config).sort()) === configKey
|
|
452
452
|
);
|
|
453
453
|
const avgMetrics =
|
|
454
454
|
records.length > 0
|
|
@@ -503,6 +503,7 @@ export class ParameterOptimizer {
|
|
|
503
503
|
this.candidates = [];
|
|
504
504
|
this.history = [];
|
|
505
505
|
this.currentGeneration = 0;
|
|
506
|
+
this.lastEvolutionTimestamp = 0;
|
|
506
507
|
this.evolutionStrategy.reset();
|
|
507
508
|
}
|
|
508
509
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { TaskProfile, ArchitectureConfig, EvolutionCandidate } from '@cogitator-ai/types';
|
|
2
|
+
import { extractJson } from '../utils';
|
|
2
3
|
|
|
3
4
|
export const ARCHITECTURE_ANALYSIS_SYSTEM_PROMPT = `You are an expert in AI agent architecture optimization.
|
|
4
5
|
Your task is to analyze tasks and recommend optimal configurations.
|
|
@@ -140,11 +141,11 @@ Respond with:
|
|
|
140
141
|
}
|
|
141
142
|
|
|
142
143
|
export function parseTaskProfileResponse(response: string): TaskProfile | null {
|
|
143
|
-
const
|
|
144
|
-
if (!
|
|
144
|
+
const json = extractJson(response);
|
|
145
|
+
if (!json) return null;
|
|
145
146
|
|
|
146
147
|
try {
|
|
147
|
-
const parsed = JSON.parse(
|
|
148
|
+
const parsed = JSON.parse(json);
|
|
148
149
|
|
|
149
150
|
return {
|
|
150
151
|
complexity: parsed.complexity || 'moderate',
|
|
@@ -197,11 +198,11 @@ export function parsePerformanceAnalysisResponse(response: string): {
|
|
|
197
198
|
shouldAdopt: boolean;
|
|
198
199
|
analysis: string;
|
|
199
200
|
} | null {
|
|
200
|
-
const
|
|
201
|
-
if (!
|
|
201
|
+
const json = extractJson(response);
|
|
202
|
+
if (!json) return null;
|
|
202
203
|
|
|
203
204
|
try {
|
|
204
|
-
const parsed = JSON.parse(
|
|
205
|
+
const parsed = JSON.parse(json);
|
|
205
206
|
|
|
206
207
|
return {
|
|
207
208
|
recommendation: String(parsed.recommendation || ''),
|
package/src/constraints/index.ts
CHANGED
|
@@ -92,23 +92,7 @@ export class ModificationValidator {
|
|
|
92
92
|
return this.evaluateExpression(rule, request.payload as Record<string, unknown>);
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
switch (rule.type) {
|
|
98
|
-
case 'invariant':
|
|
99
|
-
return this.evaluateExpression(rule.expression ?? '', payload);
|
|
100
|
-
case 'precondition':
|
|
101
|
-
return this.evaluateExpression(rule.expression ?? '', payload);
|
|
102
|
-
case 'postcondition':
|
|
103
|
-
return true;
|
|
104
|
-
case 'temporal':
|
|
105
|
-
if (rule.pattern?.source === 'never') {
|
|
106
|
-
return !this.evaluateExpression(rule.expression ?? '', payload);
|
|
107
|
-
}
|
|
108
|
-
return true;
|
|
109
|
-
default:
|
|
110
|
-
return true;
|
|
111
|
-
}
|
|
95
|
+
return this.evaluateExpression(rule.expression ?? '', request.payload as Record<string, unknown>);
|
|
112
96
|
}
|
|
113
97
|
|
|
114
98
|
private evaluateExpression(expression: string, context: Record<string, unknown>): boolean {
|
|
@@ -127,16 +111,18 @@ export class ModificationValidator {
|
|
|
127
111
|
|
|
128
112
|
if (conditions.length === 0) return true;
|
|
129
113
|
|
|
130
|
-
|
|
114
|
+
const orGroups: boolean[][] = [[]];
|
|
115
|
+
orGroups[0].push(conditions[0]);
|
|
116
|
+
|
|
131
117
|
for (let i = 0; i < operators.length; i++) {
|
|
132
118
|
if (operators[i] === 'AND') {
|
|
133
|
-
|
|
119
|
+
orGroups[orGroups.length - 1].push(conditions[i + 1]);
|
|
134
120
|
} else {
|
|
135
|
-
|
|
121
|
+
orGroups.push([conditions[i + 1]]);
|
|
136
122
|
}
|
|
137
123
|
}
|
|
138
124
|
|
|
139
|
-
return
|
|
125
|
+
return orGroups.some((group) => group.every(Boolean));
|
|
140
126
|
}
|
|
141
127
|
|
|
142
128
|
private evaluateSimpleCondition(condition: string, context: Record<string, unknown>): boolean {
|
|
@@ -238,7 +224,7 @@ export class ModificationValidator {
|
|
|
238
224
|
request: ModificationRequest
|
|
239
225
|
): Promise<ConstraintCheckResult[]> {
|
|
240
226
|
const results: ConstraintCheckResult[] = [];
|
|
241
|
-
const payload = request.payload as {
|
|
227
|
+
const payload = (request.payload ?? {}) as {
|
|
242
228
|
tokensUsed?: number;
|
|
243
229
|
cost?: number;
|
|
244
230
|
activeTools?: number;
|
|
@@ -384,6 +370,11 @@ export class ModificationValidator {
|
|
|
384
370
|
}
|
|
385
371
|
|
|
386
372
|
getConstraints(): ModificationConstraints {
|
|
387
|
-
return {
|
|
373
|
+
return {
|
|
374
|
+
safety: [...this.constraints.safety],
|
|
375
|
+
capability: [...this.constraints.capability],
|
|
376
|
+
resource: [...this.constraints.resource],
|
|
377
|
+
custom: this.constraints.custom ? [...this.constraints.custom] : [],
|
|
378
|
+
};
|
|
388
379
|
}
|
|
389
380
|
}
|
|
@@ -2,6 +2,7 @@ import type {
|
|
|
2
2
|
SafetyConstraint,
|
|
3
3
|
CapabilityConstraint,
|
|
4
4
|
ResourceConstraint,
|
|
5
|
+
CustomConstraint,
|
|
5
6
|
ModificationConstraints,
|
|
6
7
|
} from '@cogitator-ai/types';
|
|
7
8
|
import { DEFAULT_SAFETY_CONSTRAINTS } from '@cogitator-ai/types';
|
|
@@ -84,6 +85,20 @@ export function mergeResourceConstraints(
|
|
|
84
85
|
return [...result.values()];
|
|
85
86
|
}
|
|
86
87
|
|
|
88
|
+
export function mergeCustomConstraints(
|
|
89
|
+
base: CustomConstraint[],
|
|
90
|
+
additions: CustomConstraint[]
|
|
91
|
+
): CustomConstraint[] {
|
|
92
|
+
const result = new Map<string, CustomConstraint>();
|
|
93
|
+
for (const c of base) {
|
|
94
|
+
result.set(c.id, c);
|
|
95
|
+
}
|
|
96
|
+
for (const c of additions) {
|
|
97
|
+
result.set(c.id, c);
|
|
98
|
+
}
|
|
99
|
+
return [...result.values()];
|
|
100
|
+
}
|
|
101
|
+
|
|
87
102
|
export function mergeConstraints(
|
|
88
103
|
base: ModificationConstraints,
|
|
89
104
|
additions: Partial<ModificationConstraints>
|
|
@@ -96,6 +111,6 @@ export function mergeConstraints(
|
|
|
96
111
|
resource: additions.resource
|
|
97
112
|
? mergeResourceConstraints(base.resource, additions.resource)
|
|
98
113
|
: base.resource,
|
|
99
|
-
custom:
|
|
114
|
+
custom: mergeCustomConstraints(base.custom ?? [], additions.custom ?? []),
|
|
100
115
|
};
|
|
101
116
|
}
|
|
@@ -30,7 +30,15 @@ export class SelfModifyingEventEmitter {
|
|
|
30
30
|
...(wildcardHandlers ? [...wildcardHandlers] : []),
|
|
31
31
|
];
|
|
32
32
|
|
|
33
|
-
await Promise.
|
|
33
|
+
await Promise.allSettled(
|
|
34
|
+
allHandlers.map((h) => {
|
|
35
|
+
try {
|
|
36
|
+
return Promise.resolve(h(event));
|
|
37
|
+
} catch (e) {
|
|
38
|
+
return Promise.reject(e instanceof Error ? e : new Error(String(e)));
|
|
39
|
+
}
|
|
40
|
+
})
|
|
41
|
+
);
|
|
34
42
|
}
|
|
35
43
|
|
|
36
44
|
createEvent(
|
package/src/index.ts
CHANGED
|
@@ -67,6 +67,7 @@ export {
|
|
|
67
67
|
mergeSafetyConstraints,
|
|
68
68
|
mergeCapabilityConstraints,
|
|
69
69
|
mergeResourceConstraints,
|
|
70
|
+
mergeCustomConstraints,
|
|
70
71
|
type ModificationValidatorOptions,
|
|
71
72
|
type RollbackManagerOptions,
|
|
72
73
|
type CheckpointStore,
|
|
@@ -75,6 +76,8 @@ export {
|
|
|
75
76
|
|
|
76
77
|
export { SelfModifyingEventEmitter, type SelfModifyingEventHandler } from './events';
|
|
77
78
|
|
|
79
|
+
export { llmChat, extractJson } from './utils';
|
|
80
|
+
|
|
78
81
|
export type {
|
|
79
82
|
SelfModifyingConfig,
|
|
80
83
|
ToolSelfGenerationConfig,
|
|
@@ -111,6 +111,9 @@ export class MetaReasoner {
|
|
|
111
111
|
case 'progress_stall':
|
|
112
112
|
return context.stagnationCount >= this.config.triggerOnProgressStall;
|
|
113
113
|
|
|
114
|
+
case 'periodic':
|
|
115
|
+
return context.iteration > 0 && context.iteration % this.config.triggerAfterIterations === 0;
|
|
116
|
+
|
|
114
117
|
case 'tool_call_failed':
|
|
115
118
|
return true;
|
|
116
119
|
|
|
@@ -165,12 +168,17 @@ export class MetaReasoner {
|
|
|
165
168
|
|
|
166
169
|
recommendation: this.buildRecommendation(parsed, observation),
|
|
167
170
|
|
|
171
|
+
requiresAdaptation:
|
|
172
|
+
parsed?.recommendation?.action !== undefined &&
|
|
173
|
+
parsed?.recommendation?.action !== 'continue',
|
|
174
|
+
|
|
168
175
|
assessmentDuration: Date.now() - startTime,
|
|
169
176
|
assessmentCost: (response.usage?.outputTokens ?? 0) * 0.00001,
|
|
170
177
|
};
|
|
171
178
|
|
|
172
179
|
const runAssessments = this.assessments.get(observation.runId) ?? [];
|
|
173
180
|
runAssessments.push(assessment);
|
|
181
|
+
this.assessments.set(observation.runId, runAssessments);
|
|
174
182
|
this.lastAssessmentTime.set(observation.runId, Date.now());
|
|
175
183
|
|
|
176
184
|
return assessment;
|
|
@@ -277,6 +285,7 @@ export class MetaReasoner {
|
|
|
277
285
|
|
|
278
286
|
const runAdaptations = this.adaptations.get(runId) ?? [];
|
|
279
287
|
runAdaptations.push(adaptation);
|
|
288
|
+
this.adaptations.set(runId, runAdaptations);
|
|
280
289
|
this.lastAdaptationTime.set(runId, Date.now());
|
|
281
290
|
|
|
282
291
|
return adaptation;
|
|
@@ -111,14 +111,54 @@ export interface ParsedAssessment {
|
|
|
111
111
|
|
|
112
112
|
export function parseMetaAssessmentResponse(content: string): ParsedAssessment | null {
|
|
113
113
|
try {
|
|
114
|
-
const
|
|
115
|
-
if (!
|
|
116
|
-
return JSON.parse(
|
|
114
|
+
const json = extractJson(content);
|
|
115
|
+
if (!json) return null;
|
|
116
|
+
return JSON.parse(json) as ParsedAssessment;
|
|
117
117
|
} catch {
|
|
118
118
|
return null;
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
+
function extractJson(text: string): string | null {
|
|
123
|
+
const start = text.indexOf('{');
|
|
124
|
+
if (start === -1) return null;
|
|
125
|
+
|
|
126
|
+
let depth = 0;
|
|
127
|
+
let inString = false;
|
|
128
|
+
let escape = false;
|
|
129
|
+
|
|
130
|
+
for (let i = start; i < text.length; i++) {
|
|
131
|
+
const ch = text[i];
|
|
132
|
+
|
|
133
|
+
if (escape) {
|
|
134
|
+
escape = false;
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (ch === '\\' && inString) {
|
|
139
|
+
escape = true;
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (ch === '"') {
|
|
144
|
+
inString = !inString;
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (inString) continue;
|
|
149
|
+
|
|
150
|
+
if (ch === '{') depth++;
|
|
151
|
+
else if (ch === '}') {
|
|
152
|
+
depth--;
|
|
153
|
+
if (depth === 0) {
|
|
154
|
+
return text.slice(start, i + 1);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
|
|
122
162
|
export const META_REASONING_SYSTEM_PROMPT = `You are a meta-reasoning system analyzing an AI agent's reasoning process.
|
|
123
163
|
Your job is to assess whether the agent is on track and recommend strategic adjustments.
|
|
124
164
|
|
|
@@ -54,7 +54,7 @@ export class SelfModifyingAgent {
|
|
|
54
54
|
private readonly toolStore: InMemoryGeneratedToolStore;
|
|
55
55
|
private readonly metaReasoner: MetaReasoner;
|
|
56
56
|
private readonly parameterOptimizer: ParameterOptimizer;
|
|
57
|
-
private readonly
|
|
57
|
+
private readonly capabilityAnalyzer: CapabilityAnalyzer;
|
|
58
58
|
private readonly modificationValidator: ModificationValidator;
|
|
59
59
|
private readonly rollbackManager: RollbackManager;
|
|
60
60
|
|
|
@@ -91,7 +91,7 @@ export class SelfModifyingAgent {
|
|
|
91
91
|
baseConfig: baseArchConfig,
|
|
92
92
|
});
|
|
93
93
|
|
|
94
|
-
this.
|
|
94
|
+
this.capabilityAnalyzer = new CapabilityAnalyzer({
|
|
95
95
|
llm: this.llm,
|
|
96
96
|
enableLLMAnalysis: true,
|
|
97
97
|
});
|
|
@@ -217,6 +217,7 @@ export class SelfModifyingAgent {
|
|
|
217
217
|
|
|
218
218
|
throw error;
|
|
219
219
|
} finally {
|
|
220
|
+
this.metaReasoner.cleanupRun(runId);
|
|
220
221
|
this.currentContext = null;
|
|
221
222
|
}
|
|
222
223
|
}
|
|
@@ -409,18 +410,34 @@ export class SelfModifyingAgent {
|
|
|
409
410
|
|
|
410
411
|
return {
|
|
411
412
|
enabled: partial.enabled ?? defaults.enabled,
|
|
412
|
-
toolGeneration: {
|
|
413
|
-
|
|
413
|
+
toolGeneration: {
|
|
414
|
+
...defaults.toolGeneration,
|
|
415
|
+
...partial.toolGeneration,
|
|
416
|
+
sandboxConfig: partial.toolGeneration?.sandboxConfig
|
|
417
|
+
? { ...defaults.toolGeneration.sandboxConfig, ...partial.toolGeneration.sandboxConfig }
|
|
418
|
+
: defaults.toolGeneration.sandboxConfig,
|
|
419
|
+
},
|
|
420
|
+
metaReasoning: {
|
|
421
|
+
...defaults.metaReasoning,
|
|
422
|
+
...partial.metaReasoning,
|
|
423
|
+
modeProfiles: {
|
|
424
|
+
...defaults.metaReasoning.modeProfiles,
|
|
425
|
+
...partial.metaReasoning?.modeProfiles,
|
|
426
|
+
},
|
|
427
|
+
},
|
|
414
428
|
architectureEvolution: {
|
|
415
429
|
...defaults.architectureEvolution,
|
|
416
430
|
...partial.architectureEvolution,
|
|
431
|
+
strategy: partial.architectureEvolution?.strategy
|
|
432
|
+
? { ...defaults.architectureEvolution.strategy, ...partial.architectureEvolution.strategy }
|
|
433
|
+
: defaults.architectureEvolution.strategy,
|
|
417
434
|
},
|
|
418
435
|
constraints: { ...defaults.constraints, ...partial.constraints },
|
|
419
436
|
};
|
|
420
437
|
}
|
|
421
438
|
|
|
422
439
|
private getAvailableTools(): Tool[] {
|
|
423
|
-
return [];
|
|
440
|
+
return this.agent.tools ?? [];
|
|
424
441
|
}
|
|
425
442
|
|
|
426
443
|
private async optimizeArchitecture(input: string): Promise<void> {
|
|
@@ -452,7 +469,14 @@ export class SelfModifyingAgent {
|
|
|
452
469
|
});
|
|
453
470
|
}
|
|
454
471
|
}
|
|
455
|
-
} catch {
|
|
472
|
+
} catch (error) {
|
|
473
|
+
void this.emitter.emit({
|
|
474
|
+
type: 'architecture_evolved',
|
|
475
|
+
runId: this.currentContext.runId,
|
|
476
|
+
timestamp: new Date(),
|
|
477
|
+
data: { error: error instanceof Error ? error.message : String(error) },
|
|
478
|
+
});
|
|
479
|
+
}
|
|
456
480
|
}
|
|
457
481
|
|
|
458
482
|
private async analyzeAndGenerateTools(input: string): Promise<void> {
|
|
@@ -479,7 +503,19 @@ export class SelfModifyingAgent {
|
|
|
479
503
|
}
|
|
480
504
|
}
|
|
481
505
|
}
|
|
482
|
-
} catch {
|
|
506
|
+
} catch (error) {
|
|
507
|
+
void this.emitter.emit({
|
|
508
|
+
type: 'tool_generation_completed',
|
|
509
|
+
runId: this.currentContext.runId,
|
|
510
|
+
timestamp: new Date(),
|
|
511
|
+
data: {
|
|
512
|
+
toolId: '',
|
|
513
|
+
name: '',
|
|
514
|
+
success: false,
|
|
515
|
+
error: error instanceof Error ? error.message : String(error),
|
|
516
|
+
},
|
|
517
|
+
});
|
|
518
|
+
}
|
|
483
519
|
}
|
|
484
520
|
|
|
485
521
|
private async executeWithMetaReasoning(input: string, runId: string): Promise<string> {
|
|
@@ -562,7 +598,19 @@ export class SelfModifyingAgent {
|
|
|
562
598
|
}
|
|
563
599
|
|
|
564
600
|
private async executeAgentStep(input: string): Promise<string> {
|
|
565
|
-
|
|
601
|
+
const response = await this.llm.chat({
|
|
602
|
+
model: this.currentContext?.currentConfig.model ?? this.agent.model ?? 'default',
|
|
603
|
+
messages: [
|
|
604
|
+
...(this.agent.instructions
|
|
605
|
+
? [{ role: 'system' as const, content: this.agent.instructions }]
|
|
606
|
+
: []),
|
|
607
|
+
{ role: 'user' as const, content: input },
|
|
608
|
+
],
|
|
609
|
+
temperature: this.currentContext?.currentConfig.temperature,
|
|
610
|
+
maxTokens: this.currentContext?.currentConfig.maxTokens,
|
|
611
|
+
});
|
|
612
|
+
|
|
613
|
+
return response.content;
|
|
566
614
|
}
|
|
567
615
|
|
|
568
616
|
private estimateConfidence(output: string): number {
|
|
@@ -572,7 +620,7 @@ export class SelfModifyingAgent {
|
|
|
572
620
|
return 0.8;
|
|
573
621
|
}
|
|
574
622
|
|
|
575
|
-
private isTaskComplete(
|
|
576
|
-
return
|
|
623
|
+
private isTaskComplete(_output: string): boolean {
|
|
624
|
+
return true;
|
|
577
625
|
}
|
|
578
626
|
}
|
|
@@ -25,10 +25,8 @@ export class InMemoryGeneratedToolStore implements IGeneratedToolStore {
|
|
|
25
25
|
|
|
26
26
|
async save(tool: GeneratedTool): Promise<void> {
|
|
27
27
|
const existing = this.tools.get(tool.id);
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
this.tools.set(tool.id, { ...tool, updatedAt: new Date() });
|
|
28
|
+
const version = existing ? existing.version + 1 : tool.version;
|
|
29
|
+
this.tools.set(tool.id, { ...tool, version, updatedAt: new Date() });
|
|
32
30
|
}
|
|
33
31
|
|
|
34
32
|
async get(id: string): Promise<GeneratedTool | null> {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { CapabilityGap, GeneratedTool, ToolValidationResult } from '@cogitator-ai/types';
|
|
2
|
+
import { extractJson } from '../utils';
|
|
2
3
|
|
|
3
4
|
export const TOOL_GENERATION_SYSTEM_PROMPT = `You are an expert TypeScript developer specializing in creating tools for AI agents.
|
|
4
5
|
Your task is to generate safe, efficient, and well-typed tool implementations.
|
|
@@ -205,13 +206,13 @@ export function parseGapAnalysisResponse(response: string): {
|
|
|
205
206
|
canProceed: boolean;
|
|
206
207
|
alternativeApproach?: string;
|
|
207
208
|
} {
|
|
208
|
-
const
|
|
209
|
-
if (!
|
|
209
|
+
const json = extractJson(response);
|
|
210
|
+
if (!json) {
|
|
210
211
|
return { hasGap: false, gaps: [], canProceed: true };
|
|
211
212
|
}
|
|
212
213
|
|
|
213
214
|
try {
|
|
214
|
-
const parsed = JSON.parse(
|
|
215
|
+
const parsed = JSON.parse(json);
|
|
215
216
|
return {
|
|
216
217
|
hasGap: Boolean(parsed.hasGap),
|
|
217
218
|
gaps: Array.isArray(parsed.gaps)
|
|
@@ -238,13 +239,13 @@ export function parseGapAnalysisResponse(response: string): {
|
|
|
238
239
|
}
|
|
239
240
|
|
|
240
241
|
export function parseToolGenerationResponse(response: string): GeneratedTool | null {
|
|
241
|
-
const
|
|
242
|
-
if (!
|
|
242
|
+
const json = extractJson(response);
|
|
243
|
+
if (!json) {
|
|
243
244
|
return null;
|
|
244
245
|
}
|
|
245
246
|
|
|
246
247
|
try {
|
|
247
|
-
const parsed = JSON.parse(
|
|
248
|
+
const parsed = JSON.parse(json);
|
|
248
249
|
if (!parsed.name || !parsed.implementation) {
|
|
249
250
|
return null;
|
|
250
251
|
}
|
|
@@ -268,13 +269,13 @@ export function parseToolGenerationResponse(response: string): GeneratedTool | n
|
|
|
268
269
|
}
|
|
269
270
|
|
|
270
271
|
export function parseValidationResponse(response: string): ToolValidationResult | null {
|
|
271
|
-
const
|
|
272
|
-
if (!
|
|
272
|
+
const json = extractJson(response);
|
|
273
|
+
if (!json) {
|
|
273
274
|
return null;
|
|
274
275
|
}
|
|
275
276
|
|
|
276
277
|
try {
|
|
277
|
-
const parsed = JSON.parse(
|
|
278
|
+
const parsed = JSON.parse(json);
|
|
278
279
|
|
|
279
280
|
return {
|
|
280
281
|
isValid: Boolean(parsed.isValid),
|
|
@@ -8,6 +8,7 @@ import type {
|
|
|
8
8
|
} from '@cogitator-ai/types';
|
|
9
9
|
import { z, type ZodType } from 'zod';
|
|
10
10
|
import { ToolValidator } from './tool-validator';
|
|
11
|
+
import { ToolSandbox } from './tool-sandbox';
|
|
11
12
|
import {
|
|
12
13
|
TOOL_GENERATION_SYSTEM_PROMPT,
|
|
13
14
|
buildToolGenerationPrompt,
|
|
@@ -32,6 +33,7 @@ export class ToolGenerator {
|
|
|
32
33
|
private readonly llm: LLMBackend;
|
|
33
34
|
private readonly config: ToolSelfGenerationConfig;
|
|
34
35
|
private readonly validator: ToolValidator;
|
|
36
|
+
private readonly sandbox: ToolSandbox;
|
|
35
37
|
|
|
36
38
|
constructor(options: ToolGeneratorOptions) {
|
|
37
39
|
this.llm = options.llm;
|
|
@@ -40,6 +42,7 @@ export class ToolGenerator {
|
|
|
40
42
|
llm: options.llm,
|
|
41
43
|
config: options.config,
|
|
42
44
|
});
|
|
45
|
+
this.sandbox = new ToolSandbox(options.config.sandboxConfig);
|
|
43
46
|
}
|
|
44
47
|
|
|
45
48
|
async generate(
|
|
@@ -203,7 +206,16 @@ export class ToolGenerator {
|
|
|
203
206
|
}
|
|
204
207
|
|
|
205
208
|
createExecutableTool(generated: GeneratedTool): Tool {
|
|
206
|
-
const
|
|
209
|
+
const sandbox = this.sandbox;
|
|
210
|
+
const tool = generated;
|
|
211
|
+
|
|
212
|
+
const execute = async (params: unknown): Promise<unknown> => {
|
|
213
|
+
const result = await sandbox.execute(tool, params);
|
|
214
|
+
if (!result.success) {
|
|
215
|
+
throw new Error(result.error ?? 'Tool execution failed');
|
|
216
|
+
}
|
|
217
|
+
return result.result;
|
|
218
|
+
};
|
|
207
219
|
|
|
208
220
|
return {
|
|
209
221
|
name: generated.name,
|
|
@@ -221,20 +233,6 @@ export class ToolGenerator {
|
|
|
221
233
|
};
|
|
222
234
|
}
|
|
223
235
|
|
|
224
|
-
private compileImplementation(implementation: string): (params: unknown) => Promise<unknown> {
|
|
225
|
-
return async (params: unknown): Promise<unknown> => {
|
|
226
|
-
// eslint-disable-next-line @typescript-eslint/no-implied-eval
|
|
227
|
-
const factory = new Function(`
|
|
228
|
-
"use strict";
|
|
229
|
-
${implementation}
|
|
230
|
-
return execute;
|
|
231
|
-
`);
|
|
232
|
-
|
|
233
|
-
const execute = factory();
|
|
234
|
-
return execute(params);
|
|
235
|
-
};
|
|
236
|
-
}
|
|
237
|
-
|
|
238
236
|
private async callLLM(
|
|
239
237
|
messages: Array<{ role: 'system' | 'user' | 'assistant'; content: string }>,
|
|
240
238
|
temperature: number
|
|
@@ -150,7 +150,8 @@ export class ToolSandbox {
|
|
|
150
150
|
/\bexec\s*\(/,
|
|
151
151
|
/\bspawn\s*\(/,
|
|
152
152
|
/__proto__/,
|
|
153
|
-
/\bconstructor\
|
|
153
|
+
/\bconstructor\b/,
|
|
154
|
+
/\bgetPrototypeOf\b/,
|
|
154
155
|
];
|
|
155
156
|
|
|
156
157
|
if (this.config.isolationLevel === 'strict') {
|
|
@@ -267,7 +268,16 @@ export class ToolSandbox {
|
|
|
267
268
|
return execute;
|
|
268
269
|
`);
|
|
269
270
|
const execute = factory();
|
|
270
|
-
|
|
271
|
+
|
|
272
|
+
const result = await Promise.race([
|
|
273
|
+
execute(params),
|
|
274
|
+
new Promise((_, reject) =>
|
|
275
|
+
setTimeout(
|
|
276
|
+
() => reject(new Error(`Execution timeout: exceeded ${this.config.maxExecutionTime}ms`)),
|
|
277
|
+
this.config.maxExecutionTime
|
|
278
|
+
)
|
|
279
|
+
),
|
|
280
|
+
]);
|
|
271
281
|
|
|
272
282
|
return {
|
|
273
283
|
success: true,
|
package/src/utils/index.ts
CHANGED
|
@@ -1 +1,41 @@
|
|
|
1
1
|
export { llmChat } from './llm-helper';
|
|
2
|
+
|
|
3
|
+
export function extractJson(text: string): string | null {
|
|
4
|
+
const start = text.indexOf('{');
|
|
5
|
+
if (start === -1) return null;
|
|
6
|
+
|
|
7
|
+
let depth = 0;
|
|
8
|
+
let inString = false;
|
|
9
|
+
let escape = false;
|
|
10
|
+
|
|
11
|
+
for (let i = start; i < text.length; i++) {
|
|
12
|
+
const ch = text[i];
|
|
13
|
+
|
|
14
|
+
if (escape) {
|
|
15
|
+
escape = false;
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (ch === '\\' && inString) {
|
|
20
|
+
escape = true;
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (ch === '"') {
|
|
25
|
+
inString = !inString;
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (inString) continue;
|
|
30
|
+
|
|
31
|
+
if (ch === '{') depth++;
|
|
32
|
+
else if (ch === '}') {
|
|
33
|
+
depth--;
|
|
34
|
+
if (depth === 0) {
|
|
35
|
+
return text.slice(start, i + 1);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return null;
|
|
41
|
+
}
|