Skip to main content
Glama
summary-generator.ts4.78 kB
/** * Summary Generator - Creates concise 15-20 word summaries from memory content * * Target: 15-20 words (hard limit: 25 words) * Strategy: Extract key entities and main idea, preserve proper nouns */ const MAX_WORDS = 25; const TARGET_WORDS_MIN = 15; const TARGET_WORDS_MAX = 20; const FALLBACK_CHARS = 100; /** * Generate a concise summary from memory content * * @param content - The full memory content to summarize * @returns A 15-20 word summary (max 25 words) */ export function generateSummary(content: string): string { if (!content || content.trim().length === 0) { return 'Empty memory content'; } const trimmedContent = content.trim(); // Strategy 1: Use first sentence if it's concise enough const firstSentence = extractFirstSentence(trimmedContent); if (firstSentence) { const wordCount = countWords(firstSentence); if (wordCount >= TARGET_WORDS_MIN && wordCount <= TARGET_WORDS_MAX) { return firstSentence; } if (wordCount < MAX_WORDS) { return firstSentence; } } // Strategy 2: For longer content, extract key information const extracted = extractKeyInformation(trimmedContent); if (extracted) { const wordCount = countWords(extracted); if (wordCount <= MAX_WORDS) { return extracted; } } // Strategy 3: Truncate intelligently to MAX_WORDS const truncated = truncateToWords(trimmedContent, TARGET_WORDS_MAX); if (truncated.length > 0) { return truncated; } // Fallback: First 100 characters if (trimmedContent.length <= FALLBACK_CHARS) { return trimmedContent; } return trimmedContent.substring(0, FALLBACK_CHARS - 3) + '...'; } /** * Extract the first complete sentence from text */ function extractFirstSentence(text: string): string | null { // Match first sentence ending with . ! ? (but not abbreviations like Dr. or Mr.) const sentenceMatch = text.match(/^[^.!?]+[.!?](?=\s|$)/); if (sentenceMatch) { return sentenceMatch[0].trim(); } // If no sentence delimiter, check if the whole text is short enough if (text.length < 150) { return text; } return null; } /** * Extract key information from longer text * Focuses on: subject + verb + key entities/details */ function extractKeyInformation(text: string): string | null { // Split into sentences const sentences = text.match(/[^.!?]+[.!?]*/g); if (!sentences || sentences.length === 0) { return null; } // Get first sentence and try to condense it const firstSentence = sentences[0].trim(); const words = firstSentence.split(/\s+/); if (words.length <= MAX_WORDS) { return firstSentence; } // Try to extract core meaning from first sentence // Remove filler words and keep essential information const condensed = removeFillerWords(firstSentence); const condensedWords = countWords(condensed); if (condensedWords <= MAX_WORDS) { return condensed; } // If still too long, take first MAX_WORDS words of condensed version return truncateToWords(condensed, TARGET_WORDS_MAX); } /** * Remove common filler words while preserving meaning */ function removeFillerWords(text: string): string { const fillerPatterns = [ /\b(very|really|quite|rather|somewhat|actually|basically|essentially|literally)\b/gi, /\b(I think|I believe|in my opinion|it seems|it appears)\b/gi, ]; let result = text; for (const pattern of fillerPatterns) { result = result.replace(pattern, ''); } // Clean up multiple spaces result = result.replace(/\s+/g, ' ').trim(); return result; } /** * Count words in a string */ function countWords(text: string): number { return text.trim().split(/\s+/).length; } /** * Truncate text to a specific number of words */ function truncateToWords(text: string, maxWords: number): string { const words = text.trim().split(/\s+/); if (words.length <= maxWords) { return text.trim(); } const truncated = words.slice(0, maxWords).join(' '); // Add ellipsis if we truncated if (words.length > maxWords) { return truncated + '...'; } return truncated; } /** * Validate that a summary meets requirements * * @param summary - The summary to validate * @returns true if valid, false otherwise */ export function validateSummary(summary: string): boolean { const wordCount = countWords(summary); return wordCount > 0 && wordCount <= MAX_WORDS; } /** * Get word count for a summary * * @param summary - The summary to count * @returns Number of words */ export function getSummaryWordCount(summary: string): number { return countWords(summary); }

Latest Blog Posts

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/WhenMoon-afk/claude-memory-mcp'

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