UNPKG

contaigents

Version:

Modular AI Content Ecosystem with Audio Generation

256 lines (241 loc) 10 kB
import { BaseTool } from '../base/BaseTool.js'; import { IntelligentFileService } from '../../services/IntelligentFileService.js'; export class SummarizeFileTool extends BaseTool { constructor(context) { super('summarize_file', 'Generate intelligent summaries of file content with various formats and focus areas', context); this.intelligentFileService = new IntelligentFileService(context.workingDirectory); } async execute(params) { try { const { filePath, maxLength = 300, summaryType = 'detailed', focusArea } = params; if (!filePath) { return this.createErrorResult('File path is required'); } // Check if file exists const exists = await this.intelligentFileService.fileExists(filePath); if (!exists) { return this.createErrorResult(`File not found: ${filePath}`); } const content = await this.intelligentFileService.readFile(filePath); const originalLength = content.length; let summaryResult; switch (summaryType) { case 'brief': summaryResult = await this.generateBriefSummary(filePath, content, maxLength, focusArea); break; case 'detailed': summaryResult = await this.generateDetailedSummary(filePath, content, maxLength, focusArea); break; case 'bullet-points': summaryResult = await this.generateBulletPointSummary(filePath, content, maxLength, focusArea); break; case 'key-themes': summaryResult = await this.generateThematicSummary(filePath, content, maxLength, focusArea); break; default: summaryResult = await this.generateDetailedSummary(filePath, content, maxLength, focusArea); } summaryResult.originalLength = originalLength; summaryResult.compressionRatio = originalLength > 0 ? summaryResult.wordCount / originalLength : 0; return this.createSuccessResult(summaryResult, { timestamp: Date.now(), summaryType, maxLength, focusArea }); } catch (error) { return this.createErrorResult(`Summarization failed: ${error instanceof Error ? error.message : 'Unknown error'}`); } } async generateBriefSummary(filePath, content, maxLength, focusArea) { let summary; if (!this.context.llm) { // Fallback: simple truncation summary = content.substring(0, maxLength); if (content.length > maxLength) { summary += '...'; } } else { const focusPrompt = focusArea ? `Focus specifically on: ${focusArea}` : ''; const prompt = `Provide a brief summary of this file in ${maxLength} characters or less: File: ${filePath} ${focusPrompt} Content: ${content.substring(0, 2000)}${content.length > 2000 ? '...' : ''} Summary should be concise and capture the essence of the file.`; try { const response = await this.context.llm.executePrompt(prompt); summary = response.content.substring(0, maxLength); } catch (error) { summary = content.substring(0, maxLength) + (content.length > maxLength ? '...' : ''); } } return { filePath, summaryType: 'brief', summary, wordCount: summary.split(/\s+/).length, originalLength: 0, // Will be set by caller compressionRatio: 0 // Will be calculated by caller }; } async generateDetailedSummary(filePath, content, maxLength, focusArea) { if (!this.context.llm) { return this.generateBriefSummary(filePath, content, maxLength, focusArea); } const focusPrompt = focusArea ? `Pay special attention to: ${focusArea}` : ''; const prompt = `Provide a detailed summary of this file: File: ${filePath} ${focusPrompt} Content: ${content} Please provide: 1. A comprehensive summary (max ${maxLength} characters) 2. Main purpose and objectives 3. Key sections or components 4. Important details and findings Format as a coherent narrative summary.`; try { const response = await this.context.llm.executePrompt(prompt); const summary = response.content.substring(0, maxLength); // Extract key points from the detailed response const keyPoints = this.extractKeyPoints(response.content); return { filePath, summaryType: 'detailed', summary, keyPoints, wordCount: summary.split(/\s+/).length, originalLength: 0, compressionRatio: 0 }; } catch (error) { return this.generateBriefSummary(filePath, content, maxLength, focusArea); } } async generateBulletPointSummary(filePath, content, maxLength, focusArea) { if (!this.context.llm) { return this.generateBriefSummary(filePath, content, maxLength, focusArea); } const focusPrompt = focusArea ? `Focus on aspects related to: ${focusArea}` : ''; const prompt = `Summarize this file as bullet points: File: ${filePath} ${focusPrompt} Content: ${content} Provide 5-10 key bullet points that capture the most important aspects of this file. Each bullet point should be concise but informative. Total response should be under ${maxLength} characters.`; try { const response = await this.context.llm.executePrompt(prompt); const summary = response.content.substring(0, maxLength); const keyPoints = this.extractBulletPoints(response.content); return { filePath, summaryType: 'bullet-points', summary, keyPoints, wordCount: summary.split(/\s+/).length, originalLength: 0, compressionRatio: 0 }; } catch (error) { return this.generateBriefSummary(filePath, content, maxLength, focusArea); } } async generateThematicSummary(filePath, content, maxLength, focusArea) { if (!this.context.llm) { return this.generateBriefSummary(filePath, content, maxLength, focusArea); } const focusPrompt = focusArea ? `Emphasize themes related to: ${focusArea}` : ''; const prompt = `Analyze this file and identify key themes: File: ${filePath} ${focusPrompt} Content: ${content} Please provide: 1. A thematic summary (max ${maxLength} characters) 2. 3-7 main themes or topics covered 3. How these themes relate to each other Focus on the conceptual content rather than technical details.`; try { const response = await this.context.llm.executePrompt(prompt); const summary = response.content.substring(0, maxLength); const mainThemes = this.extractThemes(response.content); return { filePath, summaryType: 'key-themes', summary, mainThemes, wordCount: summary.split(/\s+/).length, originalLength: 0, compressionRatio: 0 }; } catch (error) { return this.generateBriefSummary(filePath, content, maxLength, focusArea); } } extractKeyPoints(response) { const lines = response.split('\n'); const keyPoints = []; for (const line of lines) { const trimmed = line.trim(); if (trimmed.startsWith('- ') || trimmed.startsWith('• ') || trimmed.match(/^\d+\.\s/)) { keyPoints.push(trimmed.replace(/^[-•\d.]\s*/, '')); } } return keyPoints.length > 0 ? keyPoints : [response.substring(0, 100) + '...']; } extractBulletPoints(response) { const lines = response.split('\n'); const bulletPoints = []; for (const line of lines) { const trimmed = line.trim(); if (trimmed.startsWith('- ') || trimmed.startsWith('• ')) { bulletPoints.push(trimmed.substring(2)); } else if (trimmed.match(/^\d+\.\s/)) { bulletPoints.push(trimmed.replace(/^\d+\.\s/, '')); } } return bulletPoints; } extractThemes(response) { const lines = response.split('\n'); const themes = []; let inThemeSection = false; for (const line of lines) { const trimmed = line.trim().toLowerCase(); if (trimmed.includes('theme') || trimmed.includes('topic')) { inThemeSection = true; continue; } if (inThemeSection && (trimmed.startsWith('- ') || trimmed.startsWith('• ') || trimmed.match(/^\d+\.\s/))) { themes.push(line.trim().replace(/^[-•\d.]\s*/, '')); } } // If no themes found in structured format, try to extract from content if (themes.length === 0) { const themeKeywords = ['theme', 'topic', 'subject', 'focus', 'area']; for (const line of lines) { for (const keyword of themeKeywords) { if (line.toLowerCase().includes(keyword)) { const parts = line.split(':'); if (parts.length > 1) { themes.push(parts[1].trim()); } } } } } return themes.slice(0, 7); // Limit to 7 themes } }