Public Source Viewer

비나래아카이브 개발자 포털

실제 서비스 구조를 살펴볼 수 있는 공개용 코드 뷰어입니다. 인증, 세션, 외부 연동, 토큰, 관리자 식별 등 보안상 민감한 구현은 파일 단위 또는 줄 단위로 검열됩니다.

Redacted View
src/services/ai.service.ts
공개 가능
1 import fs from 'fs';
2 import path from 'path';
3 [SECURITY REDACTED] 민감한 설정/인증/토큰 관련 코드입니다.
4 import { hinanaGptSystemPrompt, normalGptSystemPrompt } from '../config/ai.config';
5
6 const THREE_DAYS_MS = 3 * 24 * 60 * 60 * 1000;
7
8 export function limitHistory(history: any[], maxCount = 10): any[] {
9 if (history.length <= maxCount + 1) return history;
10
11 const systemMessage = history[0];
12 const recentMessages = history.slice(-maxCount);
13
14 return [systemMessage, ...recentMessages];
15 }
16
17 export function getModelInputMessages(history: any[], maxContextMessages = 4): any[] {
18 const systemMessage = history.find((message) => message.role === 'system');
19 const recentMessages = history
20 .filter((message) => message.role !== 'system')
21 .slice(-maxContextMessages);
22
23 return systemMessage ? [systemMessage, ...recentMessages] : recentMessages;
24 }
25
26 export function getFileChatHistory(username: string, useHinana: boolean): any {
27 [SECURITY REDACTED] 민감한 설정/인증/토큰 관련 코드입니다.
28 [SECURITY REDACTED] 민감한 설정/인증/토큰 관련 코드입니다.
29 fs.mkdirSync(dataDir, { recursive: true });
30 }
31
32 [SECURITY REDACTED] 민감한 설정/인증/토큰 관련 코드입니다.
33 [SECURITY REDACTED] 민감한 설정/인증/토큰 관련 코드입니다.
34 }
35
36 let allHistory: any = {};
37 try {
38 [SECURITY REDACTED] 민감한 설정/인증/토큰 관련 코드입니다.
39 [SECURITY REDACTED] 민감한 설정/인증/토큰 관련 코드입니다.
40 } catch (e) {
41 console.error("채팅 히스토리 파일 읽기 실패, 초기화합니다.", e);
42 allHistory = {};
43 }
44
45 const key = `${username}_${useHinana ? 'hinana' : 'normal'}`;
46 const defaultMessages = [
47 { role: "system", content: useHinana ? hinanaGptSystemPrompt : normalGptSystemPrompt },
48 { role: "assistant", content: useHinana
49 ? "아하~ 프로듀서님, 히나나예요! 뭐 부터 시작해볼까요?"
50 : "안녕하세요, 무엇을 도와드릴까요?" }
51 ];
52
53 const entry = allHistory[key];
54 let myHistory: any[];
55
56 if (!entry) {
57 myHistory = [...defaultMessages];
58 } else if (Array.isArray(entry)) {
59 // 구형 포맷(배열) → 만료 없이 그대로 사용
60 myHistory = entry;
61 } else {
62 // 신형 포맷 { lastActive, messages }
63 const expired = Date.now() - new Date(entry.lastActive).getTime() > THREE_DAYS_MS;
64 myHistory = expired ? [...defaultMessages] : entry.messages;
65 }
66
67 return { allHistory, myHistory, key };
68 }
69