@cogitator-ai/self-modifying 19.1.2 → 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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cogitator-ai/self-modifying",
3
- "version": "19.1.2",
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.27.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
- const mockLLM: LLMBackend = {
12
- complete: vi.fn(),
13
- name: 'mock',
14
- supportsTool: () => true,
15
- supportsStreaming: () => false,
16
- validateConfig: () => true,
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
- (mockLLM.complete as ReturnType<typeof vi.fn>).mockResolvedValue({
294
- content: JSON.stringify([
295
- {
296
- id: 'candidate_1',
297
- config: { temperature: 0.5 },
298
- reasoning: 'Lower temperature for precision',
299
- expectedImprovement: 0.7,
300
- risk: 'low',
301
- },
302
- {
303
- id: 'candidate_2',
304
- config: { temperature: 0.9, maxTokens: 8000 },
305
- reasoning: 'Higher temperature for creativity',
306
- expectedImprovement: 0.6,
307
- risk: 'medium',
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
- [{ name: 'tool1', description: 'Test', parameters: {}, execute: async () => null }],
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
- [{ name: 'tool1', description: 'Test', parameters: {}, execute: async () => null }],
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', { iteration: i }, [], []);
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: LLMBackend = {
13
- chat: vi.fn().mockResolvedValue({
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
- name: 'mock',
29
- supportsTool: () => true,
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
- maxAssessmentsPerRun: 5,
228
- maxAdaptationsPerRun: 3,
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
- [{ type: 'observation', content: 'Test insight', confidence: 0.8 }]
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);
@@ -36,6 +36,7 @@ function createMockTool(name: string, result: unknown): Tool {
36
36
 
37
37
  function chatResponse(content: string, toolCalls?: ToolCall[]): ChatResponse {
38
38
  return {
39
+ id: 'resp',
39
40
  content,
40
41
  toolCalls,
41
42
  finishReason: toolCalls?.length ? 'tool_calls' : 'stop',
@@ -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 { LLMBackend, GeneratedTool, ToolSelfGenerationConfig } from '@cogitator-ai/types';
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
- const mockLLM: LLMBackend = {
30
- complete: vi.fn(),
31
- name: 'mock',
32
- supportsTool: () => true,
33
- supportsStreaming: () => false,
34
- validateConfig: () => true,
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
- (mockLLM.complete as ReturnType<typeof vi.fn>).mockResolvedValue({
222
- content: JSON.stringify({
223
- hasGap: true,
224
- gaps: [
225
- {
226
- id: 'gap-1',
227
- description: 'Missing CSV parsing capability',
228
- requiredCapability: 'Parse CSV files',
229
- suggestedToolName: 'csv_parser',
230
- complexity: 'simple',
231
- confidence: 0.9,
232
- reasoning: 'User needs to analyze CSV data',
233
- },
234
- ],
235
- canProceed: false,
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
- (mockLLM.complete as ReturnType<typeof vi.fn>).mockResolvedValue({
262
- content: JSON.stringify({
263
- name: 'csv_parser',
264
- description: 'Parse CSV data into JSON',
265
- implementation: `
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
- parameters: {
278
- type: 'object',
279
- properties: { data: { type: 'string' } },
280
- required: ['data'],
281
- },
282
- reasoning: 'Simple CSV parsing without external dependencies',
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,