@sunub/obsidian-mcp-server 0.3.24 → 0.3.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/cli/App.d.ts +1 -1
- package/build/cli/App.js +150 -100
- package/build/cli/App.js.map +1 -1
- package/build/cli/AppContainer.d.ts +1 -1
- package/build/cli/constants.js +4 -0
- package/build/cli/constants.js.map +1 -1
- package/build/cli/context/KeypressContext.d.ts +1 -1
- package/build/cli/context/KeypressContext.js +3 -0
- package/build/cli/context/KeypressContext.js.map +1 -1
- package/build/cli/hooks/useDispatcher.js +3 -0
- package/build/cli/hooks/useDispatcher.js.map +1 -1
- package/build/cli/hooks/useLlmStream/compress.d.ts +16 -0
- package/build/cli/hooks/useLlmStream/compress.js +168 -0
- package/build/cli/hooks/useLlmStream/compress.js.map +1 -0
- package/build/cli/hooks/useLlmStream/llmService.js +12 -5
- package/build/cli/hooks/useLlmStream/llmService.js.map +1 -1
- package/build/cli/hooks/useLlmStream/markdownUtils.d.ts +6 -0
- package/build/cli/hooks/useLlmStream/markdownUtils.js +110 -0
- package/build/cli/hooks/useLlmStream/markdownUtils.js.map +1 -0
- package/build/cli/hooks/useLlmStream/types.d.ts +189 -0
- package/build/cli/hooks/useLlmStream/types.js +41 -1
- package/build/cli/hooks/useLlmStream/types.js.map +1 -1
- package/build/cli/hooks/useLlmStream/useLlmStream.d.ts +13 -1
- package/build/cli/hooks/useLlmStream/useLlmStream.js +75 -22
- package/build/cli/hooks/useLlmStream/useLlmStream.js.map +1 -1
- package/build/cli/hooks/useRagContext.js +0 -1
- package/build/cli/hooks/useRagContext.js.map +1 -1
- package/build/cli/hooks/useSlashCommand.d.ts +22 -0
- package/build/cli/hooks/useSlashCommand.js +61 -0
- package/build/cli/hooks/useSlashCommand.js.map +1 -0
- package/build/cli/hooks/useStateAndRef.d.ts +2 -0
- package/build/cli/hooks/useStateAndRef.js +18 -0
- package/build/cli/hooks/useStateAndRef.js.map +1 -0
- package/build/cli/index.js +3 -0
- package/build/cli/index.js.map +1 -1
- package/build/cli/key/textBuffer/textBuffer.d.ts +1 -0
- package/build/cli/key/textBuffer/textBuffer.js +1 -1
- package/build/cli/key/textBuffer/textBuffer.js.map +1 -1
- package/build/cli/services/InputOffloadService.d.ts +2 -0
- package/build/cli/services/InputOffloadService.js +15 -0
- package/build/cli/services/InputOffloadService.js.map +1 -1
- package/build/cli/types.d.ts +1 -1
- package/build/cli/ui/CLILogo.d.ts +1 -1
- package/build/cli/ui/HelpCommands.d.ts +1 -1
- package/build/cli/ui/HistoryItemDisplay.js +9 -3
- package/build/cli/ui/HistoryItemDisplay.js.map +1 -1
- package/build/cli/ui/InputPrompt.js +9 -7
- package/build/cli/ui/InputPrompt.js.map +1 -1
- package/build/cli/ui/LLMErrorComponent.d.ts +1 -1
- package/build/cli/ui/LLMHealthChecker.d.ts +1 -1
- package/build/cli/ui/LLMStatusLoader.d.ts +1 -1
- package/build/cli/ui/MarkdownDisplay.d.ts +1 -1
- package/build/cli/ui/SuggestionsDisplay.d.ts +1 -1
- package/build/cli/ui/SystemInfoSummaryBox.d.ts +1 -1
- package/build/cli/ui/ThinkingIndicator.d.ts +1 -1
- package/build/cli/utils/errors.d.ts +14 -0
- package/build/cli/utils/errors.js +64 -0
- package/build/cli/utils/errors.js.map +1 -0
- package/build/cli/utils/retry.d.ts +16 -0
- package/build/cli/utils/retry.js +135 -0
- package/build/cli/utils/retry.js.map +1 -0
- package/build/cli/utils/textUtil.js +0 -6
- package/build/cli/utils/textUtil.js.map +1 -1
- package/build/config.d.ts +3 -0
- package/build/config.js +4 -0
- package/build/config.js.map +1 -1
- package/build/index.js +18 -5
- package/build/index.js.map +1 -1
- package/build/shared/utils/debugLogger.js +11 -8
- package/build/shared/utils/debugLogger.js.map +1 -1
- package/build/tools/vault/params.js +1 -1
- package/build/tools/vault/params.js.map +1 -1
- package/build/tools/vault/utils/actions/collect_context.js +44 -18
- package/build/tools/vault/utils/actions/collect_context.js.map +1 -1
- package/build/tools/vault/utils/actions/read.js +39 -9
- package/build/tools/vault/utils/actions/read.js.map +1 -1
- package/build/utils/Embedder.d.ts +2 -0
- package/build/utils/Embedder.js +11 -4
- package/build/utils/Embedder.js.map +1 -1
- package/build/utils/Indexer.d.ts +3 -1
- package/build/utils/Indexer.js +35 -10
- package/build/utils/Indexer.js.map +1 -1
- package/build/utils/LocalReranker.js +1 -3
- package/build/utils/LocalReranker.js.map +1 -1
- package/build/utils/RAGIndexer.d.ts +6 -2
- package/build/utils/RAGIndexer.js +40 -106
- package/build/utils/RAGIndexer.js.map +1 -1
- package/build/utils/RerankerClient.d.ts +4 -4
- package/build/utils/VaultManger/VaultManager.d.ts +1 -0
- package/build/utils/VaultManger/VaultManager.js +84 -25
- package/build/utils/VaultManger/VaultManager.js.map +1 -1
- package/build/utils/VectorDB.d.ts +2 -1
- package/build/utils/VectorDB.js +130 -90
- package/build/utils/VectorDB.js.map +1 -1
- package/build/utils/worker/WorkerPool.d.ts +15 -0
- package/build/utils/worker/WorkerPool.js +89 -0
- package/build/utils/worker/WorkerPool.js.map +1 -0
- package/build/utils/worker/chunkingWorker.d.ts +11 -0
- package/build/utils/worker/chunkingWorker.js +92 -0
- package/build/utils/worker/chunkingWorker.js.map +1 -0
- package/package.json +1 -3
package/build/utils/Indexer.js
CHANGED
|
@@ -9,18 +9,37 @@ export class Indexer {
|
|
|
9
9
|
get totalFiles() {
|
|
10
10
|
return this.documentMap.size;
|
|
11
11
|
}
|
|
12
|
+
sourceToLinksMap = new Map();
|
|
12
13
|
async build(filePaths, ioSemaphore) {
|
|
13
14
|
this.clear();
|
|
14
15
|
const tasks = filePaths.map((filePath) => this.processFile(filePath, ioSemaphore));
|
|
15
16
|
await Promise.all(tasks);
|
|
16
|
-
|
|
17
|
+
// 전체 빌드 시에는 한 번만 호출
|
|
18
|
+
this.rebuildBacklinkIndex();
|
|
17
19
|
}
|
|
18
20
|
async upsertFile(filePath, ioSemaphore) {
|
|
19
21
|
this.removeFileEntries(filePath);
|
|
20
22
|
await this.processFile(filePath, ioSemaphore);
|
|
21
|
-
|
|
23
|
+
// 증분 업데이트
|
|
24
|
+
const doc = this.documentMap.get(filePath);
|
|
25
|
+
if (doc) {
|
|
26
|
+
this.updateBacklinksForFile(filePath, doc.documentLinks);
|
|
27
|
+
}
|
|
22
28
|
}
|
|
23
29
|
removeFileEntries(filePath) {
|
|
30
|
+
// 기존 링크 제거
|
|
31
|
+
const oldLinks = this.sourceToLinksMap.get(filePath) || [];
|
|
32
|
+
for (const link of oldLinks) {
|
|
33
|
+
const normalized = this.normalizeLink(link);
|
|
34
|
+
const sources = this.backlinkIndex.get(normalized);
|
|
35
|
+
if (sources) {
|
|
36
|
+
sources.delete(filePath);
|
|
37
|
+
if (sources.size === 0) {
|
|
38
|
+
this.backlinkIndex.delete(normalized);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
this.sourceToLinksMap.delete(filePath);
|
|
24
43
|
for (const [token, fileSet] of this.invertedIndex.entries()) {
|
|
25
44
|
if (fileSet.has(filePath)) {
|
|
26
45
|
fileSet.delete(filePath);
|
|
@@ -79,6 +98,7 @@ export class Indexer {
|
|
|
79
98
|
this.documentMap.clear();
|
|
80
99
|
this.invertedIndex.clear();
|
|
81
100
|
this.backlinkIndex.clear();
|
|
101
|
+
this.sourceToLinksMap.clear();
|
|
82
102
|
}
|
|
83
103
|
async processFile(filePath, ioSemaphore) {
|
|
84
104
|
await ioSemaphore.acquire();
|
|
@@ -150,16 +170,21 @@ export class Indexer {
|
|
|
150
170
|
this.invertedIndex.get(token)?.add(index.filePath);
|
|
151
171
|
}
|
|
152
172
|
}
|
|
153
|
-
|
|
173
|
+
updateBacklinksForFile(sourcePath, links) {
|
|
174
|
+
this.sourceToLinksMap.set(sourcePath, links);
|
|
175
|
+
for (const targetLink of links) {
|
|
176
|
+
const normalizedTarget = this.normalizeLink(targetLink);
|
|
177
|
+
if (!this.backlinkIndex.has(normalizedTarget)) {
|
|
178
|
+
this.backlinkIndex.set(normalizedTarget, new Set());
|
|
179
|
+
}
|
|
180
|
+
this.backlinkIndex.get(normalizedTarget)?.add(sourcePath);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
rebuildBacklinkIndex() {
|
|
154
184
|
this.backlinkIndex.clear();
|
|
185
|
+
this.sourceToLinksMap.clear();
|
|
155
186
|
for (const [sourcePath, sourceDoc] of this.documentMap.entries()) {
|
|
156
|
-
|
|
157
|
-
const normalizedTarget = this.normalizeLink(targetLink);
|
|
158
|
-
if (!this.backlinkIndex.has(normalizedTarget)) {
|
|
159
|
-
this.backlinkIndex.set(normalizedTarget, new Set());
|
|
160
|
-
}
|
|
161
|
-
this.backlinkIndex.get(normalizedTarget)?.add(sourcePath);
|
|
162
|
-
}
|
|
187
|
+
this.updateBacklinksForFile(sourcePath, sourceDoc.documentLinks);
|
|
163
188
|
}
|
|
164
189
|
}
|
|
165
190
|
normalizeLink(link) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Indexer.js","sourceRoot":"","sources":["../../src/utils/Indexer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,KAAK,aAAa,MAAM,8BAA8B,CAAC;AAC9D,OAAO,KAAK,YAAY,MAAM,6BAA6B,CAAC;AAI5D,MAAM,OAAO,OAAO;IACX,WAAW,GAA+B,IAAI,GAAG,EAAE,CAAC;IACpD,aAAa,GAA6B,IAAI,GAAG,EAAE,CAAC;IACpD,aAAa,GAA6B,IAAI,GAAG,EAAE,CAAC;IAE5D,IAAW,UAAU;QACpB,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;IAC9B,CAAC;
|
|
1
|
+
{"version":3,"file":"Indexer.js","sourceRoot":"","sources":["../../src/utils/Indexer.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LocalReranker.js","sourceRoot":"","sources":["../../src/utils/LocalReranker.ts"],"names":[],"mappings":"AAIA,OAAO,EACN,kCAAkC,EAClC,aAAa,EACb,GAAG,GACH,MAAM,2BAA2B,CAAC;AACnC,OAAO,CAAC,MAAM,KAAK,CAAC;AACpB,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAE5C,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CACpC,CAAC,CAAC,MAAM,CAAC;IACR,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;IACpB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;CACjB,CAAC,CACF,CAAC;AAEF,MAAM,QAAQ;IACL,SAAS,GAAG,0BAA0B,CAAC;IACvC,SAAS,GAA+B,IAAI,CAAC;IAC7C,KAAK,GAA2B,IAAI,CAAC;IACrC,WAAW,GAAyB,IAAI,CAAC;IAEjD;QACC,GAAG,CAAC,iBAAiB,GAAG,KAAK,CAAC;QAC9B,GAAG,CAAC,cAAc,GAAG,UAAU,CAAC;QAChC,GAAG,CAAC,QAAQ,GAAG,UAAU,CAAC;IAC3B,CAAC;IAEM,KAAK,CAAC,kBAAkB;QAC9B,IAAI,CAAC;YACJ,MAAM,
|
|
1
|
+
{"version":3,"file":"LocalReranker.js","sourceRoot":"","sources":["../../src/utils/LocalReranker.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import { type VectorRecord } from "./VectorDB.js";
|
|
2
|
+
export type HeadingEntry = {
|
|
3
|
+
heading: string;
|
|
4
|
+
pos: number;
|
|
5
|
+
depth: number;
|
|
6
|
+
};
|
|
2
7
|
export declare class RAGIndexer {
|
|
3
|
-
private splitter;
|
|
4
8
|
private embeddingSemaphore;
|
|
5
9
|
private ioSemaphore;
|
|
6
10
|
private spinner;
|
|
7
11
|
private totalFiles;
|
|
8
12
|
private processedFiles;
|
|
9
13
|
private _isIndexing;
|
|
10
|
-
private
|
|
14
|
+
private chukingWorkerPool;
|
|
11
15
|
constructor();
|
|
12
16
|
setSpinner(total: number): void;
|
|
13
17
|
private updateProgress;
|
|
@@ -1,56 +1,20 @@
|
|
|
1
1
|
import fs from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import { RecursiveCharacterTextSplitter } from "@langchain/textsplitters";
|
|
4
|
-
import { encodingForModel } from "js-tiktoken";
|
|
5
3
|
import ora, {} from "ora";
|
|
6
4
|
import { DirectoryWalker } from "./DirectoryWalker.js";
|
|
7
5
|
import { localEmbedder } from "./Embedder.js";
|
|
8
|
-
import { parse as parseMatter } from "./processor/MatterParser.js";
|
|
9
6
|
import { Semaphore } from "./semaphore.js";
|
|
10
7
|
import { vectorDB } from "./VectorDB.js";
|
|
11
|
-
|
|
12
|
-
const headingRegex = /^(#{1,3})\s+(.+)$/gm;
|
|
13
|
-
const results = [];
|
|
14
|
-
const matches = body.matchAll(headingRegex);
|
|
15
|
-
for (const match of matches) {
|
|
16
|
-
results.push({
|
|
17
|
-
heading: match[2].trim(),
|
|
18
|
-
pos: match.index,
|
|
19
|
-
depth: match[1].length,
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
return results;
|
|
23
|
-
}
|
|
24
|
-
function findSectionForChunk(body, chunk, headings) {
|
|
25
|
-
if (headings.length === 0)
|
|
26
|
-
return null;
|
|
27
|
-
const pos = body.indexOf(chunk.slice(0, 60));
|
|
28
|
-
if (pos === -1)
|
|
29
|
-
return null;
|
|
30
|
-
let section = null;
|
|
31
|
-
for (const h of headings) {
|
|
32
|
-
if (h.pos <= pos)
|
|
33
|
-
section = h.heading;
|
|
34
|
-
}
|
|
35
|
-
return section;
|
|
36
|
-
}
|
|
8
|
+
import { WorkerPool } from "./worker/WorkerPool.js";
|
|
37
9
|
export class RAGIndexer {
|
|
38
|
-
splitter;
|
|
39
10
|
embeddingSemaphore;
|
|
40
11
|
ioSemaphore;
|
|
41
12
|
spinner = null;
|
|
42
13
|
totalFiles = 0;
|
|
43
14
|
processedFiles = 0;
|
|
44
15
|
_isIndexing = false;
|
|
45
|
-
|
|
16
|
+
chukingWorkerPool = new WorkerPool(4);
|
|
46
17
|
constructor() {
|
|
47
|
-
this.splitter = new RecursiveCharacterTextSplitter({
|
|
48
|
-
chunkSize: 500,
|
|
49
|
-
chunkOverlap: 50,
|
|
50
|
-
lengthFunction: (text) => {
|
|
51
|
-
return this.enc.encode(text).length;
|
|
52
|
-
},
|
|
53
|
-
});
|
|
54
18
|
this.embeddingSemaphore = new Semaphore(3);
|
|
55
19
|
this.ioSemaphore = new Semaphore(10);
|
|
56
20
|
}
|
|
@@ -93,76 +57,36 @@ export class RAGIndexer {
|
|
|
93
57
|
async buildFileRecords(filePath, content) {
|
|
94
58
|
const fileStat = await fs.stat(filePath);
|
|
95
59
|
const fileContent = content ?? (await fs.readFile(filePath, "utf-8"));
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
.filter((h) => h.depth <= 2)
|
|
103
|
-
.slice(0, 4)
|
|
104
|
-
.map((h) => h.heading.slice(0, 25));
|
|
105
|
-
const metadataPrefix = [
|
|
106
|
-
`Title: ${docTitle.slice(0, 50)}`,
|
|
107
|
-
frontmatter.tags?.length
|
|
108
|
-
? `Tags: ${frontmatter.tags.slice(0, 3).join(", ")}`
|
|
109
|
-
: "",
|
|
110
|
-
frontmatter.summary ? `Summary: ${frontmatter.summary.slice(0, 60)}` : "",
|
|
111
|
-
]
|
|
112
|
-
.filter(Boolean)
|
|
113
|
-
.join("\n");
|
|
114
|
-
const chunks = await this.splitter.splitText(body);
|
|
60
|
+
const chunkMetadatas = await this.chukingWorkerPool.runTask({
|
|
61
|
+
filePath,
|
|
62
|
+
fileContent,
|
|
63
|
+
birthTime: fileStat.birthtime.toISOString(),
|
|
64
|
+
});
|
|
65
|
+
await localEmbedder.init();
|
|
115
66
|
const records = [];
|
|
116
|
-
for (
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
sectionHeading ? `Section: ${sectionHeading.slice(0, 30)}` : "",
|
|
121
|
-
docStructure.length > 1
|
|
122
|
-
? `Outline: ${docStructure.slice(0, 3).join(" > ")}`
|
|
123
|
-
: "",
|
|
67
|
+
for (const metadata of chunkMetadatas) {
|
|
68
|
+
const combined = [
|
|
69
|
+
metadata.context ? metadata.context : "",
|
|
70
|
+
metadata.content,
|
|
124
71
|
]
|
|
125
|
-
.filter(Boolean)
|
|
126
|
-
.join("\n");
|
|
127
|
-
const combined = [metadataPrefix, context, chunk]
|
|
128
72
|
.filter(Boolean)
|
|
129
73
|
.join("\n\n");
|
|
130
74
|
const MAX_EMBED_TOKENS = 500;
|
|
131
|
-
const combinedTokenCount =
|
|
75
|
+
const combinedTokenCount = localEmbedder.getTokenCount(combined);
|
|
132
76
|
const safeText = combinedTokenCount > MAX_EMBED_TOKENS
|
|
133
77
|
? combined.slice(0, Math.floor(combined.length * (MAX_EMBED_TOKENS / combinedTokenCount)))
|
|
134
78
|
: combined;
|
|
135
79
|
await this.embeddingSemaphore.acquire();
|
|
136
80
|
let vector;
|
|
137
81
|
try {
|
|
138
|
-
const isLocalReady = await localEmbedder.checkModelPresence();
|
|
139
|
-
if (!isLocalReady) {
|
|
140
|
-
await localEmbedder.init();
|
|
141
|
-
}
|
|
142
82
|
vector = await localEmbedder.embed(`search_document: ${safeText}`);
|
|
143
83
|
}
|
|
144
84
|
finally {
|
|
145
85
|
this.embeddingSemaphore.release();
|
|
146
86
|
}
|
|
147
87
|
records.push({
|
|
148
|
-
|
|
149
|
-
filePath,
|
|
150
|
-
fileName,
|
|
151
|
-
chunkIndex: i,
|
|
152
|
-
content: chunk,
|
|
153
|
-
context,
|
|
88
|
+
...metadata,
|
|
154
89
|
vector,
|
|
155
|
-
metadata: {
|
|
156
|
-
title: docTitle,
|
|
157
|
-
date: frontmatter.date instanceof Date
|
|
158
|
-
? frontmatter.date.toISOString()
|
|
159
|
-
: frontmatter.date || fileStat.birthtime.toISOString(),
|
|
160
|
-
tags: frontmatter.tags?.join(", ") ?? "",
|
|
161
|
-
summary: frontmatter.summary || "",
|
|
162
|
-
slug: frontmatter.slug || "",
|
|
163
|
-
category: frontmatter.category || "any",
|
|
164
|
-
completed: frontmatter.completed ?? false,
|
|
165
|
-
},
|
|
166
90
|
});
|
|
167
91
|
}
|
|
168
92
|
return { records, mtime: fileStat.mtime.toISOString() };
|
|
@@ -197,34 +121,44 @@ export class RAGIndexer {
|
|
|
197
121
|
}
|
|
198
122
|
async indexAll(vaultPath) {
|
|
199
123
|
this._isIndexing = true;
|
|
124
|
+
this.chukingWorkerPool.init();
|
|
200
125
|
try {
|
|
201
126
|
const walker = new DirectoryWalker();
|
|
202
127
|
const filePaths = await walker.walk(vaultPath, this.ioSemaphore);
|
|
203
128
|
const markdownFiles = filePaths.filter((f) => f.endsWith(".md") || f.endsWith(".mdx"));
|
|
204
129
|
this.setSpinner(markdownFiles.length);
|
|
205
|
-
const
|
|
206
|
-
|
|
130
|
+
const BATCH_SIZE = 50; // 50개 파일마다 DB에 기록하고 메모리 비움
|
|
131
|
+
let currentBatch = [];
|
|
132
|
+
let currentMeta = [];
|
|
207
133
|
const fileSemaphore = new Semaphore(8);
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
134
|
+
for (let i = 0; i < markdownFiles.length; i += BATCH_SIZE) {
|
|
135
|
+
const batchFiles = markdownFiles.slice(i, i + BATCH_SIZE);
|
|
136
|
+
await Promise.all(batchFiles.map(async (filePath) => {
|
|
137
|
+
await fileSemaphore.acquire();
|
|
138
|
+
try {
|
|
139
|
+
const result = await this.processFileInMemory(filePath);
|
|
140
|
+
if (result && result.records.length > 0) {
|
|
141
|
+
currentBatch.push(...result.records);
|
|
142
|
+
currentMeta.push({ filePath, mtime: result.mtime });
|
|
143
|
+
}
|
|
215
144
|
}
|
|
145
|
+
finally {
|
|
146
|
+
fileSemaphore.release();
|
|
147
|
+
}
|
|
148
|
+
}));
|
|
149
|
+
// 현재 배치를 DB에 기록하고 메모리 해제
|
|
150
|
+
if (currentBatch.length > 0) {
|
|
151
|
+
await vectorDB.upsertChunks(currentBatch);
|
|
152
|
+
await vectorDB.updateFileMetaBatch(currentMeta);
|
|
153
|
+
// 배열 초기화로 가비지 컬렉션 유도
|
|
154
|
+
currentBatch = [];
|
|
155
|
+
currentMeta = [];
|
|
216
156
|
}
|
|
217
|
-
finally {
|
|
218
|
-
fileSemaphore.release();
|
|
219
|
-
}
|
|
220
|
-
}));
|
|
221
|
-
if (allRecords.length > 0) {
|
|
222
|
-
await vectorDB.upsertChunks(allRecords);
|
|
223
|
-
await vectorDB.updateFileMetaBatch(allMeta);
|
|
224
157
|
}
|
|
225
158
|
}
|
|
226
159
|
finally {
|
|
227
160
|
this._isIndexing = false;
|
|
161
|
+
this.chukingWorkerPool.terminateAll();
|
|
228
162
|
}
|
|
229
163
|
}
|
|
230
164
|
async deleteFile(filePath) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RAGIndexer.js","sourceRoot":"","sources":["../../src/utils/RAGIndexer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,
|
|
1
|
+
{"version":3,"file":"RAGIndexer.js","sourceRoot":"","sources":["../../src/utils/RAGIndexer.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,17 +16,17 @@ export declare const RerankResponseSchema: z.ZodObject<{
|
|
|
16
16
|
index: z.ZodNumber;
|
|
17
17
|
relevance_score: z.ZodNumber;
|
|
18
18
|
}, "strip", z.ZodTypeAny, {
|
|
19
|
-
index: number;
|
|
20
19
|
relevance_score: number;
|
|
21
|
-
}, {
|
|
22
20
|
index: number;
|
|
21
|
+
}, {
|
|
23
22
|
relevance_score: number;
|
|
23
|
+
index: number;
|
|
24
24
|
}>, "many">;
|
|
25
25
|
}, "strip", z.ZodTypeAny, {
|
|
26
26
|
object: string;
|
|
27
27
|
results: {
|
|
28
|
-
index: number;
|
|
29
28
|
relevance_score: number;
|
|
29
|
+
index: number;
|
|
30
30
|
}[];
|
|
31
31
|
usage: {
|
|
32
32
|
prompt_tokens: number;
|
|
@@ -36,8 +36,8 @@ export declare const RerankResponseSchema: z.ZodObject<{
|
|
|
36
36
|
}, {
|
|
37
37
|
object: string;
|
|
38
38
|
results: {
|
|
39
|
-
index: number;
|
|
40
39
|
relevance_score: number;
|
|
40
|
+
index: number;
|
|
41
41
|
}[];
|
|
42
42
|
usage: {
|
|
43
43
|
prompt_tokens: number;
|
|
@@ -3,6 +3,7 @@ import { existsSync } from "node:fs";
|
|
|
3
3
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
4
4
|
import { basename, dirname, extname, isAbsolute, join, relative, resolve, } from "node:path";
|
|
5
5
|
import matter from "gray-matter";
|
|
6
|
+
import { debugLogger } from "../../shared/index.js";
|
|
6
7
|
import { DirectoryWalker } from "../DirectoryWalker.js";
|
|
7
8
|
import { localEmbedder } from "../Embedder.js";
|
|
8
9
|
import { Indexer } from "../Indexer.js";
|
|
@@ -19,12 +20,14 @@ export class VaultManager {
|
|
|
19
20
|
walker;
|
|
20
21
|
indexer;
|
|
21
22
|
ioSemaphore;
|
|
23
|
+
dbSemaphore;
|
|
22
24
|
hasNotifiedMissingModels = false;
|
|
23
25
|
constructor(vaultPath, maxConcurrentIO = 10) {
|
|
24
26
|
this.vaultPath = resolve(vaultPath);
|
|
25
27
|
this.walker = new DirectoryWalker([".md", ".mdx"]);
|
|
26
28
|
this.indexer = new Indexer();
|
|
27
29
|
this.ioSemaphore = new Semaphore(maxConcurrentIO);
|
|
30
|
+
this.dbSemaphore = new Semaphore(1);
|
|
28
31
|
}
|
|
29
32
|
async initialize() {
|
|
30
33
|
if (this.initPromise) {
|
|
@@ -135,30 +138,40 @@ export class VaultManager {
|
|
|
135
138
|
...f,
|
|
136
139
|
finalScore: f.score,
|
|
137
140
|
}));
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
const reranked = await localReranker.rerank(query, rerankDocs);
|
|
146
|
-
finalResults = reranked
|
|
147
|
-
.map((r) => {
|
|
148
|
-
const original = fusedResults.find((f) => {
|
|
149
|
-
const content = f.matchedChunks[0]?.content ||
|
|
150
|
-
f.document.frontmatter.summary ||
|
|
151
|
-
f.document.filePath;
|
|
152
|
-
return content === r.document;
|
|
153
|
-
});
|
|
154
|
-
if (!original)
|
|
155
|
-
return null;
|
|
156
|
-
return { ...original, finalScore: r.score };
|
|
157
|
-
})
|
|
158
|
-
.filter((r) => r !== null);
|
|
141
|
+
// 1차 검색 결과 중 이미 의미적으로 극도로 유사한(코사인 거리 < 0.20) 청크가 있는지 검증
|
|
142
|
+
const hasHighlyRelevantMatch = fusedResults.some((item) => item.matchedChunks.some((chunk) => {
|
|
143
|
+
const dist = chunk["_distance"];
|
|
144
|
+
return typeof dist === "number" && dist < 0.2;
|
|
145
|
+
}));
|
|
146
|
+
if (hasHighlyRelevantMatch) {
|
|
147
|
+
debugLogger.debug(`[RAG] Highly relevant semantic match found. Skipping rerank in hybridSearch.`);
|
|
159
148
|
}
|
|
160
|
-
|
|
161
|
-
|
|
149
|
+
else {
|
|
150
|
+
try {
|
|
151
|
+
const rerankDocs = fusedResults.map((item) => {
|
|
152
|
+
// 청크가 있으면 청크 내용, 없으면 요약이나 파일명 사용
|
|
153
|
+
return (item.matchedChunks[0]?.content ||
|
|
154
|
+
item.document.frontmatter.summary ||
|
|
155
|
+
item.document.filePath);
|
|
156
|
+
});
|
|
157
|
+
const reranked = await localReranker.rerank(query, rerankDocs);
|
|
158
|
+
finalResults = reranked
|
|
159
|
+
.map((r) => {
|
|
160
|
+
const original = fusedResults.find((f) => {
|
|
161
|
+
const content = f.matchedChunks[0]?.content ||
|
|
162
|
+
f.document.frontmatter.summary ||
|
|
163
|
+
f.document.filePath;
|
|
164
|
+
return content === r.document;
|
|
165
|
+
});
|
|
166
|
+
if (!original)
|
|
167
|
+
return null;
|
|
168
|
+
return { ...original, finalScore: r.score };
|
|
169
|
+
})
|
|
170
|
+
.filter((r) => r !== null);
|
|
171
|
+
}
|
|
172
|
+
catch (error) {
|
|
173
|
+
console.error("[VaultManager] Reranking failed:", error);
|
|
174
|
+
}
|
|
162
175
|
}
|
|
163
176
|
// AI가 준비된 상태에서도 인덱싱이 진행 중이면 메시지 추가
|
|
164
177
|
let diagnostic_message;
|
|
@@ -175,17 +188,51 @@ export class VaultManager {
|
|
|
175
188
|
if (!this.isLocalAIReady) {
|
|
176
189
|
return [];
|
|
177
190
|
}
|
|
191
|
+
await this.dbSemaphore.acquire();
|
|
178
192
|
try {
|
|
179
193
|
const isLocalReady = await localEmbedder.checkModelPresence();
|
|
180
194
|
if (!isLocalReady) {
|
|
181
195
|
await localEmbedder.init();
|
|
182
196
|
}
|
|
183
197
|
const queryVector = await localEmbedder.embed(`search_query: ${query}`);
|
|
184
|
-
|
|
198
|
+
const recallLimit = Math.max(limit * 3, 15);
|
|
199
|
+
const initialResults = await vectorDB.search(queryVector, recallLimit);
|
|
200
|
+
if (initialResults.length === 0)
|
|
201
|
+
return [];
|
|
202
|
+
const documents = initialResults.map((r) => r.content);
|
|
203
|
+
// 1차 검색 결과 중 코사인 거리가 극도로 가까운(유사도 0.80 이상) 강력한 매칭인 경우 리랭킹 건너뜀
|
|
204
|
+
const SKIP_RERANK_DISTANCE_THRESHOLD = 0.2;
|
|
205
|
+
const firstDistance = initialResults[0]["_distance"];
|
|
206
|
+
if (typeof firstDistance === "number" &&
|
|
207
|
+
firstDistance < SKIP_RERANK_DISTANCE_THRESHOLD) {
|
|
208
|
+
debugLogger.debug(`[RAG] First semantic match distance is ${firstDistance.toFixed(4)}. Skipping rerank in safeSemanticSearch.`);
|
|
209
|
+
return initialResults.slice(0, limit);
|
|
210
|
+
}
|
|
211
|
+
const isRerankerReady = await localReranker.checkModelPresence();
|
|
212
|
+
if (!isRerankerReady) {
|
|
213
|
+
await localReranker.init();
|
|
214
|
+
}
|
|
215
|
+
const reranked = await localReranker.rerank(query, documents);
|
|
216
|
+
const normalizeForComparison = (text) => text
|
|
217
|
+
.replace(/\r\n|\r|\n/g, " ")
|
|
218
|
+
.replace(/\s+/g, " ")
|
|
219
|
+
.trim();
|
|
220
|
+
const finalResults = reranked
|
|
221
|
+
.slice(0, limit)
|
|
222
|
+
.map((r) => {
|
|
223
|
+
const targetNorm = normalizeForComparison(r.document);
|
|
224
|
+
const originalIndex = documents.findIndex((doc) => normalizeForComparison(doc) === targetNorm);
|
|
225
|
+
return initialResults[originalIndex];
|
|
226
|
+
})
|
|
227
|
+
.filter((r) => r !== undefined);
|
|
228
|
+
return finalResults;
|
|
185
229
|
}
|
|
186
230
|
catch (_error) {
|
|
187
231
|
return [];
|
|
188
232
|
}
|
|
233
|
+
finally {
|
|
234
|
+
this.dbSemaphore.release();
|
|
235
|
+
}
|
|
189
236
|
}
|
|
190
237
|
async syncMissingRagIndices() {
|
|
191
238
|
// 로컬 모델이 있는 경우 우선적으로 사용
|
|
@@ -227,6 +274,7 @@ export class VaultManager {
|
|
|
227
274
|
console.error(`[VaultManager] Found ${filesToProcess.length} files to index for RAG.`);
|
|
228
275
|
ragIndexer.startIndexing(filesToProcess.length);
|
|
229
276
|
ragIndexer.setSpinner(filesToProcess.length);
|
|
277
|
+
await this.dbSemaphore.acquire();
|
|
230
278
|
try {
|
|
231
279
|
for (const filePath of filesToProcess) {
|
|
232
280
|
await ragIndexer.processFile(filePath);
|
|
@@ -234,6 +282,7 @@ export class VaultManager {
|
|
|
234
282
|
await vectorDB.createVectorIndex();
|
|
235
283
|
}
|
|
236
284
|
finally {
|
|
285
|
+
this.dbSemaphore.release();
|
|
237
286
|
ragIndexer.stopIndexing();
|
|
238
287
|
}
|
|
239
288
|
}
|
|
@@ -245,12 +294,16 @@ export class VaultManager {
|
|
|
245
294
|
}
|
|
246
295
|
const isLocalReady = await localEmbedder.checkModelPresence();
|
|
247
296
|
if (isLocalReady) {
|
|
297
|
+
await this.dbSemaphore.acquire();
|
|
248
298
|
try {
|
|
249
299
|
await ragIndexer.processFile(filePath);
|
|
250
300
|
}
|
|
251
301
|
catch (error) {
|
|
252
302
|
console.error(`[VaultManager] Failed to process RAG index for ${filePath}:`, error);
|
|
253
303
|
}
|
|
304
|
+
finally {
|
|
305
|
+
this.dbSemaphore.release();
|
|
306
|
+
}
|
|
254
307
|
}
|
|
255
308
|
else {
|
|
256
309
|
console.error(`[VaultManager] Embedding server is down. Skipping RAG index for: ${filePath}`);
|
|
@@ -258,7 +311,13 @@ export class VaultManager {
|
|
|
258
311
|
}
|
|
259
312
|
async removeDocument(filePath) {
|
|
260
313
|
this.indexer.removeFileEntries(filePath);
|
|
261
|
-
await
|
|
314
|
+
await this.dbSemaphore.acquire();
|
|
315
|
+
try {
|
|
316
|
+
await ragIndexer.deleteFile(filePath);
|
|
317
|
+
}
|
|
318
|
+
finally {
|
|
319
|
+
this.dbSemaphore.release();
|
|
320
|
+
}
|
|
262
321
|
}
|
|
263
322
|
async getAllDocuments() {
|
|
264
323
|
await this.initialize();
|