Phase 5-3 모니터링 강화 작업의 통합을 완료했습니다. 변경사항: - Logger 통합: console.log를 구조화된 로깅으로 전환 (9개 파일) - JSON 기반 로그, 환경별 자동 전환 (개발/프로덕션) - 타입 안전성 보장, 성능 측정 타이머 내장 - Metrics 통합: 실시간 성능 모니터링 시스템 연결 (3개 파일) - Circuit Breaker 상태 추적 (api_call_count, error_count, state) - Retry 재시도 횟수 추적 (retry_count) - OpenAI API 응답 시간 측정 (api_call_duration) - 알림 통합: 장애 자동 알림 시스템 구현 (2개 파일) - Circuit Breaker OPEN 상태 → 관리자 Telegram 알림 - 재시도 실패 → 관리자 Telegram 알림 - Rate Limiting 적용 (1시간에 1회) - 문서 업데이트: - CLAUDE.md: coder 에이전트 설명 강화 (20년+ 시니어 전문가) - README.md, docs/: 아키텍처 문서 추가 영향받은 파일: 16개 (수정 14개, 신규 2개) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
75 lines
2.1 KiB
TypeScript
75 lines
2.1 KiB
TypeScript
import { Env } from '../types';
|
|
import {
|
|
addToBuffer,
|
|
processAndSummarize,
|
|
generateAIResponse,
|
|
} from '../summary-service';
|
|
import { sendChatAction } from '../telegram';
|
|
|
|
export interface ConversationResult {
|
|
responseText: string;
|
|
isProfileUpdated: boolean;
|
|
keyboardData?: any;
|
|
}
|
|
|
|
export class ConversationService {
|
|
constructor(private env: Env) {}
|
|
|
|
/**
|
|
* 사용자 메시지를 처리하고 AI 응답을 생성합니다.
|
|
* 버퍼링, AI 생성, 요약 프로세스를 포함합니다.
|
|
*/
|
|
async processUserMessage(
|
|
userId: number,
|
|
chatId: string,
|
|
text: string,
|
|
telegramUserId: string
|
|
): Promise<ConversationResult> {
|
|
// 1. 타이핑 액션 전송 (비동기로 실행, 기다리지 않음)
|
|
sendChatAction(this.env.BOT_TOKEN, Number(chatId), 'typing').catch(console.error);
|
|
|
|
// 2. 사용자 메시지 버퍼에 추가
|
|
await addToBuffer(this.env.DB, userId, chatId, 'user', text);
|
|
|
|
// 3. AI 응답 생성
|
|
let responseText = await generateAIResponse(
|
|
this.env,
|
|
userId,
|
|
chatId,
|
|
text,
|
|
telegramUserId
|
|
);
|
|
|
|
// 4. 봇 응답 버퍼에 추가 (키보드 데이터 마커 등은 그대로 저장)
|
|
// 실제 사용자에게 보여질 텍스트만 저장하는 것이 좋으나,
|
|
// 현재 구조상 전체를 저장하고 나중에 컨텍스트로 활용 시 정제될 수 있음
|
|
await addToBuffer(this.env.DB, userId, chatId, 'bot', responseText);
|
|
|
|
// 5. 임계값 도달 시 프로필 업데이트 (요약)
|
|
const { summarized } = await processAndSummarize(
|
|
this.env,
|
|
userId,
|
|
chatId
|
|
);
|
|
|
|
// 키보드 데이터 파싱
|
|
let keyboardData: any = null;
|
|
const keyboardMatch = responseText.match(/__KEYBOARD__(.+?)__END__\n?/);
|
|
|
|
if (keyboardMatch) {
|
|
responseText = responseText.replace(/__KEYBOARD__.+?__END__\n?/, '');
|
|
try {
|
|
keyboardData = JSON.parse(keyboardMatch[1]);
|
|
} catch (e) {
|
|
console.error('[ConversationService] Keyboard parsing error:', e);
|
|
}
|
|
}
|
|
|
|
return {
|
|
responseText,
|
|
isProfileUpdated: summarized,
|
|
keyboardData
|
|
};
|
|
}
|
|
}
|