import type { ChatMessage } from '../../agent'; /** * 현재 사용자 메시지가 "얇은 follow-up" 인지 판정 — 직전 assistant 답변에 대한 * 짧은 정정 / 사실 보강 / 확인 / 짧은 감사 등. * * 결과 true 면 Project Chronicle Guard 의 "요청 요약 / 사용자 의도 추론 / 핵심 * 확인 질문 / 프로젝트 기록 대상 확인" 보일러플레이트를 *생략* 한다 — 이런 짧은 * 후속 메시지에 매번 4-section 템플릿을 박는 건 응답 위생을 망친다 (R1/R3 위반). * * 보수적인 판정 — false-positive 가 false-negative 보다 위험 (긴 분석 요청에 * 헤더가 없으면 사용자 경험 손상). 다음 *모든* 조건 만족할 때만 true: * (1) 직전 assistant 메시지가 history 에 존재 (즉 이게 follow-up 인 것) * (2) 짧다 (≤ 100자, 줄바꿈 후 trim 기준) * (3) 명확한 *질문* 신호가 없다 (?, "어떻게", "왜", "뭐", "어디", 등) * (4) 명확한 *새 작업 요청* 신호가 없다 (분석/평가/추천/비교/만들어줘/해줘/구현해/실행해 등) */ export function isThinFollowUp(prompt: string | null, history: ChatMessage[]): boolean { if (!prompt) return false; const t = prompt.trim(); if (t.length === 0 || t.length > 100) return false; // (1) 직전 assistant 메시지가 있어야 follow-up 임. const visible = history.filter(m => !m.internal && (m.role === 'user' || m.role === 'assistant')); const hasPriorAssistant = visible.some(m => m.role === 'assistant'); if (!hasPriorAssistant) return false; // (3) 질문 신호. if (/[??]/.test(t)) return false; if (/(어떻게|어디|언제|왜|뭐|누구|얼마|몇)/.test(t)) return false; if (/^\s*(what|how|why|where|when|who|which)\b/i.test(t)) return false; // (4) 새 작업 요청 신호 (단순 명령어 / 분석 요청). if (/(분석|평가|추천|비교|만들|짜줘|작성|구현|돌려|실행|생성|검토|리뷰|review|analyze|implement|create|build)/i.test(t)) { return false; } return true; }