capsule-ai-cli
Version:
The AI Model Orchestrator - Intelligent multi-model workflows with device-locked licensing
188 lines • 6.66 kB
JavaScript
import { BaseTool } from '../base.js';
import { subAgentManager } from '../../services/sub-agent-manager.js';
export class TaskSpawnTool extends BaseTool {
name = 'task_spawn';
displayName = '🚀 Task';
description = 'Spawn sub-agent tasks that can work independently with full tool access';
category = 'productivity';
icon = '🚀';
parameters = [
{
name: 'action',
type: 'string',
description: 'Action to perform',
required: true,
enum: ['spawn', 'status', 'cancel', 'list', 'wait']
},
{
name: 'name',
type: 'string',
description: 'Task name (for spawn)',
required: false
},
{
name: 'description',
type: 'string',
description: 'Task description/prompt (for spawn)',
required: false
},
{
name: 'provider',
type: 'string',
description: 'AI provider (for spawn)',
required: false
},
{
name: 'model',
type: 'string',
description: 'AI model (for spawn)',
required: false
},
{
name: 'parallel',
type: 'boolean',
description: 'Run in parallel mode (for spawn)',
required: false
},
{
name: 'taskId',
type: 'string',
description: 'Task ID (for status/cancel/wait)',
required: false
},
{
name: 'filterStatus',
type: 'string',
description: 'Filter by status (for list)',
required: false,
enum: ['pending', 'running', 'completed', 'failed', 'cancelled']
},
{
name: 'timeout',
type: 'number',
description: 'Wait timeout in seconds (for wait)',
required: false
}
];
permissions = {};
ui = {
showProgress: true,
collapsible: true,
dangerous: false
};
async run(params, context) {
const { action, name, description, provider, model, parallel, taskId, filterStatus, timeout } = params;
switch (action) {
case 'spawn':
return this.spawnTask({ name, description, provider, model, parallel }, context);
case 'status':
return this.getTaskStatus(taskId);
case 'cancel':
return this.cancelTask(taskId);
case 'list':
return this.listTasks(filterStatus);
case 'wait':
return this.waitForTask(taskId, context, timeout);
default:
throw new Error(`Unknown action: ${action}`);
}
}
async spawnTask(config, context) {
if (!config.name || !config.description) {
throw new Error('Task name and description are required');
}
this.reportProgress(context, `Spawning sub-agent: ${config.name}`, 10);
try {
const task = await subAgentManager.spawnTask({
name: config.name,
description: config.description,
provider: config.provider,
model: config.model,
parallel: config.parallel !== false
});
this.reportProgress(context, `Sub-agent ${task.taskId} created`, 50);
if (config.parallel === false) {
this.reportProgress(context, `Waiting for task completion...`, 70);
const completedTask = await subAgentManager.waitForTask(task.taskId);
this.reportProgress(context, `Task completed`, 100);
return this.formatTaskForResponse(completedTask);
}
return this.formatTaskForResponse(task);
}
catch (error) {
throw new Error(`Failed to spawn sub-agent: ${error.message}`);
}
}
getTaskStatus(taskId) {
if (!taskId) {
throw new Error('Task ID is required');
}
const task = subAgentManager.getTask(taskId);
if (!task) {
throw new Error(`Task ${taskId} not found`);
}
return this.formatTaskForResponse(task);
}
async cancelTask(taskId) {
if (!taskId) {
throw new Error('Task ID is required');
}
const success = await subAgentManager.cancelTask(taskId);
if (!success) {
throw new Error(`Could not cancel task ${taskId} - task not found or not running`);
}
const task = subAgentManager.getTask(taskId);
return this.formatTaskForResponse(task);
}
listTasks(filterStatus) {
let tasks = subAgentManager.getAllTasks();
if (filterStatus) {
tasks = tasks.filter(t => t.status === filterStatus);
}
tasks.sort((a, b) => b.startTime.getTime() - a.startTime.getTime());
const stats = subAgentManager.getStats();
return {
tasks: tasks.map(t => this.formatTaskForResponse(t)),
total: tasks.length,
stats
};
}
async waitForTask(taskId, context, timeout) {
if (!taskId) {
throw new Error('Task ID is required');
}
const task = subAgentManager.getTask(taskId);
if (!task) {
throw new Error(`Task ${taskId} not found`);
}
if (task.status === 'completed' || task.status === 'failed' || task.status === 'cancelled') {
return this.formatTaskForResponse(task);
}
this.reportProgress(context, `Waiting for task ${taskId} to complete...`, 20);
try {
const completedTask = await subAgentManager.waitForTask(taskId, timeout ? timeout * 1000 : undefined);
this.reportProgress(context, `Task ${completedTask.status}`, 100);
return this.formatTaskForResponse(completedTask);
}
catch (error) {
throw new Error(`Error waiting for task: ${error.message}`);
}
}
formatTaskForResponse(task) {
return {
id: task.taskId,
name: task.name,
status: task.status,
provider: task.provider,
model: task.model,
started: task.startTime.toISOString(),
completed: task.endTime?.toISOString(),
tools: task.toolCalls.length,
tokens: task.tokensUsed,
cost: task.cost,
result: task.result,
error: task.error
};
}
}
//# sourceMappingURL=task-spawn.js.map