oneie
Version:
š¤ ONE Personal Collaborative Intelligence - Creates personalized AI workspace from your me.md profile. Simple: npx oneie ā edit me.md ā generate personalized agents, workflows & missions. From students to enterprises, ONE adapts to your context.
499 lines (423 loc) ⢠17.4 kB
JavaScript
/**
* Agent Integration System
* Coordinates between tasks and the 43+ specialized agents
*/
import fs from 'fs-extra';
import path from 'path';
import yaml from 'js-yaml';
import chalk from 'chalk';
import { TaskSystem } from './task-system.js';
export class AgentIntegration {
constructor(projectPath = process.cwd()) {
this.projectPath = projectPath;
this.agentsDir = path.join(projectPath, '.claude', 'agents');
this.taskSystem = new TaskSystem(projectPath);
// Command structure - the three main orchestrators
this.commanders = {
'Mission Commander': {
file: 'mission-commander.md',
role: 'strategic planning and mission orchestration',
handoffTo: 'Story Teller'
},
'Story Teller': {
file: 'story-teller.md',
role: 'story creation and narrative development',
handoffTo: 'Task Master'
},
'Task Master': {
file: 'task-master.md',
role: 'task execution and agent coordination',
handoffTo: 'specialists'
}
};
// Agent teams organized by function
this.agentTeams = {
engineering: [
'Engineering Director',
'Engineering Architect',
'Engineering Developer',
'Engineering Quality Assurance',
'Engineering Product Manager',
'Engineering User Experience'
],
marketing: [
'Marketing Director',
'Marketing Viral Growth',
'Marketing Brand Identity',
'Marketing Content Hooks',
'Marketing Lead Capture',
'Marketing Lead Magnet',
'Marketing Network Effects'
],
content: [
'Content Team Manager',
'Content Calendar Planner',
'Content Playbook Writer'
],
research: [
'Research Team Manager',
'Research Foundation Analyst',
'Research Market Analyst'
],
service: [
'Service Team Manager',
'Service Success Manager',
'Service Advocacy Manager'
],
crypto: [
'Crypto Team Manager',
'Crypto Token Analyst',
'Crypto Market Researcher'
]
};
}
async executeTask(taskId, options = {}) {
console.log(chalk.blue(`\\nš¤ Executing task ${taskId}...`));
// Get task details
const task = await this.taskSystem.getTask(taskId);
if (!task) {
throw new Error(`Task not found: ${taskId}`);
}
console.log(chalk.cyan(`š Task: ${task.name}`));
console.log(chalk.cyan(`š¤ Assigned agents: ${task.agents.join(', ')}`));
// Start task if not already active
if (task.status === 'pending') {
await this.taskSystem.updateTaskStatus(taskId, 'active', 'Task execution started by agent integration');
console.log(chalk.yellow('š Task status updated to active'));
}
// Create execution plan
const executionPlan = await this.createExecutionPlan(task);
console.log(chalk.cyan(`\\nš Execution plan created with ${executionPlan.phases.length} phases`));
// Execute phases
for (let i = 0; i < executionPlan.phases.length; i++) {
const phase = executionPlan.phases[i];
console.log(chalk.yellow(`\\nā” Phase ${i + 1}: ${phase.name}`));
const result = await this.executePhase(phase, task, options);
if (result.success) {
console.log(chalk.green(`ā
Phase ${i + 1} completed successfully`));
} else {
console.log(chalk.red(`ā Phase ${i + 1} failed: ${result.error}`));
await this.taskSystem.updateTaskStatus(taskId, 'blocked', `Phase ${i + 1} failed: ${result.error}`);
return { success: false, error: result.error };
}
}
// Mark task as completed
await this.taskSystem.updateTaskStatus(taskId, 'completed', 'Task completed by agent integration');
console.log(chalk.green(`\\nš Task "${task.name}" completed successfully!`));
return { success: true, executionPlan };
}
async createExecutionPlan(task) {
const plan = {
taskId: task.id,
taskName: task.name,
phases: [],
totalEstimatedTime: task.duration
};
const taskType = this.identifyTaskType(task);
switch (taskType) {
case 'implementation':
plan.phases = [
{ name: 'Planning & Design', agents: ['Engineering Architect', 'Engineering Director'], duration: '1 hour' },
{ name: 'Implementation', agents: ['Engineering Developer'], duration: '3 hours' },
{ name: 'Testing & Validation', agents: ['Engineering Quality Assurance'], duration: '1 hour' },
{ name: 'Review & Documentation', agents: ['Task Master'], duration: '30 minutes' }
];
break;
case 'design':
plan.phases = [
{ name: 'Requirements Analysis', agents: ['Engineering User Experience', 'Engineering Product Manager'], duration: '1 hour' },
{ name: 'UI/UX Design', agents: ['Engineering User Experience'], duration: '2 hours' },
{ name: 'Design Review', agents: ['Engineering Architect', 'Engineering Director'], duration: '30 minutes' },
{ name: 'Documentation', agents: ['Task Master'], duration: '30 minutes' }
];
break;
case 'research':
plan.phases = [
{ name: 'Research Planning', agents: ['Research Team Manager'], duration: '30 minutes' },
{ name: 'Data Collection', agents: ['Research Foundation Analyst', 'Research Market Analyst'], duration: '2 hours' },
{ name: 'Analysis & Insights', agents: ['Research Team Manager'], duration: '1 hour' },
{ name: 'Report Generation', agents: ['Content Playbook Writer'], duration: '30 minutes' }
];
break;
case 'marketing':
plan.phases = [
{ name: 'Strategy Planning', agents: ['Marketing Director'], duration: '1 hour' },
{ name: 'Content Creation', agents: ['Marketing Content Hooks', 'Content Team Manager'], duration: '2 hours' },
{ name: 'Campaign Setup', agents: ['Marketing Viral Growth'], duration: '1 hour' },
{ name: 'Launch & Monitoring', agents: ['Task Master'], duration: '30 minutes' }
];
break;
default:
// Generic execution plan
plan.phases = [
{ name: 'Planning', agents: ['Task Master'], duration: '30 minutes' },
{ name: 'Execution', agents: task.agents.filter(a => a !== 'Task Master'), duration: '3 hours' },
{ name: 'Validation', agents: ['Task Master'], duration: '30 minutes' }
];
}
return plan;
}
identifyTaskType(task) {
const taskLower = task.name.toLowerCase();
const description = task.description?.toLowerCase() || '';
if (taskLower.includes('implement') || taskLower.includes('code') || taskLower.includes('develop')) {
return 'implementation';
}
if (taskLower.includes('design') || taskLower.includes('ui') || taskLower.includes('ux')) {
return 'design';
}
if (taskLower.includes('research') || taskLower.includes('analyze') || taskLower.includes('investigate')) {
return 'research';
}
if (taskLower.includes('marketing') || taskLower.includes('campaign') || taskLower.includes('growth')) {
return 'marketing';
}
if (taskLower.includes('test') || taskLower.includes('quality')) {
return 'testing';
}
if (taskLower.includes('content') || taskLower.includes('write') || taskLower.includes('document')) {
return 'content';
}
return 'generic';
}
async executePhase(phase, task, options = {}) {
console.log(chalk.gray(` š§ Phase: ${phase.name}`));
console.log(chalk.gray(` š„ Agents: ${phase.agents.join(', ')}`));
console.log(chalk.gray(` ā±ļø Duration: ${phase.duration}`));
try {
// Simulate agent work based on phase type
const phaseResult = await this.simulateAgentWork(phase, task, options);
// Add phase completion note to task
await this.taskSystem.updateTaskStatus(
task.id,
task.status,
`Phase "${phase.name}" completed by ${phase.agents.join(', ')}`
);
return { success: true, result: phaseResult };
} catch (error) {
console.error(chalk.red(` ā Phase failed: ${error.message}`));
return { success: false, error: error.message };
}
}
async simulateAgentWork(phase, task, options = {}) {
// In a real implementation, this would integrate with actual agent execution
// For now, we simulate the work and provide realistic output
const phaseName = phase.name.toLowerCase();
const taskName = task.name.toLowerCase();
if (options.simulate !== false) {
// Simulate work delay
await new Promise(resolve => setTimeout(resolve, 500));
}
// Generate phase-specific outputs
let output = {};
if (phaseName.includes('planning')) {
output = {
type: 'planning_document',
content: `Planning document for ${task.name}`,
deliverables: ['Requirements specification', 'Technical approach', 'Resource allocation'],
nextSteps: ['Proceed to implementation phase']
};
} else if (phaseName.includes('implementation')) {
output = {
type: 'code_implementation',
content: `Implementation of ${task.name}`,
deliverables: ['Working code', 'Unit tests', 'Integration points'],
nextSteps: ['Code review and testing']
};
} else if (phaseName.includes('design')) {
output = {
type: 'design_specification',
content: `Design specification for ${task.name}`,
deliverables: ['UI mockups', 'Component specifications', 'Design guidelines'],
nextSteps: ['Implementation planning']
};
} else if (phaseName.includes('testing')) {
output = {
type: 'test_results',
content: `Test results for ${task.name}`,
deliverables: ['Test cases', 'Test execution results', 'Quality metrics'],
nextSteps: ['Production deployment preparation']
};
} else {
output = {
type: 'generic_output',
content: `${phase.name} completed for ${task.name}`,
deliverables: ['Phase deliverables'],
nextSteps: ['Continue to next phase']
};
}
console.log(chalk.gray(` š Generated: ${output.content}`));
console.log(chalk.gray(` š¦ Deliverables: ${output.deliverables.join(', ')}`));
return output;
}
async getAgentCapabilities(agentName) {
const agentFile = path.join(this.agentsDir, `${agentName.toLowerCase().replace(/\\s+/g, '-')}.md`);
if (await fs.pathExists(agentFile)) {
const content = await fs.readFile(agentFile, 'utf8');
// Parse YAML frontmatter
const frontMatterMatch = content.match(/^---\\n([\\s\\S]*?)\\n---/);
if (frontMatterMatch) {
try {
const frontMatter = yaml.load(frontMatterMatch[1]);
return {
name: frontMatter.name,
description: frontMatter.description,
tools: frontMatter.tools || [],
color: frontMatter.color || 'white'
};
} catch (error) {
console.warn(chalk.yellow(`Warning: Could not parse frontmatter for ${agentName}`));
}
}
}
return {
name: agentName,
description: `Specialized agent: ${agentName}`,
tools: [],
color: 'white'
};
}
async cascadeWorkflow(missionId, options = {}) {
console.log(chalk.cyan.bold(`\\nš Starting cascade workflow for mission ${missionId}...`));
// Phase 1: Mission Commander creates stories
console.log(chalk.yellow('\\nš Phase 1: Mission Commander - Story Spawning'));
const mission = await this.getMission(missionId);
if (!mission) {
throw new Error(`Mission not found: ${missionId}`);
}
console.log(chalk.cyan(`š Mission: ${mission.name}`));
console.log(chalk.cyan(`šÆ Objective: ${mission.objective}`));
// Phase 2: Story Teller develops narratives and creates tasks
console.log(chalk.green('\\nš Phase 2: Story Teller - Task Generation'));
const stories = await this.getStoriesForMission(missionId);
for (const story of stories) {
console.log(chalk.cyan(` š Processing story: ${story.name}`));
// Ensure story has tasks
if (!story.tasks || story.tasks.length === 0) {
console.log(chalk.yellow(` š Generating tasks for story ${story.id}...`));
// In a real implementation, Story Teller would create tasks here
console.log(chalk.gray(` ā
Tasks would be generated by Story Teller agent`));
}
}
// Phase 3: Task Master orchestrates execution
console.log(chalk.blue('\\nā” Phase 3: Task Master - Execution Orchestration'));
for (const story of stories) {
if (story.tasks && story.tasks.length > 0) {
console.log(chalk.cyan(` š Story: ${story.name}`));
for (const taskRef of story.tasks) {
const taskId = typeof taskRef === 'object' ? taskRef.id : taskRef;
const task = await this.taskSystem.getTask(taskId);
if (task && task.status === 'pending') {
console.log(chalk.yellow(` š Orchestrating task: ${task.name}`));
if (options.execute) {
const result = await this.executeTask(taskId, { simulate: true });
if (result.success) {
console.log(chalk.green(` ā
Task completed`));
} else {
console.log(chalk.red(` ā Task failed: ${result.error}`));
}
} else {
console.log(chalk.gray(` š Task ready for execution`));
}
}
}
}
}
console.log(chalk.green.bold('\\nš Cascade workflow completed!'));
return {
mission,
stories,
totalTasks: stories.reduce((sum, story) => sum + (story.tasks?.length || 0), 0),
completedPhases: ['Mission Commander', 'Story Teller', 'Task Master']
};
}
async getMission(missionId) {
const missionPath = path.join(this.taskSystem.missionsDir, missionId, 'mission.yaml');
if (await fs.pathExists(missionPath)) {
return yaml.load(await fs.readFile(missionPath, 'utf8'));
}
return null;
}
async getStoriesForMission(missionId) {
const stories = [];
const storiesDir = path.join(this.taskSystem.missionsDir, missionId, 'stories');
if (await fs.pathExists(storiesDir)) {
const files = await fs.readdir(storiesDir);
for (const file of files) {
if (file.endsWith('.yaml') && file !== 'tasks') {
const storyPath = path.join(storiesDir, file);
const story = yaml.load(await fs.readFile(storyPath, 'utf8'));
stories.push(story);
}
}
}
return stories;
}
async getAgentWorkload() {
const tasks = await this.taskSystem.listTasks();
const activeTasks = tasks.filter(task => task.status === 'active');
const workload = {};
activeTasks.forEach(task => {
task.agents.forEach(agent => {
if (!workload[agent]) {
workload[agent] = {
activeTasks: 0,
tasks: []
};
}
workload[agent].activeTasks++;
workload[agent].tasks.push({
id: task.id,
name: task.name,
priority: task.priority
});
});
});
return workload;
}
async recommendOptimalAgent(taskType, currentWorkload = null) {
if (!currentWorkload) {
currentWorkload = await this.getAgentWorkload();
}
let candidateAgents = [];
switch (taskType) {
case 'implementation':
candidateAgents = this.agentTeams.engineering.filter(agent =>
agent.includes('Developer') || agent.includes('Engineer'));
break;
case 'design':
candidateAgents = this.agentTeams.engineering.filter(agent =>
agent.includes('User Experience') || agent.includes('Architect'));
break;
case 'research':
candidateAgents = this.agentTeams.research;
break;
case 'marketing':
candidateAgents = this.agentTeams.marketing;
break;
default:
candidateAgents = ['Task Master'];
}
// Sort by current workload (ascending - less loaded agents first)
candidateAgents.sort((a, b) => {
const aLoad = currentWorkload[a]?.activeTasks || 0;
const bLoad = currentWorkload[b]?.activeTasks || 0;
return aLoad - bLoad;
});
return candidateAgents[0] || 'Task Master';
}
}
// CLI interface functions
export async function executeTask(taskId, options = {}) {
const agentIntegration = new AgentIntegration();
return await agentIntegration.executeTask(taskId, options);
}
export async function cascadeWorkflow(missionId, options = {}) {
const agentIntegration = new AgentIntegration();
return await agentIntegration.cascadeWorkflow(missionId, options);
}
export async function getAgentWorkload() {
const agentIntegration = new AgentIntegration();
return await agentIntegration.getAgentWorkload();
}