UNPKG

autoagent-cli

Version:

Run autonomous AI agents using Claude or Gemini for task execution

247 lines (246 loc) 10.2 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.AutonomousAgent = void 0; const events_1 = require("events"); const path = __importStar(require("path")); const config_manager_1 = require("./config-manager"); const stm_manager_1 = require("../utils/stm-manager"); const providers_1 = require("../providers"); const hook_manager_1 = require("./hook-manager"); const session_manager_1 = require("./session-manager"); class AutonomousAgent extends events_1.EventEmitter { constructor(config) { super(); this.isExecuting = false; this.abortController = null; this.hookManager = null; this.currentSession = null; this.config = { workspace: process.cwd(), provider: undefined, includeCoAuthoredBy: true, autoUpdateContext: true, debug: false, dryRun: false, enableRollback: false, ...config }; this.configManager = new config_manager_1.ConfigManager(this.config.workspace); const stmTasksDir = path.join(this.config.workspace ?? process.cwd(), '.autoagent', 'stm-tasks'); this.stmManager = new stm_manager_1.STMManager({ tasksDir: stmTasksDir }); this.sessionManager = new session_manager_1.SessionManager(); if (!this.config.signal) { process.on('SIGINT', () => void this.handleInterrupt()); process.on('SIGTERM', () => void this.handleInterrupt()); } } async initialize() { await this.configManager.loadConfig(); const userConfig = this.configManager.getConfig(); if (userConfig.hooks) { this.currentSession = this.sessionManager.createSession(this.config.workspace ?? process.cwd()); await this.sessionManager.saveSession(this.currentSession); await this.sessionManager.setCurrentSession(this.currentSession.id); this.hookManager = new hook_manager_1.HookManager(userConfig.hooks, this.currentSession.id, this.config.workspace ?? process.cwd()); } } async executeTask(taskId) { if (this.isExecuting) { throw new Error('Agent is already executing a task'); } this.isExecuting = true; this.emit('execution-start', taskId); const startTime = Date.now(); try { const task = await this.stmManager.getTask(taskId); if (!task) { throw new Error(`Task ${taskId} not found`); } if (this.currentSession) { const taskIdParts = taskId.split('-'); const issueNumberStr = taskIdParts[0] !== undefined && taskIdParts[0] !== '' ? taskIdParts[0] : '0'; this.currentSession.issueNumber = parseInt(issueNumberStr, 10); this.currentSession.issueTitle = task.title; this.currentSession.status = 'active'; await this.sessionManager.saveSession(this.currentSession); } if (this.hookManager) { const hookResult = await this.hookManager.executeHooks('PreExecutionStart', { taskId, taskTitle: task.title, taskStatus: task.status }); if (hookResult.blocked) { throw new Error(`Execution blocked by hook: ${hookResult.reason ?? 'Unknown reason'}`); } } const provider = await this.getProvider(); if (!provider) { throw new Error('No available providers'); } const context = await this.buildTaskContext(task); const output = await provider.execute(context, this.config.workspace ?? process.cwd(), this.config.additionalDirectories ?? [], this.config.signal); await this.stmManager.updateTaskStatus(taskId, 'completed'); const result = { success: true, taskId, taskTitle: task.title, duration: Date.now() - startTime, output, provider: provider.getName() }; if (this.hookManager) { await this.hookManager.executeHooks('PostExecutionEnd', { taskId, taskTitle: task.title, success: true, duration: result.duration }); } this.emit('execution-end', result); return result; } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); const result = { success: false, taskId, duration: Date.now() - startTime, error: errorMessage }; try { await this.stmManager.updateTaskStatus(taskId, 'pending'); } catch (updateError) { } if (this.hookManager) { await this.hookManager.executeHooks('PostExecutionEnd', { taskId, success: false, error: errorMessage, duration: result.duration }); } this.emit('error', error); return result; } finally { this.isExecuting = false; this.abortController = null; if (this.currentSession) { this.currentSession.status = 'completed'; await this.sessionManager.saveSession(this.currentSession); } } } async createTask(title, content) { return this.stmManager.createTask(title, content); } async listTasks(status) { const filters = status !== undefined && status !== '' ? { status: status } : undefined; const tasks = await this.stmManager.listTasks(filters); return tasks.map(task => ({ id: task.id.toString(), title: task.title, status: task.status === 'done' ? 'completed' : task.status })); } async getTask(taskId) { return this.stmManager.getTask(taskId); } async updateTaskStatus(taskId, status) { await this.stmManager.updateTaskStatus(taskId, status); } async searchTasks(query) { const tasks = await this.stmManager.searchTasks(query); return tasks.map(task => ({ id: task.id.toString(), title: task.title, status: task.status === 'done' ? 'completed' : task.status })); } async getStatus() { const allTasks = await this.stmManager.listTasks(); const completedTasks = allTasks.filter(task => task.status === 'done'); const pendingTasks = allTasks.filter(task => task.status === 'pending' || task.status === 'in-progress'); return { totalTasks: allTasks.length, completedTasks: completedTasks.length, pendingTasks: pendingTasks.length, currentTaskId: this.isExecuting ? this.currentSession?.issueNumber?.toString() : undefined }; } async buildTaskContext(task) { const sections = await this.stmManager.getTaskSections(task.id.toString()); let context = `# Task: ${task.title}\n\n`; if (sections.description !== undefined && sections.description !== '') { context += `## Description\n${sections.description}\n\n`; } if (sections.details !== undefined && sections.details !== '') { context += `## Technical Details\n${sections.details}\n\n`; } if (sections.validation !== undefined && sections.validation !== '') { context += `## Validation Criteria\n${sections.validation}\n\n`; } context += 'Please complete this task. Make all necessary changes to implement the requirements.'; return context; } async getProvider() { const userConfig = this.configManager.getConfig(); if (this.config.provider) { const provider = (0, providers_1.createProvider)(this.config.provider); const isAvailable = await provider.checkAvailability(); if (isAvailable) { return provider; } } return (0, providers_1.getFirstAvailableProvider)(userConfig.providers); } async handleInterrupt() { if (this.abortController) { this.abortController.abort(); } if (this.currentSession) { this.currentSession.status = 'interrupted'; await this.sessionManager.saveSession(this.currentSession); } process.exit(0); } getSTMManager() { return this.stmManager; } } exports.AutonomousAgent = AutonomousAgent;