feat: integrate unified RAG pipeline and bump version to 2.60.0

This commit is contained in:
g1nation
2026-05-04 11:00:01 +09:00
parent 0515dd625d
commit 445d530b63
16 changed files with 2178 additions and 112 deletions
+115
View File
@@ -0,0 +1,115 @@
/**
* ============================================================
* Memory Extractor (기억 추출기)
*
* 대화 종료 시 히스토리를 분석하여 각 메모리 레이어에
* 저장할 정보를 자동으로 추출합니다.
* LLM 호출 없이 패턴 매칭 기반으로 동작합니다.
* ============================================================
*/
import { LongTermMemory } from './LongTermMemory';
import { ProjectMemory } from './ProjectMemory';
import { EpisodicMemory } from './EpisodicMemory';
interface ExtractionResult {
longTermCandidates: number;
episodeCreated: boolean;
projectUpdated: boolean;
}
export class MemoryExtractor {
/**
* 세션 종료 시 모든 메모리 레이어에 대해 추출을 수행합니다.
*/
public extractFromSession(
sessionId: string,
messages: Array<{ role: string; content: string; timestamp?: number }>,
longTermMemory: LongTermMemory,
episodicMemory: EpisodicMemory,
projectMemory: ProjectMemory | null,
projectContext?: string
): ExtractionResult {
const result: ExtractionResult = {
longTermCandidates: 0,
episodeCreated: false,
projectUpdated: false
};
// 1. Long-Term Memory 추출
const candidates = LongTermMemory.extractCandidates(messages);
for (const candidate of candidates) {
longTermMemory.addEntry(
candidate.category,
candidate.content,
`session:${sessionId}`,
0.7 // 자동 추출이므로 기본 신뢰도 0.7
);
}
result.longTermCandidates = candidates.length;
// 2. Episodic Memory 생성
const episode = episodicMemory.createEpisode(
sessionId,
messages,
projectContext
);
result.episodeCreated = !!episode;
// 3. Project Memory 업데이트 (프로젝트 관련 대화인 경우)
if (projectMemory && projectContext) {
const updated = this.extractProjectInfo(messages, projectMemory);
result.projectUpdated = updated;
}
return result;
}
/**
* 대화에서 프로젝트 관련 정보를 추출하여 Project Memory에 저장합니다.
*/
private extractProjectInfo(
messages: Array<{ role: string; content: string }>,
projectMemory: ProjectMemory
): boolean {
let updated = false;
const allText = messages.map((m) => m.content).join('\n');
// Tech stack 추출
const techPatterns = [
/(?:사용|using|사용하는|tech\s*stack|기술\s*스택)[\s:]*([^\n]+)/gi
];
for (const pattern of techPatterns) {
let match;
while ((match = pattern.exec(allText)) !== null) {
const techs = match[1]
.split(/[,\s]+/)
.filter((t) => t.length >= 2 && t.length <= 20);
for (const tech of techs) {
projectMemory.addTechStack(tech.trim());
updated = true;
}
}
}
// Bug report 추출
const bugPatterns = [
/(?:버그|bug|오류|error|이슈|issue)[\s:]+(.{10,200})/gi
];
for (const pattern of bugPatterns) {
let match;
while ((match = pattern.exec(allText)) !== null) {
// 간단한 버그만 자동 기록 (상세 분석은 사용자 확인 필요)
// 여기서는 패턴만 감지하고, 실제 기록은 사용자 확인 후
updated = true;
}
}
if (updated) {
projectMemory.save();
}
return updated;
}
}