UNPKG

@tomisakae/tomibot

Version:

TomiBot - AI Chatbot CLI với Google Genkit. Một chatbot AI thông minh chạy trên command line với giao diện đẹp.

269 lines (268 loc) 9.53 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ChatServiceImpl = void 0; const logger_util_1 = require("../../utils/logger.util"); class ChatServiceImpl { constructor(aiService) { this.currentSession = null; this.initialized = false; this.aiService = aiService; this.logger = new logger_util_1.Logger('ChatService'); } async initialize() { if (this.initialized) { this.logger.warn('Chat service already initialized'); return; } try { this.logger.info('Initializing chat service...'); if (!this.aiService.isReady()) { await this.aiService.initialize(); } this.initialized = true; this.logger.info('Chat service initialized successfully'); } catch (error) { this.logger.error('Failed to initialize chat service:', error); throw error; } } isInitialized() { return this.initialized; } async dispose() { this.logger.info('Disposing chat service...'); try { if (this.currentSession) { await this.endSession(this.currentSession.id); } this.initialized = false; this.logger.info('Chat service disposed successfully'); } catch (error) { this.logger.error('Error disposing chat service:', error); throw error; } } async startSession() { this.logger.info('Starting new chat session'); if (this.currentSession) { await this.endSession(this.currentSession.id); } this.currentSession = { id: this.generateSessionId(), startTime: new Date(), messageCount: 0, isActive: true, metadata: { aiServiceReady: this.aiService.isReady(), startedBy: 'user', }, }; this.logger.info('Chat session started', { sessionId: this.currentSession.id, aiReady: this.aiService.isReady(), }); return this.currentSession; } async endSession(sessionId) { if (!this.currentSession || this.currentSession.id !== sessionId) { this.logger.warn('Attempted to end non-existent session', { sessionId }); return; } this.logger.info('Ending chat session', { sessionId }); this.currentSession.endTime = new Date(); this.currentSession.isActive = false; const sessionDuration = this.currentSession.endTime.getTime() - this.currentSession.startTime.getTime(); this.logger.info('Chat session ended', { sessionId, duration: `${Math.round(sessionDuration / 1000)}s`, messageCount: this.currentSession.messageCount, }); this.currentSession = null; } getCurrentSession() { return this.currentSession ? { ...this.currentSession } : null; } async sendMessage(message) { if (!this.currentSession) { return { content: '', success: false, error: 'No active chat session. Please start a session first.', }; } this.logger.debug('Processing message', { sessionId: this.currentSession.id, messageLength: message.length, }); try { if (message.startsWith('/')) { return await this.handleCommand(message); } const response = await this.aiService.sendMessage(message); if (response.success) { this.currentSession.messageCount++; this.logger.debug('Message processed successfully', { sessionId: this.currentSession.id, messageCount: this.currentSession.messageCount, }); } return response; } catch (error) { this.logger.error('Error processing message:', error); return { content: '', success: false, error: `Message processing failed: ${error instanceof Error ? error.message : 'Unknown error'}`, }; } } async executeCommand(command, args) { this.logger.debug('Executing command', { command, args }); try { switch (command.toLowerCase()) { case 'help': return await this.handleHelpCommand(args); case 'clear': return await this.handleClearCommand(args); case 'history': return await this.handleHistoryCommand(args); case 'status': return await this.handleStatusCommand(args); case 'exit': case 'quit': case 'bye': return await this.handleExitCommand(args); default: return { success: false, message: `Unknown command: ${command}. Type '/help' for available commands.`, }; } } catch (error) { this.logger.error('Error executing command:', error); return { success: false, message: `Command execution failed: ${error instanceof Error ? error.message : 'Unknown error'}`, }; } } async handleCommand(message) { const parts = message.slice(1).split(' '); const command = parts[0] || ''; const args = parts.slice(1); const result = await this.executeCommand(command, args); return { content: result.message || '', success: result.success, ...(result.success ? {} : { error: result.message || 'Command failed' }), metadata: { isCommand: true, command, args, shouldExit: result.shouldExit, }, }; } async handleHelpCommand(_args) { const helpText = ` Available Commands: • /help - Show this help message • /clear - Clear conversation history • /history - Show conversation history • /status - Show session status • /exit, /quit, /bye - Exit chat session Regular Usage: • Type any message to chat with AI • Use Ctrl+C to exit quickly `.trim(); return { success: true, message: helpText, }; } async handleClearCommand(_args) { this.aiService.clearHistory(); return { success: true, message: '🗑️ Conversation history cleared.', }; } async handleHistoryCommand(_args) { const history = this.aiService.getHistory(); if (history.length === 0) { return { success: true, message: '📝 No conversation history available.', }; } let historyText = `📝 Conversation History (${history.length} messages):\n\n`; history.forEach((msg, index) => { const time = msg.timestamp.toLocaleTimeString(); const role = msg.role === 'user' ? '👤 You' : '🤖 TomiBot'; const content = msg.content.length > 100 ? msg.content.substring(0, 100) + '...' : msg.content; historyText += `${index + 1}. [${time}] ${role}: ${content}\n`; }); return { success: true, message: historyText, }; } async handleStatusCommand(_args) { if (!this.currentSession) { return { success: true, message: '📊 No active chat session.', }; } const modelInfo = this.aiService.getModelInfo(); const duration = Date.now() - this.currentSession.startTime.getTime(); const durationText = `${Math.round(duration / 1000)}s`; const statusText = ` 📊 Chat Session Status: • Session ID: ${this.currentSession.id} • Started: ${this.currentSession.startTime.toLocaleString()} • Duration: ${durationText} • Messages: ${this.currentSession.messageCount} • AI Status: ${modelInfo.initialized ? '✅ Ready' : '❌ Not Ready'} • History: ${modelInfo.historyCount} messages `.trim(); return { success: true, message: statusText, }; } async handleExitCommand(_args) { return { success: true, message: '👋 Exiting chat session...', shouldExit: true, }; } generateSessionId() { return `chat_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`; } getSessionStatistics() { return { hasActiveSession: !!this.currentSession, currentSession: this.currentSession ? { id: this.currentSession.id, startTime: this.currentSession.startTime, messageCount: this.currentSession.messageCount, isActive: this.currentSession.isActive, } : null, aiServiceReady: this.aiService.isReady(), initialized: this.initialized, }; } } exports.ChatServiceImpl = ChatServiceImpl; //# sourceMappingURL=chat.service.js.map