@gotza02/seq-thinking 1.1.21 → 1.1.23
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 +98 -86
- package/SYSTEM_INSTRUCTIONS.md +35 -35
- package/dist/__tests__/agents/base-agent.js +215 -0
- package/dist/__tests__/agents/specialist-agent.js +75 -0
- package/dist/__tests__/specialist-agent.test.js +653 -30
- package/dist/__tests__/types/index.js +278 -0
- package/dist/__tests__/utils/llm-adapter.js +93 -0
- package/dist/__tests__/utils/logger.js +48 -0
- package/dist/constants.d.ts +69 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +96 -0
- package/dist/constants.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp-server.d.ts.map +1 -1
- package/dist/mcp-server.js +16 -2
- package/dist/mcp-server.js.map +1 -1
- package/dist/utils/llm-adapter.d.ts +4 -4
- package/dist/utils/llm-adapter.d.ts.map +1 -1
- package/dist/utils/llm-adapter.js +25 -23
- package/dist/utils/llm-adapter.js.map +1 -1
- package/dist/utils/persistence.d.ts +17 -0
- package/dist/utils/persistence.d.ts.map +1 -1
- package/dist/utils/persistence.js +60 -5
- package/dist/utils/persistence.js.map +1 -1
- package/dist/validation/index.d.ts +6 -0
- package/dist/validation/index.d.ts.map +1 -0
- package/dist/validation/index.js +6 -0
- package/dist/validation/index.js.map +1 -0
- package/dist/validation/schemas.d.ts +793 -0
- package/dist/validation/schemas.d.ts.map +1 -0
- package/dist/validation/schemas.js +340 -0
- package/dist/validation/schemas.js.map +1 -0
- package/dist/validation/schemas.test.d.ts +6 -0
- package/dist/validation/schemas.test.d.ts.map +1 -0
- package/dist/validation/schemas.test.js +171 -0
- package/dist/validation/schemas.test.js.map +1 -0
- package/package.json +7 -6
|
@@ -1,39 +1,662 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Specialist Agent Test Suite
|
|
3
|
+
* Comprehensive tests for SpecialistAgent including unit tests and integration tests
|
|
4
|
+
* @module tests/specialist-agent
|
|
5
|
+
* @version 1.0.0
|
|
6
|
+
*/
|
|
7
|
+
import { describe, test, beforeEach, before } from 'node:test';
|
|
2
8
|
import assert from 'node:assert';
|
|
3
9
|
import { SpecialistAgent } from '../agents/specialist-agent.js';
|
|
4
|
-
import { AgentType } from '../types/index.js';
|
|
10
|
+
import { AgentType, TaskStatus } from '../types/index.js';
|
|
5
11
|
describe('SpecialistAgent', () => {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
12
|
+
let agent;
|
|
13
|
+
const originalEnv = process.env.MOCK_LLM;
|
|
14
|
+
// Enable LLM mocking before all tests
|
|
15
|
+
before(() => {
|
|
16
|
+
process.env.MOCK_LLM = 'true';
|
|
9
17
|
});
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
capabilities: ['logic', 'math']
|
|
14
|
-
});
|
|
15
|
-
const caps = agent.getCapabilities();
|
|
16
|
-
assert.strictEqual(caps.length, 2);
|
|
17
|
-
assert.strictEqual(caps[0].name, 'logic');
|
|
18
|
-
assert.strictEqual(caps[1].name, 'math');
|
|
18
|
+
// Cleanup after all tests
|
|
19
|
+
beforeEach(() => {
|
|
20
|
+
process.env.MOCK_LLM = 'true';
|
|
19
21
|
});
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
name: 'Test Specialist'
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
22
|
+
describe('Unit Tests - Agent Creation', () => {
|
|
23
|
+
test('should create specialist agent with default configuration', () => {
|
|
24
|
+
const defaultAgent = new SpecialistAgent({ name: 'Test Specialist' });
|
|
25
|
+
assert.strictEqual(defaultAgent.config.name, 'Test Specialist');
|
|
26
|
+
assert.strictEqual(defaultAgent.getType(), AgentType.SPECIALIST);
|
|
27
|
+
assert.ok(defaultAgent.id);
|
|
28
|
+
assert.ok(typeof defaultAgent.id === 'string');
|
|
29
|
+
});
|
|
30
|
+
test('should create specialist agent with single capability', () => {
|
|
31
|
+
const singleCapAgent = new SpecialistAgent({
|
|
32
|
+
name: 'Code Review Specialist',
|
|
33
|
+
capabilities: [
|
|
34
|
+
{
|
|
35
|
+
name: 'code-review',
|
|
36
|
+
description: 'Review code for quality and bugs',
|
|
37
|
+
confidence: 0.9,
|
|
38
|
+
performanceMetrics: {
|
|
39
|
+
tasksCompleted: 0,
|
|
40
|
+
averageQuality: 0,
|
|
41
|
+
averageTimeMs: 0
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
]
|
|
45
|
+
});
|
|
46
|
+
const caps = singleCapAgent.getCapabilities();
|
|
47
|
+
assert.strictEqual(caps.length, 1);
|
|
48
|
+
assert.strictEqual(caps[0].name, 'code-review');
|
|
49
|
+
assert.strictEqual(caps[0].confidence, 0.9);
|
|
50
|
+
});
|
|
51
|
+
test('should create specialist agent with multiple capabilities', () => {
|
|
52
|
+
agent = new SpecialistAgent({
|
|
53
|
+
name: 'Security Specialist',
|
|
54
|
+
capabilities: [
|
|
55
|
+
{
|
|
56
|
+
name: 'security-audit',
|
|
57
|
+
description: 'Security audit and vulnerability assessment',
|
|
58
|
+
confidence: 0.9,
|
|
59
|
+
performanceMetrics: {
|
|
60
|
+
tasksCompleted: 10,
|
|
61
|
+
averageQuality: 0.85,
|
|
62
|
+
averageTimeMs: 1200
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
name: 'penetration-testing',
|
|
67
|
+
description: 'Penetration testing and exploitation',
|
|
68
|
+
confidence: 0.85,
|
|
69
|
+
performanceMetrics: {
|
|
70
|
+
tasksCompleted: 5,
|
|
71
|
+
averageQuality: 0.9,
|
|
72
|
+
averageTimeMs: 3000
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
name: 'threat-analysis',
|
|
77
|
+
description: 'Threat modeling and analysis',
|
|
78
|
+
confidence: 0.88,
|
|
79
|
+
performanceMetrics: {
|
|
80
|
+
tasksCompleted: 8,
|
|
81
|
+
averageQuality: 0.82,
|
|
82
|
+
averageTimeMs: 1500
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
]
|
|
86
|
+
});
|
|
87
|
+
const caps = agent.getCapabilities();
|
|
88
|
+
assert.strictEqual(caps.length, 3);
|
|
89
|
+
assert.ok(caps.some(c => c.name === 'security-audit'));
|
|
90
|
+
assert.ok(caps.some(c => c.name === 'penetration-testing'));
|
|
91
|
+
assert.ok(caps.some(c => c.name === 'threat-analysis'));
|
|
92
|
+
});
|
|
93
|
+
test('should normalize string capabilities to AgentCapability objects', () => {
|
|
94
|
+
const stringCapAgent = new SpecialistAgent({
|
|
95
|
+
name: 'String Capabilities Specialist',
|
|
96
|
+
capabilities: ['logic', 'math', 'statistics', 'data-analysis']
|
|
97
|
+
});
|
|
98
|
+
const caps = stringCapAgent.getCapabilities();
|
|
99
|
+
assert.strictEqual(caps.length, 4);
|
|
100
|
+
// Check that all capabilities are properly normalized
|
|
101
|
+
caps.forEach((cap, index) => {
|
|
102
|
+
assert.ok(cap.name);
|
|
103
|
+
assert.ok(cap.description.includes(cap.name));
|
|
104
|
+
assert.strictEqual(cap.confidence, 0.8);
|
|
105
|
+
assert.strictEqual(cap.performanceMetrics.tasksCompleted, 0);
|
|
106
|
+
});
|
|
107
|
+
assert.strictEqual(caps[0].name, 'logic');
|
|
108
|
+
assert.strictEqual(caps[1].name, 'math');
|
|
109
|
+
assert.strictEqual(caps[2].name, 'statistics');
|
|
110
|
+
assert.strictEqual(caps[3].name, 'data-analysis');
|
|
111
|
+
});
|
|
112
|
+
test('should handle mixed string and object capabilities', () => {
|
|
113
|
+
const mixedCapAgent = new SpecialistAgent({
|
|
114
|
+
name: 'Mixed Capabilities Specialist',
|
|
115
|
+
capabilities: [
|
|
116
|
+
'string-cap-1',
|
|
117
|
+
{
|
|
118
|
+
name: 'object-cap-1',
|
|
119
|
+
description: 'An object capability',
|
|
120
|
+
confidence: 0.95,
|
|
121
|
+
performanceMetrics: {
|
|
122
|
+
tasksCompleted: 5,
|
|
123
|
+
averageQuality: 0.9,
|
|
124
|
+
averageTimeMs: 1000
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
'string-cap-2'
|
|
128
|
+
]
|
|
129
|
+
});
|
|
130
|
+
const caps = mixedCapAgent.getCapabilities();
|
|
131
|
+
assert.strictEqual(caps.length, 3);
|
|
132
|
+
// String capability should be normalized
|
|
133
|
+
assert.strictEqual(caps[0].name, 'string-cap-1');
|
|
134
|
+
assert.strictEqual(caps[0].confidence, 0.8);
|
|
135
|
+
// Object capability should preserve values
|
|
136
|
+
assert.strictEqual(caps[1].name, 'object-cap-1');
|
|
137
|
+
assert.strictEqual(caps[1].confidence, 0.95);
|
|
138
|
+
// String capability should be normalized
|
|
139
|
+
assert.strictEqual(caps[2].name, 'string-cap-2');
|
|
140
|
+
assert.strictEqual(caps[2].confidence, 0.8);
|
|
141
|
+
});
|
|
142
|
+
test('should handle empty capabilities array', () => {
|
|
143
|
+
const emptyCapAgent = new SpecialistAgent({
|
|
144
|
+
name: 'Empty Capabilities Specialist',
|
|
145
|
+
capabilities: []
|
|
146
|
+
});
|
|
147
|
+
const caps = emptyCapAgent.getCapabilities();
|
|
148
|
+
assert.strictEqual(caps.length, 0);
|
|
149
|
+
});
|
|
150
|
+
test('should handle undefined capabilities', () => {
|
|
151
|
+
const undefinedCapAgent = new SpecialistAgent({
|
|
152
|
+
name: 'Undefined Capabilities Specialist'
|
|
153
|
+
});
|
|
154
|
+
const caps = undefinedCapAgent.getCapabilities();
|
|
155
|
+
assert.strictEqual(caps.length, 0);
|
|
156
|
+
});
|
|
157
|
+
test('should use default confidence threshold when not specified', () => {
|
|
158
|
+
const defaultThresholdAgent = new SpecialistAgent({
|
|
159
|
+
name: 'Default Threshold Specialist',
|
|
160
|
+
capabilities: ['test']
|
|
161
|
+
});
|
|
162
|
+
assert.strictEqual(defaultThresholdAgent.config.confidenceThreshold, 0.7);
|
|
163
|
+
});
|
|
164
|
+
test('should use custom confidence threshold when specified', () => {
|
|
165
|
+
const customThresholdAgent = new SpecialistAgent({
|
|
166
|
+
name: 'Custom Threshold Specialist',
|
|
167
|
+
capabilities: ['test'],
|
|
168
|
+
confidenceThreshold: 0.85
|
|
169
|
+
});
|
|
170
|
+
assert.strictEqual(customThresholdAgent.config.confidenceThreshold, 0.85);
|
|
171
|
+
});
|
|
172
|
+
test('should have unique ID for each agent instance', () => {
|
|
173
|
+
const agent1 = new SpecialistAgent({ name: 'Agent 1' });
|
|
174
|
+
const agent2 = new SpecialistAgent({ name: 'Agent 2' });
|
|
175
|
+
const agent3 = new SpecialistAgent({ name: 'Agent 3' });
|
|
176
|
+
assert.notStrictEqual(agent1.id, agent2.id);
|
|
177
|
+
assert.notStrictEqual(agent2.id, agent3.id);
|
|
178
|
+
assert.notStrictEqual(agent1.id, agent3.id);
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
describe('Unit Tests - Capability Checking', () => {
|
|
182
|
+
beforeEach(() => {
|
|
183
|
+
agent = new SpecialistAgent({
|
|
184
|
+
name: 'Test Specialist',
|
|
185
|
+
capabilities: [
|
|
186
|
+
{ name: 'code-review', description: 'Code review', confidence: 0.9, performanceMetrics: { tasksCompleted: 0, averageQuality: 0, averageTimeMs: 0 } },
|
|
187
|
+
{ name: 'security-audit', description: 'Security audit', confidence: 0.85, performanceMetrics: { tasksCompleted: 0, averageQuality: 0, averageTimeMs: 0 } },
|
|
188
|
+
{ name: 'performance-optimization', description: 'Performance optimization', confidence: 0.8, performanceMetrics: { tasksCompleted: 0, averageQuality: 0, averageTimeMs: 0 } }
|
|
189
|
+
]
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
test('should return correct type', () => {
|
|
193
|
+
assert.strictEqual(agent.getType(), AgentType.SPECIALIST);
|
|
194
|
+
});
|
|
195
|
+
test('should check if has specific capability', () => {
|
|
196
|
+
assert.strictEqual(agent.hasCapability('code-review'), true);
|
|
197
|
+
assert.strictEqual(agent.hasCapability('security-audit'), true);
|
|
198
|
+
assert.strictEqual(agent.hasCapability('performance-optimization'), true);
|
|
199
|
+
assert.strictEqual(agent.hasCapability('non-existent'), false);
|
|
200
|
+
});
|
|
201
|
+
test('should get capability confidence', () => {
|
|
202
|
+
assert.strictEqual(agent.getCapabilityConfidence('code-review'), 0.9);
|
|
203
|
+
assert.strictEqual(agent.getCapabilityConfidence('security-audit'), 0.85);
|
|
204
|
+
assert.strictEqual(agent.getCapabilityConfidence('performance-optimization'), 0.8);
|
|
205
|
+
assert.strictEqual(agent.getCapabilityConfidence('unknown'), 0);
|
|
206
|
+
});
|
|
207
|
+
test('should check if can handle task with required capabilities', () => {
|
|
208
|
+
const taskWithMatchingCaps = createMockTask({
|
|
209
|
+
requirements: {
|
|
210
|
+
requiredCapabilities: ['code-review'],
|
|
211
|
+
minConfidence: 0.5,
|
|
212
|
+
maxTimeMs: 5000
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
const taskWithMultipleMatchingCaps = createMockTask({
|
|
216
|
+
requirements: {
|
|
217
|
+
requiredCapabilities: ['code-review', 'security-audit'],
|
|
218
|
+
minConfidence: 0.5,
|
|
219
|
+
maxTimeMs: 5000
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
const taskWithNonMatchingCaps = createMockTask({
|
|
223
|
+
requirements: {
|
|
224
|
+
requiredCapabilities: ['machine-learning'],
|
|
225
|
+
minConfidence: 0.5,
|
|
226
|
+
maxTimeMs: 5000
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
const taskWithPartialMatchingCaps = createMockTask({
|
|
230
|
+
requirements: {
|
|
231
|
+
requiredCapabilities: ['code-review', 'machine-learning'],
|
|
232
|
+
minConfidence: 0.5,
|
|
233
|
+
maxTimeMs: 5000
|
|
234
|
+
}
|
|
235
|
+
});
|
|
236
|
+
assert.strictEqual(agent.canHandleTask(taskWithMatchingCaps), true);
|
|
237
|
+
assert.strictEqual(agent.canHandleTask(taskWithMultipleMatchingCaps), true);
|
|
238
|
+
assert.strictEqual(agent.canHandleTask(taskWithNonMatchingCaps), false);
|
|
239
|
+
assert.strictEqual(agent.canHandleTask(taskWithPartialMatchingCaps), false);
|
|
240
|
+
});
|
|
241
|
+
test('should return all capabilities', () => {
|
|
242
|
+
const caps = agent.getCapabilities();
|
|
243
|
+
assert.ok(Array.isArray(caps));
|
|
244
|
+
assert.strictEqual(caps.length, 3);
|
|
245
|
+
caps.forEach(cap => {
|
|
246
|
+
assert.ok(cap.name);
|
|
247
|
+
assert.ok(cap.description);
|
|
248
|
+
assert.ok(typeof cap.confidence === 'number');
|
|
249
|
+
assert.ok(cap.performanceMetrics);
|
|
250
|
+
});
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
describe('Unit Tests - Task Processing', () => {
|
|
254
|
+
beforeEach(() => {
|
|
255
|
+
process.env.MOCK_LLM = 'true';
|
|
256
|
+
agent = new SpecialistAgent({
|
|
257
|
+
name: 'Code Review Specialist',
|
|
258
|
+
capabilities: [
|
|
259
|
+
{ name: 'code-review', description: 'Code review', confidence: 0.9, performanceMetrics: { tasksCompleted: 0, averageQuality: 0, averageTimeMs: 0 } },
|
|
260
|
+
{ name: 'security-audit', description: 'Security audit', confidence: 0.85, performanceMetrics: { tasksCompleted: 0, averageQuality: 0, averageTimeMs: 0 } }
|
|
261
|
+
]
|
|
262
|
+
});
|
|
263
|
+
});
|
|
264
|
+
test('should process task with single capability', async () => {
|
|
265
|
+
const task = createMockTask({
|
|
266
|
+
type: 'code-review',
|
|
267
|
+
description: 'Review this code for bugs',
|
|
268
|
+
input: { code: 'function add(a, b) { return a + b; }' }
|
|
269
|
+
});
|
|
270
|
+
const result = await agent.process(task);
|
|
271
|
+
assert.ok(result);
|
|
272
|
+
assert.strictEqual(result.taskId, task.id);
|
|
273
|
+
assert.strictEqual(result.agentId, agent.id);
|
|
274
|
+
assert.strictEqual(result.success, true);
|
|
275
|
+
assert.ok(result.output);
|
|
276
|
+
});
|
|
277
|
+
test('should process task with multiple capabilities', async () => {
|
|
278
|
+
const task = createMockTask({
|
|
279
|
+
type: 'security-audit',
|
|
280
|
+
description: 'Audit code for security vulnerabilities',
|
|
281
|
+
input: { code: 'eval(userInput);', language: 'javascript' }
|
|
282
|
+
});
|
|
283
|
+
const result = await agent.process(task);
|
|
284
|
+
assert.ok(result);
|
|
285
|
+
assert.strictEqual(result.taskId, task.id);
|
|
286
|
+
assert.strictEqual(result.agentId, agent.id);
|
|
287
|
+
assert.strictEqual(result.success, true);
|
|
288
|
+
assert.ok(result.output);
|
|
289
|
+
});
|
|
290
|
+
test('should include capabilities in prompt output', async () => {
|
|
291
|
+
const task = createMockTask({
|
|
292
|
+
description: 'Test task',
|
|
293
|
+
input: { data: 'test' }
|
|
294
|
+
});
|
|
295
|
+
const result = await agent.process(task);
|
|
296
|
+
assert.ok(result);
|
|
297
|
+
assert.ok(result.output);
|
|
298
|
+
// Output should contain conclusion with capabilities used
|
|
299
|
+
const output = result.output;
|
|
300
|
+
assert.ok(output.conclusion);
|
|
301
|
+
assert.ok(output.specialistRole);
|
|
302
|
+
assert.strictEqual(output.specialistRole, 'Code Review Specialist');
|
|
303
|
+
assert.ok(Array.isArray(output.capabilitiesUsed));
|
|
304
|
+
assert.ok(output.capabilitiesUsed.includes('code-review'));
|
|
305
|
+
assert.ok(output.capabilitiesUsed.includes('security-audit'));
|
|
306
|
+
});
|
|
307
|
+
test('should return success result on LLM success', async () => {
|
|
308
|
+
const task = createMockTask({
|
|
309
|
+
description: 'Successful task',
|
|
310
|
+
input: { data: 'test' }
|
|
311
|
+
});
|
|
312
|
+
const result = await agent.process(task);
|
|
313
|
+
assert.strictEqual(result.success, true);
|
|
314
|
+
assert.ok(result.confidence > 0);
|
|
315
|
+
assert.ok(result.processingTimeMs >= 0);
|
|
316
|
+
});
|
|
317
|
+
test('should set correct confidence on success', async () => {
|
|
318
|
+
const task = createMockTask({
|
|
319
|
+
description: 'Test confidence',
|
|
320
|
+
input: {}
|
|
321
|
+
});
|
|
322
|
+
const result = await agent.process(task);
|
|
323
|
+
// When LLM succeeds, confidence should be 0.85
|
|
324
|
+
assert.strictEqual(result.confidence, 0.85);
|
|
325
|
+
});
|
|
326
|
+
test('should handle task with empty input', async () => {
|
|
327
|
+
const task = createMockTask({
|
|
328
|
+
description: 'Empty input task',
|
|
329
|
+
input: {}
|
|
330
|
+
});
|
|
331
|
+
const result = await agent.process(task);
|
|
332
|
+
assert.ok(result);
|
|
333
|
+
assert.strictEqual(result.success, true);
|
|
334
|
+
});
|
|
335
|
+
test('should handle task with string input', async () => {
|
|
336
|
+
const task = createMockTask({
|
|
337
|
+
description: 'String input task',
|
|
338
|
+
input: 'This is a string input'
|
|
339
|
+
});
|
|
340
|
+
const result = await agent.process(task);
|
|
341
|
+
assert.ok(result);
|
|
342
|
+
assert.strictEqual(result.success, true);
|
|
343
|
+
});
|
|
344
|
+
test('should handle task with complex nested input', async () => {
|
|
345
|
+
const task = createMockTask({
|
|
346
|
+
description: 'Complex input task',
|
|
347
|
+
input: {
|
|
348
|
+
users: [
|
|
349
|
+
{ id: 1, name: 'Alice', roles: ['admin', 'user'] },
|
|
350
|
+
{ id: 2, name: 'Bob', roles: ['user'] }
|
|
351
|
+
],
|
|
352
|
+
settings: {
|
|
353
|
+
theme: 'dark',
|
|
354
|
+
notifications: true,
|
|
355
|
+
preferences: {
|
|
356
|
+
language: 'en',
|
|
357
|
+
timezone: 'UTC'
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
});
|
|
362
|
+
const result = await agent.process(task);
|
|
363
|
+
assert.ok(result);
|
|
364
|
+
assert.strictEqual(result.success, true);
|
|
365
|
+
});
|
|
366
|
+
test('should handle task with null input', async () => {
|
|
367
|
+
const task = createMockTask({
|
|
368
|
+
description: 'Null input task',
|
|
369
|
+
input: null
|
|
370
|
+
});
|
|
371
|
+
const result = await agent.process(task);
|
|
372
|
+
assert.ok(result);
|
|
373
|
+
assert.strictEqual(result.success, true);
|
|
374
|
+
});
|
|
375
|
+
test('should handle task with array input', async () => {
|
|
376
|
+
const task = createMockTask({
|
|
377
|
+
description: 'Array input task',
|
|
378
|
+
input: [1, 2, 3, 4, 5]
|
|
379
|
+
});
|
|
380
|
+
const result = await agent.process(task);
|
|
381
|
+
assert.ok(result);
|
|
382
|
+
assert.strictEqual(result.success, true);
|
|
383
|
+
});
|
|
384
|
+
test('should handle long description', async () => {
|
|
385
|
+
const task = createMockTask({
|
|
386
|
+
description: 'This is a very long description that contains a lot of text and details about what needs to be done for this particular task. It should be handled properly without any issues.',
|
|
387
|
+
input: { data: 'test' }
|
|
388
|
+
});
|
|
389
|
+
const result = await agent.process(task);
|
|
390
|
+
assert.ok(result);
|
|
391
|
+
assert.strictEqual(result.success, true);
|
|
392
|
+
});
|
|
393
|
+
});
|
|
394
|
+
describe('Integration Tests', () => {
|
|
395
|
+
beforeEach(() => {
|
|
396
|
+
process.env.MOCK_LLM = 'true';
|
|
397
|
+
});
|
|
398
|
+
test('should handle complex task input with mixed data types', async () => {
|
|
399
|
+
const complexAgent = new SpecialistAgent({
|
|
400
|
+
name: 'Data Analysis Specialist',
|
|
401
|
+
capabilities: [
|
|
402
|
+
{ name: 'data-analysis', description: 'Data analysis', confidence: 0.9, performanceMetrics: { tasksCompleted: 0, averageQuality: 0, averageTimeMs: 0 } },
|
|
403
|
+
{ name: 'visualization', description: 'Data visualization', confidence: 0.85, performanceMetrics: { tasksCompleted: 0, averageQuality: 0, averageTimeMs: 0 } }
|
|
404
|
+
]
|
|
405
|
+
});
|
|
406
|
+
const task = createMockTask({
|
|
407
|
+
type: 'data-analysis',
|
|
408
|
+
description: 'Analyze sales data and create visualizations',
|
|
409
|
+
input: {
|
|
410
|
+
salesData: [
|
|
411
|
+
{ month: 'Jan', revenue: 10000, units: 100 },
|
|
412
|
+
{ month: 'Feb', revenue: 15000, units: 150 },
|
|
413
|
+
{ month: 'Mar', revenue: 12000, units: 120 }
|
|
414
|
+
],
|
|
415
|
+
targetRevenue: 14000,
|
|
416
|
+
options: {
|
|
417
|
+
includeTrends: true,
|
|
418
|
+
includeForecast: false,
|
|
419
|
+
chartTypes: ['line', 'bar']
|
|
420
|
+
},
|
|
421
|
+
metadata: {
|
|
422
|
+
source: 'CRM',
|
|
423
|
+
lastUpdated: new Date().toISOString()
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
});
|
|
427
|
+
const result = await complexAgent.process(task);
|
|
428
|
+
assert.ok(result);
|
|
429
|
+
assert.strictEqual(result.success, true);
|
|
430
|
+
assert.ok(result.output);
|
|
431
|
+
assert.strictEqual(result.confidence, 0.85);
|
|
432
|
+
});
|
|
433
|
+
test('should process different task types', async () => {
|
|
434
|
+
const agent = new SpecialistAgent({
|
|
435
|
+
name: 'Multi-Purpose Specialist',
|
|
436
|
+
capabilities: [
|
|
437
|
+
{ name: 'code-review', description: 'Code review', confidence: 0.9, performanceMetrics: { tasksCompleted: 0, averageQuality: 0, averageTimeMs: 0 } },
|
|
438
|
+
{ name: 'documentation', description: 'Documentation', confidence: 0.85, performanceMetrics: { tasksCompleted: 0, averageQuality: 0, averageTimeMs: 0 } },
|
|
439
|
+
{ name: 'refactoring', description: 'Refactoring', confidence: 0.88, performanceMetrics: { tasksCompleted: 0, averageQuality: 0, averageTimeMs: 0 } }
|
|
440
|
+
]
|
|
441
|
+
});
|
|
442
|
+
// Code review task
|
|
443
|
+
const codeReviewTask = createMockTask({
|
|
444
|
+
type: 'code-review',
|
|
445
|
+
description: 'Review pull request',
|
|
446
|
+
input: { code: 'const x = 1;' }
|
|
447
|
+
});
|
|
448
|
+
// Documentation task
|
|
449
|
+
const docTask = createMockTask({
|
|
450
|
+
type: 'documentation',
|
|
451
|
+
description: 'Generate API docs',
|
|
452
|
+
input: { endpoints: ['/api/users', '/api/posts'] }
|
|
453
|
+
});
|
|
454
|
+
// Refactoring task
|
|
455
|
+
const refactoringTask = createMockTask({
|
|
456
|
+
type: 'refactoring',
|
|
457
|
+
description: 'Refactor legacy code',
|
|
458
|
+
input: { file: 'legacy.js', lines: 1000 }
|
|
459
|
+
});
|
|
460
|
+
const result1 = await agent.process(codeReviewTask);
|
|
461
|
+
const result2 = await agent.process(docTask);
|
|
462
|
+
const result3 = await agent.process(refactoringTask);
|
|
463
|
+
assert.strictEqual(result1.success, true);
|
|
464
|
+
assert.strictEqual(result2.success, true);
|
|
465
|
+
assert.strictEqual(result3.success, true);
|
|
466
|
+
});
|
|
467
|
+
test('should execute task through execute method', async () => {
|
|
468
|
+
const agent = new SpecialistAgent({
|
|
469
|
+
name: 'Execute Test Specialist',
|
|
470
|
+
capabilities: [
|
|
471
|
+
{ name: 'test', description: 'Test capability', confidence: 0.9, performanceMetrics: { tasksCompleted: 0, averageQuality: 0, averageTimeMs: 0 } }
|
|
472
|
+
]
|
|
473
|
+
});
|
|
474
|
+
const task = createMockTask({
|
|
475
|
+
description: 'Execute test',
|
|
476
|
+
input: { test: true }
|
|
477
|
+
});
|
|
478
|
+
const result = await agent.execute(task);
|
|
479
|
+
assert.ok(result);
|
|
480
|
+
assert.strictEqual(result.taskId, task.id);
|
|
481
|
+
assert.strictEqual(result.agentId, agent.id);
|
|
482
|
+
assert.strictEqual(result.success, true);
|
|
483
|
+
assert.ok(result.output);
|
|
484
|
+
assert.ok(typeof result.confidence === 'number');
|
|
485
|
+
assert.ok(typeof result.processingTimeMs === 'number');
|
|
486
|
+
});
|
|
487
|
+
test('should track performance metrics after task execution', async () => {
|
|
488
|
+
const agent = new SpecialistAgent({
|
|
489
|
+
name: 'Metrics Test Specialist',
|
|
490
|
+
capabilities: [
|
|
491
|
+
{ name: 'metrics-test', description: 'Metrics test', confidence: 0.9, performanceMetrics: { tasksCompleted: 0, averageQuality: 0, averageTimeMs: 0 } }
|
|
492
|
+
]
|
|
493
|
+
});
|
|
494
|
+
const initialMetrics = agent.getPerformanceMetrics();
|
|
495
|
+
assert.strictEqual(initialMetrics.tasksCompleted, 0);
|
|
496
|
+
// Execute multiple tasks
|
|
497
|
+
for (let i = 0; i < 3; i++) {
|
|
498
|
+
await agent.execute(createMockTask({
|
|
499
|
+
description: `Task ${i}`,
|
|
500
|
+
input: { index: i }
|
|
501
|
+
}));
|
|
28
502
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
503
|
+
const finalMetrics = agent.getPerformanceMetrics();
|
|
504
|
+
assert.strictEqual(finalMetrics.tasksCompleted, 3);
|
|
505
|
+
assert.ok(finalMetrics.successRate >= 0 && finalMetrics.successRate <= 1);
|
|
506
|
+
});
|
|
507
|
+
test('should handle multiple sequential tasks', async () => {
|
|
508
|
+
const agent = new SpecialistAgent({
|
|
509
|
+
name: 'Sequential Test Specialist',
|
|
510
|
+
capabilities: [
|
|
511
|
+
{ name: 'sequential', description: 'Sequential processing', confidence: 0.9, performanceMetrics: { tasksCompleted: 0, averageQuality: 0, averageTimeMs: 0 } }
|
|
512
|
+
]
|
|
513
|
+
});
|
|
514
|
+
const results = [];
|
|
515
|
+
for (let i = 0; i < 5; i++) {
|
|
516
|
+
const task = createMockTask({
|
|
517
|
+
description: `Sequential task ${i}`,
|
|
518
|
+
input: { sequence: i }
|
|
519
|
+
});
|
|
520
|
+
const result = await agent.process(task);
|
|
521
|
+
results.push(result);
|
|
34
522
|
}
|
|
35
|
-
|
|
36
|
-
|
|
523
|
+
assert.strictEqual(results.length, 5);
|
|
524
|
+
results.forEach((result, index) => {
|
|
525
|
+
assert.strictEqual(result.success, true);
|
|
526
|
+
assert.ok(result.output);
|
|
527
|
+
});
|
|
528
|
+
});
|
|
529
|
+
test('should handle task with special characters in input', async () => {
|
|
530
|
+
const agent = new SpecialistAgent({
|
|
531
|
+
name: 'Special Chars Specialist',
|
|
532
|
+
capabilities: [
|
|
533
|
+
{ name: 'text-processing', description: 'Text processing', confidence: 0.9, performanceMetrics: { tasksCompleted: 0, averageQuality: 0, averageTimeMs: 0 } }
|
|
534
|
+
]
|
|
535
|
+
});
|
|
536
|
+
const task = createMockTask({
|
|
537
|
+
description: 'Process text with special characters',
|
|
538
|
+
input: {
|
|
539
|
+
text: 'Special chars: <>&"\'\\n\\t`~!@#$%^&*()_+-=[]{}|;:,.<>?'
|
|
540
|
+
}
|
|
541
|
+
});
|
|
542
|
+
const result = await agent.process(task);
|
|
543
|
+
assert.ok(result);
|
|
544
|
+
assert.strictEqual(result.success, true);
|
|
545
|
+
});
|
|
546
|
+
test('should handle task with unicode input', async () => {
|
|
547
|
+
const agent = new SpecialistAgent({
|
|
548
|
+
name: 'Unicode Specialist',
|
|
549
|
+
capabilities: [
|
|
550
|
+
{ name: 'unicode-processing', description: 'Unicode processing', confidence: 0.9, performanceMetrics: { tasksCompleted: 0, averageQuality: 0, averageTimeMs: 0 } }
|
|
551
|
+
]
|
|
552
|
+
});
|
|
553
|
+
const task = createMockTask({
|
|
554
|
+
description: 'Process unicode text',
|
|
555
|
+
input: {
|
|
556
|
+
text: 'Unicode: 你好世界 🌍 Привет мир مرحبا بالعالم'
|
|
557
|
+
}
|
|
558
|
+
});
|
|
559
|
+
const result = await agent.process(task);
|
|
560
|
+
assert.ok(result);
|
|
561
|
+
assert.strictEqual(result.success, true);
|
|
562
|
+
});
|
|
563
|
+
});
|
|
564
|
+
describe('Edge Cases and Error Handling', () => {
|
|
565
|
+
test('should handle task with very long input', async () => {
|
|
566
|
+
process.env.MOCK_LLM = 'true';
|
|
567
|
+
const agent = new SpecialistAgent({
|
|
568
|
+
name: 'Long Input Specialist',
|
|
569
|
+
capabilities: [
|
|
570
|
+
{ name: 'processing', description: 'Processing', confidence: 0.9, performanceMetrics: { tasksCompleted: 0, averageQuality: 0, averageTimeMs: 0 } }
|
|
571
|
+
]
|
|
572
|
+
});
|
|
573
|
+
const longString = 'a'.repeat(10000);
|
|
574
|
+
const task = createMockTask({
|
|
575
|
+
description: 'Process long input',
|
|
576
|
+
input: { data: longString }
|
|
577
|
+
});
|
|
578
|
+
const result = await agent.process(task);
|
|
579
|
+
assert.ok(result);
|
|
580
|
+
assert.strictEqual(result.success, true);
|
|
581
|
+
});
|
|
582
|
+
test('should handle task with deeply nested input', async () => {
|
|
583
|
+
process.env.MOCK_LLM = 'true';
|
|
584
|
+
const agent = new SpecialistAgent({
|
|
585
|
+
name: 'Nested Input Specialist',
|
|
586
|
+
capabilities: [
|
|
587
|
+
{ name: 'processing', description: 'Processing', confidence: 0.9, performanceMetrics: { tasksCompleted: 0, averageQuality: 0, averageTimeMs: 0 } }
|
|
588
|
+
]
|
|
589
|
+
});
|
|
590
|
+
// Create deeply nested object
|
|
591
|
+
let nested = { value: 'deep' };
|
|
592
|
+
for (let i = 0; i < 10; i++) {
|
|
593
|
+
nested = { nested: nested };
|
|
594
|
+
}
|
|
595
|
+
const task = createMockTask({
|
|
596
|
+
description: 'Process nested input',
|
|
597
|
+
input: nested
|
|
598
|
+
});
|
|
599
|
+
const result = await agent.process(task);
|
|
600
|
+
assert.ok(result);
|
|
601
|
+
assert.strictEqual(result.success, true);
|
|
602
|
+
});
|
|
603
|
+
test('should set status during execution', async () => {
|
|
604
|
+
process.env.MOCK_LLM = 'true';
|
|
605
|
+
const agent = new SpecialistAgent({
|
|
606
|
+
name: 'Status Test Specialist',
|
|
607
|
+
capabilities: [
|
|
608
|
+
{ name: 'status-test', description: 'Status test', confidence: 0.9, performanceMetrics: { tasksCompleted: 0, averageQuality: 0, averageTimeMs: 0 } }
|
|
609
|
+
]
|
|
610
|
+
});
|
|
611
|
+
const task = createMockTask({
|
|
612
|
+
description: 'Status test',
|
|
613
|
+
input: {}
|
|
614
|
+
});
|
|
615
|
+
// Before execution, status should be idle
|
|
616
|
+
assert.strictEqual(agent.getStatus(), 'idle');
|
|
617
|
+
const result = await agent.execute(task);
|
|
618
|
+
// After execution, status should return to idle
|
|
619
|
+
assert.strictEqual(agent.getStatus(), 'idle');
|
|
620
|
+
assert.ok(result);
|
|
621
|
+
});
|
|
622
|
+
test('should handle capabilities with zero confidence', () => {
|
|
623
|
+
const agent = new SpecialistAgent({
|
|
624
|
+
name: 'Zero Confidence Specialist',
|
|
625
|
+
capabilities: [
|
|
626
|
+
{ name: 'zero-cap', description: 'Zero confidence capability', confidence: 0, performanceMetrics: { tasksCompleted: 0, averageQuality: 0, averageTimeMs: 0 } }
|
|
627
|
+
]
|
|
628
|
+
});
|
|
629
|
+
assert.strictEqual(agent.getCapabilityConfidence('zero-cap'), 0);
|
|
630
|
+
assert.strictEqual(agent.hasCapability('zero-cap'), true);
|
|
631
|
+
});
|
|
632
|
+
test('should handle capability with very high confidence', () => {
|
|
633
|
+
const agent = new SpecialistAgent({
|
|
634
|
+
name: 'High Confidence Specialist',
|
|
635
|
+
capabilities: [
|
|
636
|
+
{ name: 'high-cap', description: 'High confidence capability', confidence: 0.999, performanceMetrics: { tasksCompleted: 0, averageQuality: 0, averageTimeMs: 0 } }
|
|
637
|
+
]
|
|
638
|
+
});
|
|
639
|
+
assert.strictEqual(agent.getCapabilityConfidence('high-cap'), 0.999);
|
|
640
|
+
});
|
|
37
641
|
});
|
|
38
642
|
});
|
|
39
|
-
|
|
643
|
+
// Helper function to create mock tasks
|
|
644
|
+
function createMockTask(overrides = {}) {
|
|
645
|
+
return {
|
|
646
|
+
id: `task-${Math.random().toString(36).substr(2, 9)}`,
|
|
647
|
+
type: 'test',
|
|
648
|
+
description: 'Test task',
|
|
649
|
+
input: {},
|
|
650
|
+
context: { dependencies: [] },
|
|
651
|
+
requirements: {
|
|
652
|
+
requiredCapabilities: [],
|
|
653
|
+
minConfidence: 0.5,
|
|
654
|
+
maxTimeMs: 5000,
|
|
655
|
+
},
|
|
656
|
+
assignedAgentId: null,
|
|
657
|
+
status: TaskStatus.PENDING,
|
|
658
|
+
result: null,
|
|
659
|
+
metadata: { createdAt: new Date() },
|
|
660
|
+
...overrides,
|
|
661
|
+
};
|
|
662
|
+
}
|