@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
JavaScript
"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