This commit is contained in:
143
packages/agent/tests/wave-e-topology.test.ts
Normal file
143
packages/agent/tests/wave-e-topology.test.ts
Normal file
@@ -0,0 +1,143 @@
|
||||
/**
|
||||
* Wave E — Agent/Workspace Topology Productization tests.
|
||||
*
|
||||
* Verifies:
|
||||
* 1. ROLE_TOOL_PRESETS is exported and has expected shape
|
||||
* 2. Role presets have valid tool lists
|
||||
* 3. Workflow templates are introspectable
|
||||
* 4. Agent topology data structure is complete
|
||||
*/
|
||||
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import {
|
||||
ROLE_TOOL_PRESETS,
|
||||
listWorkflowTemplates,
|
||||
WORKFLOW_TEMPLATES,
|
||||
} from '../src/index.js';
|
||||
|
||||
describe('Wave E: Agent Topology', () => {
|
||||
describe('Role Presets', () => {
|
||||
it('exports ROLE_TOOL_PRESETS with at least 6 roles', () => {
|
||||
expect(ROLE_TOOL_PRESETS).toBeDefined();
|
||||
expect(Object.keys(ROLE_TOOL_PRESETS).length).toBeGreaterThanOrEqual(6);
|
||||
});
|
||||
|
||||
it('includes core roles: researcher, writer, coder, analyst, reviewer, planner', () => {
|
||||
const roles = Object.keys(ROLE_TOOL_PRESETS);
|
||||
expect(roles).toContain('researcher');
|
||||
expect(roles).toContain('writer');
|
||||
expect(roles).toContain('coder');
|
||||
expect(roles).toContain('analyst');
|
||||
expect(roles).toContain('reviewer');
|
||||
expect(roles).toContain('planner');
|
||||
});
|
||||
|
||||
it('each role has a non-empty tool array', () => {
|
||||
for (const [role, tools] of Object.entries(ROLE_TOOL_PRESETS)) {
|
||||
expect(Array.isArray(tools), `${role} tools should be an array`).toBe(true);
|
||||
expect(tools.length, `${role} should have at least 1 tool`).toBeGreaterThan(0);
|
||||
}
|
||||
});
|
||||
|
||||
it('researcher has web_search and search_memory', () => {
|
||||
expect(ROLE_TOOL_PRESETS.researcher).toContain('web_search');
|
||||
expect(ROLE_TOOL_PRESETS.researcher).toContain('search_memory');
|
||||
});
|
||||
|
||||
it('coder has bash and git tools', () => {
|
||||
expect(ROLE_TOOL_PRESETS.coder).toContain('bash');
|
||||
expect(ROLE_TOOL_PRESETS.coder).toContain('git_status');
|
||||
});
|
||||
|
||||
it('writer has document generation', () => {
|
||||
expect(ROLE_TOOL_PRESETS.writer).toContain('write_file');
|
||||
expect(ROLE_TOOL_PRESETS.writer).toContain('generate_docx');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Workflow Templates', () => {
|
||||
it('lists at least 3 workflow templates', () => {
|
||||
const names = listWorkflowTemplates();
|
||||
expect(names.length).toBeGreaterThanOrEqual(3);
|
||||
});
|
||||
|
||||
it('includes research-team, review-pair, plan-execute', () => {
|
||||
const names = listWorkflowTemplates();
|
||||
expect(names).toContain('research-team');
|
||||
expect(names).toContain('review-pair');
|
||||
expect(names).toContain('plan-execute');
|
||||
});
|
||||
|
||||
it('each template factory produces valid structure with steps', () => {
|
||||
const names = listWorkflowTemplates();
|
||||
for (const name of names) {
|
||||
const factory = WORKFLOW_TEMPLATES[name];
|
||||
expect(factory, `${name} should have a factory`).toBeDefined();
|
||||
const tmpl = factory!('test task');
|
||||
expect(tmpl.name).toBe(name);
|
||||
expect(tmpl.description).toBeTruthy();
|
||||
expect(tmpl.steps.length).toBeGreaterThan(0);
|
||||
expect(tmpl.aggregation).toBeDefined();
|
||||
}
|
||||
});
|
||||
|
||||
it('research-team has 3 steps: researcher → synthesizer → reviewer', () => {
|
||||
const tmpl = WORKFLOW_TEMPLATES['research-team']!('test');
|
||||
expect(tmpl.steps).toHaveLength(3);
|
||||
expect(tmpl.steps[0].role).toBe('researcher');
|
||||
expect(tmpl.steps[1].role).toBe('synthesizer');
|
||||
expect(tmpl.steps[2].role).toBe('reviewer');
|
||||
});
|
||||
|
||||
it('workflow steps have dependency ordering', () => {
|
||||
const tmpl = WORKFLOW_TEMPLATES['research-team']!('test');
|
||||
// Synthesizer depends on Researcher
|
||||
expect(tmpl.steps[1].dependsOn).toContain('Researcher');
|
||||
// Reviewer depends on Synthesizer
|
||||
expect(tmpl.steps[2].dependsOn).toContain('Synthesizer');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Agent Topology Data Shape', () => {
|
||||
it('can construct a valid agentTopology object from available data', () => {
|
||||
const rolePresets = Object.keys(ROLE_TOOL_PRESETS);
|
||||
const workflows = listWorkflowTemplates().map(name => {
|
||||
const factory = WORKFLOW_TEMPLATES[name];
|
||||
const tmpl = factory?.('_introspect_');
|
||||
return { name, description: tmpl?.description ?? '', steps: tmpl?.steps?.length ?? 0 };
|
||||
});
|
||||
|
||||
const topology = {
|
||||
model: 'claude-sonnet-4-20250514',
|
||||
rolePresets,
|
||||
workflows,
|
||||
toolCount: 25,
|
||||
isTeam: false,
|
||||
teamTools: [],
|
||||
};
|
||||
|
||||
expect(topology.rolePresets.length).toBeGreaterThanOrEqual(6);
|
||||
expect(topology.workflows.length).toBeGreaterThanOrEqual(3);
|
||||
expect(topology.toolCount).toBeGreaterThan(0);
|
||||
expect(topology.isTeam).toBe(false);
|
||||
expect(topology.teamTools).toEqual([]);
|
||||
});
|
||||
|
||||
it('team topology includes team tool names', () => {
|
||||
const teamTools = ['check_hive', 'share_to_team', 'create_team_task', 'claim_team_task', 'send_waggle_message'];
|
||||
const topology = {
|
||||
model: 'claude-sonnet-4-20250514',
|
||||
rolePresets: Object.keys(ROLE_TOOL_PRESETS),
|
||||
workflows: [],
|
||||
toolCount: 30,
|
||||
isTeam: true,
|
||||
teamTools,
|
||||
};
|
||||
|
||||
expect(topology.isTeam).toBe(true);
|
||||
expect(topology.teamTools).toHaveLength(5);
|
||||
expect(topology.teamTools).toContain('check_hive');
|
||||
expect(topology.teamTools).toContain('share_to_team');
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user