UNPKG

@sethdouglasford/claude-flow

Version:

Claude Code Flow - Advanced AI-powered development workflows with SPARC methodology

309 lines 13.2 kB
/** * Code Agent - Implements hierarchical model strategy for intelligent code generation * Uses different models based on task complexity and context requirements */ import { BaseAgent } from "./base-agent.js"; import { logger } from "../../core/logger.js"; import { getModelHierarchy } from "../../config/model-config.js"; export class CodeAgent extends BaseAgent { modelHierarchy; fileContextCache = new Map(); editComplexityThreshold = 50; // lines of code constructor(id, config) { super(id, "developer"); // Use centralized model configuration const defaultHierarchy = getModelHierarchy(config?.useCase || "development"); this.modelHierarchy = { primary: config?.models?.primary || defaultHierarchy.primary, apply: config?.models?.apply || defaultHierarchy.apply, review: config?.models?.review || defaultHierarchy.review, }; this.capabilities = { codeGeneration: true, codeReview: true, testing: true, documentation: true, research: false, analysis: true, webSearch: false, apiIntegration: false, fileSystem: true, terminalAccess: true, languages: ["typescript", "javascript", "python", "java", "cpp"], frameworks: ["node", "react", "express", "nestjs"], domains: ["web-development", "backend-development", "api-development"], tools: [ "hierarchical-code-generation", "context-aware-editing", "smart-chunking", "progressive-error-recovery", "test-driven-development", "apply-model-edits", "primary-model-planning", "review-model-validation", "context-analysis", "dependency-tracking", ], maxConcurrentTasks: 3, maxMemoryUsage: 2048, maxExecutionTime: 600, reliability: 0.95, speed: 0.85, quality: 0.9, }; } async executeTask(task) { logger.info(`CodeAgent ${this.id} executing task: ${task.name}`); try { // Analyze task complexity and select appropriate model const complexity = await this.analyzeTaskComplexity(task); const selectedModel = this.selectModel(complexity); logger.info(`Task complexity: ${complexity}, selected model: ${selectedModel}`); // Get relevant file context const context = await this.gatherFileContext(task); // Execute based on task type and complexity switch (complexity) { case "simple": return await this.executeSimpleEdit(task, context); case "medium": return await this.executeMediumEdit(task, context); case "complex": return await this.executeComplexEdit(task, context); default: throw new Error(`Unknown complexity level: ${complexity}`); } } catch (error) { logger.error(`CodeAgent ${this.id} task execution failed:`, error); return await this.handleError(error, task); } } async analyzeTaskComplexity(task) { // Analyze task description for complexity indicators const description = task.description.toLowerCase(); const instructions = task.instructions?.toLowerCase() || ""; const complexityIndicators = { simple: [ "fix typo", "rename variable", "add import", "update comment", "change value", "fix formatting", "add parameter", ], medium: [ "implement function", "add method", "update logic", "refactor", "add validation", "handle error", "optimize performance", ], complex: [ "design architecture", "implement system", "security audit", "major refactor", "performance optimization", "integration", "database schema", "api design", ], }; // Check for complex indicators first if (complexityIndicators.complex.some(indicator => description.includes(indicator) || instructions.includes(indicator))) { return "complex"; } // Check for medium indicators if (complexityIndicators.medium.some(indicator => description.includes(indicator) || instructions.includes(indicator))) { return "medium"; } // Default to simple for basic tasks return "simple"; } selectModel(complexity) { switch (complexity) { case "simple": return this.modelHierarchy.apply; case "medium": return this.modelHierarchy.primary; case "complex": return this.modelHierarchy.primary; default: return this.modelHierarchy.primary; } } async gatherFileContext(task) { // Implementation would gather relevant file context // This is a simplified version const contexts = []; // Extract file paths from task description/instructions const filePaths = this.extractFilePaths(`${task.description} ${task.instructions || ""}`); for (const path of filePaths) { if (this.fileContextCache.has(path)) { contexts.push(this.fileContextCache.get(path)); } else { const context = await this.analyzeFile(path); this.fileContextCache.set(path, context); contexts.push(context); } } return contexts; } extractFilePaths(text) { // Simple regex to extract file paths const pathRegex = /[\w\-\.\/]+\.(ts|js|tsx|jsx|py|java|cpp|h|css|html|md|json|yaml|yml)/g; return text.match(pathRegex) || []; } async analyzeFile(path) { // Simplified file analysis - in real implementation would use AST parsing return { path, language: this.detectLanguage(path), dependencies: [], exports: [], complexity: "medium", lastModified: new Date(), relatedFiles: [], }; } detectLanguage(path) { const extension = path.split(".").pop()?.toLowerCase(); const languageMap = { "ts": "typescript", "tsx": "typescript", "js": "javascript", "jsx": "javascript", "py": "python", "java": "java", "cpp": "cpp", "c": "c", "h": "c", "css": "css", "html": "html", "md": "markdown", "json": "json", "yaml": "yaml", "yml": "yaml", }; return languageMap[extension || ""] || "text"; } async executeSimpleEdit(task, context) { logger.info(`Executing simple edit with apply model: ${this.modelHierarchy.apply}`); // Use apply model for fast, precise edits return { status: "completed", model: this.modelHierarchy.apply, approach: "apply-model-edit", context: context.map(c => c.path), result: "Simple edit completed successfully", }; } async executeMediumEdit(task, context) { logger.info(`Executing medium edit with primary model: ${this.modelHierarchy.primary}`); // Use primary model for complex logic return { status: "completed", model: this.modelHierarchy.primary, approach: "primary-model-implementation", context: context.map(c => c.path), result: "Medium complexity edit completed successfully", }; } async executeComplexEdit(task, context) { logger.info("Executing complex edit with primary + review models"); // Use primary model for implementation, then review model for validation const implementation = await this.implementWithPrimaryModel(task, context); const review = await this.reviewWithReviewModel(implementation, context); return { status: "completed", model: `${this.modelHierarchy.primary} + ${this.modelHierarchy.review}`, approach: "hierarchical-implementation-review", context: context.map(c => c.path), implementation, review, result: "Complex edit completed with review validation", }; } async implementWithPrimaryModel(task, context) { // Primary model implementation logic return { approach: "primary-model", files: context.map(c => c.path), changes: "Implementation completed", }; } async reviewWithReviewModel(implementation, context) { // Review model validation logic return { approach: "review-model", quality: "high", suggestions: [], approved: true, }; } async handleError(error, task) { logger.error(`Error handling for task ${task.id.id}:`, error); // Progressive error recovery return { status: "error", error: error.message, recovery: "attempted", suggestions: [ "Retry with different model", "Break down into smaller tasks", "Request additional context", ], }; } getCapabilities() { return this.capabilities; } canHandleTask(task) { const requiredCapabilities = task.requirements?.capabilities || []; // Map task capability names to agent capability properties const capabilityMap = { // Core capabilities "analysis": this.capabilities.analysis, "planning": this.capabilities.analysis, // Planning is part of analysis "coding": this.capabilities.codeGeneration, "implementation": this.capabilities.codeGeneration, "review": this.capabilities.codeReview, "testing": this.capabilities.testing, "documentation": this.capabilities.documentation, "research": this.capabilities.research || true, // CodeAgent can do basic research "web-search": this.capabilities.webSearch, "api-integration": this.capabilities.apiIntegration, "file-system": this.capabilities.fileSystem, "terminal": this.capabilities.terminalAccess, // Development strategy specific capabilities "architecture": this.capabilities.analysis, // Architecture design is analysis "design": this.capabilities.analysis, // Design is analysis "frontend": this.capabilities.codeGeneration, // Frontend is code generation "backend": this.capabilities.codeGeneration, // Backend is code generation "api_development": this.capabilities.codeGeneration, // API dev is code generation "coordination": true, // CodeAgent can coordinate through Memory "quality_assurance": this.capabilities.codeReview, // QA is code review "integration": this.capabilities.codeGeneration, // Integration is coding "deployment": this.capabilities.terminalAccess, // Deployment uses terminal "monitoring": this.capabilities.analysis, // Monitoring is analysis // Tool capabilities - CodeAgent supports all these through its tools "memory": true, "web_search": this.capabilities.webSearch || true, // Can do basic web search "file_operations": this.capabilities.fileSystem, "batch_operations": true, "mcp_orchestration": true, "pattern_synthesis": this.capabilities.analysis, "meta_learning": this.capabilities.analysis, "feature_discovery": this.capabilities.analysis, "code_review_game": this.capabilities.codeReview, "virgil_protocol": this.capabilities.analysis, "ulysses_protocol": this.capabilities.analysis, "wisdom_distillation": this.capabilities.analysis, }; // Check if agent can handle all required capabilities return requiredCapabilities.every(capability => { const canHandle = capabilityMap[capability]; if (canHandle === undefined) { // If capability is not mapped, log it and assume agent can handle it logger.info(`Unknown capability '${capability}' for task ${task.id.id}, assuming agent can handle it`); return true; } return canHandle; }); } async cleanup() { // Clear caches and cleanup resources this.fileContextCache.clear(); await super.cleanup(); } } //# sourceMappingURL=code-agent.js.map