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 <keyword> 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 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,11 @@
|
|||||||
import { Env } from './types';
|
import { Env } from './types';
|
||||||
import { getConversationContext, getLatestSummary } from './summary-service';
|
import { getConversationContext, getLatestSummary } from './summary-service';
|
||||||
|
import {
|
||||||
|
getConversationHistory,
|
||||||
|
searchConversations,
|
||||||
|
getConversationStats,
|
||||||
|
extractKeywords
|
||||||
|
} from './services/conversation-storage';
|
||||||
|
|
||||||
export async function handleCommand(
|
export async function handleCommand(
|
||||||
env: Env,
|
env: Env,
|
||||||
@@ -26,6 +32,8 @@ export async function handleCommand(
|
|||||||
/server - 내 서버 목록
|
/server - 내 서버 목록
|
||||||
/security - DDoS 방어 현황
|
/security - DDoS 방어 현황
|
||||||
/phantomx - PhantomX VPN
|
/phantomx - PhantomX VPN
|
||||||
|
/history - 대화 기록
|
||||||
|
/search - 대화 검색
|
||||||
|
|
||||||
무엇을 도와드릴까요?`;
|
무엇을 도와드릴까요?`;
|
||||||
|
|
||||||
@@ -38,6 +46,8 @@ export async function handleCommand(
|
|||||||
/server - 내 서버 목록
|
/server - 내 서버 목록
|
||||||
/security - DDoS 방어 서비스
|
/security - DDoS 방어 서비스
|
||||||
/phantomx - PhantomX VPN 서비스
|
/phantomx - PhantomX VPN 서비스
|
||||||
|
/history [N] - 대화 기록 (기본 20개)
|
||||||
|
/search 키워드 - 대화 검색
|
||||||
|
|
||||||
<b>자연어로 요청:</b>
|
<b>자연어로 요청:</b>
|
||||||
• "도메인 등록" - 도메인 검색/등록
|
• "도메인 등록" - 도메인 검색/등록
|
||||||
@@ -90,19 +100,88 @@ ${summary.summary}
|
|||||||
<i>업데이트: ${createdAt}</i>`;
|
<i>업데이트: ${createdAt}</i>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 `📜 <b>최근 대화</b> (${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 `🔍 <b>"${_args}"</b> 검색 결과 (${results.length}건)\n\n${formatted}`;
|
||||||
|
}
|
||||||
|
|
||||||
case '/stats': {
|
case '/stats': {
|
||||||
const ctx = await getConversationContext(env.DB, userId, chatId);
|
const stats = await getConversationStats(env.DB, chatId);
|
||||||
const profileCount = await env.DB
|
|
||||||
.prepare('SELECT COUNT(*) as cnt FROM summaries WHERE user_id = ?')
|
if (!stats) {
|
||||||
.bind(userId)
|
return '📈 아직 대화 기록이 없습니다.';
|
||||||
.first<{ cnt: number }>();
|
}
|
||||||
|
|
||||||
|
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 `📈 <b>대화 통계</b>
|
return `📈 <b>대화 통계</b>
|
||||||
|
|
||||||
총 메시지: ${ctx.totalMessages}개
|
총 메시지: ${stats.message_count.toLocaleString()}개
|
||||||
프로필 버전: ${ctx.previousSummary?.generation ?? 0}
|
첫 대화: ${firstDate}
|
||||||
저장된 프로필: ${profileCount?.cnt ?? 0}개
|
최근 대화: ${lastDate}
|
||||||
버퍼 대기: ${ctx.recentMessages.length}개`;
|
아카이브된 요약: ${stats.archived_summaries}개
|
||||||
|
|
||||||
|
/history - 대화 기록 보기
|
||||||
|
/search 키워드 - 대화 검색`;
|
||||||
}
|
}
|
||||||
|
|
||||||
case '/domain': {
|
case '/domain': {
|
||||||
|
|||||||
Reference in New Issue
Block a user