UNPKG

abyss-ai

Version:

Autonomous AI coding agent - enhanced OpenCode with autonomous capabilities

302 lines (253 loc) 9.67 kB
import { Log } from "../../util/log" import { AgentTask, AgentType, ReasoningMode } from "../types/agent" import { Config } from "../../config/config" export interface GeneratedQuestion { id: string question: string perspective: string targetAgentName: string // Changed to use OpenCode's agent names reasoningMode: ReasoningMode priority: number expectedCapabilities: string[] } export interface QuestionGenerationResult { questions: GeneratedQuestion[] context: { originalQuery: string analysisScope: string complexity: number estimatedProcessingTime: number } } export class QuestionGenerator { private log = Log.create({ service: "question-generator" }) constructor() { this.log.info("QuestionGenerator initialized") } /** * Generate specialized research questions from a user query or task * Similar to make-it-heavy's approach but tailored for code analysis */ async generateQuestions(task: AgentTask): Promise<QuestionGenerationResult> { this.log.info("Generating specialized questions for task", { taskId: task.id, taskType: task.type }) const questions = await this.createQuestionSet(task) const context = this.analyzeTaskContext(task) const result: QuestionGenerationResult = { questions, context: { originalQuery: task.type, analysisScope: this.determineAnalysisScope(task), complexity: this.assessComplexity(task), estimatedProcessingTime: this.estimateProcessingTime(questions) } } this.log.debug("Questions generated", { questionCount: questions.length, perspectives: questions.map(q => q.perspective), complexity: result.context.complexity }) return result } /** * Create a diverse set of research questions for comprehensive analysis */ private async createQuestionSet(task: AgentTask): Promise<GeneratedQuestion[]> { const questions: GeneratedQuestion[] = [] // Generate questions based on task type and content const baseQuestions = this.generateBaseQuestions(task) const perspectiveQuestions = this.generatePerspectiveQuestions(task) const validationQuestions = this.generateValidationQuestions(task) const innovationQuestions = this.generateInnovationQuestions(task) questions.push(...baseQuestions, ...perspectiveQuestions, ...validationQuestions, ...innovationQuestions) // Sort by priority and limit to avoid overwhelming return questions .sort((a, b) => b.priority - a.priority) .slice(0, 6) // Limit to 6 questions max } /** * Generate foundational analysis questions */ private generateBaseQuestions(task: AgentTask): GeneratedQuestion[] { const questions: GeneratedQuestion[] = [] // Code structure and quality analysis if (this.isCodeAnalysisTask(task)) { questions.push({ id: `base-structure-${task.id}`, question: "Analyze the code structure, architecture patterns, and overall design quality", perspective: "Structural Analysis", targetAgentName: "code-analyzer", reasoningMode: ReasoningMode.ULTRAREASONING, priority: 0.9, expectedCapabilities: ["analysis", "architecture", "design-patterns"] }) } // Error detection and potential issues if (this.needsErrorDetection(task)) { questions.push({ id: `base-errors-${task.id}`, question: "Identify potential errors, bugs, and code quality issues with their severity levels", perspective: "Error Detection", targetAgentName: "error-detector", reasoningMode: ReasoningMode.ULTRATHINKING, priority: 0.85, expectedCapabilities: ["error-detection", "debugging", "validation"] }) } return questions } /** * Generate multi-perspective analysis questions */ private generatePerspectiveQuestions(task: AgentTask): GeneratedQuestion[] { const questions: GeneratedQuestion[] = [] // Security perspective questions.push({ id: `perspective-security-${task.id}`, question: "Evaluate security vulnerabilities, potential attack vectors, and compliance with security best practices", perspective: "Security Analysis", targetAgentName: "security-analyzer", reasoningMode: ReasoningMode.HYBRID_REASONING, priority: 0.8, expectedCapabilities: ["security", "vulnerability-detection", "compliance"] }) // Performance perspective questions.push({ id: `perspective-performance-${task.id}`, question: "Assess performance characteristics, bottlenecks, and optimization opportunities", perspective: "Performance Analysis", targetAgentName: "performance-analyzer", reasoningMode: ReasoningMode.HYBRID_REASONING, priority: 0.75, expectedCapabilities: ["performance", "optimization", "profiling"] }) return questions } /** * Generate validation and verification questions */ private generateValidationQuestions(task: AgentTask): GeneratedQuestion[] { const questions: GeneratedQuestion[] = [] // Cross-validation question questions.push({ id: `validation-cross-${task.id}`, question: "Cross-validate findings from other analyses and identify potential conflicts or complementary insights", perspective: "Cross-Validation", targetAgentName: "code-analyzer", reasoningMode: ReasoningMode.HYBRID_THINKING, priority: 0.6, expectedCapabilities: ["validation", "synthesis", "conflict-resolution"] }) return questions } /** * Generate innovative and creative analysis questions */ private generateInnovationQuestions(task: AgentTask): GeneratedQuestion[] { const questions: GeneratedQuestion[] = [] // For now, skip innovation questions to keep it simple // Can be added later when we have more specialized agents return questions } /** * Analyze the context and scope of the task */ private analyzeTaskContext(task: AgentTask): any { return { hasCodeContent: this.hasCodeContent(task), projectSize: this.estimateProjectSize(task), languageContext: this.extractLanguageContext(task), frameworkContext: this.extractFrameworkContext(task) } } /** * Determine the scope of analysis needed */ private determineAnalysisScope(task: AgentTask): string { if (this.isFileProcessingTask(task)) { return "file-level" } if (this.isProjectAnalysisTask(task)) { return "project-level" } if (this.isCodeSnippetTask(task)) { return "snippet-level" } return "general" } /** * Assess the complexity of the task */ private assessComplexity(task: AgentTask): number { let complexity = 0.5 // Base complexity // Factor in data size if (task.data && typeof task.data === 'string') { const lines = task.data.split('\n').length if (lines > 1000) complexity += 0.3 else if (lines > 100) complexity += 0.2 else if (lines > 10) complexity += 0.1 } // Factor in reasoning modes if (task.reasoningModes.length > 2) { complexity += 0.2 } // Factor in task type if (task.type.includes('refactor') || task.type.includes('security')) { complexity += 0.2 } return Math.min(1, complexity) } /** * Estimate processing time based on questions and complexity */ private estimateProcessingTime(questions: GeneratedQuestion[]): number { const baseTimePerQuestion = 30000 // 30 seconds const complexityMultiplier = questions.length > 4 ? 1.5 : 1.2 return questions.length * baseTimePerQuestion * complexityMultiplier } // Helper methods for task classification private isCodeAnalysisTask(task: AgentTask): boolean { return task.type.includes('analysis') || task.type.includes('code') } private needsErrorDetection(task: AgentTask): boolean { return !task.type.includes('documentation') && this.hasCodeContent(task) } private needsDocumentationAnalysis(task: AgentTask): boolean { return task.type.includes('documentation') || task.type.includes('analysis') } private needsRefactoringAnalysis(task: AgentTask): boolean { return task.type.includes('refactor') || task.type.includes('improvement') } private isFileProcessingTask(task: AgentTask): boolean { return task.type.includes('file') || task.type.includes('process') } private isProjectAnalysisTask(task: AgentTask): boolean { return task.type.includes('project') || (task.context.projectPath && task.context.projectPath.length > 0) } private isCodeSnippetTask(task: AgentTask): boolean { return task.data && typeof task.data === 'string' && task.data.length < 1000 } private hasCodeContent(task: AgentTask): boolean { if (!task.data) return false if (typeof task.data !== 'string') return false // Simple heuristic to detect code content const codeIndicators = ['{', '}', '(', ')', ';', 'function', 'class', 'import', 'export'] return codeIndicators.some(indicator => task.data.includes(indicator)) } private estimateProjectSize(task: AgentTask): 'small' | 'medium' | 'large' { if (task.data && typeof task.data === 'string') { const length = task.data.length if (length > 50000) return 'large' if (length > 5000) return 'medium' } return 'small' } private extractLanguageContext(task: AgentTask): string | undefined { return task.context.language } private extractFrameworkContext(task: AgentTask): string[] { return task.context.frameworks || [] } }