@gotza02/seq-thinking 1.1.4 → 1.1.6
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 +31 -27
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/mcp-server.js +1 -1
- package/package.json +8 -2
- package/agents_test.log +0 -15
- package/data/agents/1770106504306-dljh9ef.json +0 -68
- package/data/agents/1770106504310-4oarrst.json +0 -58
- package/data/agents/1770106540588-pvitt55.json +0 -68
- package/data/agents/1770106540595-z2ya871.json +0 -58
- package/data/agents/1770106710890-0e2naq1.json +0 -68
- package/data/agents/1770106710893-r076yxx.json +0 -58
- package/data/agents/1770109212161-4ybd0i7.json +0 -68
- package/data/agents/1770109212166-gkhya8h.json +0 -58
- package/data/agents/1770117726716-lrnm415.json +0 -68
- package/data/agents/1770117726719-w6hsf3v.json +0 -58
- package/data/sessions/1770100622009-5afiuyv.json +0 -499
- package/data/sessions/1770106504312-75zk750.json +0 -107
- package/data/sessions/1770106540597-z8e8soo.json +0 -150
- package/data/sessions/1770106710894-0kxgy5x.json +0 -150
- package/data/sessions/1770109212169-zpddeb9.json +0 -150
- package/data/sessions/1770117726720-frcwj99.json +0 -150
- package/real_world_test.log +0 -200
- package/real_world_test_dynamic.log +0 -184
- package/real_world_test_real.log +0 -184
- package/src/__tests__/agents.test.ts +0 -858
- package/src/__tests__/mcp-server.test.ts +0 -380
- package/src/__tests__/sequential-thinking.test.ts +0 -687
- package/src/__tests__/swarm-coordinator.test.ts +0 -903
- package/src/__tests__/types.test.ts +0 -839
- package/src/__tests__/utils.test.ts +0 -322
- package/src/agents/base-agent.ts +0 -288
- package/src/agents/critic-agent.ts +0 -582
- package/src/agents/index.ts +0 -11
- package/src/agents/meta-reasoning-agent.ts +0 -314
- package/src/agents/reasoner-agent.ts +0 -312
- package/src/agents/synthesizer-agent.ts +0 -641
- package/src/index.ts +0 -118
- package/src/mcp-server.ts +0 -391
- package/src/real_world_test.ts +0 -89
- package/src/sequential-thinking.ts +0 -614
- package/src/swarm-coordinator.ts +0 -772
- package/src/types/index.ts +0 -915
- package/src/utils/index.ts +0 -1004
- package/src/utils/llm-adapter.ts +0 -110
- package/src/utils/logger.ts +0 -56
- package/src/utils/persistence.ts +0 -109
- package/test_output.log +0 -0
- package/tsconfig.json +0 -21
|
@@ -1,858 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Agents Test Suite
|
|
3
|
-
* Tests for BaseAgent, ReasonerAgent, CriticAgent, SynthesizerAgent, and MetaReasoningAgent
|
|
4
|
-
*/
|
|
5
|
-
import { test, describe, beforeEach } from 'node:test';
|
|
6
|
-
import assert from 'node:assert';
|
|
7
|
-
import {
|
|
8
|
-
BaseAgent,
|
|
9
|
-
ReasonerAgent,
|
|
10
|
-
CriticAgent,
|
|
11
|
-
SynthesizerAgent,
|
|
12
|
-
MetaReasoningAgent,
|
|
13
|
-
} from '../agents/index.js';
|
|
14
|
-
import {
|
|
15
|
-
AgentType,
|
|
16
|
-
ThoughtType,
|
|
17
|
-
ReasoningStrategy,
|
|
18
|
-
CriticType,
|
|
19
|
-
SynthesizerType,
|
|
20
|
-
AgentStatus,
|
|
21
|
-
TaskStatus,
|
|
22
|
-
type AgentConfig,
|
|
23
|
-
type AgentCapability,
|
|
24
|
-
type Task,
|
|
25
|
-
type TaskResult,
|
|
26
|
-
type SwarmMessage,
|
|
27
|
-
MessageType,
|
|
28
|
-
} from '../types/index.js';
|
|
29
|
-
|
|
30
|
-
// Concrete implementation of BaseAgent for testing
|
|
31
|
-
class TestAgent extends BaseAgent {
|
|
32
|
-
getType(): AgentType {
|
|
33
|
-
return AgentType.UTILITY;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
getCapabilities(): AgentCapability[] {
|
|
37
|
-
return [
|
|
38
|
-
{
|
|
39
|
-
name: 'test-capability',
|
|
40
|
-
description: 'For testing purposes',
|
|
41
|
-
confidence: 0.9,
|
|
42
|
-
performanceMetrics: {
|
|
43
|
-
tasksCompleted: 10,
|
|
44
|
-
averageQuality: 0.85,
|
|
45
|
-
averageTimeMs: 100,
|
|
46
|
-
},
|
|
47
|
-
},
|
|
48
|
-
];
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
public createTaskResult(
|
|
52
|
-
taskId: string,
|
|
53
|
-
output: any,
|
|
54
|
-
confidence: number,
|
|
55
|
-
processingTimeMs: number,
|
|
56
|
-
metadata: any = {}
|
|
57
|
-
): TaskResult {
|
|
58
|
-
return super.createTaskResult(taskId, output, confidence, processingTimeMs, metadata);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
async process(task: Task): Promise<TaskResult> {
|
|
62
|
-
return this.createTaskResult(
|
|
63
|
-
task.id,
|
|
64
|
-
{ processed: true, input: task.input },
|
|
65
|
-
0.9,
|
|
66
|
-
100
|
|
67
|
-
);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
describe('BaseAgent', () => {
|
|
72
|
-
let agent: TestAgent;
|
|
73
|
-
|
|
74
|
-
beforeEach(() => {
|
|
75
|
-
agent = new TestAgent({
|
|
76
|
-
name: 'Test Agent',
|
|
77
|
-
capabilities: [
|
|
78
|
-
{
|
|
79
|
-
name: 'test-capability',
|
|
80
|
-
description: 'For testing purposes',
|
|
81
|
-
confidence: 0.9,
|
|
82
|
-
performanceMetrics: {
|
|
83
|
-
tasksCompleted: 10,
|
|
84
|
-
averageQuality: 0.85,
|
|
85
|
-
averageTimeMs: 100,
|
|
86
|
-
},
|
|
87
|
-
}
|
|
88
|
-
],
|
|
89
|
-
maxConcurrentTasks: 3,
|
|
90
|
-
confidenceThreshold: 0.7,
|
|
91
|
-
});
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
test('should have unique id', () => {
|
|
95
|
-
const agent2 = new TestAgent({ name: 'Test Agent 2', capabilities: [], maxConcurrentTasks: 1, confidenceThreshold: 0.5 });
|
|
96
|
-
assert.notStrictEqual(agent.id, agent2.id);
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
test('should return correct type', () => {
|
|
100
|
-
assert.strictEqual(agent.getType(), AgentType.UTILITY);
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
test('should return capabilities', () => {
|
|
104
|
-
const capabilities = agent.getCapabilities();
|
|
105
|
-
assert.ok(Array.isArray(capabilities));
|
|
106
|
-
assert.ok(capabilities.length > 0);
|
|
107
|
-
assert.ok(capabilities[0].name);
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
test('should execute task', async () => {
|
|
111
|
-
const task = createMockTask();
|
|
112
|
-
const result = await agent.execute(task);
|
|
113
|
-
|
|
114
|
-
assert.ok(result);
|
|
115
|
-
assert.strictEqual(result.taskId, task.id);
|
|
116
|
-
assert.strictEqual(result.agentId, agent.id);
|
|
117
|
-
assert.strictEqual(result.success, true);
|
|
118
|
-
assert.ok(result.output);
|
|
119
|
-
assert.ok(typeof result.confidence === 'number');
|
|
120
|
-
assert.ok(typeof result.processingTimeMs === 'number');
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
test('should set status to busy during execution', async () => {
|
|
124
|
-
const task = createMockTask();
|
|
125
|
-
|
|
126
|
-
// Status should be idle before execution
|
|
127
|
-
assert.strictEqual(agent.getStatus(), 'idle');
|
|
128
|
-
|
|
129
|
-
const executionPromise = agent.execute(task);
|
|
130
|
-
|
|
131
|
-
// Status might be busy during execution (implementation dependent)
|
|
132
|
-
const result = await executionPromise;
|
|
133
|
-
|
|
134
|
-
assert.ok(result);
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
test('should track current tasks', async () => {
|
|
138
|
-
const task = createMockTask();
|
|
139
|
-
|
|
140
|
-
assert.deepStrictEqual(agent.getCurrentTasks(), []);
|
|
141
|
-
|
|
142
|
-
await agent.execute(task);
|
|
143
|
-
|
|
144
|
-
// After execution, task should be removed from current tasks
|
|
145
|
-
assert.deepStrictEqual(agent.getCurrentTasks(), []);
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
test('should handle message subscription', () => {
|
|
149
|
-
const messages: SwarmMessage[] = [];
|
|
150
|
-
|
|
151
|
-
const unsubscribe = agent.onMessage((msg) => {
|
|
152
|
-
messages.push(msg);
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
assert.ok(typeof unsubscribe === 'function');
|
|
156
|
-
|
|
157
|
-
const testMessage = createMockMessage();
|
|
158
|
-
agent.receiveMessage(testMessage);
|
|
159
|
-
|
|
160
|
-
assert.strictEqual(messages.length, 1);
|
|
161
|
-
assert.strictEqual(messages[0].id, testMessage.id);
|
|
162
|
-
|
|
163
|
-
unsubscribe();
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
test('should unsubscribe from messages', () => {
|
|
167
|
-
const messages: SwarmMessage[] = [];
|
|
168
|
-
|
|
169
|
-
const unsubscribe = agent.onMessage((msg) => {
|
|
170
|
-
messages.push(msg);
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
unsubscribe();
|
|
174
|
-
|
|
175
|
-
const testMessage = createMockMessage();
|
|
176
|
-
agent.receiveMessage(testMessage);
|
|
177
|
-
|
|
178
|
-
// After unsubscribe, should not receive messages
|
|
179
|
-
assert.strictEqual(messages.length, 0);
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
test('should get performance metrics', async () => {
|
|
183
|
-
const task = createMockTask();
|
|
184
|
-
await agent.execute(task);
|
|
185
|
-
|
|
186
|
-
const metrics = agent.getPerformanceMetrics();
|
|
187
|
-
|
|
188
|
-
assert.ok(typeof metrics.tasksCompleted === 'number');
|
|
189
|
-
assert.ok(typeof metrics.averageQuality === 'number');
|
|
190
|
-
assert.ok(typeof metrics.averageTimeMs === 'number');
|
|
191
|
-
assert.ok(typeof metrics.successRate === 'number');
|
|
192
|
-
|
|
193
|
-
assert.strictEqual(metrics.tasksCompleted, 1);
|
|
194
|
-
assert.ok(metrics.successRate >= 0 && metrics.successRate <= 1);
|
|
195
|
-
});
|
|
196
|
-
|
|
197
|
-
test('should check capability', () => {
|
|
198
|
-
assert.strictEqual(agent.hasCapability('test-capability'), true);
|
|
199
|
-
assert.strictEqual(agent.hasCapability('non-existent'), false);
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
test('should get capability confidence', () => {
|
|
203
|
-
assert.strictEqual(agent.getCapabilityConfidence('test-capability'), 0.9);
|
|
204
|
-
assert.strictEqual(agent.getCapabilityConfidence('non-existent'), 0);
|
|
205
|
-
});
|
|
206
|
-
|
|
207
|
-
test('should check if can handle task', () => {
|
|
208
|
-
const taskWithCapability = createMockTask({
|
|
209
|
-
requirements: {
|
|
210
|
-
requiredCapabilities: ['test-capability'],
|
|
211
|
-
minConfidence: 0.5,
|
|
212
|
-
maxTimeMs: 5000
|
|
213
|
-
}
|
|
214
|
-
});
|
|
215
|
-
const taskWithoutCapability = createMockTask({
|
|
216
|
-
requirements: {
|
|
217
|
-
requiredCapabilities: ['unknown-capability'],
|
|
218
|
-
minConfidence: 0.5,
|
|
219
|
-
maxTimeMs: 5000
|
|
220
|
-
}
|
|
221
|
-
});
|
|
222
|
-
|
|
223
|
-
assert.strictEqual(agent.canHandleTask(taskWithCapability), true);
|
|
224
|
-
assert.strictEqual(agent.canHandleTask(taskWithoutCapability), false);
|
|
225
|
-
});
|
|
226
|
-
|
|
227
|
-
test('should create task result', () => {
|
|
228
|
-
const result = (agent as TestAgent).createTaskResult(
|
|
229
|
-
'task-001',
|
|
230
|
-
{ answer: 42 },
|
|
231
|
-
0.95,
|
|
232
|
-
500,
|
|
233
|
-
{ tokensUsed: 100 }
|
|
234
|
-
);
|
|
235
|
-
|
|
236
|
-
assert.strictEqual(result.taskId, 'task-001');
|
|
237
|
-
assert.strictEqual(result.agentId, agent.id);
|
|
238
|
-
assert.strictEqual(result.success, true);
|
|
239
|
-
assert.deepStrictEqual(result.output, { answer: 42 });
|
|
240
|
-
assert.strictEqual(result.confidence, 0.95);
|
|
241
|
-
assert.strictEqual(result.processingTimeMs, 500);
|
|
242
|
-
assert.strictEqual(result.metadata.tokensUsed, 100);
|
|
243
|
-
});
|
|
244
|
-
|
|
245
|
-
test('should set and get status', () => {
|
|
246
|
-
agent.setStatus(AgentStatus.OFFLINE);
|
|
247
|
-
assert.strictEqual(agent.getStatus(), AgentStatus.OFFLINE);
|
|
248
|
-
});
|
|
249
|
-
|
|
250
|
-
test('should track multiple executions', async () => {
|
|
251
|
-
for (let i = 0; i < 5; i++) {
|
|
252
|
-
await agent.execute(createMockTask());
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
const metrics = agent.getPerformanceMetrics();
|
|
256
|
-
assert.strictEqual(metrics.tasksCompleted, 5);
|
|
257
|
-
});
|
|
258
|
-
});
|
|
259
|
-
|
|
260
|
-
describe('ReasonerAgent', () => {
|
|
261
|
-
let agent: ReasonerAgent;
|
|
262
|
-
|
|
263
|
-
beforeEach(() => {
|
|
264
|
-
agent = new ReasonerAgent({
|
|
265
|
-
name: 'Test Reasoner',
|
|
266
|
-
strategy: ReasoningStrategy.CHAIN_OF_THOUGHT,
|
|
267
|
-
maxIterations: 5,
|
|
268
|
-
confidenceThreshold: 0.7,
|
|
269
|
-
});
|
|
270
|
-
});
|
|
271
|
-
|
|
272
|
-
test('should return correct type', () => {
|
|
273
|
-
assert.strictEqual(agent.getType(), AgentType.REASONER);
|
|
274
|
-
});
|
|
275
|
-
|
|
276
|
-
test('should return reasoning capabilities', () => {
|
|
277
|
-
const capabilities = agent.getCapabilities();
|
|
278
|
-
assert.ok(capabilities.length > 0);
|
|
279
|
-
assert.ok(capabilities.some(c => c.name.includes('reasoning') || c.name.includes('chain')));
|
|
280
|
-
});
|
|
281
|
-
|
|
282
|
-
test('should process reasoning task', async () => {
|
|
283
|
-
const task = createMockTask({
|
|
284
|
-
type: 'reasoning',
|
|
285
|
-
input: { problem: 'What is 2 + 2?' },
|
|
286
|
-
});
|
|
287
|
-
|
|
288
|
-
const result = await agent.process(task);
|
|
289
|
-
|
|
290
|
-
assert.ok(result);
|
|
291
|
-
assert.strictEqual(result.success, true);
|
|
292
|
-
assert.ok(result.output);
|
|
293
|
-
});
|
|
294
|
-
|
|
295
|
-
test('should handle chain of thought reasoning', async () => {
|
|
296
|
-
const cotAgent = new ReasonerAgent({
|
|
297
|
-
name: 'CoT Reasoner',
|
|
298
|
-
strategy: ReasoningStrategy.CHAIN_OF_THOUGHT,
|
|
299
|
-
});
|
|
300
|
-
|
|
301
|
-
const task = createMockTask({ input: { problem: 'Complex problem' } });
|
|
302
|
-
const result = await cotAgent.process(task);
|
|
303
|
-
|
|
304
|
-
assert.ok(result);
|
|
305
|
-
});
|
|
306
|
-
|
|
307
|
-
test('should handle tree of thought reasoning', async () => {
|
|
308
|
-
const totAgent = new ReasonerAgent({
|
|
309
|
-
name: 'ToT Reasoner',
|
|
310
|
-
strategy: ReasoningStrategy.TREE_OF_THOUGHT,
|
|
311
|
-
});
|
|
312
|
-
|
|
313
|
-
const task = createMockTask({ input: { problem: 'Multi-path problem' } });
|
|
314
|
-
const result = await totAgent.process(task);
|
|
315
|
-
|
|
316
|
-
assert.ok(result);
|
|
317
|
-
});
|
|
318
|
-
|
|
319
|
-
test('should handle analogical reasoning', async () => {
|
|
320
|
-
const analogicalAgent = new ReasonerAgent({
|
|
321
|
-
name: 'Analogical Reasoner',
|
|
322
|
-
strategy: ReasoningStrategy.ANALOGICAL,
|
|
323
|
-
});
|
|
324
|
-
|
|
325
|
-
const task = createMockTask({ input: { problem: 'Find analogy' } });
|
|
326
|
-
const result = await analogicalAgent.process(task);
|
|
327
|
-
|
|
328
|
-
assert.ok(result);
|
|
329
|
-
});
|
|
330
|
-
|
|
331
|
-
test('should handle abductive reasoning', async () => {
|
|
332
|
-
const abductiveAgent = new ReasonerAgent({
|
|
333
|
-
name: 'Abductive Reasoner',
|
|
334
|
-
strategy: ReasoningStrategy.ABDUCTIVE,
|
|
335
|
-
});
|
|
336
|
-
|
|
337
|
-
const task = createMockTask({ input: { problem: 'Find best explanation' } });
|
|
338
|
-
const result = await abductiveAgent.process(task);
|
|
339
|
-
|
|
340
|
-
assert.ok(result);
|
|
341
|
-
});
|
|
342
|
-
|
|
343
|
-
test('should respect max iterations', async () => {
|
|
344
|
-
const limitedAgent = new ReasonerAgent({
|
|
345
|
-
name: 'Limited Reasoner',
|
|
346
|
-
maxIterations: 2,
|
|
347
|
-
});
|
|
348
|
-
|
|
349
|
-
const task = createMockTask({ input: { problem: 'Iterative problem' } });
|
|
350
|
-
const result = await limitedAgent.process(task);
|
|
351
|
-
|
|
352
|
-
assert.ok(result);
|
|
353
|
-
});
|
|
354
|
-
|
|
355
|
-
test('should respect confidence threshold', async () => {
|
|
356
|
-
const highThresholdAgent = new ReasonerAgent({
|
|
357
|
-
name: 'High Threshold Reasoner',
|
|
358
|
-
confidenceThreshold: 0.95,
|
|
359
|
-
});
|
|
360
|
-
|
|
361
|
-
const task = createMockTask({ input: { problem: 'Difficult problem' } });
|
|
362
|
-
const result = await highThresholdAgent.process(task);
|
|
363
|
-
|
|
364
|
-
assert.ok(result);
|
|
365
|
-
// Result confidence should be below threshold if not confident enough
|
|
366
|
-
assert.ok(result.confidence <= 1);
|
|
367
|
-
});
|
|
368
|
-
});
|
|
369
|
-
|
|
370
|
-
describe('CriticAgent', () => {
|
|
371
|
-
let agent: CriticAgent;
|
|
372
|
-
|
|
373
|
-
beforeEach(() => {
|
|
374
|
-
agent = new CriticAgent({
|
|
375
|
-
name: 'Test Critic',
|
|
376
|
-
criticType: CriticType.LOGICAL,
|
|
377
|
-
severityThreshold: 0.5,
|
|
378
|
-
});
|
|
379
|
-
});
|
|
380
|
-
|
|
381
|
-
test('should return correct type', () => {
|
|
382
|
-
assert.strictEqual(agent.getType(), AgentType.CRITIC);
|
|
383
|
-
});
|
|
384
|
-
|
|
385
|
-
test('should return critic capabilities', () => {
|
|
386
|
-
const capabilities = agent.getCapabilities();
|
|
387
|
-
assert.ok(capabilities.length > 0);
|
|
388
|
-
assert.ok(capabilities.some(c => c.name.includes('critique') || c.name.includes('evaluation')));
|
|
389
|
-
});
|
|
390
|
-
|
|
391
|
-
test('should process evaluation task', async () => {
|
|
392
|
-
const task = createMockTask({
|
|
393
|
-
type: 'evaluation',
|
|
394
|
-
input: { content: 'This is a statement to evaluate' },
|
|
395
|
-
});
|
|
396
|
-
|
|
397
|
-
const result = await agent.process(task);
|
|
398
|
-
|
|
399
|
-
assert.ok(result);
|
|
400
|
-
assert.strictEqual(result.success, true);
|
|
401
|
-
assert.ok(result.output);
|
|
402
|
-
});
|
|
403
|
-
|
|
404
|
-
test('should evaluate logical consistency', async () => {
|
|
405
|
-
const logicalCritic = new CriticAgent({
|
|
406
|
-
name: 'Logical Critic',
|
|
407
|
-
criticType: CriticType.LOGICAL,
|
|
408
|
-
});
|
|
409
|
-
|
|
410
|
-
const task = createMockTask({
|
|
411
|
-
input: { content: 'If A then B. A is true. Therefore B is true.' },
|
|
412
|
-
});
|
|
413
|
-
const result = await logicalCritic.process(task);
|
|
414
|
-
|
|
415
|
-
assert.ok(result);
|
|
416
|
-
});
|
|
417
|
-
|
|
418
|
-
test('should check factual accuracy', async () => {
|
|
419
|
-
const factualCritic = new CriticAgent({
|
|
420
|
-
name: 'Factual Critic',
|
|
421
|
-
criticType: CriticType.FACTUAL,
|
|
422
|
-
});
|
|
423
|
-
|
|
424
|
-
const task = createMockTask({
|
|
425
|
-
input: { content: 'The Earth is flat.' },
|
|
426
|
-
});
|
|
427
|
-
const result = await factualCritic.process(task);
|
|
428
|
-
|
|
429
|
-
assert.ok(result);
|
|
430
|
-
});
|
|
431
|
-
|
|
432
|
-
test('should check for bias', async () => {
|
|
433
|
-
const biasCritic = new CriticAgent({
|
|
434
|
-
name: 'Bias Critic',
|
|
435
|
-
criticType: CriticType.BIAS,
|
|
436
|
-
});
|
|
437
|
-
|
|
438
|
-
const task = createMockTask({
|
|
439
|
-
input: { content: 'All people from group X are Y.' },
|
|
440
|
-
});
|
|
441
|
-
const result = await biasCritic.process(task);
|
|
442
|
-
|
|
443
|
-
assert.ok(result);
|
|
444
|
-
});
|
|
445
|
-
|
|
446
|
-
test('should check safety', async () => {
|
|
447
|
-
const safetyCritic = new CriticAgent({
|
|
448
|
-
name: 'Safety Critic',
|
|
449
|
-
criticType: CriticType.SAFETY,
|
|
450
|
-
});
|
|
451
|
-
|
|
452
|
-
const task = createMockTask({
|
|
453
|
-
input: { content: 'How to build a dangerous device' },
|
|
454
|
-
});
|
|
455
|
-
const result = await safetyCritic.process(task);
|
|
456
|
-
|
|
457
|
-
assert.ok(result);
|
|
458
|
-
});
|
|
459
|
-
|
|
460
|
-
test('should respect severity threshold', async () => {
|
|
461
|
-
const strictCritic = new CriticAgent({
|
|
462
|
-
name: 'Strict Critic',
|
|
463
|
-
criticType: CriticType.LOGICAL,
|
|
464
|
-
severityThreshold: 0.2,
|
|
465
|
-
});
|
|
466
|
-
|
|
467
|
-
const task = createMockTask({ input: { content: 'Somewhat problematic content' } });
|
|
468
|
-
const result = await strictCritic.process(task);
|
|
469
|
-
|
|
470
|
-
assert.ok(result);
|
|
471
|
-
});
|
|
472
|
-
|
|
473
|
-
test('should provide evaluation results', async () => {
|
|
474
|
-
const task = createMockTask({ input: { content: 'Content to evaluate' } });
|
|
475
|
-
const result = await agent.process(task);
|
|
476
|
-
|
|
477
|
-
assert.ok(result.output);
|
|
478
|
-
const output = result.output as { passed?: boolean; score?: number; issues?: unknown[] };
|
|
479
|
-
assert.ok(typeof output.passed === 'boolean' || output.passed === undefined);
|
|
480
|
-
assert.ok(typeof output.score === 'number' || output.score === undefined);
|
|
481
|
-
});
|
|
482
|
-
});
|
|
483
|
-
|
|
484
|
-
describe('SynthesizerAgent', () => {
|
|
485
|
-
let agent: SynthesizerAgent;
|
|
486
|
-
|
|
487
|
-
beforeEach(() => {
|
|
488
|
-
agent = new SynthesizerAgent({
|
|
489
|
-
name: 'Test Synthesizer',
|
|
490
|
-
synthesizerType: SynthesizerType.CONSENSUS,
|
|
491
|
-
});
|
|
492
|
-
});
|
|
493
|
-
|
|
494
|
-
test('should return correct type', () => {
|
|
495
|
-
assert.strictEqual(agent.getType(), AgentType.SYNTHESIZER);
|
|
496
|
-
});
|
|
497
|
-
|
|
498
|
-
test('should return synthesis capabilities', () => {
|
|
499
|
-
const capabilities = agent.getCapabilities();
|
|
500
|
-
assert.ok(capabilities.length > 0);
|
|
501
|
-
assert.ok(capabilities.some(c => c.name.includes('synthesis') || c.name.includes('consensus')));
|
|
502
|
-
});
|
|
503
|
-
|
|
504
|
-
test('should process synthesis task', async () => {
|
|
505
|
-
const task = createMockTask({
|
|
506
|
-
type: 'synthesis',
|
|
507
|
-
input: {
|
|
508
|
-
outputs: [
|
|
509
|
-
{ agentId: 'agent-1', output: 'Result A is long enough to be a key point.', confidence: 0.8 },
|
|
510
|
-
{ agentId: 'agent-2', output: 'Result B is also long enough to be a key point.', confidence: 0.7 },
|
|
511
|
-
],
|
|
512
|
-
goal: 'Combine results',
|
|
513
|
-
},
|
|
514
|
-
});
|
|
515
|
-
|
|
516
|
-
const result = await agent.process(task);
|
|
517
|
-
|
|
518
|
-
assert.ok(result);
|
|
519
|
-
assert.strictEqual(result.success, true);
|
|
520
|
-
assert.ok(result.output);
|
|
521
|
-
});
|
|
522
|
-
|
|
523
|
-
test('should build consensus', async () => {
|
|
524
|
-
const consensusAgent = new SynthesizerAgent({
|
|
525
|
-
name: 'Consensus Synthesizer',
|
|
526
|
-
synthesizerType: SynthesizerType.CONSENSUS,
|
|
527
|
-
});
|
|
528
|
-
|
|
529
|
-
const task = createMockTask({
|
|
530
|
-
input: {
|
|
531
|
-
outputs: [
|
|
532
|
-
{ agentId: 'a1', output: 'Agree', confidence: 0.9 },
|
|
533
|
-
{ agentId: 'a2', output: 'Agree', confidence: 0.85 },
|
|
534
|
-
{ agentId: 'a3', output: 'Agree', confidence: 0.8 },
|
|
535
|
-
],
|
|
536
|
-
goal: 'Find consensus',
|
|
537
|
-
},
|
|
538
|
-
});
|
|
539
|
-
const result = await consensusAgent.process(task);
|
|
540
|
-
|
|
541
|
-
assert.ok(result);
|
|
542
|
-
});
|
|
543
|
-
|
|
544
|
-
test('should perform creative synthesis', async () => {
|
|
545
|
-
const creativeAgent = new SynthesizerAgent({
|
|
546
|
-
name: 'Creative Synthesizer',
|
|
547
|
-
synthesizerType: SynthesizerType.CREATIVE,
|
|
548
|
-
});
|
|
549
|
-
|
|
550
|
-
const task = createMockTask({
|
|
551
|
-
input: {
|
|
552
|
-
outputs: [
|
|
553
|
-
{ agentId: 'a1', output: 'Idea 1', confidence: 0.7 },
|
|
554
|
-
{ agentId: 'a2', output: 'Idea 2', confidence: 0.6 },
|
|
555
|
-
],
|
|
556
|
-
goal: 'Generate creative combination',
|
|
557
|
-
},
|
|
558
|
-
});
|
|
559
|
-
const result = await creativeAgent.process(task);
|
|
560
|
-
|
|
561
|
-
assert.ok(result);
|
|
562
|
-
});
|
|
563
|
-
|
|
564
|
-
test('should resolve conflicts', async () => {
|
|
565
|
-
const conflictAgent = new SynthesizerAgent({
|
|
566
|
-
name: 'Conflict Resolver',
|
|
567
|
-
synthesizerType: SynthesizerType.CONFLICT_RESOLUTION,
|
|
568
|
-
});
|
|
569
|
-
|
|
570
|
-
const task = createMockTask({
|
|
571
|
-
input: {
|
|
572
|
-
outputs: [
|
|
573
|
-
{ agentId: 'a1', output: 'Option A', confidence: 0.8 },
|
|
574
|
-
{ agentId: 'a2', output: 'Option B', confidence: 0.75 },
|
|
575
|
-
],
|
|
576
|
-
goal: 'Resolve disagreement',
|
|
577
|
-
},
|
|
578
|
-
});
|
|
579
|
-
const result = await conflictAgent.process(task);
|
|
580
|
-
|
|
581
|
-
assert.ok(result);
|
|
582
|
-
});
|
|
583
|
-
|
|
584
|
-
test('should handle dissenting views', async () => {
|
|
585
|
-
const task = createMockTask({
|
|
586
|
-
input: {
|
|
587
|
-
outputs: [
|
|
588
|
-
{ agentId: 'a1', output: 'Majority view', confidence: 0.8, reasoning: 'Because X' },
|
|
589
|
-
{ agentId: 'a2', output: 'Majority view', confidence: 0.75 },
|
|
590
|
-
{ agentId: 'a3', output: 'Minority view', confidence: 0.6, reasoning: 'Because Y' },
|
|
591
|
-
],
|
|
592
|
-
goal: 'Synthesize with dissent',
|
|
593
|
-
},
|
|
594
|
-
});
|
|
595
|
-
const result = await agent.process(task);
|
|
596
|
-
|
|
597
|
-
assert.ok(result);
|
|
598
|
-
const output = result.output as { dissentingViews?: unknown[] };
|
|
599
|
-
// May or may not have dissenting views depending on implementation
|
|
600
|
-
assert.ok(output);
|
|
601
|
-
});
|
|
602
|
-
|
|
603
|
-
test('should handle empty inputs', async () => {
|
|
604
|
-
const task = createMockTask({
|
|
605
|
-
input: {
|
|
606
|
-
outputs: [],
|
|
607
|
-
goal: 'Synthesize nothing',
|
|
608
|
-
},
|
|
609
|
-
});
|
|
610
|
-
const result = await agent.process(task);
|
|
611
|
-
|
|
612
|
-
assert.ok(result);
|
|
613
|
-
});
|
|
614
|
-
|
|
615
|
-
test('should handle single input', async () => {
|
|
616
|
-
const task = createMockTask({
|
|
617
|
-
input: {
|
|
618
|
-
outputs: [{ agentId: 'a1', output: 'Only result', confidence: 0.9 }],
|
|
619
|
-
goal: 'Synthesize single input',
|
|
620
|
-
},
|
|
621
|
-
});
|
|
622
|
-
const result = await agent.process(task);
|
|
623
|
-
|
|
624
|
-
assert.ok(result);
|
|
625
|
-
});
|
|
626
|
-
});
|
|
627
|
-
|
|
628
|
-
describe('MetaReasoningAgent', () => {
|
|
629
|
-
let agent: MetaReasoningAgent;
|
|
630
|
-
|
|
631
|
-
beforeEach(() => {
|
|
632
|
-
agent = new MetaReasoningAgent({
|
|
633
|
-
name: 'Test Meta Reasoner',
|
|
634
|
-
});
|
|
635
|
-
});
|
|
636
|
-
|
|
637
|
-
test('should return correct type', () => {
|
|
638
|
-
assert.strictEqual(agent.getType(), AgentType.META_REASONING);
|
|
639
|
-
});
|
|
640
|
-
|
|
641
|
-
test('should return meta-reasoning capabilities', () => {
|
|
642
|
-
const capabilities = agent.getCapabilities();
|
|
643
|
-
assert.ok(capabilities.length > 0);
|
|
644
|
-
assert.ok(capabilities.some(c => c.name.includes('meta') || c.name.includes('reflection')));
|
|
645
|
-
});
|
|
646
|
-
|
|
647
|
-
test('should process meta-reasoning task', async () => {
|
|
648
|
-
const task = createMockTask({
|
|
649
|
-
type: 'meta-reasoning',
|
|
650
|
-
input: {
|
|
651
|
-
thoughts: [
|
|
652
|
-
{ id: 't1', content: 'First thought', type: ThoughtType.HYPOTHESIS },
|
|
653
|
-
{ id: 't2', content: 'Second thought', type: ThoughtType.ANALYSIS },
|
|
654
|
-
],
|
|
655
|
-
sessionContext: { topic: 'Test topic' },
|
|
656
|
-
},
|
|
657
|
-
});
|
|
658
|
-
|
|
659
|
-
const result = await agent.process(task);
|
|
660
|
-
|
|
661
|
-
assert.ok(result);
|
|
662
|
-
assert.strictEqual(result.success, true);
|
|
663
|
-
assert.ok(result.output);
|
|
664
|
-
});
|
|
665
|
-
|
|
666
|
-
test('should identify patterns', async () => {
|
|
667
|
-
const task = createMockTask({
|
|
668
|
-
input: {
|
|
669
|
-
thoughts: Array(5).fill(0).map((_, i) => ({
|
|
670
|
-
id: `t${i}`,
|
|
671
|
-
content: `Thought ${i}`,
|
|
672
|
-
type: i % 2 === 0 ? ThoughtType.HYPOTHESIS : ThoughtType.ANALYSIS,
|
|
673
|
-
})),
|
|
674
|
-
sessionContext: { topic: 'Pattern detection test' },
|
|
675
|
-
},
|
|
676
|
-
});
|
|
677
|
-
const result = await agent.process(task);
|
|
678
|
-
|
|
679
|
-
assert.ok(result);
|
|
680
|
-
const output = result.output as { observations?: Array<{ type: string }> };
|
|
681
|
-
// May identify patterns
|
|
682
|
-
assert.ok(output);
|
|
683
|
-
});
|
|
684
|
-
|
|
685
|
-
test('should detect concerns', async () => {
|
|
686
|
-
const task = createMockTask({
|
|
687
|
-
input: {
|
|
688
|
-
thoughts: [
|
|
689
|
-
{ id: 't1', content: 'Low confidence thought', confidence: 0.3 },
|
|
690
|
-
{ id: 't2', content: 'Contradictory statement' },
|
|
691
|
-
],
|
|
692
|
-
sessionContext: { topic: 'Concern detection test' },
|
|
693
|
-
},
|
|
694
|
-
});
|
|
695
|
-
const result = await agent.process(task);
|
|
696
|
-
|
|
697
|
-
assert.ok(result);
|
|
698
|
-
});
|
|
699
|
-
|
|
700
|
-
test('should provide recommendations', async () => {
|
|
701
|
-
const task = createMockTask({
|
|
702
|
-
input: {
|
|
703
|
-
thoughts: [{ id: 't1', content: 'Single thought' }],
|
|
704
|
-
sessionContext: { topic: 'Recommendation test' },
|
|
705
|
-
},
|
|
706
|
-
});
|
|
707
|
-
const result = await agent.process(task);
|
|
708
|
-
|
|
709
|
-
assert.ok(result);
|
|
710
|
-
const output = result.output as { recommendations?: string[] };
|
|
711
|
-
// Should provide some recommendations
|
|
712
|
-
assert.ok(output);
|
|
713
|
-
});
|
|
714
|
-
|
|
715
|
-
test('should handle empty thoughts', async () => {
|
|
716
|
-
const task = createMockTask({
|
|
717
|
-
input: {
|
|
718
|
-
thoughts: [],
|
|
719
|
-
sessionContext: { topic: 'Empty test' },
|
|
720
|
-
},
|
|
721
|
-
});
|
|
722
|
-
const result = await agent.process(task);
|
|
723
|
-
|
|
724
|
-
assert.ok(result);
|
|
725
|
-
});
|
|
726
|
-
|
|
727
|
-
test('should track meta-observations', async () => {
|
|
728
|
-
const task = createMockTask({
|
|
729
|
-
input: {
|
|
730
|
-
thoughts: Array(10).fill(0).map((_, i) => ({
|
|
731
|
-
id: `t${i}`,
|
|
732
|
-
content: `Thought ${i}`,
|
|
733
|
-
})),
|
|
734
|
-
sessionContext: { topic: 'Tracking test' },
|
|
735
|
-
},
|
|
736
|
-
});
|
|
737
|
-
const result = await agent.process(task);
|
|
738
|
-
|
|
739
|
-
assert.ok(result);
|
|
740
|
-
const output = result.output as { observations?: unknown[] };
|
|
741
|
-
// May have multiple observations
|
|
742
|
-
assert.ok(output);
|
|
743
|
-
});
|
|
744
|
-
});
|
|
745
|
-
|
|
746
|
-
describe('Agent Interactions', () => {
|
|
747
|
-
test('reasoner and critic should work together', async () => {
|
|
748
|
-
const reasoner = new ReasonerAgent({ name: 'Reasoner' });
|
|
749
|
-
const critic = new CriticAgent({ name: 'Critic', criticType: CriticType.LOGICAL });
|
|
750
|
-
|
|
751
|
-
const reasoningTask = createMockTask({ input: { problem: 'Solve X' } });
|
|
752
|
-
const reasoningResult = await reasoner.process(reasoningTask);
|
|
753
|
-
|
|
754
|
-
const evaluationTask = createMockTask({
|
|
755
|
-
input: { content: reasoningResult.output },
|
|
756
|
-
});
|
|
757
|
-
const evaluationResult = await critic.process(evaluationTask);
|
|
758
|
-
|
|
759
|
-
assert.ok(reasoningResult.success);
|
|
760
|
-
assert.ok(evaluationResult.success);
|
|
761
|
-
});
|
|
762
|
-
|
|
763
|
-
test('multiple agents can process same task type', async () => {
|
|
764
|
-
const reasoner1 = new ReasonerAgent({
|
|
765
|
-
name: 'Reasoner 1',
|
|
766
|
-
strategy: ReasoningStrategy.CHAIN_OF_THOUGHT,
|
|
767
|
-
});
|
|
768
|
-
const reasoner2 = new ReasonerAgent({
|
|
769
|
-
name: 'Reasoner 2',
|
|
770
|
-
strategy: ReasoningStrategy.TREE_OF_THOUGHT,
|
|
771
|
-
});
|
|
772
|
-
|
|
773
|
-
const task = createMockTask({ input: { problem: 'Compare strategies' } });
|
|
774
|
-
|
|
775
|
-
const result1 = await reasoner1.process(task);
|
|
776
|
-
const result2 = await reasoner2.process(task);
|
|
777
|
-
|
|
778
|
-
assert.ok(result1.success);
|
|
779
|
-
assert.ok(result2.success);
|
|
780
|
-
});
|
|
781
|
-
|
|
782
|
-
test('synthesizer can combine multiple agent outputs', async () => {
|
|
783
|
-
const synthesizer = new SynthesizerAgent({
|
|
784
|
-
name: 'Synthesizer',
|
|
785
|
-
synthesizerType: SynthesizerType.CONSENSUS,
|
|
786
|
-
});
|
|
787
|
-
|
|
788
|
-
const task = createMockTask({
|
|
789
|
-
input: {
|
|
790
|
-
outputs: [
|
|
791
|
-
{ agentId: 'reasoner', output: 'Reasoning result', confidence: 0.8 },
|
|
792
|
-
{ agentId: 'critic', output: 'Evaluation result', confidence: 0.75 },
|
|
793
|
-
],
|
|
794
|
-
goal: 'Combine agent outputs',
|
|
795
|
-
},
|
|
796
|
-
});
|
|
797
|
-
|
|
798
|
-
const result = await synthesizer.process(task);
|
|
799
|
-
assert.ok(result.success);
|
|
800
|
-
});
|
|
801
|
-
|
|
802
|
-
test('meta-reasoner can observe other agents', async () => {
|
|
803
|
-
const metaReasoner = new MetaReasoningAgent({ name: 'Meta' });
|
|
804
|
-
const reasoner = new ReasonerAgent({ name: 'Reasoner' });
|
|
805
|
-
|
|
806
|
-
const reasoningTask = createMockTask({ input: { problem: 'Problem' } });
|
|
807
|
-
const reasoningResult = await reasoner.process(reasoningTask);
|
|
808
|
-
|
|
809
|
-
const metaTask = createMockTask({
|
|
810
|
-
input: {
|
|
811
|
-
thoughts: [{ id: '1', content: JSON.stringify(reasoningResult.output) }],
|
|
812
|
-
sessionContext: { topic: 'Observe reasoning' },
|
|
813
|
-
},
|
|
814
|
-
});
|
|
815
|
-
const metaResult = await metaReasoner.process(metaTask);
|
|
816
|
-
|
|
817
|
-
assert.ok(metaResult.success);
|
|
818
|
-
});
|
|
819
|
-
});
|
|
820
|
-
|
|
821
|
-
// Helper functions
|
|
822
|
-
function createMockTask(overrides: Partial<Task> = {}): Task {
|
|
823
|
-
return {
|
|
824
|
-
id: `task-${Math.random().toString(36).substr(2, 9)}`,
|
|
825
|
-
type: 'test',
|
|
826
|
-
description: 'Test task',
|
|
827
|
-
input: {},
|
|
828
|
-
context: { dependencies: [] },
|
|
829
|
-
requirements: {
|
|
830
|
-
requiredCapabilities: [],
|
|
831
|
-
minConfidence: 0.5,
|
|
832
|
-
maxTimeMs: 5000,
|
|
833
|
-
},
|
|
834
|
-
assignedAgentId: null,
|
|
835
|
-
status: TaskStatus.PENDING,
|
|
836
|
-
result: null,
|
|
837
|
-
metadata: { createdAt: new Date() },
|
|
838
|
-
...overrides,
|
|
839
|
-
};
|
|
840
|
-
}
|
|
841
|
-
|
|
842
|
-
function createMockMessage(overrides: Partial<SwarmMessage> = {}): SwarmMessage {
|
|
843
|
-
return {
|
|
844
|
-
id: `msg-${Math.random().toString(36).substr(2, 9)}`,
|
|
845
|
-
type: MessageType.BROADCAST,
|
|
846
|
-
senderId: 'agent-test',
|
|
847
|
-
recipientId: null,
|
|
848
|
-
timestamp: new Date(),
|
|
849
|
-
payload: {},
|
|
850
|
-
context: {},
|
|
851
|
-
metadata: {
|
|
852
|
-
priority: 0,
|
|
853
|
-
ttl: 30000,
|
|
854
|
-
retryCount: 0,
|
|
855
|
-
},
|
|
856
|
-
...overrides,
|
|
857
|
-
};
|
|
858
|
-
}
|