@cogitator-ai/self-modifying 19.1.1 → 19.1.3
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/package.json +3 -3
- package/src/__tests__/architecture-evolution.test.ts +37 -27
- package/src/__tests__/constraints.test.ts +25 -19
- package/src/__tests__/meta-reasoning.test.ts +24 -12
- package/src/__tests__/self-modifying-agent.test.ts +1 -0
- package/src/__tests__/tool-generation.test.ts +62 -39
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cogitator-ai/self-modifying",
|
|
3
|
-
"version": "19.1.
|
|
3
|
+
"version": "19.1.3",
|
|
4
4
|
"description": "Self-modifying agent capabilities for Cogitator - tool generation, meta-reasoning, architecture evolution",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"node": ">=22.12.0"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@cogitator-ai/types": "0.
|
|
23
|
+
"@cogitator-ai/types": "0.28.0",
|
|
24
24
|
"nanoid": "^6.0.1",
|
|
25
25
|
"zod": "^4.6.5"
|
|
26
26
|
},
|
|
@@ -53,6 +53,6 @@
|
|
|
53
53
|
"test": "vitest run",
|
|
54
54
|
"test:watch": "vitest",
|
|
55
55
|
"lint": "eslint src --ext .ts",
|
|
56
|
-
"typecheck": "tsc --noEmit"
|
|
56
|
+
"typecheck": "tsc --noEmit -p tsconfig.test.json"
|
|
57
57
|
}
|
|
58
58
|
}
|
|
@@ -6,15 +6,23 @@ import {
|
|
|
6
6
|
parseTaskProfileResponse,
|
|
7
7
|
parseCandidateGenerationResponse,
|
|
8
8
|
} from '../architecture-evolution';
|
|
9
|
-
import type { LLMBackend, EvolutionCandidate } from '@cogitator-ai/types';
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
};
|
|
9
|
+
import type { ChatResponse, LLMBackend, EvolutionCandidate } from '@cogitator-ai/types';
|
|
10
|
+
|
|
11
|
+
function chatResponse(content: string): ChatResponse {
|
|
12
|
+
return {
|
|
13
|
+
id: 'resp',
|
|
14
|
+
content,
|
|
15
|
+
finishReason: 'stop',
|
|
16
|
+
usage: { inputTokens: 0, outputTokens: 0, totalTokens: 0 },
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const mockLLM = {
|
|
21
|
+
provider: 'ollama',
|
|
22
|
+
chat: vi.fn<LLMBackend['chat']>(),
|
|
23
|
+
chatStream: async function* () {},
|
|
24
|
+
complete: vi.fn<NonNullable<LLMBackend['complete']>>(),
|
|
25
|
+
} satisfies LLMBackend;
|
|
18
26
|
|
|
19
27
|
describe('CapabilityAnalyzer', () => {
|
|
20
28
|
it('analyzes task with heuristics', async () => {
|
|
@@ -290,24 +298,26 @@ describe('EvolutionStrategy', () => {
|
|
|
290
298
|
describe('ParameterOptimizer', () => {
|
|
291
299
|
beforeEach(() => {
|
|
292
300
|
vi.clearAllMocks();
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
301
|
+
mockLLM.complete.mockResolvedValue(
|
|
302
|
+
chatResponse(
|
|
303
|
+
JSON.stringify([
|
|
304
|
+
{
|
|
305
|
+
id: 'candidate_1',
|
|
306
|
+
config: { temperature: 0.5 },
|
|
307
|
+
reasoning: 'Lower temperature for precision',
|
|
308
|
+
expectedImprovement: 0.7,
|
|
309
|
+
risk: 'low',
|
|
310
|
+
},
|
|
311
|
+
{
|
|
312
|
+
id: 'candidate_2',
|
|
313
|
+
config: { temperature: 0.9, maxTokens: 8000 },
|
|
314
|
+
reasoning: 'Higher temperature for creativity',
|
|
315
|
+
expectedImprovement: 0.6,
|
|
316
|
+
risk: 'medium',
|
|
317
|
+
},
|
|
318
|
+
])
|
|
319
|
+
)
|
|
320
|
+
);
|
|
311
321
|
});
|
|
312
322
|
|
|
313
323
|
it('optimizes architecture for task', async () => {
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { describe, it, expect, beforeEach } from 'vitest';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import type { AgentConfig, Tool } from '@cogitator-ai/types';
|
|
2
4
|
import {
|
|
3
5
|
ModificationValidator,
|
|
4
6
|
RollbackManager,
|
|
@@ -7,6 +9,20 @@ import {
|
|
|
7
9
|
mergeSafetyConstraints,
|
|
8
10
|
} from '../constraints';
|
|
9
11
|
|
|
12
|
+
function agentConfig(overrides: Partial<AgentConfig>): AgentConfig {
|
|
13
|
+
return { name: 'agent', instructions: 'Test agent', ...overrides };
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function makeTool(name: string, description: string): Tool {
|
|
17
|
+
return {
|
|
18
|
+
name,
|
|
19
|
+
description,
|
|
20
|
+
parameters: z.object({}),
|
|
21
|
+
execute: async () => null,
|
|
22
|
+
toJSON: () => ({ name, description, parameters: { type: 'object', properties: {} } }),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
10
26
|
describe('ModificationValidator', () => {
|
|
11
27
|
let validator: ModificationValidator;
|
|
12
28
|
|
|
@@ -132,8 +148,8 @@ describe('RollbackManager', () => {
|
|
|
132
148
|
it('creates checkpoints', async () => {
|
|
133
149
|
const checkpoint = await manager.createCheckpoint(
|
|
134
150
|
'agent-1',
|
|
135
|
-
{ model: 'gpt-4', temperature: 0.7 },
|
|
136
|
-
[
|
|
151
|
+
agentConfig({ model: 'gpt-4', temperature: 0.7 }),
|
|
152
|
+
[makeTool('tool1', 'Test')],
|
|
137
153
|
[]
|
|
138
154
|
);
|
|
139
155
|
|
|
@@ -145,15 +161,8 @@ describe('RollbackManager', () => {
|
|
|
145
161
|
it('rolls back to checkpoint', async () => {
|
|
146
162
|
const checkpoint = await manager.createCheckpoint(
|
|
147
163
|
'agent-1',
|
|
148
|
-
{ model: 'gpt-4', temperature: 0.7 },
|
|
149
|
-
[
|
|
150
|
-
{
|
|
151
|
-
name: 'original_tool',
|
|
152
|
-
description: 'Original',
|
|
153
|
-
parameters: {},
|
|
154
|
-
execute: async () => null,
|
|
155
|
-
},
|
|
156
|
-
],
|
|
164
|
+
agentConfig({ model: 'gpt-4', temperature: 0.7 }),
|
|
165
|
+
[makeTool('original_tool', 'Original')],
|
|
157
166
|
[]
|
|
158
167
|
);
|
|
159
168
|
|
|
@@ -168,18 +177,15 @@ describe('RollbackManager', () => {
|
|
|
168
177
|
it('compares checkpoints', async () => {
|
|
169
178
|
const cp1 = await manager.createCheckpoint(
|
|
170
179
|
'agent-1',
|
|
171
|
-
{ model: 'gpt-4', temperature: 0.7 },
|
|
172
|
-
[
|
|
180
|
+
agentConfig({ model: 'gpt-4', temperature: 0.7 }),
|
|
181
|
+
[makeTool('tool1', 'Test')],
|
|
173
182
|
[]
|
|
174
183
|
);
|
|
175
184
|
|
|
176
185
|
const cp2 = await manager.createCheckpoint(
|
|
177
186
|
'agent-1',
|
|
178
|
-
{ model: 'gpt-4o', temperature: 0.9 },
|
|
179
|
-
[
|
|
180
|
-
{ name: 'tool1', description: 'Test', parameters: {}, execute: async () => null },
|
|
181
|
-
{ name: 'tool2', description: 'New', parameters: {}, execute: async () => null },
|
|
182
|
-
],
|
|
187
|
+
agentConfig({ model: 'gpt-4o', temperature: 0.9 }),
|
|
188
|
+
[makeTool('tool1', 'Test'), makeTool('tool2', 'New')],
|
|
183
189
|
[]
|
|
184
190
|
);
|
|
185
191
|
|
|
@@ -195,7 +201,7 @@ describe('RollbackManager', () => {
|
|
|
195
201
|
const customManager = new RollbackManager({ maxCheckpoints: 3 });
|
|
196
202
|
|
|
197
203
|
for (let i = 0; i < 5; i++) {
|
|
198
|
-
await customManager.createCheckpoint('agent-1', {
|
|
204
|
+
await customManager.createCheckpoint('agent-1', agentConfig({ name: `agent-${i}` }), [], []);
|
|
199
205
|
}
|
|
200
206
|
|
|
201
207
|
const checkpoints = await customManager.listCheckpoints('agent-1');
|
|
@@ -9,8 +9,11 @@ import {
|
|
|
9
9
|
} from '../meta-reasoning';
|
|
10
10
|
import type { LLMBackend, MetaObservation } from '@cogitator-ai/types';
|
|
11
11
|
|
|
12
|
-
const mockLLM
|
|
13
|
-
|
|
12
|
+
const mockLLM = {
|
|
13
|
+
provider: 'ollama',
|
|
14
|
+
chat: vi.fn<LLMBackend['chat']>().mockResolvedValue({
|
|
15
|
+
id: 'resp',
|
|
16
|
+
finishReason: 'stop',
|
|
14
17
|
content: JSON.stringify({
|
|
15
18
|
onTrack: true,
|
|
16
19
|
confidence: 0.8,
|
|
@@ -23,13 +26,10 @@ const mockLLM: LLMBackend = {
|
|
|
23
26
|
reasoning: 'Making good progress',
|
|
24
27
|
},
|
|
25
28
|
}),
|
|
26
|
-
usage: { outputTokens: 100 },
|
|
29
|
+
usage: { inputTokens: 0, outputTokens: 100, totalTokens: 100 },
|
|
27
30
|
}),
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
supportsStreaming: () => false,
|
|
31
|
-
validateConfig: () => true,
|
|
32
|
-
};
|
|
31
|
+
chatStream: async function* () {},
|
|
32
|
+
} satisfies LLMBackend;
|
|
33
33
|
|
|
34
34
|
describe('ObservationCollector', () => {
|
|
35
35
|
let collector: ObservationCollector;
|
|
@@ -224,9 +224,8 @@ describe('MetaReasoner', () => {
|
|
|
224
224
|
model: 'gpt-4o',
|
|
225
225
|
config: {
|
|
226
226
|
enabled: true,
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
assessmentCooldown: 0,
|
|
227
|
+
maxMetaAssessments: 5,
|
|
228
|
+
maxAdaptations: 3,
|
|
230
229
|
metaAssessmentCooldown: 0,
|
|
231
230
|
adaptationCooldown: 0,
|
|
232
231
|
triggers: ['iteration_complete', 'confidence_drop', 'progress_stall'],
|
|
@@ -270,7 +269,20 @@ describe('MetaReasoner', () => {
|
|
|
270
269
|
iterationsRemaining: 5,
|
|
271
270
|
budgetRemaining: 0.8,
|
|
272
271
|
},
|
|
273
|
-
[
|
|
272
|
+
[
|
|
273
|
+
{
|
|
274
|
+
id: 'insight-1',
|
|
275
|
+
type: 'pattern',
|
|
276
|
+
content: 'Test insight',
|
|
277
|
+
context: 'Test goal',
|
|
278
|
+
confidence: 0.8,
|
|
279
|
+
usageCount: 0,
|
|
280
|
+
createdAt: new Date(0),
|
|
281
|
+
lastUsedAt: new Date(0),
|
|
282
|
+
agentId: 'agent-1',
|
|
283
|
+
source: { runId, reflectionId: 'reflection-1' },
|
|
284
|
+
},
|
|
285
|
+
]
|
|
274
286
|
);
|
|
275
287
|
|
|
276
288
|
expect(observation.tokensUsed).toBe(1000);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
|
2
|
+
import { z } from 'zod';
|
|
2
3
|
import {
|
|
3
4
|
GapAnalyzer,
|
|
4
5
|
ToolGenerator,
|
|
@@ -8,7 +9,12 @@ import {
|
|
|
8
9
|
parseGapAnalysisResponse,
|
|
9
10
|
parseToolGenerationResponse,
|
|
10
11
|
} from '../tool-generation';
|
|
11
|
-
import type {
|
|
12
|
+
import type {
|
|
13
|
+
ChatResponse,
|
|
14
|
+
LLMBackend,
|
|
15
|
+
GeneratedTool,
|
|
16
|
+
ToolSelfGenerationConfig,
|
|
17
|
+
} from '@cogitator-ai/types';
|
|
12
18
|
|
|
13
19
|
const mockToolConfig: ToolSelfGenerationConfig = {
|
|
14
20
|
enabled: true,
|
|
@@ -26,13 +32,21 @@ const mockToolConfig: ToolSelfGenerationConfig = {
|
|
|
26
32
|
},
|
|
27
33
|
};
|
|
28
34
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
};
|
|
35
|
+
function chatResponse(content: string): ChatResponse {
|
|
36
|
+
return {
|
|
37
|
+
id: 'resp',
|
|
38
|
+
content,
|
|
39
|
+
finishReason: 'stop',
|
|
40
|
+
usage: { inputTokens: 0, outputTokens: 0, totalTokens: 0 },
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const mockLLM = {
|
|
45
|
+
provider: 'ollama',
|
|
46
|
+
chat: vi.fn<LLMBackend['chat']>(),
|
|
47
|
+
chatStream: async function* () {},
|
|
48
|
+
complete: vi.fn<NonNullable<LLMBackend['complete']>>(),
|
|
49
|
+
} satisfies LLMBackend;
|
|
36
50
|
|
|
37
51
|
describe('ToolSandbox', () => {
|
|
38
52
|
let sandbox: ToolSandbox;
|
|
@@ -218,23 +232,25 @@ describe('GapAnalyzer', () => {
|
|
|
218
232
|
});
|
|
219
233
|
|
|
220
234
|
it('analyzes capability gaps', async () => {
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
235
|
+
mockLLM.complete.mockResolvedValue(
|
|
236
|
+
chatResponse(
|
|
237
|
+
JSON.stringify({
|
|
238
|
+
hasGap: true,
|
|
239
|
+
gaps: [
|
|
240
|
+
{
|
|
241
|
+
id: 'gap-1',
|
|
242
|
+
description: 'Missing CSV parsing capability',
|
|
243
|
+
requiredCapability: 'Parse CSV files',
|
|
244
|
+
suggestedToolName: 'csv_parser',
|
|
245
|
+
complexity: 'simple',
|
|
246
|
+
confidence: 0.9,
|
|
247
|
+
reasoning: 'User needs to analyze CSV data',
|
|
248
|
+
},
|
|
249
|
+
],
|
|
250
|
+
canProceed: false,
|
|
251
|
+
})
|
|
252
|
+
)
|
|
253
|
+
);
|
|
238
254
|
|
|
239
255
|
const analyzer = new GapAnalyzer({ llm: mockLLM, config: mockToolConfig, model: 'test-model' });
|
|
240
256
|
|
|
@@ -242,8 +258,13 @@ describe('GapAnalyzer', () => {
|
|
|
242
258
|
{
|
|
243
259
|
name: 'calculator',
|
|
244
260
|
description: 'Perform calculations',
|
|
245
|
-
parameters: {},
|
|
261
|
+
parameters: z.object({}),
|
|
246
262
|
execute: async () => null,
|
|
263
|
+
toJSON: () => ({
|
|
264
|
+
name: 'calculator',
|
|
265
|
+
description: 'Perform calculations',
|
|
266
|
+
parameters: { type: 'object', properties: {} },
|
|
267
|
+
}),
|
|
247
268
|
},
|
|
248
269
|
]);
|
|
249
270
|
|
|
@@ -258,11 +279,12 @@ describe('ToolGenerator', () => {
|
|
|
258
279
|
});
|
|
259
280
|
|
|
260
281
|
it('generates tools from gaps', async () => {
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
282
|
+
mockLLM.complete.mockResolvedValue(
|
|
283
|
+
chatResponse(
|
|
284
|
+
JSON.stringify({
|
|
285
|
+
name: 'csv_parser',
|
|
286
|
+
description: 'Parse CSV data into JSON',
|
|
287
|
+
implementation: `
|
|
266
288
|
async function execute(params) {
|
|
267
289
|
const lines = params.data.split('\\n');
|
|
268
290
|
const headers = lines[0].split(',');
|
|
@@ -274,14 +296,15 @@ describe('ToolGenerator', () => {
|
|
|
274
296
|
});
|
|
275
297
|
}
|
|
276
298
|
`,
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
299
|
+
parameters: {
|
|
300
|
+
type: 'object',
|
|
301
|
+
properties: { data: { type: 'string' } },
|
|
302
|
+
required: ['data'],
|
|
303
|
+
},
|
|
304
|
+
reasoning: 'Simple CSV parsing without external dependencies',
|
|
305
|
+
})
|
|
306
|
+
)
|
|
307
|
+
);
|
|
285
308
|
|
|
286
309
|
const generator = new ToolGenerator({
|
|
287
310
|
llm: mockLLM,
|