UNPKG

claude-flow

Version:

Ruflo - Enterprise AI agent orchestration for Claude Code. Deploy 60+ specialized agents in coordinated swarms with self-learning, fault-tolerant consensus, vector memory, and MCP integration

231 lines 12.3 kB
/** * Autopilot MCP Tools * * 10 MCP tools for persistent swarm completion management. * Allows programmatic control of the autopilot loop via MCP. * * ADR-072: Autopilot Integration * @module @claude-flow/cli/mcp-tools/autopilot */ import { validateText } from './validate-input.js'; import { loadState, saveState, appendLog, loadLog, discoverTasks, isTerminal, tryLoadLearning, validateNumber, validateTaskSources, VALID_TASK_SOURCES, } from '../autopilot-state.js'; function ok(data) { return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] }; } // ── MCP Tool Definitions ────────────────────────────────────── const autopilotStatus = { name: 'autopilot_status', description: 'Get autopilot state including enabled status, iteration count, task progress, and learning metrics. Use when running long-horizon goals that should resume automatically across sessions — Claude Code has no native autonomous-loop scheduler. Pair with autopilot_enable + a goal description, then let cron fires advance the work. For interactive single-task sessions, native Task is fine.', category: 'autopilot', inputSchema: { type: 'object', properties: {} }, handler: async () => { const state = loadState(); const tasks = discoverTasks(state.taskSources); const completed = tasks.filter(t => isTerminal(t.status)).length; return ok({ enabled: state.enabled, sessionId: state.sessionId, iterations: state.iterations, maxIterations: state.maxIterations, timeoutMinutes: state.timeoutMinutes, elapsedMs: state.enabled ? Date.now() - state.startTime : 0, tasks: { completed, total: tasks.length, percent: tasks.length === 0 ? 100 : Math.round((completed / tasks.length) * 100) }, taskSources: state.taskSources, }); }, }; const autopilotEnable = { name: 'autopilot_enable', description: 'Enable autopilot persistent completion. Agents will be re-engaged when tasks remain incomplete. Use when running long-horizon goals that should resume automatically across sessions — Claude Code has no native autonomous-loop scheduler. Pair with autopilot_enable + a goal description, then let cron fires advance the work. For interactive single-task sessions, native Task is fine.', category: 'autopilot', inputSchema: { type: 'object', properties: {} }, handler: async () => { const state = loadState(); state.enabled = true; state.startTime = Date.now(); state.iterations = 0; saveState(state); appendLog({ ts: Date.now(), event: 'enabled', sessionId: state.sessionId }); return ok({ enabled: true, maxIterations: state.maxIterations, timeoutMinutes: state.timeoutMinutes }); }, }; const autopilotDisable = { name: 'autopilot_disable', description: 'Disable autopilot. Agents will be allowed to stop even if tasks remain. Use when running long-horizon goals that should resume automatically across sessions — Claude Code has no native autonomous-loop scheduler. Pair with autopilot_enable + a goal description, then let cron fires advance the work. For interactive single-task sessions, native Task is fine.', category: 'autopilot', inputSchema: { type: 'object', properties: {} }, handler: async () => { const state = loadState(); state.enabled = false; saveState(state); appendLog({ ts: Date.now(), event: 'disabled', iterations: state.iterations }); return ok({ enabled: false }); }, }; const autopilotConfig = { name: 'autopilot_config', description: 'Configure autopilot limits: max iterations (1-1000), timeout in minutes (1-1440), and task sources. Use when running long-horizon goals that should resume automatically across sessions — Claude Code has no native autonomous-loop scheduler. Pair with autopilot_enable + a goal description, then let cron fires advance the work. For interactive single-task sessions, native Task is fine.', category: 'autopilot', inputSchema: { type: 'object', properties: { maxIterations: { type: 'number', description: 'Max re-engagement iterations (1-1000)' }, timeoutMinutes: { type: 'number', description: 'Timeout in minutes (1-1440)' }, taskSources: { type: 'array', items: { type: 'string' }, description: `Task sources: ${[...VALID_TASK_SOURCES].join(', ')}` }, }, }, handler: async (params) => { const state = loadState(); if (params.maxIterations !== undefined) { state.maxIterations = validateNumber(params.maxIterations, 1, 1000, state.maxIterations); } if (params.timeoutMinutes !== undefined) { state.timeoutMinutes = validateNumber(params.timeoutMinutes, 1, 1440, state.timeoutMinutes); } if (params.taskSources !== undefined) { state.taskSources = validateTaskSources(params.taskSources); } saveState(state); return ok({ maxIterations: state.maxIterations, timeoutMinutes: state.timeoutMinutes, taskSources: state.taskSources }); }, }; const autopilotReset = { name: 'autopilot_reset', description: 'Reset autopilot iteration counter and restart the timer. Use when running long-horizon goals that should resume automatically across sessions — Claude Code has no native autonomous-loop scheduler. Pair with autopilot_enable + a goal description, then let cron fires advance the work. For interactive single-task sessions, native Task is fine.', category: 'autopilot', inputSchema: { type: 'object', properties: {} }, handler: async () => { const state = loadState(); state.iterations = 0; state.startTime = Date.now(); state.history = []; state.lastCheck = null; saveState(state); appendLog({ ts: Date.now(), event: 'reset' }); return ok({ reset: true, iterations: 0 }); }, }; const autopilotLog = { name: 'autopilot_log', description: 'Retrieve the autopilot event log. Shows enable/disable events, re-engagements, completions. Use when running long-horizon goals that should resume automatically across sessions — Claude Code has no native autonomous-loop scheduler. Pair with autopilot_enable + a goal description, then let cron fires advance the work. For interactive single-task sessions, native Task is fine.', category: 'autopilot', inputSchema: { type: 'object', properties: { last: { type: 'number', description: 'Return only the last N entries' }, }, }, handler: async (params) => { const log = loadLog(); const last = validateNumber(params.last, 1, 10000, 0); return ok(last > 0 ? log.slice(-last) : log); }, }; const autopilotProgress = { name: 'autopilot_progress', description: 'Detailed task progress broken down by source (team-tasks, swarm-tasks, file-checklist). Use when running long-horizon goals that should resume automatically across sessions — Claude Code has no native autonomous-loop scheduler. Pair with autopilot_enable + a goal description, then let cron fires advance the work. For interactive single-task sessions, native Task is fine.', category: 'autopilot', inputSchema: { type: 'object', properties: {} }, handler: async () => { const state = loadState(); const tasks = discoverTasks(state.taskSources); const bySource = {}; for (const t of tasks) { if (!bySource[t.source]) bySource[t.source] = { completed: 0, total: 0, tasks: [] }; bySource[t.source].total++; if (isTerminal(t.status)) { bySource[t.source].completed++; } bySource[t.source].tasks.push(t); } const completed = tasks.filter(t => isTerminal(t.status)).length; return ok({ overall: { completed, total: tasks.length, percent: tasks.length === 0 ? 100 : Math.round((completed / tasks.length) * 100) }, bySource, }); }, }; const autopilotLearn = { name: 'autopilot_learn', description: 'Discover success patterns from past task completions. Requires AgentDB for full functionality. Use when running long-horizon goals that should resume automatically across sessions — Claude Code has no native autonomous-loop scheduler. Pair with autopilot_enable + a goal description, then let cron fires advance the work. For interactive single-task sessions, native Task is fine.', category: 'autopilot', inputSchema: { type: 'object', properties: {} }, handler: async () => { const learning = await tryLoadLearning(); if (learning) { const [metrics, patterns] = await Promise.all([ learning.getMetrics(), learning.discoverSuccessPatterns(), ]); return ok({ metrics, patterns }); } return ok({ available: false, reason: 'AgentDB/AutopilotLearning not initialized', patterns: [] }); }, }; const autopilotHistory = { name: 'autopilot_history', description: 'Search past completion episodes by keyword. Requires AgentDB. Use when running long-horizon goals that should resume automatically across sessions — Claude Code has no native autonomous-loop scheduler. Pair with autopilot_enable + a goal description, then let cron fires advance the work. For interactive single-task sessions, native Task is fine.', category: 'autopilot', inputSchema: { type: 'object', properties: { query: { type: 'string', description: 'Search query' }, limit: { type: 'number', description: 'Max results (default 10)' }, }, required: ['query'], }, handler: async (params) => { const vQuery = validateText(params.query, 'query'); if (!vQuery.valid) return ok({ query: '', results: [], error: vQuery.error }); const query = String(params.query || ''); const limit = validateNumber(params.limit, 1, 100, 10); const learning = await tryLoadLearning(); if (learning) { const results = await learning.recallSimilarTasks(query, limit); return ok({ query, results }); } return ok({ query, results: [], available: false }); }, }; const autopilotPredict = { name: 'autopilot_predict', description: 'Predict the optimal next action based on current state and learned patterns. Use when running long-horizon goals that should resume automatically across sessions — Claude Code has no native autonomous-loop scheduler. Pair with autopilot_enable + a goal description, then let cron fires advance the work. For interactive single-task sessions, native Task is fine.', category: 'autopilot', inputSchema: { type: 'object', properties: {} }, handler: async () => { const state = loadState(); const learning = await tryLoadLearning(); if (learning) { const prediction = await learning.predictNextAction(state); return ok(prediction); } // Heuristic fallback const tasks = discoverTasks(state.taskSources); const incomplete = tasks.filter(t => !isTerminal(t.status)); if (incomplete.length === 0) { return ok({ action: 'none', confidence: 1.0, reason: 'All tasks complete' }); } return ok({ action: `Work on: ${incomplete[0].subject}`, confidence: 0.5, reason: 'Heuristic (learning not available)', remaining: incomplete.length, }); }, }; // ── Export ───────────────────────────────────────────────────── export const autopilotTools = [ autopilotStatus, autopilotEnable, autopilotDisable, autopilotConfig, autopilotReset, autopilotLog, autopilotProgress, autopilotLearn, autopilotHistory, autopilotPredict, ]; //# sourceMappingURL=autopilot-tools.js.map