- Fixed memory backend API: getAll() now includes all memory types (lesson, gotcha, pattern, preference, discovery, context, ephemeral) - Fixed memory test assertions: use MEMORY_TYPES.LESSON instead of undefined FACT, await retrieve() calls - Added getAll() method to JSONBackend for grouped memory access - Fixed InMemoryBackend to support all memory types in getAll() - Fixed smoke test to properly await async methods and check correct properties
197 lines
7.6 KiB
JavaScript
197 lines
7.6 KiB
JavaScript
/**
|
|
* zCode Agent Definitions — Expanded from Ruflo agent types
|
|
* 9 agent types with full capabilities, optimized for multi-agent workflows.
|
|
*/
|
|
|
|
import { logger } from '../utils/logger.js';
|
|
import { Agent } from './Agent.js';
|
|
import { Task } from './Task.js';
|
|
import { SwarmCoordinator } from './SwarmCoordinator.js';
|
|
|
|
const AGENT_DEFINITIONS = [
|
|
{
|
|
id: 'coder',
|
|
type: 'coder',
|
|
name: 'Code Generator',
|
|
description: 'Write, generate, refactor, and debug code. Primary implementation agent.',
|
|
capabilities: ['code_generation', 'refactoring', 'debugging', 'code_review', 'testing'],
|
|
systemPrompt: 'You are a senior software engineer. Write clean, optimized, production-ready code. Always consider edge cases, performance, and maintainability.',
|
|
},
|
|
{
|
|
id: 'architect',
|
|
type: 'architect',
|
|
name: 'System Architect',
|
|
description: 'Design system architecture, API contracts, and data models. High-level design decisions.',
|
|
capabilities: ['system_design', 'api_design', 'architecture', 'documentation', 'pattern_recognition'],
|
|
systemPrompt: 'You are a software architect. Design scalable, maintainable systems. Focus on separation of concerns, modularity, and future-proofing.',
|
|
},
|
|
{
|
|
id: 'reviewer',
|
|
type: 'reviewer',
|
|
name: 'Code Reviewer',
|
|
description: 'Review code for bugs, security issues, performance, and adherence to best practices.',
|
|
capabilities: ['code_review', 'quality_analysis', 'best_practices', 'security_review', 'performance_review'],
|
|
systemPrompt: 'You are a senior code reviewer. Analyze code critically for bugs, security vulnerabilities, performance issues, and maintainability concerns. Be thorough but constructive.',
|
|
},
|
|
{
|
|
id: 'tester',
|
|
type: 'tester',
|
|
name: 'Test Engineer',
|
|
description: 'Write unit tests, integration tests, and end-to-end tests. Ensure test coverage.',
|
|
capabilities: ['unit_testing', 'integration_testing', 'e2e_testing', 'coverage', 'test_design'],
|
|
systemPrompt: 'You are a QA engineer focused on testing. Write comprehensive tests covering edge cases, error paths, and happy paths. Suggest test frameworks and strategies.',
|
|
},
|
|
{
|
|
id: 'devops',
|
|
type: 'deployer',
|
|
name: 'DevOps Engineer',
|
|
description: 'Handle deployment, CI/CD pipelines, infrastructure-as-code, and DevOps workflows.',
|
|
capabilities: ['deployment', 'ci_cd', 'infrastructure', 'docker', 'monitoring'],
|
|
systemPrompt: 'You are a DevOps engineer. Automate deployment, manage infrastructure, and ensure reliable CI/CD. Focus on reproducibility and observability.',
|
|
},
|
|
{
|
|
id: 'researcher',
|
|
type: 'researcher',
|
|
name: 'Researcher',
|
|
description: 'Search for information, analyze documentation, and provide research-backed recommendations.',
|
|
capabilities: ['research', 'documentation_analysis', 'comparison', 'fact_checking', 'trend_analysis'],
|
|
systemPrompt: 'You are a technical researcher. Gather information from multiple sources, verify facts, and present findings with clear evidence and citations.',
|
|
},
|
|
{
|
|
id: 'security',
|
|
type: 'security',
|
|
name: 'Security Architect',
|
|
description: 'Identify security vulnerabilities, perform threat modeling, and recommend security improvements.',
|
|
capabilities: ['threat_modeling', 'vulnerability_analysis', 'security_review', 'penetration_testing', 'compliance'],
|
|
systemPrompt: 'You are a security engineer. Identify vulnerabilities, perform threat modeling, and recommend security improvements. Follow OWASP guidelines and defense-in-depth principles.',
|
|
},
|
|
{
|
|
id: 'designer',
|
|
type: 'designer',
|
|
name: 'UI/UX Designer',
|
|
description: 'Design user interfaces, create frontend components, and ensure good UX patterns.',
|
|
capabilities: ['ui_design', 'ux_design', 'frontend', 'css', 'accessibility'],
|
|
systemPrompt: 'You are a UI/UX designer. Create beautiful, accessible, and responsive interfaces. Follow modern design patterns and ensure great user experience.',
|
|
},
|
|
{
|
|
id: 'coordinator',
|
|
type: 'coordinator',
|
|
name: 'Swarm Coordinator',
|
|
description: 'Coordinate multi-agent workflows, delegate tasks, and synthesize results from multiple agents.',
|
|
capabilities: ['coordination', 'delegation', 'synthesis', 'planning', 'task_management'],
|
|
systemPrompt: 'You are a multi-agent coordinator. Decompose complex tasks into sub-tasks, delegate to appropriate agents, and synthesize results. Think about dependencies and parallel execution.',
|
|
},
|
|
];
|
|
|
|
export async function initAgents() {
|
|
const agents = AGENT_DEFINITIONS.map(def => ({
|
|
...def,
|
|
enabled: true,
|
|
}));
|
|
|
|
logger.info(`✓ Loaded ${agents.length} agent types`);
|
|
return agents;
|
|
}
|
|
|
|
export class AgentOrchestrator {
|
|
constructor(agents, options = {}) {
|
|
this.agentDefs = agents;
|
|
this.agentMap = new Map(agents.map(a => [a.id, a]));
|
|
this.swarm = new SwarmCoordinator({
|
|
topology: options.topology || 'simple',
|
|
maxAgents: options.maxAgents || 10,
|
|
});
|
|
this._spawnedAgents = new Map();
|
|
}
|
|
|
|
/**
|
|
* Execute a task with a specific agent
|
|
*/
|
|
async execute(agentId, task, context = {}) {
|
|
const def = this.agentMap.get(agentId);
|
|
if (!def) throw new Error(`Agent not found: ${agentId}`);
|
|
|
|
logger.info(`🤖 ${def.name}: ${task.substring(0, 120)}...`);
|
|
|
|
// Get or spawn an agent instance
|
|
let agent = this._spawnedAgents.get(agentId);
|
|
if (!agent) {
|
|
agent = await this.swarm.spawnAgent({
|
|
id: agentId,
|
|
type: def.type,
|
|
name: def.name,
|
|
description: def.description,
|
|
capabilities: def.capabilities,
|
|
});
|
|
this._spawnedAgents.set(agentId, agent);
|
|
}
|
|
|
|
return {
|
|
success: true,
|
|
agent: def.name,
|
|
agentId,
|
|
task,
|
|
context,
|
|
systemPrompt: def.systemPrompt,
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Execute a multi-agent workflow — delegates to appropriate agents
|
|
*/
|
|
async executeMultiAgent(tasks, context = {}) {
|
|
const taskObjects = tasks.map((t, i) => {
|
|
const def = this.agentMap.get(t.agentId);
|
|
return new Task({
|
|
id: t.id || `task_${i}`,
|
|
type: def?.type || 'generic',
|
|
description: t.description || '',
|
|
priority: t.priority || 'medium',
|
|
dependencies: t.dependencies || [],
|
|
requiredCapabilities: def?.capabilities || [],
|
|
assignedTo: t.agentId,
|
|
agentId: t.agentId,
|
|
});
|
|
});
|
|
|
|
// Distribute and execute
|
|
const assignments = await this.swarm.distributeTasks(taskObjects);
|
|
const results = [];
|
|
|
|
for (const { agentId, taskId } of assignments) {
|
|
if (!agentId) continue;
|
|
const task = taskObjects.find(t => t.id === taskId);
|
|
// Attach execute handler for the agent to call
|
|
task._customExecute = async () => ({
|
|
status: 'completed',
|
|
agentId,
|
|
output: `Task '${task.description}' executed by ${this.agentMap.get(agentId)?.name}`,
|
|
});
|
|
const result = await this.swarm.executeTask(agentId, task);
|
|
results.push({ agentId, taskId, result });
|
|
}
|
|
|
|
return results;
|
|
}
|
|
|
|
getAgent(agentId) { return this.agentMap.get(agentId); }
|
|
listAgents() { return this.agentDefs; }
|
|
getSwarmState() { return this.swarm.getSwarmState(); }
|
|
|
|
/**
|
|
* Find agent best suited for a task
|
|
*/
|
|
findBestAgent(taskType, requiredCaps = []) {
|
|
const scored = this.agentDefs.map(a => {
|
|
const capScore = requiredCaps.filter(c => a.capabilities.includes(c)).length;
|
|
const typeMatch = a.type === taskType ? 2 : 0;
|
|
return { agent: a, score: capScore + typeMatch };
|
|
});
|
|
scored.sort((a, b) => b.score - a.score);
|
|
return scored[0]?.agent || null;
|
|
}
|
|
}
|
|
|
|
export { AGENT_DEFINITIONS };
|
|
export default initAgents;
|