Skip to main content
Glama

mcp-github-project-manager

TaskContextGenerationService.ts12.7 kB
import { generateObject } from 'ai'; import { AIServiceFactory } from './ai/AIServiceFactory'; import { CONTEXT_GENERATION_CONFIGS, formatContextPrompt, BusinessContextSchema, TechnicalContextSchema, ImplementationGuidanceSchema, ContextualReferencesSchema, EnhancedAcceptanceCriteriaSchema } from './ai/prompts/ContextGenerationPrompts'; import { AITask, EnhancedAITask, PRDDocument, EnhancedTaskGenerationConfig, TaskExecutionContext, EnhancedAcceptanceCriteria, ContextualReferences, ImplementationGuidance, EnhancedTaskDependency } from '../domain/ai-types'; import { RequirementsTraceabilityService } from './RequirementsTraceabilityService'; import { ENHANCED_TASK_GENERATION, INCLUDE_BUSINESS_CONTEXT, INCLUDE_TECHNICAL_CONTEXT, INCLUDE_IMPLEMENTATION_GUIDANCE, ENHANCED_CONTEXT_LEVEL } from '../env'; /** * Service for generating comprehensive task context using AI and traceability */ export class TaskContextGenerationService { private aiFactory: AIServiceFactory; private traceabilityService: RequirementsTraceabilityService; constructor() { this.aiFactory = AIServiceFactory.getInstance(); this.traceabilityService = new RequirementsTraceabilityService(); } /** * Generate comprehensive context for a task */ async generateTaskContext( task: AITask, prd: PRDDocument | string, config: EnhancedTaskGenerationConfig ): Promise<TaskExecutionContext> { try { const prdContent = typeof prd === 'string' ? prd : JSON.stringify(prd, null, 2); // Start with traceability-based context (always available) const traceabilityContext = await this.generateTraceabilityContext(task, prd); // Add AI-enhanced context if enabled and available let aiEnhancedContext = {}; if (config.enableEnhancedGeneration && this.aiFactory.getBestAvailableModel()) { aiEnhancedContext = await this.generateAIEnhancedContext(task, prdContent, config); } // Merge contexts with AI enhancement taking precedence return this.mergeContexts(traceabilityContext, aiEnhancedContext); } catch (error) { process.stderr.write(`Error generating task context: ${error instanceof Error ? error.message : String(error)}\n`); // Fallback to basic traceability context return this.generateTraceabilityContext(task, prd); } } /** * Generate context from traceability system (default, always available) */ private async generateTraceabilityContext( task: AITask, prd: PRDDocument | string ): Promise<TaskExecutionContext> { try { // Create basic context from traceability information const prdObj = typeof prd === 'object' ? prd : { objectives: ['Deliver high-quality software solution'], title: 'Project Requirements' }; return { businessObjective: `Supports project objective: ${prdObj.objectives?.[0] || 'Deliver software solution'}`, userImpact: `Contributes to overall user experience and system functionality`, successMetrics: ['Task completed according to acceptance criteria', 'Code review approved', 'Tests passing'], parentFeature: { id: task.sourcePRD || 'unknown', title: 'Related Feature', description: 'Feature containing this task', userStories: ['As a user, I want this functionality to work correctly'], businessValue: 'Provides essential system functionality' }, technicalConstraints: ['Follow existing code patterns', 'Maintain system performance', 'Ensure security standards'], architecturalDecisions: ['Use established architecture patterns', 'Follow team coding standards'], integrationPoints: ['Integrate with existing system components'], dataRequirements: ['Use existing data models where applicable'], prdContextSummary: { relevantObjectives: prdObj.objectives || ['Deliver software solution'], relevantRequirements: ['Implement according to specifications'], scopeConstraints: ['Stay within defined project scope'] } }; } catch (error) { process.stderr.write(`Error generating traceability context: ${error instanceof Error ? error.message : String(error)}\n`); return this.getMinimalContext(task); } } /** * Generate AI-enhanced context (when AI is available and enabled) */ private async generateAIEnhancedContext( task: AITask, prdContent: string, config: EnhancedTaskGenerationConfig ): Promise<Partial<TaskExecutionContext>> { const enhancedContext: Partial<TaskExecutionContext> = {}; try { // Generate business context if enabled if (config.includeBusinessContext) { const businessContext = await this.generateBusinessContext(task, prdContent); if (businessContext) { enhancedContext.businessObjective = businessContext.businessObjective; enhancedContext.userImpact = businessContext.userImpact; enhancedContext.successMetrics = businessContext.successMetrics; } } // Generate technical context if enabled if (config.includeTechnicalContext) { const technicalContext = await this.generateTechnicalContext(task, prdContent); if (technicalContext) { enhancedContext.technicalConstraints = technicalContext.technicalConstraints; enhancedContext.architecturalDecisions = technicalContext.architecturalDecisions.map((ad: any) => ad.decision); enhancedContext.integrationPoints = technicalContext.integrationPoints.map((ip: any) => ip.description); enhancedContext.dataRequirements = technicalContext.dataRequirements.map((dr: any) => dr.description); } } return enhancedContext; } catch (error) { process.stderr.write(`Error generating AI-enhanced context: ${error instanceof Error ? error.message : String(error)}\n`); return {}; } } /** * Generate business context using AI */ private async generateBusinessContext(task: AITask, prdContent: string): Promise<any> { try { const model = this.aiFactory.getBestAvailableModel(); if (!model) return null; const config = CONTEXT_GENERATION_CONFIGS.businessContext; const prompt = formatContextPrompt(config.userPrompt, { prdContent, taskTitle: task.title, taskDescription: task.description, taskPriority: task.priority }); const result = await generateObject({ model, system: config.systemPrompt, prompt, schema: BusinessContextSchema, maxTokens: config.maxTokens, temperature: config.temperature }); return result.object; } catch (error) { process.stderr.write(`Error generating business context: ${error instanceof Error ? error.message : String(error)}\n`); return null; } } /** * Generate technical context using AI */ private async generateTechnicalContext(task: AITask, prdContent: string): Promise<any> { try { const model = this.aiFactory.getBestAvailableModel(); if (!model) return null; const config = CONTEXT_GENERATION_CONFIGS.technicalContext; const prompt = formatContextPrompt(config.userPrompt, { prdContent, taskTitle: task.title, taskDescription: task.description, taskComplexity: task.complexity }); const result = await generateObject({ model, system: config.systemPrompt, prompt, schema: TechnicalContextSchema, maxTokens: config.maxTokens, temperature: config.temperature }); return result.object; } catch (error) { process.stderr.write(`Error generating technical context: ${error instanceof Error ? error.message : String(error)}\n`); return null; } } /** * Generate implementation guidance using AI */ async generateImplementationGuidance( task: AITask, businessContext?: any, technicalContext?: any ): Promise<ImplementationGuidance | null> { try { const model = this.aiFactory.getBestAvailableModel(); if (!model) return null; const config = CONTEXT_GENERATION_CONFIGS.implementationGuidance; const prompt = formatContextPrompt(config.userPrompt, { taskTitle: task.title, taskDescription: task.description, taskComplexity: task.complexity, taskPriority: task.priority, businessContext: businessContext ? JSON.stringify(businessContext, null, 2) : 'Not available', technicalContext: technicalContext ? JSON.stringify(technicalContext, null, 2) : 'Not available' }); const result = await generateObject({ model, system: config.systemPrompt, prompt, schema: ImplementationGuidanceSchema, maxTokens: config.maxTokens, temperature: config.temperature }); return this.transformImplementationGuidance(result.object); } catch (error) { process.stderr.write(`Error generating implementation guidance: ${error instanceof Error ? error.message : String(error)}\n`); return null; } } /** * Transform AI implementation guidance to our format */ private transformImplementationGuidance(aiGuidance: any): ImplementationGuidance { return { recommendedApproach: aiGuidance.recommendedApproach, implementationSteps: aiGuidance.implementationSteps.map((step: any) => step.description || step), technicalConsiderations: aiGuidance.technicalConsiderations, commonPitfalls: aiGuidance.commonPitfalls.map((pitfall: any) => pitfall.pitfall || pitfall), testingStrategy: aiGuidance.testingStrategy?.approach || 'Standard testing approach', recommendedTools: aiGuidance.bestPractices?.map((bp: any) => bp.practice) || [], codeQualityStandards: aiGuidance.qualityAssurance || [], performanceConsiderations: aiGuidance.performanceOptimization || [], securityConsiderations: [] }; } /** * Merge traceability and AI contexts */ private mergeContexts( traceabilityContext: TaskExecutionContext, aiContext: Partial<TaskExecutionContext> ): TaskExecutionContext { return { ...traceabilityContext, ...aiContext, // Merge arrays intelligently successMetrics: [ ...(aiContext.successMetrics || []), ...traceabilityContext.successMetrics ].filter((metric, index, arr) => arr.indexOf(metric) === index), technicalConstraints: [ ...(aiContext.technicalConstraints || []), ...traceabilityContext.technicalConstraints ].filter((constraint, index, arr) => arr.indexOf(constraint) === index) }; } /** * Get minimal context as fallback */ private getMinimalContext(task: AITask): TaskExecutionContext { return { businessObjective: 'Complete assigned development task', userImpact: 'Contributes to overall system functionality', successMetrics: ['Task completed', 'Tests passing', 'Code reviewed'], parentFeature: { id: 'unknown', title: 'Development Task', description: task.description, userStories: ['As a developer, I need to complete this task'], businessValue: 'Maintains system functionality' }, technicalConstraints: ['Follow coding standards'], architecturalDecisions: ['Use existing patterns'], integrationPoints: ['Standard system integration'], dataRequirements: ['Use appropriate data structures'], prdContextSummary: { relevantObjectives: ['Complete development work'], relevantRequirements: ['Implement as specified'], scopeConstraints: ['Stay within task scope'] } }; } /** * Check if AI context generation is available */ isAIContextAvailable(): boolean { return ENHANCED_TASK_GENERATION && !!this.aiFactory.getBestAvailableModel(); } /** * Get context generation configuration from environment */ getDefaultContextConfig(): EnhancedTaskGenerationConfig { return { enableEnhancedGeneration: ENHANCED_TASK_GENERATION, createTraceabilityMatrix: true, generateUseCases: true, createLifecycleTracking: true, contextLevel: ENHANCED_CONTEXT_LEVEL as 'minimal' | 'standard' | 'full', includeBusinessContext: INCLUDE_BUSINESS_CONTEXT, includeTechnicalContext: INCLUDE_TECHNICAL_CONTEXT, includeImplementationGuidance: INCLUDE_IMPLEMENTATION_GUIDANCE, enforceTraceability: true, requireBusinessJustification: INCLUDE_BUSINESS_CONTEXT, trackRequirementCoverage: true }; } }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/kunwarVivek/mcp-github-project-manager'

If you have feedback or need assistance with the MCP directory API, please join our Discord server