Public Source Viewer
비나래아카이브 개발자 포털
실제 서비스 구조를 살펴볼 수 있는 공개용 코드 뷰어입니다. 인증, 세션, 외부 연동, 토큰, 관리자 식별 등 보안상 민감한 구현은 파일 단위 또는 줄 단위로 검열됩니다.
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