@bndynet/ragbox 0.1.0
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/README.md +765 -0
- package/README.zh-CN.md +774 -0
- package/dist/src/advanced.d.ts +13 -0
- package/dist/src/advanced.js +29 -0
- package/dist/src/cli.d.ts +2 -0
- package/dist/src/cli.js +1013 -0
- package/dist/src/config-file.d.ts +69 -0
- package/dist/src/config-file.js +246 -0
- package/dist/src/folder-index/config.d.ts +2 -0
- package/dist/src/folder-index/config.js +56 -0
- package/dist/src/folder-index/hash.d.ts +1 -0
- package/dist/src/folder-index/hash.js +14 -0
- package/dist/src/folder-index/indexer.d.ts +2 -0
- package/dist/src/folder-index/indexer.js +154 -0
- package/dist/src/folder-index/llm-client.d.ts +3 -0
- package/dist/src/folder-index/llm-client.js +45 -0
- package/dist/src/folder-index/manifest.d.ts +17 -0
- package/dist/src/folder-index/manifest.js +158 -0
- package/dist/src/folder-index/multi-query.d.ts +45 -0
- package/dist/src/folder-index/multi-query.js +109 -0
- package/dist/src/folder-index/pageindex-runner.d.ts +3 -0
- package/dist/src/folder-index/pageindex-runner.js +218 -0
- package/dist/src/folder-index/path-utils.d.ts +5 -0
- package/dist/src/folder-index/path-utils.js +33 -0
- package/dist/src/folder-index/query.d.ts +19 -0
- package/dist/src/folder-index/query.js +597 -0
- package/dist/src/folder-index/queue.d.ts +1 -0
- package/dist/src/folder-index/queue.js +18 -0
- package/dist/src/folder-index/root-tree.d.ts +3 -0
- package/dist/src/folder-index/root-tree.js +82 -0
- package/dist/src/folder-index/scan.d.ts +14 -0
- package/dist/src/folder-index/scan.js +152 -0
- package/dist/src/folder-index/types.d.ts +368 -0
- package/dist/src/folder-index/types.js +2 -0
- package/dist/src/folder-index/watch.d.ts +17 -0
- package/dist/src/folder-index/watch.js +550 -0
- package/dist/src/index.d.ts +6 -0
- package/dist/src/index.js +45 -0
- package/dist/src/sdk.d.ts +101 -0
- package/dist/src/sdk.js +352 -0
- package/dist/src/serve.d.ts +64 -0
- package/dist/src/serve.js +466 -0
- package/dist/src/setup-pageindex.d.ts +30 -0
- package/dist/src/setup-pageindex.js +184 -0
- package/package.json +43 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ScannedFile } from "./types";
|
|
2
|
+
type ScanMarkdownFilesOptions = {
|
|
3
|
+
excludedDirs?: string[];
|
|
4
|
+
exclude?: string[];
|
|
5
|
+
include?: string[];
|
|
6
|
+
};
|
|
7
|
+
export declare function isMarkdownDocument(filePath: string): boolean;
|
|
8
|
+
export declare function createDocId(relativePath: string): string;
|
|
9
|
+
export declare function docIdToIndexFileName(docId: string): string;
|
|
10
|
+
export declare function createIndexPath(docId: string): string;
|
|
11
|
+
export declare function isIncludedPath(relativePath: string, options?: Pick<ScanMarkdownFilesOptions, "exclude" | "include">): boolean;
|
|
12
|
+
export declare function deriveMarkdownTitle(filePath: string): Promise<string>;
|
|
13
|
+
export declare function scanMarkdownFiles(rootDir: string, options?: ScanMarkdownFilesOptions): Promise<ScannedFile[]>;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.isMarkdownDocument = isMarkdownDocument;
|
|
7
|
+
exports.createDocId = createDocId;
|
|
8
|
+
exports.docIdToIndexFileName = docIdToIndexFileName;
|
|
9
|
+
exports.createIndexPath = createIndexPath;
|
|
10
|
+
exports.isIncludedPath = isIncludedPath;
|
|
11
|
+
exports.deriveMarkdownTitle = deriveMarkdownTitle;
|
|
12
|
+
exports.scanMarkdownFiles = scanMarkdownFiles;
|
|
13
|
+
const node_crypto_1 = require("node:crypto");
|
|
14
|
+
const promises_1 = __importDefault(require("node:fs/promises"));
|
|
15
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
16
|
+
const node_readline_1 = __importDefault(require("node:readline"));
|
|
17
|
+
const node_fs_1 = require("node:fs");
|
|
18
|
+
const hash_1 = require("./hash");
|
|
19
|
+
const manifest_1 = require("./manifest");
|
|
20
|
+
const path_utils_1 = require("./path-utils");
|
|
21
|
+
const DEFAULT_EXCLUDED_DIRS = new Set(["node_modules", ".git", ".pageindex", "dist", "build"]);
|
|
22
|
+
function isMarkdownDocument(filePath) {
|
|
23
|
+
const ext = node_path_1.default.extname(filePath).toLowerCase();
|
|
24
|
+
return ext === ".md" || ext === ".mdx";
|
|
25
|
+
}
|
|
26
|
+
function createDocId(relativePath) {
|
|
27
|
+
const normalizedPath = (0, path_utils_1.normalizeRelativePath)(relativePath);
|
|
28
|
+
const digest = (0, node_crypto_1.createHash)("sha1").update(normalizedPath).digest("hex");
|
|
29
|
+
return `doc:${digest}`;
|
|
30
|
+
}
|
|
31
|
+
function docIdToIndexFileName(docId) {
|
|
32
|
+
return `${docId.replace(/[^a-zA-Z0-9_-]/g, "_")}.pageindex.json`;
|
|
33
|
+
}
|
|
34
|
+
function createIndexPath(docId) {
|
|
35
|
+
return [manifest_1.INDEXES_DIR, docIdToIndexFileName(docId)].join("/");
|
|
36
|
+
}
|
|
37
|
+
function escapeRegex(value) {
|
|
38
|
+
return value.replace(/[|\\{}()[\]^$+?.]/g, "\\$&");
|
|
39
|
+
}
|
|
40
|
+
function globToRegExp(pattern) {
|
|
41
|
+
const normalizedPattern = (0, path_utils_1.normalizeRelativePath)(pattern).replace(/^\/+/, "");
|
|
42
|
+
let regex = "^";
|
|
43
|
+
let index = 0;
|
|
44
|
+
while (index < normalizedPattern.length) {
|
|
45
|
+
const char = normalizedPattern[index];
|
|
46
|
+
const next = normalizedPattern[index + 1];
|
|
47
|
+
const afterNext = normalizedPattern[index + 2];
|
|
48
|
+
if (char === "*" && next === "*" && afterNext === "/") {
|
|
49
|
+
regex += "(?:.*/)?";
|
|
50
|
+
index += 3;
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
if (char === "*" && next === "*") {
|
|
54
|
+
regex += ".*";
|
|
55
|
+
index += 2;
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if (char === "*") {
|
|
59
|
+
regex += "[^/]*";
|
|
60
|
+
index += 1;
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
if (char === "?") {
|
|
64
|
+
regex += "[^/]";
|
|
65
|
+
index += 1;
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
regex += escapeRegex(char);
|
|
69
|
+
index += 1;
|
|
70
|
+
}
|
|
71
|
+
return new RegExp(`${regex}$`);
|
|
72
|
+
}
|
|
73
|
+
function matchesPattern(relativePath, patterns) {
|
|
74
|
+
if (!patterns?.length) {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
const normalizedPath = (0, path_utils_1.normalizeRelativePath)(relativePath);
|
|
78
|
+
return patterns.some((pattern) => globToRegExp(pattern).test(normalizedPath));
|
|
79
|
+
}
|
|
80
|
+
function isIncludedPath(relativePath, options = {}) {
|
|
81
|
+
const normalizedPath = (0, path_utils_1.normalizeRelativePath)(relativePath);
|
|
82
|
+
const includePatterns = options.include?.length ? options.include : undefined;
|
|
83
|
+
if (includePatterns && !matchesPattern(normalizedPath, includePatterns)) {
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
return !matchesPattern(normalizedPath, options.exclude);
|
|
87
|
+
}
|
|
88
|
+
async function deriveMarkdownTitle(filePath) {
|
|
89
|
+
const stream = (0, node_fs_1.createReadStream)(filePath, { encoding: "utf8" });
|
|
90
|
+
const reader = node_readline_1.default.createInterface({
|
|
91
|
+
input: stream,
|
|
92
|
+
crlfDelay: Infinity
|
|
93
|
+
});
|
|
94
|
+
try {
|
|
95
|
+
for await (const line of reader) {
|
|
96
|
+
const match = /^#\s+(.+?)\s*#*\s*$/.exec(line.trim());
|
|
97
|
+
if (match?.[1]) {
|
|
98
|
+
return match[1].trim();
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
finally {
|
|
103
|
+
reader.close();
|
|
104
|
+
stream.destroy();
|
|
105
|
+
}
|
|
106
|
+
return node_path_1.default.basename(filePath, node_path_1.default.extname(filePath));
|
|
107
|
+
}
|
|
108
|
+
async function scanMarkdownFiles(rootDir, options = {}) {
|
|
109
|
+
const absoluteRoot = node_path_1.default.resolve(rootDir);
|
|
110
|
+
const excludedDirs = (options.excludedDirs ?? []).map((dir) => node_path_1.default.resolve(dir));
|
|
111
|
+
const files = [];
|
|
112
|
+
function isExcludedDirectory(entryName, absolutePath) {
|
|
113
|
+
const relativePath = (0, path_utils_1.normalizeRelativePath)(absolutePath, absoluteRoot);
|
|
114
|
+
return (DEFAULT_EXCLUDED_DIRS.has(entryName) ||
|
|
115
|
+
excludedDirs.some((excludedDir) => (0, path_utils_1.isSubPath)(excludedDir, absolutePath)) ||
|
|
116
|
+
matchesPattern(relativePath, options.exclude) ||
|
|
117
|
+
matchesPattern(`${relativePath}/`, options.exclude));
|
|
118
|
+
}
|
|
119
|
+
async function walk(currentDir) {
|
|
120
|
+
const entries = await promises_1.default.readdir(currentDir, { withFileTypes: true });
|
|
121
|
+
for (const entry of entries) {
|
|
122
|
+
const absolutePath = node_path_1.default.join(currentDir, entry.name);
|
|
123
|
+
if (entry.isDirectory()) {
|
|
124
|
+
if (!isExcludedDirectory(entry.name, absolutePath)) {
|
|
125
|
+
await walk(absolutePath);
|
|
126
|
+
}
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
if (!entry.isFile() || !isMarkdownDocument(entry.name)) {
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
const stat = await promises_1.default.stat(absolutePath);
|
|
133
|
+
const relativePath = (0, path_utils_1.normalizeRelativePath)(absolutePath, absoluteRoot);
|
|
134
|
+
if (!isIncludedPath(relativePath, options)) {
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
const docId = createDocId(relativePath);
|
|
138
|
+
files.push({
|
|
139
|
+
docId,
|
|
140
|
+
path: relativePath,
|
|
141
|
+
absolutePath: (0, path_utils_1.normalizeAbsolutePath)(absolutePath),
|
|
142
|
+
contentHash: await (0, hash_1.hashFile)(absolutePath),
|
|
143
|
+
size: stat.size,
|
|
144
|
+
mtimeMs: stat.mtimeMs,
|
|
145
|
+
title: await deriveMarkdownTitle(absolutePath),
|
|
146
|
+
indexPath: createIndexPath(docId)
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
await walk(absoluteRoot);
|
|
151
|
+
return files.sort((left, right) => left.path.localeCompare(right.path));
|
|
152
|
+
}
|
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
export type DocumentStatus = "ready" | "failed" | "deleted";
|
|
2
|
+
export type Manifest = {
|
|
3
|
+
version: 1;
|
|
4
|
+
rootDir: string;
|
|
5
|
+
generatedAt: string;
|
|
6
|
+
documents: DocumentRecord[];
|
|
7
|
+
};
|
|
8
|
+
export type DocumentRecord = {
|
|
9
|
+
docId: string;
|
|
10
|
+
path: string;
|
|
11
|
+
absolutePath: string;
|
|
12
|
+
contentHash: string;
|
|
13
|
+
size: number;
|
|
14
|
+
mtimeMs: number;
|
|
15
|
+
title: string;
|
|
16
|
+
summary?: string;
|
|
17
|
+
indexPath: string;
|
|
18
|
+
status: DocumentStatus;
|
|
19
|
+
error?: string;
|
|
20
|
+
};
|
|
21
|
+
export type RootTreeNode = {
|
|
22
|
+
node_id: string;
|
|
23
|
+
type: "root" | "directory" | "document";
|
|
24
|
+
title: string;
|
|
25
|
+
summary?: string;
|
|
26
|
+
path?: string;
|
|
27
|
+
index_path?: string;
|
|
28
|
+
children?: RootTreeNode[];
|
|
29
|
+
};
|
|
30
|
+
export type ChatMessage = {
|
|
31
|
+
role: "system" | "user" | "assistant";
|
|
32
|
+
content: string;
|
|
33
|
+
};
|
|
34
|
+
export type LlmChatRequest = {
|
|
35
|
+
messages: ChatMessage[];
|
|
36
|
+
model: string;
|
|
37
|
+
temperature: number;
|
|
38
|
+
};
|
|
39
|
+
export type LlmClient = {
|
|
40
|
+
chatCompletion: (request: LlmChatRequest) => Promise<string>;
|
|
41
|
+
};
|
|
42
|
+
export type PageIndexOptions = {
|
|
43
|
+
pythonPath?: string;
|
|
44
|
+
cliPath?: string;
|
|
45
|
+
model?: string;
|
|
46
|
+
baseUrl?: string;
|
|
47
|
+
apiKey?: string;
|
|
48
|
+
llmClient?: LlmClient;
|
|
49
|
+
concurrency?: number;
|
|
50
|
+
exclude?: string[];
|
|
51
|
+
include?: string[];
|
|
52
|
+
outputDir?: string;
|
|
53
|
+
outputArg?: string;
|
|
54
|
+
extraArgs?: string[];
|
|
55
|
+
env?: NodeJS.ProcessEnv;
|
|
56
|
+
progress?: (event: IndexProgressEvent) => void;
|
|
57
|
+
trace?: boolean;
|
|
58
|
+
watchDebounceMs?: number;
|
|
59
|
+
watchHealthFile?: string;
|
|
60
|
+
watchLockFile?: string;
|
|
61
|
+
watchProgress?: (event: WatchProgressEvent) => void;
|
|
62
|
+
watchRetryAttempts?: number;
|
|
63
|
+
watchRetryDelayMs?: number;
|
|
64
|
+
watchStaging?: boolean;
|
|
65
|
+
watchStagingOutputDir?: string;
|
|
66
|
+
watchWebhookUrl?: string;
|
|
67
|
+
};
|
|
68
|
+
export type IndexProgressEvent = {
|
|
69
|
+
type: "scan";
|
|
70
|
+
rootDir: string;
|
|
71
|
+
outputDir: string;
|
|
72
|
+
total: number;
|
|
73
|
+
toIndex: number;
|
|
74
|
+
unchanged: number;
|
|
75
|
+
deleted: number;
|
|
76
|
+
} | {
|
|
77
|
+
type: "index-start";
|
|
78
|
+
path: string;
|
|
79
|
+
index: number;
|
|
80
|
+
total: number;
|
|
81
|
+
} | {
|
|
82
|
+
type: "index-done";
|
|
83
|
+
path: string;
|
|
84
|
+
index: number;
|
|
85
|
+
total: number;
|
|
86
|
+
summary?: string;
|
|
87
|
+
} | {
|
|
88
|
+
type: "index-failed";
|
|
89
|
+
path: string;
|
|
90
|
+
index: number;
|
|
91
|
+
total: number;
|
|
92
|
+
error: string;
|
|
93
|
+
} | {
|
|
94
|
+
type: "write";
|
|
95
|
+
manifestPath: string;
|
|
96
|
+
rootTreePath: string;
|
|
97
|
+
};
|
|
98
|
+
export type WatchProgressEvent = {
|
|
99
|
+
version: 1;
|
|
100
|
+
timestamp: string;
|
|
101
|
+
type: "watch-start";
|
|
102
|
+
rootDir: string;
|
|
103
|
+
outputDir: string;
|
|
104
|
+
pid?: number;
|
|
105
|
+
} | {
|
|
106
|
+
version: 1;
|
|
107
|
+
timestamp: string;
|
|
108
|
+
type: "watch-lock-acquired";
|
|
109
|
+
rootDir: string;
|
|
110
|
+
outputDir: string;
|
|
111
|
+
lockFile: string;
|
|
112
|
+
} | {
|
|
113
|
+
version: 1;
|
|
114
|
+
timestamp: string;
|
|
115
|
+
type: "watch-lock-released";
|
|
116
|
+
rootDir: string;
|
|
117
|
+
outputDir: string;
|
|
118
|
+
lockFile: string;
|
|
119
|
+
} | {
|
|
120
|
+
version: 1;
|
|
121
|
+
timestamp: string;
|
|
122
|
+
type: "watch-file-event";
|
|
123
|
+
rootDir: string;
|
|
124
|
+
outputDir: string;
|
|
125
|
+
eventName: "add" | "change" | "unlink";
|
|
126
|
+
path: string;
|
|
127
|
+
} | {
|
|
128
|
+
version: 1;
|
|
129
|
+
timestamp: string;
|
|
130
|
+
type: "watch-index-start";
|
|
131
|
+
rootDir: string;
|
|
132
|
+
outputDir: string;
|
|
133
|
+
reason: "initial" | "change";
|
|
134
|
+
attempt: number;
|
|
135
|
+
maxAttempts: number;
|
|
136
|
+
} | {
|
|
137
|
+
version: 1;
|
|
138
|
+
timestamp: string;
|
|
139
|
+
type: "watch-index-retry";
|
|
140
|
+
rootDir: string;
|
|
141
|
+
outputDir: string;
|
|
142
|
+
reason: "initial" | "change";
|
|
143
|
+
attempt: number;
|
|
144
|
+
maxAttempts: number;
|
|
145
|
+
delayMs: number;
|
|
146
|
+
error: string;
|
|
147
|
+
} | {
|
|
148
|
+
version: 1;
|
|
149
|
+
timestamp: string;
|
|
150
|
+
type: "watch-index-done";
|
|
151
|
+
rootDir: string;
|
|
152
|
+
outputDir: string;
|
|
153
|
+
reason: "initial" | "change";
|
|
154
|
+
attempt: number;
|
|
155
|
+
maxAttempts: number;
|
|
156
|
+
result: IndexCounts;
|
|
157
|
+
manifestPath: string;
|
|
158
|
+
rootTreePath: string;
|
|
159
|
+
} | {
|
|
160
|
+
version: 1;
|
|
161
|
+
timestamp: string;
|
|
162
|
+
type: "watch-index-partial-failure";
|
|
163
|
+
rootDir: string;
|
|
164
|
+
outputDir: string;
|
|
165
|
+
reason: "initial" | "change";
|
|
166
|
+
attempt: number;
|
|
167
|
+
maxAttempts: number;
|
|
168
|
+
failed: number;
|
|
169
|
+
result: IndexCounts;
|
|
170
|
+
} | {
|
|
171
|
+
version: 1;
|
|
172
|
+
timestamp: string;
|
|
173
|
+
type: "watch-index-failed";
|
|
174
|
+
rootDir: string;
|
|
175
|
+
outputDir: string;
|
|
176
|
+
reason: "initial" | "change";
|
|
177
|
+
attempt: number;
|
|
178
|
+
maxAttempts: number;
|
|
179
|
+
error: string;
|
|
180
|
+
} | {
|
|
181
|
+
version: 1;
|
|
182
|
+
timestamp: string;
|
|
183
|
+
type: "watch-output-promoted";
|
|
184
|
+
rootDir: string;
|
|
185
|
+
outputDir: string;
|
|
186
|
+
stagingOutputDir: string;
|
|
187
|
+
} | {
|
|
188
|
+
version: 1;
|
|
189
|
+
timestamp: string;
|
|
190
|
+
type: "watch-health";
|
|
191
|
+
rootDir: string;
|
|
192
|
+
outputDir: string;
|
|
193
|
+
healthFile: string;
|
|
194
|
+
status: WatchHealthStatus;
|
|
195
|
+
ok: boolean;
|
|
196
|
+
} | {
|
|
197
|
+
version: 1;
|
|
198
|
+
timestamp: string;
|
|
199
|
+
type: "watch-health-failed";
|
|
200
|
+
rootDir: string;
|
|
201
|
+
outputDir: string;
|
|
202
|
+
healthFile: string;
|
|
203
|
+
error: string;
|
|
204
|
+
} | {
|
|
205
|
+
version: 1;
|
|
206
|
+
timestamp: string;
|
|
207
|
+
type: "watch-webhook-failed";
|
|
208
|
+
rootDir: string;
|
|
209
|
+
outputDir: string;
|
|
210
|
+
url: string;
|
|
211
|
+
error: string;
|
|
212
|
+
} | {
|
|
213
|
+
version: 1;
|
|
214
|
+
timestamp: string;
|
|
215
|
+
type: "watch-stop";
|
|
216
|
+
rootDir: string;
|
|
217
|
+
outputDir: string;
|
|
218
|
+
};
|
|
219
|
+
export type WatchHealthStatus = "starting" | "indexing" | "ready" | "degraded" | "failed" | "stopped";
|
|
220
|
+
export type WatchHealthFile = {
|
|
221
|
+
version: 1;
|
|
222
|
+
ok: boolean;
|
|
223
|
+
status: WatchHealthStatus;
|
|
224
|
+
rootDir: string;
|
|
225
|
+
outputDir: string;
|
|
226
|
+
pid: number;
|
|
227
|
+
startedAt: string;
|
|
228
|
+
updatedAt: string;
|
|
229
|
+
lastSuccessAt?: string;
|
|
230
|
+
lastFailureAt?: string;
|
|
231
|
+
reason?: "initial" | "change";
|
|
232
|
+
result?: IndexCounts;
|
|
233
|
+
error?: string;
|
|
234
|
+
};
|
|
235
|
+
export type ScannedFile = {
|
|
236
|
+
docId: string;
|
|
237
|
+
path: string;
|
|
238
|
+
absolutePath: string;
|
|
239
|
+
contentHash: string;
|
|
240
|
+
size: number;
|
|
241
|
+
mtimeMs: number;
|
|
242
|
+
title: string;
|
|
243
|
+
indexPath: string;
|
|
244
|
+
};
|
|
245
|
+
export type ManifestDiff = {
|
|
246
|
+
added: ScannedFile[];
|
|
247
|
+
modified: ScannedFile[];
|
|
248
|
+
retryFailed: ScannedFile[];
|
|
249
|
+
unchanged: ScannedFile[];
|
|
250
|
+
deleted: DocumentRecord[];
|
|
251
|
+
toIndex: ScannedFile[];
|
|
252
|
+
};
|
|
253
|
+
export type IndexCounts = {
|
|
254
|
+
total: number;
|
|
255
|
+
ready: number;
|
|
256
|
+
failed: number;
|
|
257
|
+
added: number;
|
|
258
|
+
modified: number;
|
|
259
|
+
retryFailed: number;
|
|
260
|
+
unchanged: number;
|
|
261
|
+
deleted: number;
|
|
262
|
+
};
|
|
263
|
+
export type IndexFolderResult = {
|
|
264
|
+
manifest: Manifest;
|
|
265
|
+
rootTree: RootTreeNode;
|
|
266
|
+
outputDir: string;
|
|
267
|
+
manifestPath: string;
|
|
268
|
+
rootTreePath: string;
|
|
269
|
+
added: number;
|
|
270
|
+
modified: number;
|
|
271
|
+
retryFailed: number;
|
|
272
|
+
unchanged: number;
|
|
273
|
+
deleted: number;
|
|
274
|
+
failed: number;
|
|
275
|
+
ready: number;
|
|
276
|
+
};
|
|
277
|
+
export type QuerySelectedDocument = {
|
|
278
|
+
docId: string;
|
|
279
|
+
available: boolean;
|
|
280
|
+
path?: string;
|
|
281
|
+
title?: string;
|
|
282
|
+
status?: DocumentStatus;
|
|
283
|
+
indexPath?: string;
|
|
284
|
+
selectionReason: "selected_by_document_planner";
|
|
285
|
+
skipReason?: "missing_root_tree_document" | "missing_manifest_record" | "missing_index_path" | "document_not_ready";
|
|
286
|
+
};
|
|
287
|
+
export type QuerySelectedNode = {
|
|
288
|
+
docId: string;
|
|
289
|
+
path: string;
|
|
290
|
+
nodeId: string;
|
|
291
|
+
found: boolean;
|
|
292
|
+
hasText: boolean;
|
|
293
|
+
reference?: string;
|
|
294
|
+
selectionReason: "selected_by_node_planner" | "matched_query_text";
|
|
295
|
+
skipReason?: "node_not_found" | "missing_text";
|
|
296
|
+
textBytes?: number;
|
|
297
|
+
};
|
|
298
|
+
export type QuerySource = {
|
|
299
|
+
path: string;
|
|
300
|
+
nodeId: string;
|
|
301
|
+
reference: string;
|
|
302
|
+
text: string;
|
|
303
|
+
};
|
|
304
|
+
export type QueryTimings = {
|
|
305
|
+
resolve: number;
|
|
306
|
+
selectDocuments: number;
|
|
307
|
+
selectNodes: number;
|
|
308
|
+
answer: number;
|
|
309
|
+
total: number;
|
|
310
|
+
};
|
|
311
|
+
export type QueryFailureStage = "resolve" | "read-index" | "select-documents" | "read-document-index" | "select-nodes" | "extract-context" | "answer";
|
|
312
|
+
export type QueryTraceFailure = {
|
|
313
|
+
stage: QueryFailureStage;
|
|
314
|
+
code: string;
|
|
315
|
+
message: string;
|
|
316
|
+
docId?: string;
|
|
317
|
+
nodeId?: string;
|
|
318
|
+
path?: string;
|
|
319
|
+
reference?: string;
|
|
320
|
+
};
|
|
321
|
+
export type QueryDocumentSelectionTrace = {
|
|
322
|
+
promptBytes: number;
|
|
323
|
+
responseBytes: number;
|
|
324
|
+
rawResponse: string;
|
|
325
|
+
selectedDocumentIds: string[];
|
|
326
|
+
};
|
|
327
|
+
export type QueryNodeSelectionTrace = {
|
|
328
|
+
docId: string;
|
|
329
|
+
path: string;
|
|
330
|
+
promptBytes: number;
|
|
331
|
+
responseBytes: number;
|
|
332
|
+
rawResponse: string;
|
|
333
|
+
selectedNodeIds: string[];
|
|
334
|
+
};
|
|
335
|
+
export type QueryContextTrace = {
|
|
336
|
+
sourceCount: number;
|
|
337
|
+
bytes: number;
|
|
338
|
+
tokens: number;
|
|
339
|
+
};
|
|
340
|
+
export type QueryAnswerTrace = {
|
|
341
|
+
promptBytes: number;
|
|
342
|
+
responseBytes: number;
|
|
343
|
+
};
|
|
344
|
+
export type QueryTrace = {
|
|
345
|
+
version: 1;
|
|
346
|
+
documentSelection?: QueryDocumentSelectionTrace;
|
|
347
|
+
nodeSelections: QueryNodeSelectionTrace[];
|
|
348
|
+
context: QueryContextTrace;
|
|
349
|
+
answer?: QueryAnswerTrace;
|
|
350
|
+
failures: QueryTraceFailure[];
|
|
351
|
+
};
|
|
352
|
+
export type QueryResult = {
|
|
353
|
+
version: 1;
|
|
354
|
+
target: string;
|
|
355
|
+
rootDir: string;
|
|
356
|
+
outputDir: string;
|
|
357
|
+
question: string;
|
|
358
|
+
model: string;
|
|
359
|
+
answer: string;
|
|
360
|
+
contextBytes: number;
|
|
361
|
+
contextTokens: number;
|
|
362
|
+
selectedDocuments: QuerySelectedDocument[];
|
|
363
|
+
selectedNodes: QuerySelectedNode[];
|
|
364
|
+
sources: QuerySource[];
|
|
365
|
+
warnings: string[];
|
|
366
|
+
timingsMs: QueryTimings;
|
|
367
|
+
trace?: QueryTrace;
|
|
368
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { IndexFolderResult, PageIndexOptions } from "./types";
|
|
2
|
+
export type WatchFolderReadyResult = {
|
|
3
|
+
ok: true;
|
|
4
|
+
result: IndexFolderResult;
|
|
5
|
+
} | {
|
|
6
|
+
ok: false;
|
|
7
|
+
error: string;
|
|
8
|
+
};
|
|
9
|
+
export type WatchFolderHandle = {
|
|
10
|
+
rootDir: string;
|
|
11
|
+
outputDir: string;
|
|
12
|
+
ready: Promise<WatchFolderReadyResult>;
|
|
13
|
+
closed: Promise<void>;
|
|
14
|
+
close: () => Promise<void>;
|
|
15
|
+
};
|
|
16
|
+
export declare function startWatchFolder(folder: string, options?: PageIndexOptions): Promise<WatchFolderHandle>;
|
|
17
|
+
export declare function watchFolder(folder: string, options?: PageIndexOptions): Promise<void>;
|