UNPKG

create-ai-chat-context-experimental

Version:

Phase 2: TypeScript rewrite - AI Chat Context & Memory System with conversation extraction and AICF format support (powered by aicf-core v2.1.0).

155 lines 5.71 kB
"use strict"; /** * This file is part of create-ai-chat-context-experimental. * Licensed under the GNU Affero General Public License v3.0 or later (AGPL-3.0-or-later). * See LICENSE file for details. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.StateExtractor = void 0; const index_js_1 = require("../types/index.js"); const index_js_2 = require("../types/index.js"); /** * Extract working state using priority-based approach * PRIORITY 1: Use conversation summary (full content) * PRIORITY 2: Extract from individual messages (fallback) */ class StateExtractor { /** * Extract working state from messages and summary * * @param messages - Array of messages * @param summary - Conversation summary (optional) * @returns Result with WorkingState or error */ extract(messages, summary) { try { // PRIORITY 1: Extract from conversation summary if (summary && summary.fullConversation) { return (0, index_js_2.Ok)(this.extractFromSummary(summary)); } // PRIORITY 2: Extract from individual messages return (0, index_js_2.Ok)(this.extractFromMessages(messages)); } catch (error) { const message = error instanceof Error ? error.message : 'Unknown error'; return (0, index_js_2.Err)(new index_js_1.ExtractionError(`Failed to extract working state: ${message}`, error)); } } /** * Extract working state from conversation summary * @param summary - Conversation summary * @returns WorkingState */ extractFromSummary(summary) { const fullConv = summary.fullConversation; const currentTask = this.extractCurrentTask(fullConv); const blockers = this.extractBlockers(fullConv); const nextAction = this.extractNextAction(fullConv); return { currentTask, blockers, nextAction, lastUpdate: new Date().toISOString(), }; } /** * Extract working state from individual messages * @param messages - Array of messages * @returns WorkingState */ extractFromMessages(messages) { const fullContent = messages.map((m) => m.content).join('\n'); const currentTask = this.extractCurrentTask(fullContent); const blockers = this.extractBlockers(fullContent); const nextAction = this.extractNextAction(fullContent); const lastMessage = messages[messages.length - 1]; const lastUpdate = lastMessage?.timestamp ?? new Date().toISOString(); return { currentTask, blockers, nextAction, lastUpdate, }; } /** * Extract current task from content * @param content - Full content * @returns Current task */ extractCurrentTask(content) { // Look for current task patterns const patterns = [ /(?:currently|now)\s+(?:working on|implementing|building|creating)\s+([^.!?]+)/i, /(?:current task|working on)\s*:?\s*([^.!?]+)/i, /(?:task|focus)\s*:?\s*([^.!?]+)/i, ]; for (const pattern of patterns) { const match = content.match(pattern); if (match && match[1]) { return match[1].trim(); } } // Default: extract first meaningful sentence const sentences = content.split(/[.!?]+/).filter((s) => s.trim().length > 10); const firstSentence = sentences[0]; return firstSentence?.trim() ?? 'Unknown task'; } /** * Extract blockers from content * @param content - Full content * @returns Array of blockers */ extractBlockers(content) { const blockers = []; // Look for blocker patterns const blockerPatterns = [ /blocked\s+by\s+([^.!?]+)/gi, /(?:blocking|issue|problem|error|bug)\s*:?\s*([^.!?]+)/gi, /(?:can't|cannot|unable to|stuck on)\s+([^.!?]+)/gi, /(?:need to|waiting for|depends on)\s+([^.!?]+)/gi, ]; blockerPatterns.forEach((pattern) => { let match; while ((match = pattern.exec(content)) !== null) { const blocker = match[1]?.trim(); if (blocker && blocker.length > 5 && blocker.length < 200) { blockers.push(blocker); } } }); return [...new Set(blockers)]; // Remove duplicates } /** * Extract next action from content * @param content - Full content * @returns Next action */ extractNextAction(content) { // Look for next action patterns const patterns = [ /(?:next|then|after that)\s+(?:we|I|should|will)\s+([^.!?]+)/i, /(?:next step|next action)\s*:?\s*([^.!?]+)/i, /(?:todo|to do)\s*:?\s*([^.!?]+)/i, /(?:plan to|going to)\s+([^.!?]+)/i, ]; for (const pattern of patterns) { const match = content.match(pattern); if (match && match[1]) { return match[1].trim(); } } // Default: suggest next logical step if (content.toLowerCase().includes('implement')) { return 'Test the implementation'; } if (content.toLowerCase().includes('test')) { return 'Review test results'; } if (content.toLowerCase().includes('review')) { return 'Deploy changes'; } return 'Continue with next task'; } } exports.StateExtractor = StateExtractor; //# sourceMappingURL=StateExtractor.js.map