From e764dd683ec753b24acf836b67f473bf48ae3977 Mon Sep 17 00:00:00 2001 From: kappa Date: Thu, 5 Feb 2026 12:32:45 +0900 Subject: [PATCH] feat: add /history and /search commands - Add /history [N] command to view recent conversation history - Default 20 messages, max 100 - Shows date/time, role (user/bot), and message preview - Add /search command to search conversations - Uses extractKeywords() for smart keyword extraction - Shows up to 15 results with date and content preview - Update /stats command to use new conversation-storage service - Shows total message count, first/last message dates - Shows archived summary count - Links to /history and /search commands - Update /start and /help commands to include new commands - Import conversation-storage functions Co-Authored-By: Claude Opus 4.5 --- src/commands.ts | 97 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 88 insertions(+), 9 deletions(-) diff --git a/src/commands.ts b/src/commands.ts index c6d895e..0ac1f03 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -1,5 +1,11 @@ import { Env } from './types'; import { getConversationContext, getLatestSummary } from './summary-service'; +import { + getConversationHistory, + searchConversations, + getConversationStats, + extractKeywords +} from './services/conversation-storage'; export async function handleCommand( env: Env, @@ -26,6 +32,8 @@ export async function handleCommand( /server - 내 서버 목록 /security - DDoS 방어 현황 /phantomx - PhantomX VPN +/history - 대화 기록 +/search - 대화 검색 무엇을 도와드릴까요?`; @@ -38,6 +46,8 @@ export async function handleCommand( /server - 내 서버 목록 /security - DDoS 방어 서비스 /phantomx - PhantomX VPN 서비스 +/history [N] - 대화 기록 (기본 20개) +/search 키워드 - 대화 검색 자연어로 요청: • "도메인 등록" - 도메인 검색/등록 @@ -90,19 +100,88 @@ ${summary.summary} 업데이트: ${createdAt}`; } + case '/history': { + const limit = _args ? parseInt(_args, 10) : 20; + const validLimit = Math.min(Math.max(limit, 1), 100); // 1-100 제한 + + const messages = await getConversationHistory(env.DB, chatId, validLimit); + + if (messages.length === 0) { + return '📜 저장된 대화가 없습니다.'; + } + + const formatted = messages.map(m => { + const time = m.created_at + ? new Date(m.created_at).toLocaleString('ko-KR', { + timeZone: 'Asia/Seoul', + month: '2-digit', + day: '2-digit', + hour: '2-digit', + minute: '2-digit' + }) + : ''; + const role = m.role === 'user' ? '나' : '봇'; + const content = m.content.length > 50 + ? m.content.substring(0, 50) + '...' + : m.content; + return `[${time}] ${role}: ${content}`; + }).join('\n'); + + return `📜 최근 대화 (${messages.length}개)\n\n${formatted}\n\n/history 50 으로 더 보기`; + } + + case '/search': { + if (!_args || _args.trim().length < 2) { + return '🔍 검색어를 입력해주세요.\n예: /search 도메인'; + } + + const keywords = extractKeywords(_args); + if (keywords.length === 0) { + return '🔍 유효한 검색어가 없습니다.'; + } + + const results = await searchConversations(env.DB, chatId, keywords, 15); + + if (results.length === 0) { + return `🔍 "${_args}" 검색 결과가 없습니다.`; + } + + const formatted = results.map(m => { + const date = m.created_at + ? new Date(m.created_at).toLocaleDateString('ko-KR') + : ''; + const content = m.content.length > 60 + ? m.content.substring(0, 60) + '...' + : m.content; + return `[${date}] ${content}`; + }).join('\n'); + + return `🔍 "${_args}" 검색 결과 (${results.length}건)\n\n${formatted}`; + } + case '/stats': { - const ctx = await getConversationContext(env.DB, userId, chatId); - const profileCount = await env.DB - .prepare('SELECT COUNT(*) as cnt FROM summaries WHERE user_id = ?') - .bind(userId) - .first<{ cnt: number }>(); + const stats = await getConversationStats(env.DB, chatId); + + if (!stats) { + return '📈 아직 대화 기록이 없습니다.'; + } + + const firstDate = stats.first_message_at + ? new Date(stats.first_message_at).toLocaleDateString('ko-KR') + : '없음'; + const lastDate = stats.last_message_at + ? new Date(stats.last_message_at).toLocaleDateString('ko-KR') + : '없음'; return `📈 대화 통계 -총 메시지: ${ctx.totalMessages}개 -프로필 버전: ${ctx.previousSummary?.generation ?? 0} -저장된 프로필: ${profileCount?.cnt ?? 0}개 -버퍼 대기: ${ctx.recentMessages.length}개`; +총 메시지: ${stats.message_count.toLocaleString()}개 +첫 대화: ${firstDate} +최근 대화: ${lastDate} +아카이브된 요약: ${stats.archived_summaries}개 + +/history - 대화 기록 보기 +/search 키워드 - 대화 검색`; } case '/domain': {