@autorag/librarian 2.5.3 → 2.6.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/NOTICE +10 -13
- package/README.md +46 -7
- package/dist/agent/agent.d.ts +16 -1
- package/dist/agent/refresh-progress.d.ts +30 -0
- package/dist/agent/search-documents.d.ts +1 -1
- package/dist/cli/commands/report.d.ts +3 -0
- package/dist/cli/commands/serve.d.ts +2 -1
- package/dist/cli/config.d.ts +1 -10
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.js +4927 -6925
- package/dist/core.d.ts +1 -1
- package/dist/core.js +1120 -1175
- package/dist/index.js +1123 -1179
- package/dist/language.d.ts +21 -0
- package/dist/memory/memory.d.ts +0 -1
- package/dist/mirror/paths.d.ts +2 -0
- package/dist/mirror/sync.d.ts +1 -1
- package/dist/p2p/simplex-server.d.ts +21 -5
- package/dist/p2p/simplex-transport.d.ts +21 -4
- package/dist/parser/defaults.d.ts +10 -4
- package/dist/parser/index.d.ts +3 -5
- package/dist/parser/kordoc.d.ts +53 -0
- package/dist/parser/ocr-engines.d.ts +12 -0
- package/dist/parser/ocr.d.ts +7 -1
- package/dist/parser/office.d.ts +1 -10
- package/dist/parser/types.d.ts +1 -1
- package/package.json +10 -10
- package/skills/autorag-lite-search/SKILL.md +57 -7
- package/skills/autorag-lite-setup/SKILL.md +2 -2
- package/skills/autorag-setup/SKILL.md +2 -2
- package/dist/cli/commands/ui.d.ts +0 -13
- package/dist/parser/hwp-markdown.d.ts +0 -25
- package/dist/parser/hwp.d.ts +0 -13
- package/dist/parser/opendataloader-pdf.d.ts +0 -31
- package/dist/parser/rhwp-adapter.d.ts +0 -30
- package/dist/ui/browse.d.ts +0 -11
- package/dist/ui/catalog.d.ts +0 -59
- package/dist/ui/config-store.d.ts +0 -43
- package/dist/ui/discover.d.ts +0 -17
- package/dist/ui/html.d.ts +0 -2
- package/dist/ui/probe.d.ts +0 -24
- package/dist/ui/prompt.d.ts +0 -21
- package/dist/ui/server.d.ts +0 -28
package/dist/core.js
CHANGED
|
@@ -146,7 +146,10 @@ function parsedOutputPath(root, virtualPath) {
|
|
|
146
146
|
function refreshReadinessPath(root) {
|
|
147
147
|
return join2(root, ".autorag", REFRESH_READINESS_FILE);
|
|
148
148
|
}
|
|
149
|
-
|
|
149
|
+
function refreshProgressPath(root) {
|
|
150
|
+
return join2(root, ".autorag", REFRESH_PROGRESS_FILE);
|
|
151
|
+
}
|
|
152
|
+
var PARSED_MIRROR_SUBDIR, PARSED_FILES_SUBDIR = "files", PARSED_INDEX_FILE = "index.json", REFRESH_READINESS_FILE = "refresh-complete.json", REFRESH_PROGRESS_FILE = "refresh-progress.json";
|
|
150
153
|
var init_paths = __esm(() => {
|
|
151
154
|
PARSED_MIRROR_SUBDIR = join2(".autorag", "parsed");
|
|
152
155
|
});
|
|
@@ -1212,6 +1215,72 @@ var init_jikji = __esm(() => {
|
|
|
1212
1215
|
init_types();
|
|
1213
1216
|
});
|
|
1214
1217
|
|
|
1218
|
+
// src/language.ts
|
|
1219
|
+
function supportedList() {
|
|
1220
|
+
return AUTORAG_LANGUAGE_TAGS.join(", ");
|
|
1221
|
+
}
|
|
1222
|
+
function toTag(raw) {
|
|
1223
|
+
const tag = raw.trim().toLowerCase();
|
|
1224
|
+
if (!AUTORAG_LANGUAGE_TAGS.includes(tag)) {
|
|
1225
|
+
throw new LanguageError(`Unsupported language "${raw.trim()}". Supported: ${supportedList()}.`);
|
|
1226
|
+
}
|
|
1227
|
+
return tag;
|
|
1228
|
+
}
|
|
1229
|
+
function dedupe(tags) {
|
|
1230
|
+
return [...new Set(tags)];
|
|
1231
|
+
}
|
|
1232
|
+
function normalizeLanguages(raw) {
|
|
1233
|
+
if (raw === undefined || raw === null)
|
|
1234
|
+
return [...DEFAULT_LANGUAGES];
|
|
1235
|
+
if (typeof raw === "string")
|
|
1236
|
+
return parseLanguageList(raw);
|
|
1237
|
+
if (!Array.isArray(raw)) {
|
|
1238
|
+
throw new LanguageError(`languages must be a string or an array of language tags; received ${typeof raw}.`);
|
|
1239
|
+
}
|
|
1240
|
+
const entries = raw.map((entry, index) => {
|
|
1241
|
+
if (typeof entry !== "string") {
|
|
1242
|
+
throw new LanguageError(`languages[${index}] must be a string language tag; received ${typeof entry}.`);
|
|
1243
|
+
}
|
|
1244
|
+
return entry;
|
|
1245
|
+
});
|
|
1246
|
+
const tags = entries.filter((entry) => entry.trim() !== "").map(toTag);
|
|
1247
|
+
if (tags.length === 0) {
|
|
1248
|
+
throw new LanguageError(`languages must list at least one language. Supported: ${supportedList()}.`);
|
|
1249
|
+
}
|
|
1250
|
+
return dedupe(tags);
|
|
1251
|
+
}
|
|
1252
|
+
function parseLanguageList(value) {
|
|
1253
|
+
const tags = value.split(",").map((entry) => entry.trim()).filter((entry) => entry !== "").map(toTag);
|
|
1254
|
+
if (tags.length === 0) {
|
|
1255
|
+
throw new LanguageError(`languages must list at least one language. Supported: ${supportedList()}.`);
|
|
1256
|
+
}
|
|
1257
|
+
return dedupe(tags);
|
|
1258
|
+
}
|
|
1259
|
+
var AUTORAG_LANGUAGE_TAGS, DEFAULT_LANGUAGES, LanguageError;
|
|
1260
|
+
var init_language = __esm(() => {
|
|
1261
|
+
AUTORAG_LANGUAGE_TAGS = [
|
|
1262
|
+
"ko",
|
|
1263
|
+
"en",
|
|
1264
|
+
"ja",
|
|
1265
|
+
"zh-hans",
|
|
1266
|
+
"zh-hant",
|
|
1267
|
+
"fr",
|
|
1268
|
+
"de",
|
|
1269
|
+
"es",
|
|
1270
|
+
"ru",
|
|
1271
|
+
"it",
|
|
1272
|
+
"pt",
|
|
1273
|
+
"vi",
|
|
1274
|
+
"th",
|
|
1275
|
+
"ar",
|
|
1276
|
+
"hi"
|
|
1277
|
+
];
|
|
1278
|
+
DEFAULT_LANGUAGES = ["ko", "en"];
|
|
1279
|
+
LanguageError = class LanguageError extends Error {
|
|
1280
|
+
name = "LanguageError";
|
|
1281
|
+
};
|
|
1282
|
+
});
|
|
1283
|
+
|
|
1215
1284
|
// src/manifest/loader.ts
|
|
1216
1285
|
import { existsSync as existsSync5, readdirSync, readFileSync as readFileSync3 } from "node:fs";
|
|
1217
1286
|
import { extname as extname2, join as join6 } from "node:path";
|
|
@@ -4981,475 +5050,220 @@ var init_eml = __esm(() => {
|
|
|
4981
5050
|
};
|
|
4982
5051
|
});
|
|
4983
5052
|
|
|
4984
|
-
// src/parser/
|
|
4985
|
-
|
|
4986
|
-
|
|
4987
|
-
|
|
4988
|
-
const key = `${table.sectionIndex}:${table.parentParagraphIndex}`;
|
|
4989
|
-
const group = tables.get(key) ?? [];
|
|
4990
|
-
group.push(table);
|
|
4991
|
-
tables.set(key, group);
|
|
4992
|
-
}
|
|
4993
|
-
for (const group of tables.values()) {
|
|
4994
|
-
group.sort((left, right) => left.controlIndex - right.controlIndex);
|
|
4995
|
-
}
|
|
4996
|
-
const blocks = [];
|
|
4997
|
-
for (const paragraph of document.paragraphs) {
|
|
4998
|
-
const text = cleanText(paragraph.text);
|
|
4999
|
-
if (hasRenderableText(text))
|
|
5000
|
-
blocks.push(text);
|
|
5001
|
-
for (const table of tables.get(`${paragraph.sectionIndex}:${paragraph.paragraphIndex}`) ?? []) {
|
|
5002
|
-
const rendered = renderTable(table);
|
|
5003
|
-
if (rendered.length > 0)
|
|
5004
|
-
blocks.push(rendered);
|
|
5005
|
-
}
|
|
5006
|
-
}
|
|
5007
|
-
return blocks.join(`
|
|
5008
|
-
|
|
5009
|
-
`);
|
|
5010
|
-
}
|
|
5011
|
-
function cleanText(text) {
|
|
5012
|
-
return text.replace(/[\u0000\uFFFC]/gu, "");
|
|
5013
|
-
}
|
|
5014
|
-
function hasRenderableText(text) {
|
|
5015
|
-
return text.trim().length > 0;
|
|
5016
|
-
}
|
|
5017
|
-
function renderTable(table) {
|
|
5018
|
-
const cells = table.cells.map((cell) => ({ ...cell, text: renderCell(cell) }));
|
|
5019
|
-
if (!cells.some((cell) => hasRenderableText(cell.text)))
|
|
5020
|
-
return "";
|
|
5021
|
-
if (cells.some((cell) => cell.rowSpan > 1 || cell.columnSpan > 1))
|
|
5022
|
-
return renderMergedTable(cells);
|
|
5023
|
-
const cellsByPosition = new Map(cells.map((cell) => [`${cell.row}:${cell.column}`, cell.text]));
|
|
5024
|
-
const header = Array.from({ length: table.columnCount }, (_, column) => `Column ${column + 1}`);
|
|
5025
|
-
const rows = Array.from({ length: table.rowCount }, (_, row) => Array.from({ length: table.columnCount }, (_, column) => cellsByPosition.get(`${row}:${column}`) ?? ""));
|
|
5026
|
-
return [
|
|
5027
|
-
`| ${header.join(" | ")} |`,
|
|
5028
|
-
`| ${header.map(() => "---").join(" | ")} |`,
|
|
5029
|
-
...rows.map((row) => `| ${row.join(" | ")} |`)
|
|
5030
|
-
].join(`
|
|
5031
|
-
`);
|
|
5053
|
+
// src/parser/kordoc.ts
|
|
5054
|
+
import { parse as kordocParse } from "kordoc";
|
|
5055
|
+
function toKordocInput(bytes) {
|
|
5056
|
+
return Buffer.isBuffer(bytes) ? bytes : Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
5032
5057
|
}
|
|
5033
|
-
|
|
5034
|
-
const
|
|
5035
|
-
|
|
5036
|
-
|
|
5037
|
-
|
|
5038
|
-
|
|
5039
|
-
|
|
5040
|
-
|
|
5041
|
-
|
|
5042
|
-
|
|
5043
|
-
|
|
5044
|
-
|
|
5045
|
-
if (rowIndex !== cell.row || columnIndex !== cell.column)
|
|
5046
|
-
coveredPositions.add(`${rowIndex}:${columnIndex}`);
|
|
5047
|
-
}
|
|
5048
|
-
}
|
|
5058
|
+
var KORDOC_EXTENSIONS, defaultParse = async (bytes, options) => {
|
|
5059
|
+
const result = await kordocParse(toKordocInput(bytes), {
|
|
5060
|
+
plain: true,
|
|
5061
|
+
...options.ocr === undefined ? {} : { ocr: options.ocr }
|
|
5062
|
+
});
|
|
5063
|
+
if (result.success) {
|
|
5064
|
+
return {
|
|
5065
|
+
success: true,
|
|
5066
|
+
fileType: result.fileType,
|
|
5067
|
+
markdown: result.markdown,
|
|
5068
|
+
warnings: result.warnings
|
|
5069
|
+
};
|
|
5049
5070
|
}
|
|
5050
|
-
|
|
5051
|
-
|
|
5052
|
-
|
|
5053
|
-
|
|
5054
|
-
|
|
5055
|
-
|
|
5056
|
-
|
|
5057
|
-
|
|
5058
|
-
|
|
5059
|
-
|
|
5060
|
-
|
|
5061
|
-
|
|
5062
|
-
|
|
5063
|
-
|
|
5064
|
-
function createRhwpExtractor(runtime = defaultRhwpRuntime, overrides = {}) {
|
|
5065
|
-
const limits = resolveLimits(overrides);
|
|
5066
|
-
const initialize = runtime === defaultRhwpRuntime ? initializeDefaultRhwpRuntime : createRuntimeInitializer(runtime);
|
|
5067
|
-
return async (bytes) => {
|
|
5068
|
-
await initialize();
|
|
5069
|
-
const document = runtime.open(bytes);
|
|
5070
|
-
try {
|
|
5071
|
-
return extractDocument(document, limits);
|
|
5072
|
-
} finally {
|
|
5073
|
-
document.free();
|
|
5071
|
+
return { success: false, fileType: result.fileType, error: result.error, code: result.code };
|
|
5072
|
+
}, KordocParser;
|
|
5073
|
+
var init_kordoc = __esm(() => {
|
|
5074
|
+
init_errors();
|
|
5075
|
+
KORDOC_EXTENSIONS = [".hwp", ".hwpx", ".hml", ".hwpml", ".pdf", ".docx", ".xlsx", ".xls"];
|
|
5076
|
+
KordocParser = class KordocParser extends Parser {
|
|
5077
|
+
name = "kordoc";
|
|
5078
|
+
extensions = KORDOC_EXTENSIONS;
|
|
5079
|
+
#parse;
|
|
5080
|
+
#ocr;
|
|
5081
|
+
constructor(options = {}) {
|
|
5082
|
+
super();
|
|
5083
|
+
this.#parse = options.parse ?? defaultParse;
|
|
5084
|
+
this.#ocr = options.ocr;
|
|
5074
5085
|
}
|
|
5075
|
-
|
|
5076
|
-
|
|
5077
|
-
|
|
5078
|
-
|
|
5079
|
-
|
|
5080
|
-
|
|
5081
|
-
|
|
5082
|
-
|
|
5083
|
-
|
|
5084
|
-
|
|
5085
|
-
|
|
5086
|
+
async parse(input) {
|
|
5087
|
+
let result;
|
|
5088
|
+
try {
|
|
5089
|
+
result = await this.#parse(input.bytes, { ocr: this.#ocr });
|
|
5090
|
+
} catch (cause) {
|
|
5091
|
+
throw new ParseError(this.name, input.virtualPath, cause);
|
|
5092
|
+
}
|
|
5093
|
+
if (!result.success) {
|
|
5094
|
+
throw new ParseError(this.name, input.virtualPath, new Error(`${result.code ?? "PARSE_ERROR"}: ${result.error}`));
|
|
5095
|
+
}
|
|
5096
|
+
const diagnostics = (result.warnings ?? []).map((warning) => ({
|
|
5097
|
+
code: "parser-warning",
|
|
5098
|
+
severity: "warning",
|
|
5099
|
+
message: warning.code ? `${warning.code}: ${warning.message}` : warning.message
|
|
5100
|
+
}));
|
|
5101
|
+
return {
|
|
5102
|
+
markdown: result.markdown,
|
|
5103
|
+
metadata: { parser: this.name, format: result.fileType ?? "unknown" },
|
|
5104
|
+
...diagnostics.length > 0 ? { diagnostics } : {}
|
|
5105
|
+
};
|
|
5086
5106
|
}
|
|
5087
|
-
return initialization;
|
|
5088
5107
|
};
|
|
5108
|
+
});
|
|
5109
|
+
|
|
5110
|
+
// src/parser/ocr.ts
|
|
5111
|
+
import { createWorker } from "tesseract.js";
|
|
5112
|
+
function engineWithNoopCleanup(engine) {
|
|
5113
|
+
return (input) => ({ result: engine(input), cleanup: Promise.resolve() });
|
|
5089
5114
|
}
|
|
5090
|
-
function
|
|
5091
|
-
|
|
5092
|
-
const paragraphCounts = [];
|
|
5093
|
-
const counters = { characters: 0, tables: 0, cells: 0, cellParagraphs: 0 };
|
|
5094
|
-
const sectionCount = readCount(document.getSectionCount(), "section count");
|
|
5095
|
-
checkBudget("maxSections", sectionCount, limits);
|
|
5096
|
-
for (let sectionIndex = 0;sectionIndex < sectionCount; sectionIndex += 1) {
|
|
5097
|
-
const paragraphCount = readCount(document.getParagraphCount(sectionIndex), `paragraph count for section ${sectionIndex}`);
|
|
5098
|
-
paragraphCounts.push(paragraphCount);
|
|
5099
|
-
checkBudget("maxBodyParagraphs", paragraphs.length + paragraphCount, limits);
|
|
5100
|
-
for (let paragraphIndex = 0;paragraphIndex < paragraphCount; paragraphIndex += 1) {
|
|
5101
|
-
const length = readCount(document.getParagraphLength(sectionIndex, paragraphIndex), `paragraph length at ${sectionIndex}:${paragraphIndex}`);
|
|
5102
|
-
const text = readText(document.getTextRange(sectionIndex, paragraphIndex, 0, length), `paragraph text at ${sectionIndex}:${paragraphIndex}`);
|
|
5103
|
-
counters.characters += [...text].length;
|
|
5104
|
-
checkBudget("maxCharacters", counters.characters, limits);
|
|
5105
|
-
paragraphs.push({
|
|
5106
|
-
sectionIndex,
|
|
5107
|
-
paragraphIndex,
|
|
5108
|
-
text
|
|
5109
|
-
});
|
|
5110
|
-
}
|
|
5111
|
-
}
|
|
5112
|
-
return { paragraphs, tables: extractTables(document, limits, counters, paragraphCounts) };
|
|
5113
|
-
}
|
|
5114
|
-
function extractTables(document, limits, counters, paragraphCounts) {
|
|
5115
|
-
const tables = [];
|
|
5116
|
-
const seen = new Set;
|
|
5117
|
-
const pageCount = readCount(document.pageCount(), "page count");
|
|
5118
|
-
for (let pageIndex = 0;pageIndex < pageCount; pageIndex += 1) {
|
|
5119
|
-
const layout = readJsonRecord(document.getPageControlLayout(pageIndex), `page ${pageIndex} control layout`);
|
|
5120
|
-
const controls = readArray(layout.controls, `controls for page ${pageIndex}`);
|
|
5121
|
-
for (let layoutIndex = 0;layoutIndex < controls.length; layoutIndex += 1) {
|
|
5122
|
-
const control = readRecord(controls[layoutIndex], `control ${layoutIndex} on page ${pageIndex}`);
|
|
5123
|
-
if (typeof control.type !== "string") {
|
|
5124
|
-
throw new TypeError(`rhwp returned an invalid control type at page ${pageIndex}:${layoutIndex}`);
|
|
5125
|
-
}
|
|
5126
|
-
if (control.type !== "table")
|
|
5127
|
-
continue;
|
|
5128
|
-
const label = `table at page ${pageIndex}:${layoutIndex}`;
|
|
5129
|
-
const coordinates = readTableCoordinates(control, label, paragraphCounts, limits);
|
|
5130
|
-
if (coordinates === undefined)
|
|
5131
|
-
continue;
|
|
5132
|
-
const key = `${coordinates.sectionIndex}:${coordinates.parentParagraphIndex}:${coordinates.controlIndex}`;
|
|
5133
|
-
if (seen.has(key))
|
|
5134
|
-
continue;
|
|
5135
|
-
seen.add(key);
|
|
5136
|
-
counters.tables += 1;
|
|
5137
|
-
checkBudget("maxTables", counters.tables, limits);
|
|
5138
|
-
tables.push(extractTable(document, coordinates, limits, counters));
|
|
5139
|
-
}
|
|
5140
|
-
}
|
|
5141
|
-
return tables;
|
|
5115
|
+
function tesseractOcr(input) {
|
|
5116
|
+
return createTesseractOcrOperation(input);
|
|
5142
5117
|
}
|
|
5143
|
-
function
|
|
5144
|
-
|
|
5145
|
-
const hasParagraphIndex = Object.hasOwn(control, "paraIdx");
|
|
5146
|
-
const hasControlIndex = Object.hasOwn(control, "controlIdx");
|
|
5147
|
-
const coordinateCount = Number(hasSectionIndex) + Number(hasParagraphIndex) + Number(hasControlIndex);
|
|
5148
|
-
if (coordinateCount === 0) {
|
|
5149
|
-
validateDeferredNestedTable(control, label, limits);
|
|
5118
|
+
function createTesseractOcrOperation(input) {
|
|
5119
|
+
let cleanupResolve = () => {
|
|
5150
5120
|
return;
|
|
5151
|
-
}
|
|
5152
|
-
if (coordinateCount !== 3) {
|
|
5153
|
-
throw new TypeError(`rhwp returned a partial coordinate set for ${label}`);
|
|
5154
|
-
}
|
|
5155
|
-
if (Object.hasOwn(control, "cellPath") || Object.hasOwn(control, "parentParaIdx")) {
|
|
5156
|
-
throw new TypeError(`rhwp returned conflicting top-level and nested context for ${label}`);
|
|
5157
|
-
}
|
|
5158
|
-
const coordinates = {
|
|
5159
|
-
sectionIndex: readCount(control.secIdx, `secIdx for ${label}`),
|
|
5160
|
-
parentParagraphIndex: readCount(control.paraIdx, `paraIdx for ${label}`),
|
|
5161
|
-
controlIndex: readCount(control.controlIdx, `controlIdx for ${label}`)
|
|
5162
5121
|
};
|
|
5163
|
-
|
|
5164
|
-
if (paragraphCount === undefined) {
|
|
5165
|
-
throw new TypeError(`rhwp returned a section coordinate outside the announced document range for ${label}`);
|
|
5166
|
-
}
|
|
5167
|
-
if (coordinates.parentParagraphIndex >= paragraphCount) {
|
|
5168
|
-
throw new TypeError(`rhwp returned a parent paragraph coordinate outside the announced section range for ${label}`);
|
|
5169
|
-
}
|
|
5170
|
-
return coordinates;
|
|
5171
|
-
}
|
|
5172
|
-
function validateDeferredNestedTable(control, label, limits) {
|
|
5173
|
-
if (!Object.hasOwn(control, "cellPath") && !Object.hasOwn(control, "parentParaIdx")) {
|
|
5174
|
-
validateDeferredNestedLayout(control, label, limits);
|
|
5122
|
+
let cleanupReject = () => {
|
|
5175
5123
|
return;
|
|
5176
|
-
}
|
|
5177
|
-
readCount(control.parentParaIdx, `parentParaIdx for deferred nested ${label}`);
|
|
5178
|
-
const cellPath = readArray(control.cellPath, `cellPath for deferred nested ${label}`);
|
|
5179
|
-
if (cellPath.length === 0) {
|
|
5180
|
-
throw new TypeError(`rhwp returned an empty cellPath for deferred nested ${label}`);
|
|
5181
|
-
}
|
|
5182
|
-
checkBudget("maxCells", cellPath.length, limits);
|
|
5183
|
-
for (let pathIndex = 0;pathIndex < cellPath.length; pathIndex += 1) {
|
|
5184
|
-
const entry = readRecord(cellPath[pathIndex], `cellPath entry ${pathIndex} for deferred nested ${label}`);
|
|
5185
|
-
readCount(entry.controlIndex, `controlIndex in cellPath entry ${pathIndex} for deferred nested ${label}`);
|
|
5186
|
-
readCount(entry.cellIndex, `cellIndex in cellPath entry ${pathIndex} for deferred nested ${label}`);
|
|
5187
|
-
readCount(entry.cellParaIndex, `cellParaIndex in cellPath entry ${pathIndex} for deferred nested ${label}`);
|
|
5188
|
-
}
|
|
5189
|
-
}
|
|
5190
|
-
function validateDeferredNestedLayout(control, label, limits) {
|
|
5191
|
-
readFiniteNumber(control.x, `x for deferred nested ${label}`);
|
|
5192
|
-
readFiniteNumber(control.y, `y for deferred nested ${label}`);
|
|
5193
|
-
readPositiveFiniteNumber(control.w, `w for deferred nested ${label}`);
|
|
5194
|
-
readPositiveFiniteNumber(control.h, `h for deferred nested ${label}`);
|
|
5195
|
-
const rowCount = readPositiveCount(control.rowCount, `rowCount for deferred nested ${label}`);
|
|
5196
|
-
const columnCount = readPositiveCount(control.colCount, `colCount for deferred nested ${label}`);
|
|
5197
|
-
const logicalCellCount = readLogicalCellCount(rowCount, columnCount, limits);
|
|
5198
|
-
readCount(control.plane, `plane for deferred nested ${label}`);
|
|
5199
|
-
readSafeInteger(control.zOrder, `zOrder for deferred nested ${label}`);
|
|
5200
|
-
readCount(control.stableIndex, `stableIndex for deferred nested ${label}`);
|
|
5201
|
-
const cells = readArray(control.cells, `cells for deferred nested ${label}`);
|
|
5202
|
-
if (cells.length === 0) {
|
|
5203
|
-
throw new TypeError(`rhwp returned empty cells for deferred nested ${label}`);
|
|
5204
|
-
}
|
|
5205
|
-
checkBudget("maxCells", cells.length, limits);
|
|
5206
|
-
if (cells.length > logicalCellCount) {
|
|
5207
|
-
throw new TypeError(`rhwp returned too many cells for deferred nested ${label}`);
|
|
5208
|
-
}
|
|
5209
|
-
const anchors = new Set;
|
|
5210
|
-
const cellIndexes = new Set;
|
|
5211
|
-
const coveredCoordinates = new Set;
|
|
5212
|
-
for (let cellIndex = 0;cellIndex < cells.length; cellIndex += 1) {
|
|
5213
|
-
const cell = readRecord(cells[cellIndex], `cell ${cellIndex} for deferred nested ${label}`);
|
|
5214
|
-
readFiniteNumber(cell.x, `x for cell ${cellIndex} in deferred nested ${label}`);
|
|
5215
|
-
readFiniteNumber(cell.y, `y for cell ${cellIndex} in deferred nested ${label}`);
|
|
5216
|
-
readPositiveFiniteNumber(cell.w, `w for cell ${cellIndex} in deferred nested ${label}`);
|
|
5217
|
-
readPositiveFiniteNumber(cell.h, `h for cell ${cellIndex} in deferred nested ${label}`);
|
|
5218
|
-
const row = readCount(cell.row, `row for cell ${cellIndex} in deferred nested ${label}`);
|
|
5219
|
-
const column = readCount(cell.col, `col for cell ${cellIndex} in deferred nested ${label}`);
|
|
5220
|
-
const rowSpan = readPositiveCount(cell.rowSpan, `rowSpan for cell ${cellIndex} in deferred nested ${label}`);
|
|
5221
|
-
const columnSpan = readPositiveCount(cell.colSpan, `colSpan for cell ${cellIndex} in deferred nested ${label}`);
|
|
5222
|
-
const runtimeCellIndex = readCount(cell.cellIdx, `cellIdx for cell ${cellIndex} in deferred nested ${label}`);
|
|
5223
|
-
if (row >= rowCount || rowSpan > rowCount - row) {
|
|
5224
|
-
throw new TypeError(`rhwp returned an out-of-range row span for cell ${cellIndex} in deferred nested ${label}`);
|
|
5225
|
-
}
|
|
5226
|
-
if (column >= columnCount || columnSpan > columnCount - column) {
|
|
5227
|
-
throw new TypeError(`rhwp returned an out-of-range col span for cell ${cellIndex} in deferred nested ${label}`);
|
|
5228
|
-
}
|
|
5229
|
-
if (cellIndexes.has(runtimeCellIndex)) {
|
|
5230
|
-
throw new TypeError(`rhwp returned a duplicate cellIdx for deferred nested ${label}`);
|
|
5231
|
-
}
|
|
5232
|
-
cellIndexes.add(runtimeCellIndex);
|
|
5233
|
-
const anchor = `${row}:${column}`;
|
|
5234
|
-
if (anchors.has(anchor)) {
|
|
5235
|
-
throw new TypeError(`rhwp returned a duplicate cell anchor for deferred nested ${label}`);
|
|
5236
|
-
}
|
|
5237
|
-
anchors.add(anchor);
|
|
5238
|
-
for (let coveredRow = row;coveredRow < row + rowSpan; coveredRow += 1) {
|
|
5239
|
-
for (let coveredColumn = column;coveredColumn < column + columnSpan; coveredColumn += 1) {
|
|
5240
|
-
const coordinate = `${coveredRow}:${coveredColumn}`;
|
|
5241
|
-
if (coveredCoordinates.has(coordinate)) {
|
|
5242
|
-
throw new TypeError(`rhwp returned overlapping cell spans for deferred nested ${label}`);
|
|
5243
|
-
}
|
|
5244
|
-
coveredCoordinates.add(coordinate);
|
|
5245
|
-
}
|
|
5246
|
-
}
|
|
5247
|
-
}
|
|
5248
|
-
}
|
|
5249
|
-
function extractTable(document, coordinates, limits, counters) {
|
|
5250
|
-
const { sectionIndex, parentParagraphIndex, controlIndex } = coordinates;
|
|
5251
|
-
const key = `${sectionIndex}:${parentParagraphIndex}:${controlIndex}`;
|
|
5252
|
-
const dimensions = readJsonRecord(document.getTableDimensions(sectionIndex, parentParagraphIndex, controlIndex), `table dimensions at ${key}`);
|
|
5253
|
-
const rowCount = readPositiveCount(dimensions.rowCount, `rowCount for table ${key}`);
|
|
5254
|
-
const columnCount = readPositiveCount(dimensions.colCount, `colCount for table ${key}`);
|
|
5255
|
-
const cellCount = readCount(dimensions.cellCount, `cellCount for table ${key}`);
|
|
5256
|
-
const logicalCellCount = chargeLogicalCells(rowCount, columnCount, counters, limits);
|
|
5257
|
-
if (cellCount === 0 || cellCount > logicalCellCount) {
|
|
5258
|
-
throw new TypeError(`rhwp returned an invalid cellCount for table ${key}; expected 1..${logicalCellCount}, received ${cellCount}`);
|
|
5259
|
-
}
|
|
5260
|
-
const cellGeometry = [];
|
|
5261
|
-
const anchors = new Set;
|
|
5262
|
-
const coveredCoordinates = new Set;
|
|
5263
|
-
for (let cellIndex = 0;cellIndex < cellCount; cellIndex += 1) {
|
|
5264
|
-
const cellInfo = readJsonRecord(document.getCellInfo(sectionIndex, parentParagraphIndex, controlIndex, cellIndex), `cell metadata at ${key}:${cellIndex}`);
|
|
5265
|
-
const row = readCount(cellInfo.row, `row for cell ${key}:${cellIndex}`);
|
|
5266
|
-
const column = readCount(cellInfo.col, `col for cell ${key}:${cellIndex}`);
|
|
5267
|
-
const rowSpan = readPositiveCount(cellInfo.rowSpan, `rowSpan for cell ${key}:${cellIndex}`);
|
|
5268
|
-
const columnSpan = readPositiveCount(cellInfo.colSpan, `colSpan for cell ${key}:${cellIndex}`);
|
|
5269
|
-
if (row >= rowCount) {
|
|
5270
|
-
throw new TypeError(`rhwp returned a row outside the table range for cell ${key}:${cellIndex}`);
|
|
5271
|
-
}
|
|
5272
|
-
if (column >= columnCount) {
|
|
5273
|
-
throw new TypeError(`rhwp returned a col outside the table range for cell ${key}:${cellIndex}`);
|
|
5274
|
-
}
|
|
5275
|
-
if (rowSpan > rowCount - row) {
|
|
5276
|
-
throw new TypeError(`rhwp returned a rowSpan outside the table range for cell ${key}:${cellIndex}`);
|
|
5277
|
-
}
|
|
5278
|
-
if (columnSpan > columnCount - column) {
|
|
5279
|
-
throw new TypeError(`rhwp returned a colSpan outside the table range for cell ${key}:${cellIndex}`);
|
|
5280
|
-
}
|
|
5281
|
-
const anchor = row * columnCount + column;
|
|
5282
|
-
if (anchors.has(anchor)) {
|
|
5283
|
-
throw new TypeError(`rhwp returned a duplicate cell anchor for table ${key} at ${row}:${column}`);
|
|
5284
|
-
}
|
|
5285
|
-
anchors.add(anchor);
|
|
5286
|
-
for (let coveredRow = row;coveredRow < row + rowSpan; coveredRow += 1) {
|
|
5287
|
-
for (let coveredColumn = column;coveredColumn < column + columnSpan; coveredColumn += 1) {
|
|
5288
|
-
const coordinate = coveredRow * columnCount + coveredColumn;
|
|
5289
|
-
if (coveredCoordinates.has(coordinate)) {
|
|
5290
|
-
throw new TypeError(`rhwp returned overlapping cell spans for table ${key} at ${coveredRow}:${coveredColumn}`);
|
|
5291
|
-
}
|
|
5292
|
-
coveredCoordinates.add(coordinate);
|
|
5293
|
-
}
|
|
5294
|
-
}
|
|
5295
|
-
cellGeometry.push({ row, column, rowSpan, columnSpan });
|
|
5296
|
-
}
|
|
5297
|
-
if (coveredCoordinates.size !== logicalCellCount) {
|
|
5298
|
-
throw new TypeError(`rhwp returned cellCount ${cellCount} that covers ${coveredCoordinates.size} of ${logicalCellCount} logical grid coordinates for table ${key}`);
|
|
5299
|
-
}
|
|
5300
|
-
const cells = [];
|
|
5301
|
-
for (let cellIndex = 0;cellIndex < cellGeometry.length; cellIndex += 1) {
|
|
5302
|
-
const geometry = cellGeometry[cellIndex];
|
|
5303
|
-
if (geometry === undefined)
|
|
5304
|
-
throw new TypeError(`rhwp omitted cell geometry at ${key}:${cellIndex}`);
|
|
5305
|
-
const paragraphCount = readCount(document.getCellParagraphCount(sectionIndex, parentParagraphIndex, controlIndex, cellIndex), `cell paragraph count at ${key}:${cellIndex}`);
|
|
5306
|
-
counters.cellParagraphs += paragraphCount;
|
|
5307
|
-
checkBudget("maxCellParagraphs", counters.cellParagraphs, limits);
|
|
5308
|
-
const paragraphs = [];
|
|
5309
|
-
for (let cellParagraphIndex = 0;cellParagraphIndex < paragraphCount; cellParagraphIndex += 1) {
|
|
5310
|
-
const length = readCount(document.getCellParagraphLength(sectionIndex, parentParagraphIndex, controlIndex, cellIndex, cellParagraphIndex), `cell paragraph length at ${key}:${cellIndex}:${cellParagraphIndex}`);
|
|
5311
|
-
const text = readText(document.getTextInCell(sectionIndex, parentParagraphIndex, controlIndex, cellIndex, cellParagraphIndex, 0, length), `cell paragraph text at ${key}:${cellIndex}:${cellParagraphIndex}`);
|
|
5312
|
-
counters.characters += [...text].length;
|
|
5313
|
-
checkBudget("maxCharacters", counters.characters, limits);
|
|
5314
|
-
paragraphs.push(text);
|
|
5315
|
-
}
|
|
5316
|
-
cells.push({
|
|
5317
|
-
...geometry,
|
|
5318
|
-
paragraphs
|
|
5319
|
-
});
|
|
5320
|
-
}
|
|
5321
|
-
return {
|
|
5322
|
-
sectionIndex,
|
|
5323
|
-
parentParagraphIndex,
|
|
5324
|
-
controlIndex,
|
|
5325
|
-
rowCount,
|
|
5326
|
-
columnCount,
|
|
5327
|
-
cells
|
|
5328
5124
|
};
|
|
5125
|
+
const cleanup = new Promise((resolve, reject) => {
|
|
5126
|
+
cleanupResolve = resolve;
|
|
5127
|
+
cleanupReject = reject;
|
|
5128
|
+
});
|
|
5129
|
+
const result = runTesseractOcr(input, cleanupResolve, cleanupReject);
|
|
5130
|
+
return { result, cleanup };
|
|
5329
5131
|
}
|
|
5330
|
-
function
|
|
5331
|
-
|
|
5332
|
-
|
|
5333
|
-
|
|
5334
|
-
|
|
5335
|
-
|
|
5336
|
-
|
|
5337
|
-
|
|
5338
|
-
|
|
5339
|
-
|
|
5340
|
-
|
|
5341
|
-
|
|
5342
|
-
|
|
5343
|
-
|
|
5344
|
-
function resolveLimits(overrides) {
|
|
5345
|
-
const limits = { ...DEFAULT_LIMITS };
|
|
5346
|
-
for (const name of Object.keys(DEFAULT_LIMITS)) {
|
|
5347
|
-
const value = overrides[name];
|
|
5348
|
-
if (value === undefined)
|
|
5349
|
-
continue;
|
|
5350
|
-
if (!Number.isSafeInteger(value) || value <= 0) {
|
|
5351
|
-
throw new TypeError(`${name} must be a positive finite safe integer`);
|
|
5132
|
+
async function runTesseractOcr(input, cleanupResolve, cleanupReject) {
|
|
5133
|
+
let worker;
|
|
5134
|
+
let termination;
|
|
5135
|
+
const terminate = async () => {
|
|
5136
|
+
if (worker === undefined)
|
|
5137
|
+
return;
|
|
5138
|
+
termination ??= worker.terminate().then(() => {
|
|
5139
|
+
return;
|
|
5140
|
+
});
|
|
5141
|
+
await termination;
|
|
5142
|
+
};
|
|
5143
|
+
const abort = () => {
|
|
5144
|
+
if (worker !== undefined) {
|
|
5145
|
+
terminate().then(cleanupResolve, cleanupReject);
|
|
5352
5146
|
}
|
|
5353
|
-
|
|
5354
|
-
}
|
|
5355
|
-
return limits;
|
|
5356
|
-
}
|
|
5357
|
-
function checkBudget(name, actual, limits) {
|
|
5358
|
-
if (actual > limits[name])
|
|
5359
|
-
throw new HwpExtractionBudgetError(name, actual, limits[name]);
|
|
5360
|
-
}
|
|
5361
|
-
function readCount(value, label) {
|
|
5362
|
-
if (!Number.isSafeInteger(value) || value < 0) {
|
|
5363
|
-
throw new TypeError(`rhwp returned an invalid ${label}; expected a non-negative safe integer`);
|
|
5364
|
-
}
|
|
5365
|
-
return value;
|
|
5366
|
-
}
|
|
5367
|
-
function readPositiveCount(value, label) {
|
|
5368
|
-
const count = readCount(value, label);
|
|
5369
|
-
if (count === 0) {
|
|
5370
|
-
throw new TypeError(`rhwp returned an invalid ${label}; expected a positive safe integer`);
|
|
5371
|
-
}
|
|
5372
|
-
return count;
|
|
5373
|
-
}
|
|
5374
|
-
function readSafeInteger(value, label) {
|
|
5375
|
-
if (!Number.isSafeInteger(value)) {
|
|
5376
|
-
throw new TypeError(`rhwp returned an invalid ${label}; expected a safe integer`);
|
|
5377
|
-
}
|
|
5378
|
-
return value;
|
|
5379
|
-
}
|
|
5380
|
-
function readFiniteNumber(value, label) {
|
|
5381
|
-
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
5382
|
-
throw new TypeError(`rhwp returned an invalid ${label}; expected a finite number`);
|
|
5383
|
-
}
|
|
5384
|
-
return value;
|
|
5385
|
-
}
|
|
5386
|
-
function readPositiveFiniteNumber(value, label) {
|
|
5387
|
-
const number = readFiniteNumber(value, label);
|
|
5388
|
-
if (number <= 0) {
|
|
5389
|
-
throw new TypeError(`rhwp returned an invalid ${label}; expected a positive finite number`);
|
|
5390
|
-
}
|
|
5391
|
-
return number;
|
|
5392
|
-
}
|
|
5393
|
-
function readText(value, label) {
|
|
5394
|
-
if (typeof value !== "string")
|
|
5395
|
-
throw new TypeError(`rhwp returned invalid ${label}; expected a string`);
|
|
5396
|
-
return value;
|
|
5397
|
-
}
|
|
5398
|
-
function readJsonRecord(value, label) {
|
|
5399
|
-
const text = readText(value, label);
|
|
5400
|
-
let parsed;
|
|
5147
|
+
};
|
|
5148
|
+
input.signal.addEventListener("abort", abort, { once: true });
|
|
5401
5149
|
try {
|
|
5402
|
-
|
|
5403
|
-
|
|
5404
|
-
|
|
5405
|
-
|
|
5406
|
-
|
|
5407
|
-
}
|
|
5408
|
-
|
|
5409
|
-
|
|
5410
|
-
throw new TypeError(`rhwp returned invalid ${label}; expected an object`);
|
|
5150
|
+
worker = await createWorker(input.languages.join("+"));
|
|
5151
|
+
if (input.signal.aborted)
|
|
5152
|
+
throw new Error("OCR aborted before worker was ready");
|
|
5153
|
+
const result = await worker.recognize(Buffer.from(input.bytes));
|
|
5154
|
+
return result.data.text;
|
|
5155
|
+
} finally {
|
|
5156
|
+
input.signal.removeEventListener("abort", abort);
|
|
5157
|
+
await terminate().then(cleanupResolve, cleanupReject);
|
|
5411
5158
|
}
|
|
5412
|
-
return value;
|
|
5413
5159
|
}
|
|
5414
|
-
function
|
|
5415
|
-
|
|
5416
|
-
|
|
5417
|
-
|
|
5160
|
+
function withTimeout(operation, timeoutMs, onTimeout) {
|
|
5161
|
+
return new Promise((resolve, reject) => {
|
|
5162
|
+
const timeout = setTimeout(() => {
|
|
5163
|
+
onTimeout();
|
|
5164
|
+
operation.cleanup.finally(() => reject(new Error(`OCR timed out after ${timeoutMs}ms`)));
|
|
5165
|
+
}, timeoutMs);
|
|
5166
|
+
operation.result.then((value) => {
|
|
5167
|
+
clearTimeout(timeout);
|
|
5168
|
+
resolve(value);
|
|
5169
|
+
}, (error) => {
|
|
5170
|
+
clearTimeout(timeout);
|
|
5171
|
+
operation.cleanup.then(() => reject(error), (cleanupError) => reject(cleanupError));
|
|
5172
|
+
});
|
|
5173
|
+
});
|
|
5418
5174
|
}
|
|
5419
|
-
var
|
|
5420
|
-
var
|
|
5421
|
-
|
|
5422
|
-
|
|
5423
|
-
|
|
5424
|
-
|
|
5425
|
-
|
|
5426
|
-
|
|
5427
|
-
|
|
5428
|
-
|
|
5429
|
-
|
|
5430
|
-
|
|
5431
|
-
|
|
5432
|
-
|
|
5433
|
-
|
|
5434
|
-
|
|
5435
|
-
|
|
5436
|
-
this.
|
|
5437
|
-
this.limit = limit;
|
|
5438
|
-
this.actual = actual;
|
|
5439
|
-
this.maximum = maximum;
|
|
5175
|
+
var DEFAULT_OCR_TIMEOUT_MS = 30000, DEFAULT_OCR_LANGUAGES, ImageOcrParser;
|
|
5176
|
+
var init_ocr = __esm(() => {
|
|
5177
|
+
init_errors();
|
|
5178
|
+
init_text();
|
|
5179
|
+
DEFAULT_OCR_LANGUAGES = ["eng"];
|
|
5180
|
+
ImageOcrParser = class ImageOcrParser extends Parser {
|
|
5181
|
+
name = "image-ocr";
|
|
5182
|
+
extensions = [".jpg", ".jpeg", ".png", ".bmp", ".tiff", ".webp"];
|
|
5183
|
+
languages;
|
|
5184
|
+
timeoutMs;
|
|
5185
|
+
maxBytes;
|
|
5186
|
+
engine;
|
|
5187
|
+
constructor(options) {
|
|
5188
|
+
super();
|
|
5189
|
+
this.languages = options.languages ?? DEFAULT_OCR_LANGUAGES;
|
|
5190
|
+
this.timeoutMs = options.timeoutMs ?? DEFAULT_OCR_TIMEOUT_MS;
|
|
5191
|
+
this.maxBytes = options.maxBytes;
|
|
5192
|
+
this.engine = options.engine ? engineWithNoopCleanup(options.engine) : tesseractOcr;
|
|
5440
5193
|
}
|
|
5441
|
-
|
|
5442
|
-
|
|
5443
|
-
|
|
5444
|
-
|
|
5445
|
-
|
|
5446
|
-
|
|
5447
|
-
|
|
5448
|
-
|
|
5449
|
-
|
|
5194
|
+
async parse(input) {
|
|
5195
|
+
const controller = new AbortController;
|
|
5196
|
+
try {
|
|
5197
|
+
if (this.maxBytes !== undefined && input.bytes.byteLength > this.maxBytes) {
|
|
5198
|
+
throw new Error(`OCR input exceeds maxBytes budget of ${this.maxBytes}`);
|
|
5199
|
+
}
|
|
5200
|
+
const operation = this.engine({
|
|
5201
|
+
bytes: input.bytes,
|
|
5202
|
+
languages: this.languages,
|
|
5203
|
+
timeoutMs: this.timeoutMs,
|
|
5204
|
+
signal: controller.signal
|
|
5205
|
+
});
|
|
5206
|
+
const markdown = await withTimeout(operation, this.timeoutMs, () => controller.abort());
|
|
5207
|
+
return {
|
|
5208
|
+
markdown: normalizeMarkdown(markdown),
|
|
5209
|
+
metadata: { parser: this.name, languages: [...this.languages] }
|
|
5210
|
+
};
|
|
5211
|
+
} catch (cause) {
|
|
5212
|
+
throw new ParseError(this.name, input.virtualPath, cause);
|
|
5213
|
+
} finally {
|
|
5214
|
+
controller.abort();
|
|
5215
|
+
}
|
|
5450
5216
|
}
|
|
5451
5217
|
};
|
|
5452
|
-
|
|
5218
|
+
});
|
|
5219
|
+
|
|
5220
|
+
// src/parser/ocr-engines.ts
|
|
5221
|
+
function tesseractLanguageListFor(tags) {
|
|
5222
|
+
const languages = [...new Set(tags)].map((tag) => TESSERACT_LANGUAGES[tag]);
|
|
5223
|
+
if (languages.length === 0) {
|
|
5224
|
+
throw new Error("OCR provider requires at least one language.");
|
|
5225
|
+
}
|
|
5226
|
+
return languages;
|
|
5227
|
+
}
|
|
5228
|
+
function tesseractLanguageFor(tags) {
|
|
5229
|
+
return tesseractLanguageListFor(tags).join("+");
|
|
5230
|
+
}
|
|
5231
|
+
function createTesseractOcrProvider(options) {
|
|
5232
|
+
const language = tesseractLanguageFor(options.languages);
|
|
5233
|
+
const timeoutMs = options.timeoutMs ?? DEFAULT_TESSERACT_TIMEOUT_MS;
|
|
5234
|
+
const engine = options.engine ?? ((resolvedLanguage, pageImage, pageNumber, mimeType) => defaultTesseractEngine(resolvedLanguage, pageImage, pageNumber, mimeType, timeoutMs));
|
|
5235
|
+
return (pageImage, pageNumber, mimeType) => engine(language, pageImage, pageNumber, mimeType);
|
|
5236
|
+
}
|
|
5237
|
+
async function defaultTesseractEngine(language, pageImage, _pageNumber, _mimeType, timeoutMs) {
|
|
5238
|
+
const controller = new AbortController;
|
|
5239
|
+
const operation = createTesseractOcrOperation({
|
|
5240
|
+
bytes: pageImage,
|
|
5241
|
+
languages: [language],
|
|
5242
|
+
timeoutMs,
|
|
5243
|
+
signal: controller.signal
|
|
5244
|
+
});
|
|
5245
|
+
return withTimeout(operation, timeoutMs, () => controller.abort());
|
|
5246
|
+
}
|
|
5247
|
+
var TESSERACT_LANGUAGES, DEFAULT_TESSERACT_TIMEOUT_MS = 30000;
|
|
5248
|
+
var init_ocr_engines = __esm(() => {
|
|
5249
|
+
init_ocr();
|
|
5250
|
+
TESSERACT_LANGUAGES = {
|
|
5251
|
+
ko: "kor",
|
|
5252
|
+
en: "eng",
|
|
5253
|
+
ja: "jpn",
|
|
5254
|
+
"zh-hans": "chi_sim",
|
|
5255
|
+
"zh-hant": "chi_tra",
|
|
5256
|
+
fr: "fra",
|
|
5257
|
+
de: "deu",
|
|
5258
|
+
es: "spa",
|
|
5259
|
+
ru: "rus",
|
|
5260
|
+
it: "ita",
|
|
5261
|
+
pt: "por",
|
|
5262
|
+
vi: "vie",
|
|
5263
|
+
th: "tha",
|
|
5264
|
+
ar: "ara",
|
|
5265
|
+
hi: "hin"
|
|
5266
|
+
};
|
|
5453
5267
|
});
|
|
5454
5268
|
|
|
5455
5269
|
// src/parser/xml-text.ts
|
|
@@ -5552,38 +5366,22 @@ var init_xml_text = __esm(() => {
|
|
|
5552
5366
|
});
|
|
5553
5367
|
});
|
|
5554
5368
|
|
|
5555
|
-
// src/parser/
|
|
5556
|
-
|
|
5557
|
-
var
|
|
5558
|
-
var init_hwp = __esm(() => {
|
|
5369
|
+
// src/parser/office.ts
|
|
5370
|
+
var PptxParser;
|
|
5371
|
+
var init_office = __esm(() => {
|
|
5559
5372
|
init_errors();
|
|
5560
|
-
init_rhwp_adapter();
|
|
5561
5373
|
init_text();
|
|
5562
5374
|
init_xml_text();
|
|
5563
|
-
|
|
5564
|
-
name = "
|
|
5565
|
-
extensions = [".
|
|
5566
|
-
extractor;
|
|
5567
|
-
constructor(options = {}) {
|
|
5568
|
-
super();
|
|
5569
|
-
this.extractor = options.extractor ?? createRhwpExtractor(undefined, options.limits);
|
|
5570
|
-
}
|
|
5375
|
+
PptxParser = class PptxParser extends Parser {
|
|
5376
|
+
name = "pptx";
|
|
5377
|
+
extensions = [".pptx"];
|
|
5571
5378
|
async parse(input) {
|
|
5572
5379
|
try {
|
|
5573
|
-
|
|
5574
|
-
|
|
5575
|
-
return {
|
|
5576
|
-
markdown: normalizeMarkdown(renderHwpMarkdown(document)),
|
|
5577
|
-
metadata: { parser: this.name, format: "hwp5" }
|
|
5578
|
-
};
|
|
5579
|
-
}
|
|
5580
|
-
const chunks = await readZipXmlText(input.bytes, /^(?:Contents|content)\/.*\.xml$/i);
|
|
5581
|
-
return {
|
|
5582
|
-
markdown: normalizeMarkdown(chunks.join(`
|
|
5380
|
+
const chunks = await readZipXmlText(input.bytes, /^ppt\/(?:slides\/slide\d+|notesSlides\/notesSlide\d+)\.xml$/);
|
|
5381
|
+
const markdown = normalizeMarkdown(chunks.filter((chunk) => chunk.trim().length > 0).join(`
|
|
5583
5382
|
|
|
5584
|
-
`))
|
|
5585
|
-
|
|
5586
|
-
};
|
|
5383
|
+
`));
|
|
5384
|
+
return { markdown, metadata: { parser: this.name } };
|
|
5587
5385
|
} catch (cause) {
|
|
5588
5386
|
throw new ParseError(this.name, input.virtualPath, cause);
|
|
5589
5387
|
}
|
|
@@ -5591,340 +5389,21 @@ var init_hwp = __esm(() => {
|
|
|
5591
5389
|
};
|
|
5592
5390
|
});
|
|
5593
5391
|
|
|
5594
|
-
// src/parser/
|
|
5595
|
-
|
|
5596
|
-
|
|
5597
|
-
|
|
5598
|
-
|
|
5599
|
-
|
|
5600
|
-
|
|
5601
|
-
|
|
5602
|
-
|
|
5603
|
-
|
|
5604
|
-
return;
|
|
5605
|
-
};
|
|
5606
|
-
const cleanup = new Promise((resolve, reject) => {
|
|
5607
|
-
cleanupResolve = resolve;
|
|
5608
|
-
cleanupReject = reject;
|
|
5609
|
-
});
|
|
5610
|
-
const result = runTesseractOcr(input, cleanupResolve, cleanupReject);
|
|
5611
|
-
return { result, cleanup };
|
|
5612
|
-
}
|
|
5613
|
-
async function runTesseractOcr(input, cleanupResolve, cleanupReject) {
|
|
5614
|
-
let worker;
|
|
5615
|
-
let termination;
|
|
5616
|
-
const terminate = async () => {
|
|
5617
|
-
if (worker === undefined)
|
|
5618
|
-
return;
|
|
5619
|
-
termination ??= worker.terminate().then(() => {
|
|
5620
|
-
return;
|
|
5621
|
-
});
|
|
5622
|
-
await termination;
|
|
5623
|
-
};
|
|
5624
|
-
const abort = () => {
|
|
5625
|
-
if (worker !== undefined) {
|
|
5626
|
-
terminate().then(cleanupResolve, cleanupReject);
|
|
5627
|
-
}
|
|
5628
|
-
};
|
|
5629
|
-
input.signal.addEventListener("abort", abort, { once: true });
|
|
5630
|
-
try {
|
|
5631
|
-
worker = await createWorker(input.languages.join("+"));
|
|
5632
|
-
if (input.signal.aborted)
|
|
5633
|
-
throw new Error("OCR aborted before worker was ready");
|
|
5634
|
-
const result = await worker.recognize(Buffer.from(input.bytes));
|
|
5635
|
-
return result.data.text;
|
|
5636
|
-
} finally {
|
|
5637
|
-
input.signal.removeEventListener("abort", abort);
|
|
5638
|
-
await terminate().then(cleanupResolve, cleanupReject);
|
|
5639
|
-
}
|
|
5640
|
-
}
|
|
5641
|
-
function withTimeout(operation, timeoutMs, onTimeout) {
|
|
5642
|
-
return new Promise((resolve, reject) => {
|
|
5643
|
-
const timeout = setTimeout(() => {
|
|
5644
|
-
onTimeout();
|
|
5645
|
-
operation.cleanup.finally(() => reject(new Error(`OCR timed out after ${timeoutMs}ms`)));
|
|
5646
|
-
}, timeoutMs);
|
|
5647
|
-
operation.result.then((value) => {
|
|
5648
|
-
clearTimeout(timeout);
|
|
5649
|
-
resolve(value);
|
|
5650
|
-
}, (error) => {
|
|
5651
|
-
clearTimeout(timeout);
|
|
5652
|
-
operation.cleanup.then(() => reject(error), (cleanupError) => reject(cleanupError));
|
|
5653
|
-
});
|
|
5654
|
-
});
|
|
5655
|
-
}
|
|
5656
|
-
var DEFAULT_OCR_TIMEOUT_MS = 30000, DEFAULT_OCR_LANGUAGES, ImageOcrParser;
|
|
5657
|
-
var init_ocr = __esm(() => {
|
|
5658
|
-
init_errors();
|
|
5659
|
-
init_text();
|
|
5660
|
-
DEFAULT_OCR_LANGUAGES = ["eng"];
|
|
5661
|
-
ImageOcrParser = class ImageOcrParser extends Parser {
|
|
5662
|
-
name = "image-ocr";
|
|
5663
|
-
extensions = [".jpg", ".jpeg", ".png", ".bmp", ".tiff"];
|
|
5664
|
-
languages;
|
|
5665
|
-
timeoutMs;
|
|
5666
|
-
maxBytes;
|
|
5667
|
-
engine;
|
|
5668
|
-
constructor(options) {
|
|
5669
|
-
super();
|
|
5670
|
-
this.languages = options.languages ?? DEFAULT_OCR_LANGUAGES;
|
|
5671
|
-
this.timeoutMs = options.timeoutMs ?? DEFAULT_OCR_TIMEOUT_MS;
|
|
5672
|
-
this.maxBytes = options.maxBytes;
|
|
5673
|
-
this.engine = options.engine ? engineWithNoopCleanup(options.engine) : tesseractOcr;
|
|
5674
|
-
}
|
|
5675
|
-
async parse(input) {
|
|
5676
|
-
const controller = new AbortController;
|
|
5677
|
-
try {
|
|
5678
|
-
if (this.maxBytes !== undefined && input.bytes.byteLength > this.maxBytes) {
|
|
5679
|
-
throw new Error(`OCR input exceeds maxBytes budget of ${this.maxBytes}`);
|
|
5680
|
-
}
|
|
5681
|
-
const operation = this.engine({
|
|
5682
|
-
bytes: input.bytes,
|
|
5683
|
-
languages: this.languages,
|
|
5684
|
-
timeoutMs: this.timeoutMs,
|
|
5685
|
-
signal: controller.signal
|
|
5686
|
-
});
|
|
5687
|
-
const markdown = await withTimeout(operation, this.timeoutMs, () => controller.abort());
|
|
5688
|
-
return {
|
|
5689
|
-
markdown: normalizeMarkdown(markdown),
|
|
5690
|
-
metadata: { parser: this.name, languages: [...this.languages] }
|
|
5691
|
-
};
|
|
5692
|
-
} catch (cause) {
|
|
5693
|
-
throw new ParseError(this.name, input.virtualPath, cause);
|
|
5694
|
-
} finally {
|
|
5695
|
-
controller.abort();
|
|
5696
|
-
}
|
|
5697
|
-
}
|
|
5698
|
-
};
|
|
5699
|
-
});
|
|
5700
|
-
|
|
5701
|
-
// src/parser/office.ts
|
|
5702
|
-
import { extname as extname4 } from "node:path";
|
|
5703
|
-
import * as XLSX from "xlsx";
|
|
5704
|
-
function formatLegacyXls(bytes) {
|
|
5705
|
-
const oleMagic = [208, 207, 17, 224, 161, 177, 26, 225];
|
|
5706
|
-
if (bytes.length < oleMagic.length || !oleMagic.every((byte, index) => bytes[index] === byte)) {
|
|
5707
|
-
throw new Error("legacy XLS input is not an OLE compound document");
|
|
5708
|
-
}
|
|
5709
|
-
const workbook = XLSX.read(Buffer.from(bytes), { type: "buffer", cellText: true, cellDates: true });
|
|
5710
|
-
const markdown = workbook.SheetNames.map((sheetName) => {
|
|
5711
|
-
const worksheet = workbook.Sheets[sheetName];
|
|
5712
|
-
if (!worksheet)
|
|
5713
|
-
return `## ${sheetName}`;
|
|
5714
|
-
const rows = XLSX.utils.sheet_to_json(worksheet, {
|
|
5715
|
-
header: 1,
|
|
5716
|
-
raw: false,
|
|
5717
|
-
blankrows: false,
|
|
5718
|
-
defval: ""
|
|
5719
|
-
});
|
|
5720
|
-
const lines = rows.map((row) => formatLegacyXlsRow(row)).filter((row) => row !== undefined);
|
|
5721
|
-
return [`## ${sheetName}`, ...lines].join(`
|
|
5722
|
-
`);
|
|
5723
|
-
}).join(`
|
|
5724
|
-
|
|
5725
|
-
`);
|
|
5726
|
-
return { markdown: normalizeMarkdown(markdown), metadata: { parser: "xlsx", format: "xls" } };
|
|
5727
|
-
}
|
|
5728
|
-
function formatLegacyXlsRow(row) {
|
|
5729
|
-
let lastContentIndex = -1;
|
|
5730
|
-
for (let index = row.length - 1;index >= 0; index -= 1) {
|
|
5731
|
-
if (String(row[index] ?? "").length > 0) {
|
|
5732
|
-
lastContentIndex = index;
|
|
5733
|
-
break;
|
|
5734
|
-
}
|
|
5735
|
-
}
|
|
5736
|
-
if (lastContentIndex < 0)
|
|
5737
|
-
return;
|
|
5738
|
-
return row.slice(0, lastContentIndex + 1).map((cell) => escapeMarkdownTableCell(String(cell ?? ""))).join(" | ");
|
|
5739
|
-
}
|
|
5740
|
-
function escapeMarkdownTableCell(value) {
|
|
5741
|
-
return value.replaceAll("\\", "\\\\").replaceAll("|", "\\|").replace(/\r\n|\r|\n/g, "<br>");
|
|
5742
|
-
}
|
|
5743
|
-
function formatMarkdown(parserName, chunks) {
|
|
5744
|
-
const markdown = normalizeMarkdown(chunks.filter((chunk) => chunk.trim().length > 0).join(`
|
|
5745
|
-
|
|
5746
|
-
`));
|
|
5747
|
-
return { markdown, metadata: { parser: parserName } };
|
|
5748
|
-
}
|
|
5749
|
-
var DocxParser, PptxParser, XlsxParser;
|
|
5750
|
-
var init_office = __esm(() => {
|
|
5751
|
-
init_errors();
|
|
5752
|
-
init_text();
|
|
5753
|
-
init_xml_text();
|
|
5754
|
-
DocxParser = class DocxParser extends Parser {
|
|
5755
|
-
name = "docx";
|
|
5756
|
-
extensions = [".docx"];
|
|
5757
|
-
async parse(input) {
|
|
5758
|
-
try {
|
|
5759
|
-
const chunks = await readZipXmlText(input.bytes, /^word\/(?:document|header\d+|footer\d+)\.xml$/);
|
|
5760
|
-
return formatMarkdown(this.name, chunks);
|
|
5761
|
-
} catch (cause) {
|
|
5762
|
-
throw new ParseError(this.name, input.virtualPath, cause);
|
|
5763
|
-
}
|
|
5764
|
-
}
|
|
5765
|
-
};
|
|
5766
|
-
PptxParser = class PptxParser extends Parser {
|
|
5767
|
-
name = "pptx";
|
|
5768
|
-
extensions = [".pptx"];
|
|
5769
|
-
async parse(input) {
|
|
5770
|
-
try {
|
|
5771
|
-
const chunks = await readZipXmlText(input.bytes, /^ppt\/(?:slides\/slide\d+|notesSlides\/notesSlide\d+)\.xml$/);
|
|
5772
|
-
return formatMarkdown(this.name, chunks);
|
|
5773
|
-
} catch (cause) {
|
|
5774
|
-
throw new ParseError(this.name, input.virtualPath, cause);
|
|
5775
|
-
}
|
|
5776
|
-
}
|
|
5777
|
-
};
|
|
5778
|
-
XlsxParser = class XlsxParser extends Parser {
|
|
5779
|
-
name = "xlsx";
|
|
5780
|
-
extensions = [".xlsx", ".xls"];
|
|
5781
|
-
async parse(input) {
|
|
5782
|
-
try {
|
|
5783
|
-
if (extname4(input.virtualPath).toLowerCase() === ".xls") {
|
|
5784
|
-
return formatLegacyXls(input.bytes);
|
|
5785
|
-
}
|
|
5786
|
-
const sharedStrings = await readZipXmlText(input.bytes, /^xl\/sharedStrings\.xml$/);
|
|
5787
|
-
const sheetText = await readZipXmlText(input.bytes, /^xl\/worksheets\/sheet\d+\.xml$/);
|
|
5788
|
-
return formatMarkdown(this.name, [...sharedStrings, ...sheetText]);
|
|
5789
|
-
} catch (cause) {
|
|
5790
|
-
throw new ParseError(this.name, input.virtualPath, cause);
|
|
5791
|
-
}
|
|
5792
|
-
}
|
|
5793
|
-
};
|
|
5794
|
-
});
|
|
5795
|
-
|
|
5796
|
-
// src/parser/opendataloader-pdf.ts
|
|
5797
|
-
import { mkdtemp as mkdtemp2, readFile as readFile4, rm as rm3, writeFile as writeFile3 } from "node:fs/promises";
|
|
5798
|
-
import { tmpdir as tmpdir2 } from "node:os";
|
|
5799
|
-
import { basename as basename8, join as join16, parse as parse2 } from "node:path";
|
|
5800
|
-
import { convert } from "@opendataloader/pdf";
|
|
5801
|
-
async function readMarkdown(outputDir, inputPath) {
|
|
5802
|
-
return readFile4(markdownOutputPath(outputDir, inputPath), "utf8");
|
|
5803
|
-
}
|
|
5804
|
-
function countPdfPages(bytes) {
|
|
5805
|
-
const text = Buffer.from(bytes).toString("latin1");
|
|
5806
|
-
return Math.max(1, [...text.matchAll(/\/Type\s*\/Page\b/gu)].length);
|
|
5807
|
-
}
|
|
5808
|
-
async function withTimeout2(operation, timeoutMs) {
|
|
5809
|
-
let timer;
|
|
5810
|
-
try {
|
|
5811
|
-
return await Promise.race([
|
|
5812
|
-
operation,
|
|
5813
|
-
new Promise((_, reject) => {
|
|
5814
|
-
timer = setTimeout(() => reject(new Error(`PDF hybrid extraction timed out after ${timeoutMs}ms`)), timeoutMs);
|
|
5815
|
-
})
|
|
5816
|
-
]);
|
|
5817
|
-
} finally {
|
|
5818
|
-
if (timer !== undefined)
|
|
5819
|
-
clearTimeout(timer);
|
|
5820
|
-
}
|
|
5821
|
-
}
|
|
5822
|
-
function markdownOutputPath(outputDir, inputPath) {
|
|
5823
|
-
return join16(outputDir, `${parse2(inputPath).name}.md`);
|
|
5824
|
-
}
|
|
5825
|
-
var OpendataloaderPdfParser;
|
|
5826
|
-
var init_opendataloader_pdf = __esm(() => {
|
|
5827
|
-
init_errors();
|
|
5828
|
-
init_text();
|
|
5829
|
-
OpendataloaderPdfParser = class OpendataloaderPdfParser extends Parser {
|
|
5830
|
-
name = "opendataloader-pdf";
|
|
5831
|
-
extensions = [".pdf"];
|
|
5832
|
-
options;
|
|
5833
|
-
converter;
|
|
5834
|
-
constructor(options = {}) {
|
|
5835
|
-
super();
|
|
5836
|
-
this.options = options;
|
|
5837
|
-
this.converter = options.converter ?? convert;
|
|
5838
|
-
}
|
|
5839
|
-
async parse(input) {
|
|
5840
|
-
const tempRoot = await mkdtemp2(join16(tmpdir2(), "autorag-pdf-"));
|
|
5841
|
-
try {
|
|
5842
|
-
const inputPath = input.sourcePath ?? join16(tempRoot, basename8(input.virtualPath));
|
|
5843
|
-
if (!input.sourcePath) {
|
|
5844
|
-
await writeFile3(inputPath, input.bytes);
|
|
5845
|
-
}
|
|
5846
|
-
if (this.options.ocr?.enabled && this.options.ocr.maxBytes !== undefined && input.bytes.byteLength > this.options.ocr.maxBytes) {
|
|
5847
|
-
throw new Error(`PDF OCR input exceeds maxBytes budget of ${this.options.ocr.maxBytes}`);
|
|
5848
|
-
}
|
|
5849
|
-
const localOptions = {
|
|
5850
|
-
outputDir: tempRoot,
|
|
5851
|
-
format: "markdown",
|
|
5852
|
-
quiet: true,
|
|
5853
|
-
imageOutput: "off",
|
|
5854
|
-
...this.options.ocr?.enabled ? {
|
|
5855
|
-
hybrid: this.options.ocr.hybrid ?? "docling-fast",
|
|
5856
|
-
hybridMode: this.options.ocr.hybridMode ?? "auto",
|
|
5857
|
-
hybridTimeout: String(this.options.ocr.timeoutMs ?? 30000)
|
|
5858
|
-
} : {}
|
|
5859
|
-
};
|
|
5860
|
-
await this.converter(inputPath, localOptions);
|
|
5861
|
-
const localMarkdown = normalizeMarkdown(await readMarkdown(tempRoot, inputPath));
|
|
5862
|
-
const pages = countPdfPages(input.bytes);
|
|
5863
|
-
const thin = this.options.thinExtract;
|
|
5864
|
-
const shouldRetry = this.options.ocr?.enabled !== true && thin?.enabled !== false && pages >= (thin?.minPages ?? 3) && (localMarkdown.length < (thin?.minChars ?? 800) || localMarkdown.length / pages < (thin?.minCharsPerPage ?? 40));
|
|
5865
|
-
if (shouldRetry) {
|
|
5866
|
-
try {
|
|
5867
|
-
await withTimeout2(this.converter(inputPath, {
|
|
5868
|
-
...localOptions,
|
|
5869
|
-
hybrid: thin?.hybrid ?? "docling-fast",
|
|
5870
|
-
hybridMode: thin?.hybridMode ?? "auto",
|
|
5871
|
-
hybridTimeout: String(thin?.timeoutMs ?? 30000)
|
|
5872
|
-
}), thin?.timeoutMs ?? 30000);
|
|
5873
|
-
return {
|
|
5874
|
-
markdown: normalizeMarkdown(await readMarkdown(tempRoot, inputPath)),
|
|
5875
|
-
metadata: { parser: this.name, pages, pdfExtract: "hybrid-retry" }
|
|
5876
|
-
};
|
|
5877
|
-
} catch {
|
|
5878
|
-
return {
|
|
5879
|
-
markdown: localMarkdown,
|
|
5880
|
-
metadata: {
|
|
5881
|
-
parser: this.name,
|
|
5882
|
-
pages,
|
|
5883
|
-
pdfExtract: "thin-local-fallback"
|
|
5884
|
-
},
|
|
5885
|
-
diagnostics: [
|
|
5886
|
-
{
|
|
5887
|
-
code: "pdf-extract-thin",
|
|
5888
|
-
severity: "warning",
|
|
5889
|
-
message: `Local PDF extraction yielded only ${localMarkdown.length} characters across ${pages} pages.`
|
|
5890
|
-
},
|
|
5891
|
-
{
|
|
5892
|
-
code: "pdf-hybrid-unavailable",
|
|
5893
|
-
severity: "warning",
|
|
5894
|
-
message: "Hybrid PDF extraction was unavailable; local markdown was retained."
|
|
5895
|
-
}
|
|
5896
|
-
]
|
|
5897
|
-
};
|
|
5898
|
-
}
|
|
5899
|
-
}
|
|
5900
|
-
return {
|
|
5901
|
-
markdown: localMarkdown,
|
|
5902
|
-
metadata: { parser: this.name, pages }
|
|
5903
|
-
};
|
|
5904
|
-
} catch (cause) {
|
|
5905
|
-
throw new ParseError(this.name, input.virtualPath, cause);
|
|
5906
|
-
} finally {
|
|
5907
|
-
await rm3(tempRoot, { recursive: true, force: true });
|
|
5908
|
-
}
|
|
5909
|
-
}
|
|
5910
|
-
};
|
|
5911
|
-
});
|
|
5912
|
-
|
|
5913
|
-
// src/parser/plain-text.ts
|
|
5914
|
-
var PlainTextParser;
|
|
5915
|
-
var init_plain_text = __esm(() => {
|
|
5916
|
-
init_text();
|
|
5917
|
-
PlainTextParser = class PlainTextParser extends Parser {
|
|
5918
|
-
name = "plain-text";
|
|
5919
|
-
extensions = [".txt", ".text", ".md", ".markdown"];
|
|
5920
|
-
async parse(input) {
|
|
5921
|
-
return { markdown: decodeText(input.bytes), metadata: { parser: this.name } };
|
|
5922
|
-
}
|
|
5392
|
+
// src/parser/plain-text.ts
|
|
5393
|
+
var PlainTextParser;
|
|
5394
|
+
var init_plain_text = __esm(() => {
|
|
5395
|
+
init_text();
|
|
5396
|
+
PlainTextParser = class PlainTextParser extends Parser {
|
|
5397
|
+
name = "plain-text";
|
|
5398
|
+
extensions = [".txt", ".text", ".md", ".markdown"];
|
|
5399
|
+
async parse(input) {
|
|
5400
|
+
return { markdown: decodeText(input.bytes), metadata: { parser: this.name } };
|
|
5401
|
+
}
|
|
5923
5402
|
};
|
|
5924
5403
|
});
|
|
5925
5404
|
|
|
5926
5405
|
// src/parser/registry.ts
|
|
5927
|
-
import { extname as
|
|
5406
|
+
import { extname as extname3 } from "node:path";
|
|
5928
5407
|
|
|
5929
5408
|
class ParserRegistry {
|
|
5930
5409
|
parsersByExtension = new Map;
|
|
@@ -5943,7 +5422,7 @@ class ParserRegistry {
|
|
|
5943
5422
|
}
|
|
5944
5423
|
}
|
|
5945
5424
|
getForVirtualPath(virtualPath) {
|
|
5946
|
-
return this.parsersByExtension.get(normalizeExtension(
|
|
5425
|
+
return this.parsersByExtension.get(normalizeExtension(extname3(virtualPath)));
|
|
5947
5426
|
}
|
|
5948
5427
|
list() {
|
|
5949
5428
|
return Array.from(new Set(this.parsersByExtension.values()));
|
|
@@ -5956,26 +5435,38 @@ function normalizeExtension(extension) {
|
|
|
5956
5435
|
var init_registry = () => {};
|
|
5957
5436
|
|
|
5958
5437
|
// src/parser/defaults.ts
|
|
5438
|
+
function resolveParserOptions(parserOptions, languages) {
|
|
5439
|
+
return { ...parserOptions, languages: parserOptions?.languages ?? languages };
|
|
5440
|
+
}
|
|
5959
5441
|
function createDefaultParserRegistry(options = {}) {
|
|
5442
|
+
const languages = options.languages ?? DEFAULT_LANGUAGES;
|
|
5443
|
+
const ocrEnabled = options.ocr?.enabled === true;
|
|
5444
|
+
const kordocOptions = {
|
|
5445
|
+
...options.kordoc,
|
|
5446
|
+
...options.kordoc?.ocr === undefined && ocrEnabled ? { ocr: createTesseractOcrProvider({ languages, timeoutMs: options.ocr?.timeoutMs }) } : {}
|
|
5447
|
+
};
|
|
5960
5448
|
const parsers = [
|
|
5961
5449
|
new PlainTextParser,
|
|
5962
|
-
new
|
|
5963
|
-
new DocxParser,
|
|
5450
|
+
new KordocParser(kordocOptions),
|
|
5964
5451
|
new PptxParser,
|
|
5965
|
-
new XlsxParser,
|
|
5966
|
-
new HwpParser(options.hwp),
|
|
5967
5452
|
new EmlParser
|
|
5968
5453
|
];
|
|
5969
|
-
if (
|
|
5970
|
-
parsers.push(new ImageOcrParser(
|
|
5454
|
+
if (ocrEnabled) {
|
|
5455
|
+
parsers.push(new ImageOcrParser({
|
|
5456
|
+
...options.ocr,
|
|
5457
|
+
enabled: true,
|
|
5458
|
+
languages: options.ocr?.languages ?? tesseractLanguageListFor(languages)
|
|
5459
|
+
}));
|
|
5460
|
+
}
|
|
5971
5461
|
return new ParserRegistry(parsers);
|
|
5972
5462
|
}
|
|
5973
5463
|
var init_defaults = __esm(() => {
|
|
5464
|
+
init_language();
|
|
5974
5465
|
init_eml();
|
|
5975
|
-
|
|
5466
|
+
init_kordoc();
|
|
5976
5467
|
init_ocr();
|
|
5468
|
+
init_ocr_engines();
|
|
5977
5469
|
init_office();
|
|
5978
|
-
init_opendataloader_pdf();
|
|
5979
5470
|
init_plain_text();
|
|
5980
5471
|
init_registry();
|
|
5981
5472
|
});
|
|
@@ -5983,17 +5474,8 @@ var init_defaults = __esm(() => {
|
|
|
5983
5474
|
// src/mirror/sync.ts
|
|
5984
5475
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
5985
5476
|
import { existsSync as existsSync12, mkdirSync as mkdirSync6, renameSync as renameSync5, rmSync as rmSync3, writeFileSync as writeFileSync6 } from "node:fs";
|
|
5986
|
-
import { opendir, readFile as
|
|
5987
|
-
import { dirname as dirname7, extname as
|
|
5988
|
-
function parserFailureCode(parser, error) {
|
|
5989
|
-
return parser.name === "opendataloader-pdf" && /UnsupportedClassVersionError/.test(error.message) ? "pdf-java-version" : "parser-failed";
|
|
5990
|
-
}
|
|
5991
|
-
function parserFailureMessage(parser, error) {
|
|
5992
|
-
if (parserFailureCode(parser, error) === "pdf-java-version") {
|
|
5993
|
-
return "PDF parsing requires Java 11 or newer; the Java runtime selected from PATH is too old.";
|
|
5994
|
-
}
|
|
5995
|
-
return "The registered parser failed on this file; it was skipped during indexing.";
|
|
5996
|
-
}
|
|
5477
|
+
import { opendir, readFile as readFile3, stat as stat4 } from "node:fs/promises";
|
|
5478
|
+
import { dirname as dirname7, extname as extname4, resolve as resolve9 } from "node:path";
|
|
5997
5479
|
async function syncParsedMirrors(options) {
|
|
5998
5480
|
const registry = options.registry ?? createDefaultParserRegistry(options.parserOptions);
|
|
5999
5481
|
const maxSourceBytes = options.maxSourceBytes ?? DEFAULT_MAX_SOURCE_BYTES;
|
|
@@ -6075,7 +5557,7 @@ async function syncParsedMirrors(options) {
|
|
|
6075
5557
|
if (!unchanged) {
|
|
6076
5558
|
let parsed;
|
|
6077
5559
|
try {
|
|
6078
|
-
const bytes = await
|
|
5560
|
+
const bytes = await readFile3(entry.sourcePath);
|
|
6079
5561
|
parsed = await parser.parse({ virtualPath: entry.virtualPath, sourcePath: entry.sourcePath, bytes });
|
|
6080
5562
|
} catch (error) {
|
|
6081
5563
|
if (!(error instanceof ParseError))
|
|
@@ -6085,9 +5567,9 @@ async function syncParsedMirrors(options) {
|
|
|
6085
5567
|
skipped += 1;
|
|
6086
5568
|
recordSkip(entry, "parser-failed");
|
|
6087
5569
|
diagnostics.push({
|
|
6088
|
-
code:
|
|
5570
|
+
code: "parser-failed",
|
|
6089
5571
|
severity: "warning",
|
|
6090
|
-
message:
|
|
5572
|
+
message: PARSER_FAILURE_MESSAGE,
|
|
6091
5573
|
source: entry.virtualPath
|
|
6092
5574
|
});
|
|
6093
5575
|
sinceCheckpoint += 1;
|
|
@@ -6214,7 +5696,7 @@ async function collectFiles(sourceRoot, directory, entries, supportedExtensions)
|
|
|
6214
5696
|
}
|
|
6215
5697
|
if (!entry.isFile())
|
|
6216
5698
|
continue;
|
|
6217
|
-
const extension = normalizeExtension2(
|
|
5699
|
+
const extension = normalizeExtension2(extname4(entry.name));
|
|
6218
5700
|
if (!supportedExtensions.has(extension))
|
|
6219
5701
|
continue;
|
|
6220
5702
|
let fileStat;
|
|
@@ -6248,7 +5730,7 @@ function removeFile(path) {
|
|
|
6248
5730
|
if (existsSync12(path))
|
|
6249
5731
|
rmSync3(path, { force: true });
|
|
6250
5732
|
}
|
|
6251
|
-
var DEFAULT_MAX_SOURCE_BYTES, MIRROR_CHECKPOINT_EVERY = 25, PRODUCT_ARTIFACT_FILE_NAMES, SKIP_DIR_NAMES;
|
|
5733
|
+
var DEFAULT_MAX_SOURCE_BYTES, MIRROR_CHECKPOINT_EVERY = 25, PRODUCT_ARTIFACT_FILE_NAMES, SKIP_DIR_NAMES, PARSER_FAILURE_MESSAGE = "The registered parser failed on this file; it was skipped during indexing.";
|
|
6252
5734
|
var init_sync = __esm(() => {
|
|
6253
5735
|
init_source_paths();
|
|
6254
5736
|
init_defaults();
|
|
@@ -6534,6 +6016,18 @@ var init_injection_classifier = __esm(() => {
|
|
|
6534
6016
|
});
|
|
6535
6017
|
});
|
|
6536
6018
|
|
|
6019
|
+
// src/parser/index.ts
|
|
6020
|
+
var init_parser = __esm(() => {
|
|
6021
|
+
init_defaults();
|
|
6022
|
+
init_eml();
|
|
6023
|
+
init_errors();
|
|
6024
|
+
init_kordoc();
|
|
6025
|
+
init_ocr();
|
|
6026
|
+
init_office();
|
|
6027
|
+
init_plain_text();
|
|
6028
|
+
init_registry();
|
|
6029
|
+
});
|
|
6030
|
+
|
|
6537
6031
|
// src/retrieval/skip.ts
|
|
6538
6032
|
function retrievalSurfaceFor(descriptor) {
|
|
6539
6033
|
const datasourceId = descriptor.datasourceId;
|
|
@@ -7664,11 +7158,11 @@ var init_jikji_find_tool = __esm(() => {
|
|
|
7664
7158
|
// src/agent/local-model.ts
|
|
7665
7159
|
import { readFileSync as readFileSync9 } from "node:fs";
|
|
7666
7160
|
import { homedir as homedir2 } from "node:os";
|
|
7667
|
-
import { join as
|
|
7668
|
-
import { parse as
|
|
7161
|
+
import { join as join16 } from "node:path";
|
|
7162
|
+
import { parse as parse2 } from "smol-toml";
|
|
7669
7163
|
function loadLocalAutoRAGModel(options = {}) {
|
|
7670
|
-
const configPath = options.configPath ??
|
|
7671
|
-
const config =
|
|
7164
|
+
const configPath = options.configPath ?? join16(homedir2(), ".codex", "config.toml");
|
|
7165
|
+
const config = parse2(readFileSync9(configPath, "utf8"));
|
|
7672
7166
|
const provider = config.model_provider;
|
|
7673
7167
|
if (typeof provider !== "string" || provider.length === 0) {
|
|
7674
7168
|
throw new Error(`AutoRAG requires model_provider in ${configPath}`);
|
|
@@ -7719,18 +7213,18 @@ import {
|
|
|
7719
7213
|
watch,
|
|
7720
7214
|
writeFileSync as writeFileSync7
|
|
7721
7215
|
} from "node:fs";
|
|
7722
|
-
import { dirname as dirname10, join as
|
|
7216
|
+
import { dirname as dirname10, join as join17 } from "node:path";
|
|
7723
7217
|
function requestsDir(workspacePath) {
|
|
7724
|
-
return
|
|
7218
|
+
return join17(workspacePath, P2P_DIR, "requests");
|
|
7725
7219
|
}
|
|
7726
7220
|
function decisionsDir(workspacePath) {
|
|
7727
|
-
return
|
|
7221
|
+
return join17(workspacePath, P2P_DIR, "decisions");
|
|
7728
7222
|
}
|
|
7729
7223
|
function requestPath(workspacePath, id) {
|
|
7730
|
-
return
|
|
7224
|
+
return join17(requestsDir(workspacePath), `${id}.json`);
|
|
7731
7225
|
}
|
|
7732
7226
|
function decisionPath(workspacePath, id) {
|
|
7733
|
-
return
|
|
7227
|
+
return join17(decisionsDir(workspacePath), `${id}.json`);
|
|
7734
7228
|
}
|
|
7735
7229
|
function isRecord10(value) {
|
|
7736
7230
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -7862,7 +7356,7 @@ var init_approval_store = __esm(() => {
|
|
|
7862
7356
|
this.name = "ApprovalAbortedError";
|
|
7863
7357
|
}
|
|
7864
7358
|
};
|
|
7865
|
-
P2P_DIR =
|
|
7359
|
+
P2P_DIR = join17(".autorag", "p2p");
|
|
7866
7360
|
});
|
|
7867
7361
|
|
|
7868
7362
|
// src/p2p/pii-gate.ts
|
|
@@ -8141,7 +7635,7 @@ var init_egress_gate = __esm(() => {
|
|
|
8141
7635
|
|
|
8142
7636
|
// src/p2p/policy.ts
|
|
8143
7637
|
import { existsSync as existsSync14, mkdirSync as mkdirSync9, readFileSync as readFileSync11, writeFileSync as writeFileSync8 } from "node:fs";
|
|
8144
|
-
import { basename as
|
|
7638
|
+
import { basename as basename8, dirname as dirname11, join as join18, resolve as resolve10 } from "node:path";
|
|
8145
7639
|
import { parse as parseToml } from "smol-toml";
|
|
8146
7640
|
function isRecord11(value) {
|
|
8147
7641
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -8405,8 +7899,8 @@ function loadSeenSources(path, workspacePath) {
|
|
|
8405
7899
|
}
|
|
8406
7900
|
function resolveGlobalConfigPath(homePath) {
|
|
8407
7901
|
if (homePath === undefined)
|
|
8408
|
-
return
|
|
8409
|
-
return
|
|
7902
|
+
return join18(resolveAutoRAGHome(), "config.json");
|
|
7903
|
+
return basename8(homePath) === ".autorag" ? join18(homePath, "config.json") : join18(homePath, ".autorag", "config.json");
|
|
8410
7904
|
}
|
|
8411
7905
|
|
|
8412
7906
|
class PolicyStore {
|
|
@@ -8427,7 +7921,7 @@ class PolicyStore {
|
|
|
8427
7921
|
this.workspacePath = resolve10(normalizedOptions.workspacePath);
|
|
8428
7922
|
this.sourceRoots = normalizedOptions.sourceRoots;
|
|
8429
7923
|
const globalConfigPath = normalizedOptions.globalConfigPath ?? resolveGlobalConfigPath(normalizedOptions.homePath);
|
|
8430
|
-
const workspacePolicyPath = normalizedOptions.workspacePolicyPath ??
|
|
7924
|
+
const workspacePolicyPath = normalizedOptions.workspacePolicyPath ?? join18(this.workspacePath, ".autorag", "p2p", "policy.toml");
|
|
8431
7925
|
const global = readGlobalPolicy(readJsonFile(globalConfigPath), this.workspacePath, globalConfigPath);
|
|
8432
7926
|
const workspacePolicy = readTomlFile(workspacePolicyPath);
|
|
8433
7927
|
const workspaceEntries = readPolicyEntries(workspacePolicy, this.workspacePath, workspacePolicyPath);
|
|
@@ -8444,7 +7938,7 @@ class PolicyStore {
|
|
|
8444
7938
|
throw new PolicyError("newFilesPublic must be a boolean");
|
|
8445
7939
|
}
|
|
8446
7940
|
this.newFilesPublic = normalizedOptions.newFilesPublic ?? workspaceNewFilesPublic ?? configuredNewFilesPublic ?? false;
|
|
8447
|
-
this.seenSourcesPath = normalizedOptions.seenSourcesPath ??
|
|
7941
|
+
this.seenSourcesPath = normalizedOptions.seenSourcesPath ?? join18(this.workspacePath, ".autorag", "p2p", "seen-sources.json");
|
|
8448
7942
|
const seenState = loadSeenSources(this.seenSourcesPath, this.workspacePath);
|
|
8449
7943
|
this.seenSources = seenState.promoted;
|
|
8450
7944
|
this.pendingSources = seenState.pending;
|
|
@@ -8555,73 +8049,423 @@ class PolicyStore {
|
|
|
8555
8049
|
if (isNewAllowSource && !this.newFilesPublic && !this.seenSources.has(canonical.normalize("NFC"))) {
|
|
8556
8050
|
return privateResolution();
|
|
8557
8051
|
}
|
|
8558
|
-
return resolveEntry(selected, peerFingerprint);
|
|
8052
|
+
return resolveEntry(selected, peerFingerprint);
|
|
8053
|
+
}
|
|
8054
|
+
}
|
|
8055
|
+
function privateResolution() {
|
|
8056
|
+
return { tier: "private", allowed: false, shareBytes: false, redact: true };
|
|
8057
|
+
}
|
|
8058
|
+
function resolveEntry(entry, peerFingerprint) {
|
|
8059
|
+
switch (entry.tier) {
|
|
8060
|
+
case "private":
|
|
8061
|
+
case "never":
|
|
8062
|
+
return { tier: entry.tier, allowed: false, shareBytes: false, redact: true };
|
|
8063
|
+
case "always":
|
|
8064
|
+
return { tier: "always", allowed: true, shareBytes: true, redact: false };
|
|
8065
|
+
case "peers":
|
|
8066
|
+
return {
|
|
8067
|
+
tier: "peers",
|
|
8068
|
+
allowed: peerFingerprint !== undefined && (entry.peers ?? []).includes(peerFingerprint),
|
|
8069
|
+
shareBytes: false,
|
|
8070
|
+
redact: true
|
|
8071
|
+
};
|
|
8072
|
+
}
|
|
8073
|
+
}
|
|
8074
|
+
var PolicyError, DEFAULT_QUOTAS, POLICY_TIERS, UNSAFE_POLICY_CHARACTERS, WINDOWS_ABSOLUTE_PATH, POSIX_FILESYSTEM_ROOTS, DEFAULT_POLICY_QUOTAS;
|
|
8075
|
+
var init_policy = __esm(() => {
|
|
8076
|
+
init_home();
|
|
8077
|
+
init_source_paths();
|
|
8078
|
+
PolicyError = class PolicyError extends Error {
|
|
8079
|
+
cause;
|
|
8080
|
+
constructor(message, options) {
|
|
8081
|
+
super(message);
|
|
8082
|
+
this.name = "PolicyError";
|
|
8083
|
+
this.cause = options?.cause;
|
|
8084
|
+
}
|
|
8085
|
+
};
|
|
8086
|
+
DEFAULT_QUOTAS = {
|
|
8087
|
+
queriesPerHour: 10,
|
|
8088
|
+
burst: 3,
|
|
8089
|
+
maxBodyBytes: 65536,
|
|
8090
|
+
maxFileBytes: 26214400
|
|
8091
|
+
};
|
|
8092
|
+
POLICY_TIERS = new Set(["private", "never", "always", "peers"]);
|
|
8093
|
+
UNSAFE_POLICY_CHARACTERS = /[\p{Cc}\p{Cf}]/u;
|
|
8094
|
+
WINDOWS_ABSOLUTE_PATH = /^[a-z]:[\\/]/iu;
|
|
8095
|
+
POSIX_FILESYSTEM_ROOTS = new Set([
|
|
8096
|
+
"applications",
|
|
8097
|
+
"bin",
|
|
8098
|
+
"dev",
|
|
8099
|
+
"etc",
|
|
8100
|
+
"home",
|
|
8101
|
+
"library",
|
|
8102
|
+
"media",
|
|
8103
|
+
"mnt",
|
|
8104
|
+
"opt",
|
|
8105
|
+
"private",
|
|
8106
|
+
"proc",
|
|
8107
|
+
"root",
|
|
8108
|
+
"run",
|
|
8109
|
+
"users",
|
|
8110
|
+
"sbin",
|
|
8111
|
+
"srv",
|
|
8112
|
+
"system",
|
|
8113
|
+
"tmp",
|
|
8114
|
+
"usr",
|
|
8115
|
+
"var",
|
|
8116
|
+
"volumes"
|
|
8117
|
+
]);
|
|
8118
|
+
DEFAULT_POLICY_QUOTAS = Object.freeze({ ...DEFAULT_QUOTAS });
|
|
8119
|
+
});
|
|
8120
|
+
|
|
8121
|
+
// src/p2p/simplex-transport.ts
|
|
8122
|
+
import { spawn as spawn7 } from "node:child_process";
|
|
8123
|
+
function isRecord12(value) {
|
|
8124
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
8125
|
+
}
|
|
8126
|
+
function responseType(payload) {
|
|
8127
|
+
if (!isRecord12(payload))
|
|
8128
|
+
return;
|
|
8129
|
+
return typeof payload.type === "string" ? payload.type : undefined;
|
|
8130
|
+
}
|
|
8131
|
+
function parseSimplexProfile(value) {
|
|
8132
|
+
if (!isRecord12(value))
|
|
8133
|
+
return;
|
|
8134
|
+
if (typeof value.displayName !== "string" || value.displayName.trim().length === 0)
|
|
8135
|
+
return;
|
|
8136
|
+
const fullName = typeof value.fullName === "string" ? value.fullName : undefined;
|
|
8137
|
+
const shortDescr = typeof value.shortDescr === "string" ? value.shortDescr : undefined;
|
|
8138
|
+
const description = typeof value.description === "string" ? value.description : undefined;
|
|
8139
|
+
const image = typeof value.image === "string" ? value.image : undefined;
|
|
8140
|
+
return {
|
|
8141
|
+
displayName: value.displayName,
|
|
8142
|
+
...fullName !== undefined ? { fullName } : {},
|
|
8143
|
+
...shortDescr !== undefined ? { shortDescr } : {},
|
|
8144
|
+
...description !== undefined ? { description } : {},
|
|
8145
|
+
...image !== undefined ? { image } : {}
|
|
8146
|
+
};
|
|
8147
|
+
}
|
|
8148
|
+
function contactOf(payload) {
|
|
8149
|
+
if (!isRecord12(payload))
|
|
8150
|
+
return;
|
|
8151
|
+
const contact = payload.contact;
|
|
8152
|
+
if (!isRecord12(contact))
|
|
8153
|
+
return;
|
|
8154
|
+
if (typeof contact.contactId !== "number" || typeof contact.localDisplayName !== "string")
|
|
8155
|
+
return;
|
|
8156
|
+
const profile = parseSimplexProfile(contact.profile);
|
|
8157
|
+
return {
|
|
8158
|
+
contactId: contact.contactId,
|
|
8159
|
+
localDisplayName: contact.localDisplayName,
|
|
8160
|
+
...profile !== undefined ? { profile } : {}
|
|
8161
|
+
};
|
|
8162
|
+
}
|
|
8163
|
+
function userIdOf(payload) {
|
|
8164
|
+
if (!isRecord12(payload))
|
|
8165
|
+
return;
|
|
8166
|
+
const user = payload.user;
|
|
8167
|
+
if (!isRecord12(user) || typeof user.userId !== "number")
|
|
8168
|
+
return;
|
|
8169
|
+
return user.userId;
|
|
8170
|
+
}
|
|
8171
|
+
function extractTextFromChatItem(item) {
|
|
8172
|
+
if (!isRecord12(item))
|
|
8173
|
+
return;
|
|
8174
|
+
const chatItem = item.chatItem;
|
|
8175
|
+
if (!isRecord12(chatItem))
|
|
8176
|
+
return;
|
|
8177
|
+
const meta = chatItem.meta;
|
|
8178
|
+
const content = chatItem.content;
|
|
8179
|
+
if (!isRecord12(meta) || !isRecord12(content))
|
|
8180
|
+
return;
|
|
8181
|
+
if (typeof meta.itemId !== "number")
|
|
8182
|
+
return;
|
|
8183
|
+
const msgContent = content.msgContent;
|
|
8184
|
+
if (!isRecord12(msgContent))
|
|
8185
|
+
return;
|
|
8186
|
+
if (msgContent.type !== "text" || typeof msgContent.text !== "string")
|
|
8187
|
+
return;
|
|
8188
|
+
return { chatItemId: meta.itemId, text: msgContent.text };
|
|
8189
|
+
}
|
|
8190
|
+
async function waitForPort(port, proc, timeoutMs) {
|
|
8191
|
+
const deadline = Date.now() + timeoutMs;
|
|
8192
|
+
for (;; ) {
|
|
8193
|
+
if (proc.exitCode !== null) {
|
|
8194
|
+
throw new SimplexError(`simplex-chat exited with code ${proc.exitCode} before the WebSocket server started`);
|
|
8195
|
+
}
|
|
8196
|
+
try {
|
|
8197
|
+
const ws = new WebSocket(`ws://127.0.0.1:${port}`);
|
|
8198
|
+
await new Promise((resolve, reject) => {
|
|
8199
|
+
ws.addEventListener("open", () => {
|
|
8200
|
+
ws.close();
|
|
8201
|
+
resolve();
|
|
8202
|
+
});
|
|
8203
|
+
ws.addEventListener("error", () => reject(new Error("connect failed")));
|
|
8204
|
+
});
|
|
8205
|
+
return;
|
|
8206
|
+
} catch {
|
|
8207
|
+
if (Date.now() >= deadline) {
|
|
8208
|
+
throw new SimplexError(`simplex-chat WebSocket server did not start within ${timeoutMs}ms`);
|
|
8209
|
+
}
|
|
8210
|
+
await new Promise((resolve) => setTimeout(resolve, 150));
|
|
8211
|
+
}
|
|
8212
|
+
}
|
|
8213
|
+
}
|
|
8214
|
+
|
|
8215
|
+
class SimplexClient {
|
|
8216
|
+
dbPrefix;
|
|
8217
|
+
displayName;
|
|
8218
|
+
proc;
|
|
8219
|
+
ws;
|
|
8220
|
+
nextCorrId = 1;
|
|
8221
|
+
pending = new Map;
|
|
8222
|
+
messageHandlers = [];
|
|
8223
|
+
closed = false;
|
|
8224
|
+
userId;
|
|
8225
|
+
constructor(dbPrefix, displayName, proc, ws) {
|
|
8226
|
+
this.dbPrefix = dbPrefix;
|
|
8227
|
+
this.displayName = displayName;
|
|
8228
|
+
this.proc = proc;
|
|
8229
|
+
this.ws = ws;
|
|
8230
|
+
ws.addEventListener("message", (event) => {
|
|
8231
|
+
const data = typeof event.data === "string" ? event.data : Buffer.from(event.data).toString();
|
|
8232
|
+
this.dispatch(data);
|
|
8233
|
+
});
|
|
8234
|
+
ws.addEventListener("close", () => this.failAllPending(new SimplexError("simplex-chat WebSocket closed")));
|
|
8235
|
+
ws.addEventListener("error", () => {});
|
|
8236
|
+
}
|
|
8237
|
+
dispatch(raw) {
|
|
8238
|
+
let parsed;
|
|
8239
|
+
try {
|
|
8240
|
+
parsed = JSON.parse(raw);
|
|
8241
|
+
} catch {
|
|
8242
|
+
return;
|
|
8243
|
+
}
|
|
8244
|
+
if (!isRecord12(parsed) || !isRecord12(parsed.resp))
|
|
8245
|
+
return;
|
|
8246
|
+
const resp = parsed.resp;
|
|
8247
|
+
if (typeof parsed.corrId === "string") {
|
|
8248
|
+
const entry = this.pending.get(parsed.corrId);
|
|
8249
|
+
if (entry !== undefined) {
|
|
8250
|
+
this.pending.delete(parsed.corrId);
|
|
8251
|
+
const type = responseType(resp);
|
|
8252
|
+
if (type === "chatCmdError" || type === "chatError") {
|
|
8253
|
+
entry.reject(new SimplexError(`simplex-chat command error: ${JSON.stringify(resp).slice(0, 300)}`));
|
|
8254
|
+
} else {
|
|
8255
|
+
entry.resolve(resp);
|
|
8256
|
+
}
|
|
8257
|
+
}
|
|
8258
|
+
return;
|
|
8259
|
+
}
|
|
8260
|
+
this.handleEvent(resp);
|
|
8261
|
+
}
|
|
8262
|
+
handleEvent(resp) {
|
|
8263
|
+
if (responseType(resp) !== "newChatItems" || !isRecord12(resp))
|
|
8264
|
+
return;
|
|
8265
|
+
const chatItems = resp.chatItems;
|
|
8266
|
+
if (!Array.isArray(chatItems))
|
|
8267
|
+
return;
|
|
8268
|
+
for (const item of chatItems) {
|
|
8269
|
+
if (!isRecord12(item))
|
|
8270
|
+
continue;
|
|
8271
|
+
const chatInfo = item.chatInfo;
|
|
8272
|
+
if (!isRecord12(chatInfo) || chatInfo.type !== "direct")
|
|
8273
|
+
continue;
|
|
8274
|
+
const contact = contactOf(chatInfo);
|
|
8275
|
+
const extracted = extractTextFromChatItem(item);
|
|
8276
|
+
if (contact === undefined || extracted === undefined)
|
|
8277
|
+
continue;
|
|
8278
|
+
const chatItem = item.chatItem;
|
|
8279
|
+
if (!isRecord12(chatItem))
|
|
8280
|
+
continue;
|
|
8281
|
+
const chatDir = chatItem.chatDir;
|
|
8282
|
+
if (!isRecord12(chatDir) || chatDir.type !== "directRcv")
|
|
8283
|
+
continue;
|
|
8284
|
+
const message = {
|
|
8285
|
+
contactId: contact.contactId,
|
|
8286
|
+
contactName: contact.localDisplayName,
|
|
8287
|
+
text: extracted.text,
|
|
8288
|
+
chatItemId: extracted.chatItemId
|
|
8289
|
+
};
|
|
8290
|
+
for (const handler of this.messageHandlers) {
|
|
8291
|
+
try {
|
|
8292
|
+
handler(message);
|
|
8293
|
+
} catch {}
|
|
8294
|
+
}
|
|
8295
|
+
}
|
|
8296
|
+
}
|
|
8297
|
+
cmd(command) {
|
|
8298
|
+
if (this.closed)
|
|
8299
|
+
return Promise.reject(new SimplexError("transport is closed"));
|
|
8300
|
+
const corrId = String(this.nextCorrId++);
|
|
8301
|
+
return new Promise((resolve, reject) => {
|
|
8302
|
+
this.pending.set(corrId, { resolve, reject });
|
|
8303
|
+
const request = { corrId, cmd: command };
|
|
8304
|
+
try {
|
|
8305
|
+
this.ws.send(JSON.stringify(request));
|
|
8306
|
+
} catch (error) {
|
|
8307
|
+
this.pending.delete(corrId);
|
|
8308
|
+
reject(new SimplexError(`WebSocket send failed: ${error instanceof Error ? error.message : String(error)}`));
|
|
8309
|
+
}
|
|
8310
|
+
});
|
|
8311
|
+
}
|
|
8312
|
+
failAllPending(error) {
|
|
8313
|
+
for (const entry of this.pending.values())
|
|
8314
|
+
entry.reject(error);
|
|
8315
|
+
this.pending.clear();
|
|
8316
|
+
}
|
|
8317
|
+
async requireUserId() {
|
|
8318
|
+
if (this.userId !== undefined)
|
|
8319
|
+
return this.userId;
|
|
8320
|
+
const active = await this.cmd("/user");
|
|
8321
|
+
if (responseType(active) === "activeUser") {
|
|
8322
|
+
const id = userIdOf(active);
|
|
8323
|
+
if (id !== undefined) {
|
|
8324
|
+
this.userId = id;
|
|
8325
|
+
return id;
|
|
8326
|
+
}
|
|
8327
|
+
}
|
|
8328
|
+
const created = await this.cmd(`/_create user ${JSON.stringify({
|
|
8329
|
+
profile: { displayName: this.displayName, fullName: "" },
|
|
8330
|
+
pastTimestamp: false,
|
|
8331
|
+
userChatRelay: false,
|
|
8332
|
+
clientService: false
|
|
8333
|
+
})}`);
|
|
8334
|
+
if (responseType(created) !== "activeUser") {
|
|
8335
|
+
throw new SimplexError(`failed to create SimpleX user profile: ${JSON.stringify(created).slice(0, 300)}`);
|
|
8336
|
+
}
|
|
8337
|
+
const id = userIdOf(created);
|
|
8338
|
+
if (id === undefined)
|
|
8339
|
+
throw new SimplexError("simplex-chat did not return a user id");
|
|
8340
|
+
this.userId = id;
|
|
8341
|
+
return id;
|
|
8342
|
+
}
|
|
8343
|
+
async getUserId() {
|
|
8344
|
+
return this.requireUserId();
|
|
8345
|
+
}
|
|
8346
|
+
async getOrCreateAddress() {
|
|
8347
|
+
const userId = await this.requireUserId();
|
|
8348
|
+
try {
|
|
8349
|
+
const existing = await this.cmd(`/_show_address ${userId}`);
|
|
8350
|
+
if (responseType(existing) === "userContactLink" && isRecord12(existing)) {
|
|
8351
|
+
const link = existing.contactLink;
|
|
8352
|
+
if (isRecord12(link) && isRecord12(link.connLinkContact)) {
|
|
8353
|
+
const full = link.connLinkContact.connFullLink;
|
|
8354
|
+
if (typeof full === "string")
|
|
8355
|
+
return full;
|
|
8356
|
+
}
|
|
8357
|
+
}
|
|
8358
|
+
} catch {}
|
|
8359
|
+
const created = await this.cmd(`/_address ${userId}`);
|
|
8360
|
+
if (responseType(created) !== "userContactLinkCreated" || !isRecord12(created)) {
|
|
8361
|
+
throw new SimplexError(`failed to create SimpleX address: ${JSON.stringify(created).slice(0, 300)}`);
|
|
8362
|
+
}
|
|
8363
|
+
const link = created.connLinkContact;
|
|
8364
|
+
if (!isRecord12(link) || typeof link.connFullLink !== "string") {
|
|
8365
|
+
throw new SimplexError("simplex-chat did not return a contact address");
|
|
8366
|
+
}
|
|
8367
|
+
await this.cmd(`/_address_settings ${userId} ${JSON.stringify({
|
|
8368
|
+
businessAddress: false,
|
|
8369
|
+
autoAccept: { acceptIncognito: false }
|
|
8370
|
+
})}`);
|
|
8371
|
+
return link.connFullLink;
|
|
8372
|
+
}
|
|
8373
|
+
async createInvitation() {
|
|
8374
|
+
const userId = await this.requireUserId();
|
|
8375
|
+
const resp = await this.cmd(`/_connect ${userId}`);
|
|
8376
|
+
if (responseType(resp) !== "invitation" || !isRecord12(resp)) {
|
|
8377
|
+
throw new SimplexError(`failed to create invitation: ${JSON.stringify(resp).slice(0, 300)}`);
|
|
8378
|
+
}
|
|
8379
|
+
const link = resp.connLinkInvitation;
|
|
8380
|
+
if (!isRecord12(link) || typeof link.connFullLink !== "string") {
|
|
8381
|
+
throw new SimplexError("simplex-chat did not return an invitation link");
|
|
8382
|
+
}
|
|
8383
|
+
return link.connFullLink;
|
|
8384
|
+
}
|
|
8385
|
+
async connect(link) {
|
|
8386
|
+
const userId = await this.requireUserId();
|
|
8387
|
+
const resp = await this.cmd(`/_connect ${userId} ${link}`);
|
|
8388
|
+
const type = responseType(resp);
|
|
8389
|
+
if (type === "sentInvitation" || type === "sentConfirmation" || type === "contactAlreadyExists")
|
|
8390
|
+
return;
|
|
8391
|
+
throw new SimplexError(`failed to connect via link: ${JSON.stringify(resp).slice(0, 300)}`);
|
|
8392
|
+
}
|
|
8393
|
+
async listContacts() {
|
|
8394
|
+
const userId = await this.requireUserId();
|
|
8395
|
+
const resp = await this.cmd(`/_contacts ${userId}`);
|
|
8396
|
+
if (responseType(resp) !== "contactsList" || !isRecord12(resp) || !Array.isArray(resp.contacts)) {
|
|
8397
|
+
throw new SimplexError(`failed to list contacts: ${JSON.stringify(resp).slice(0, 300)}`);
|
|
8398
|
+
}
|
|
8399
|
+
const contacts = [];
|
|
8400
|
+
for (const entry of resp.contacts) {
|
|
8401
|
+
const contact = contactOf({ contact: entry });
|
|
8402
|
+
if (contact !== undefined)
|
|
8403
|
+
contacts.push(contact);
|
|
8404
|
+
}
|
|
8405
|
+
return contacts;
|
|
8559
8406
|
}
|
|
8560
|
-
|
|
8561
|
-
|
|
8562
|
-
|
|
8563
|
-
}
|
|
8564
|
-
|
|
8565
|
-
|
|
8566
|
-
|
|
8567
|
-
|
|
8568
|
-
|
|
8569
|
-
|
|
8570
|
-
|
|
8571
|
-
|
|
8572
|
-
|
|
8573
|
-
|
|
8574
|
-
|
|
8575
|
-
|
|
8576
|
-
|
|
8577
|
-
|
|
8407
|
+
async sendMessage(contactId, text) {
|
|
8408
|
+
const resp = await this.cmd(`/_send @${contactId} json ${JSON.stringify([{ msgContent: { type: "text", text }, mentions: {} }])}`);
|
|
8409
|
+
if (responseType(resp) !== "newChatItems") {
|
|
8410
|
+
throw new SimplexError(`failed to send message: ${JSON.stringify(resp).slice(0, 300)}`);
|
|
8411
|
+
}
|
|
8412
|
+
}
|
|
8413
|
+
onMessage(handler) {
|
|
8414
|
+
this.messageHandlers.push(handler);
|
|
8415
|
+
return () => {
|
|
8416
|
+
const index = this.messageHandlers.indexOf(handler);
|
|
8417
|
+
if (index !== -1)
|
|
8418
|
+
this.messageHandlers.splice(index, 1);
|
|
8419
|
+
};
|
|
8420
|
+
}
|
|
8421
|
+
async close() {
|
|
8422
|
+
if (this.closed)
|
|
8423
|
+
return;
|
|
8424
|
+
this.closed = true;
|
|
8425
|
+
this.failAllPending(new SimplexError("transport closed"));
|
|
8426
|
+
try {
|
|
8427
|
+
this.ws.close();
|
|
8428
|
+
} catch {}
|
|
8429
|
+
this.proc.kill("SIGTERM");
|
|
8430
|
+
await new Promise((resolve) => {
|
|
8431
|
+
const timer = setTimeout(() => {
|
|
8432
|
+
this.proc.kill("SIGKILL");
|
|
8433
|
+
resolve();
|
|
8434
|
+
}, 3000);
|
|
8435
|
+
this.proc.once("exit", () => {
|
|
8436
|
+
clearTimeout(timer);
|
|
8437
|
+
resolve();
|
|
8438
|
+
});
|
|
8439
|
+
});
|
|
8578
8440
|
}
|
|
8579
8441
|
}
|
|
8580
|
-
|
|
8581
|
-
|
|
8582
|
-
|
|
8583
|
-
|
|
8584
|
-
|
|
8585
|
-
|
|
8586
|
-
|
|
8442
|
+
async function startSimplexChat(options) {
|
|
8443
|
+
const port = options.port ?? 5225;
|
|
8444
|
+
const binary = options.binary ?? "simplex-chat";
|
|
8445
|
+
const args = ["-p", String(port), "-d", options.dbPrefix];
|
|
8446
|
+
if (options.displayName !== undefined)
|
|
8447
|
+
args.push("--create-bot-display-name", options.displayName);
|
|
8448
|
+
const proc = spawn7(binary, args, {
|
|
8449
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
8450
|
+
});
|
|
8451
|
+
await waitForPort(port, proc, options.connectTimeoutMs ?? 15000);
|
|
8452
|
+
const ws = await new Promise((resolve, reject) => {
|
|
8453
|
+
const sock = new WebSocket(`ws://127.0.0.1:${port}`);
|
|
8454
|
+
sock.addEventListener("open", () => resolve(sock));
|
|
8455
|
+
sock.addEventListener("error", () => reject(new SimplexError(`WebSocket connect failed on port ${port}`)));
|
|
8456
|
+
});
|
|
8457
|
+
const client = new SimplexClient(options.dbPrefix, options.displayName, proc, ws);
|
|
8458
|
+
await client.getUserId();
|
|
8459
|
+
return client;
|
|
8460
|
+
}
|
|
8461
|
+
var SimplexError;
|
|
8462
|
+
var init_simplex_transport = __esm(() => {
|
|
8463
|
+
SimplexError = class SimplexError extends Error {
|
|
8464
|
+
constructor(message) {
|
|
8587
8465
|
super(message);
|
|
8588
|
-
this.name = "
|
|
8589
|
-
this.cause = options?.cause;
|
|
8466
|
+
this.name = "SimplexError";
|
|
8590
8467
|
}
|
|
8591
8468
|
};
|
|
8592
|
-
DEFAULT_QUOTAS = {
|
|
8593
|
-
queriesPerHour: 10,
|
|
8594
|
-
burst: 3,
|
|
8595
|
-
maxBodyBytes: 65536,
|
|
8596
|
-
maxFileBytes: 26214400
|
|
8597
|
-
};
|
|
8598
|
-
POLICY_TIERS = new Set(["private", "never", "always", "peers"]);
|
|
8599
|
-
UNSAFE_POLICY_CHARACTERS = /[\p{Cc}\p{Cf}]/u;
|
|
8600
|
-
WINDOWS_ABSOLUTE_PATH = /^[a-z]:[\\/]/iu;
|
|
8601
|
-
POSIX_FILESYSTEM_ROOTS = new Set([
|
|
8602
|
-
"applications",
|
|
8603
|
-
"bin",
|
|
8604
|
-
"dev",
|
|
8605
|
-
"etc",
|
|
8606
|
-
"home",
|
|
8607
|
-
"library",
|
|
8608
|
-
"media",
|
|
8609
|
-
"mnt",
|
|
8610
|
-
"opt",
|
|
8611
|
-
"private",
|
|
8612
|
-
"proc",
|
|
8613
|
-
"root",
|
|
8614
|
-
"run",
|
|
8615
|
-
"users",
|
|
8616
|
-
"sbin",
|
|
8617
|
-
"srv",
|
|
8618
|
-
"system",
|
|
8619
|
-
"tmp",
|
|
8620
|
-
"usr",
|
|
8621
|
-
"var",
|
|
8622
|
-
"volumes"
|
|
8623
|
-
]);
|
|
8624
|
-
DEFAULT_POLICY_QUOTAS = Object.freeze({ ...DEFAULT_QUOTAS });
|
|
8625
8469
|
});
|
|
8626
8470
|
|
|
8627
8471
|
// src/p2p/wire.ts
|
|
@@ -8683,24 +8527,34 @@ var init_wire = __esm(() => {
|
|
|
8683
8527
|
|
|
8684
8528
|
// src/p2p/simplex-server.ts
|
|
8685
8529
|
import { existsSync as existsSync15, mkdirSync as mkdirSync10, readFileSync as readFileSync12, writeFileSync as writeFileSync9 } from "node:fs";
|
|
8686
|
-
import { join as
|
|
8530
|
+
import { join as join19 } from "node:path";
|
|
8687
8531
|
import { Type as Type9 } from "typebox";
|
|
8688
8532
|
import { Value } from "typebox/value";
|
|
8689
8533
|
function targetTokens(value) {
|
|
8690
8534
|
return new Set((value.toLocaleLowerCase().match(TARGET_TOKEN_PATTERN) ?? []).filter((token) => token.length > 1));
|
|
8691
8535
|
}
|
|
8536
|
+
function contactText(alias, peer) {
|
|
8537
|
+
return [
|
|
8538
|
+
alias,
|
|
8539
|
+
peer.description,
|
|
8540
|
+
peer.profile?.displayName,
|
|
8541
|
+
peer.profile?.fullName,
|
|
8542
|
+
peer.profile?.shortDescr,
|
|
8543
|
+
peer.profile?.description
|
|
8544
|
+
].filter((value) => value !== undefined).join(" ");
|
|
8545
|
+
}
|
|
8692
8546
|
function rankSimplexPeerTargets(query, registry) {
|
|
8693
8547
|
const queryTerms = targetTokens(query);
|
|
8694
8548
|
if (queryTerms.size === 0)
|
|
8695
8549
|
return [];
|
|
8696
8550
|
return Object.entries(registry).map(([alias, peer]) => {
|
|
8697
|
-
const peerTerms = targetTokens(
|
|
8551
|
+
const peerTerms = targetTokens(contactText(alias, peer));
|
|
8698
8552
|
const matchedTerms = [...queryTerms].filter((term) => peerTerms.has(term)).sort();
|
|
8699
8553
|
return { alias, score: matchedTerms.length, matchedTerms };
|
|
8700
8554
|
}).filter((match) => match.score > 0).sort((left, right) => right.score - left.score || left.alias.localeCompare(right.alias));
|
|
8701
8555
|
}
|
|
8702
8556
|
function loadSimplexPeerRegistry(workspacePath) {
|
|
8703
|
-
const path =
|
|
8557
|
+
const path = join19(workspacePath, PEERS_DIR, PEERS_FILENAME);
|
|
8704
8558
|
if (!existsSync15(path))
|
|
8705
8559
|
return {};
|
|
8706
8560
|
try {
|
|
@@ -8711,15 +8565,13 @@ function loadSimplexPeerRegistry(workspacePath) {
|
|
|
8711
8565
|
for (const [alias, record] of Object.entries(parsed)) {
|
|
8712
8566
|
if (typeof record === "object" && record !== null && typeof record.contactId === "number" && typeof record.addedAt === "string") {
|
|
8713
8567
|
const raw = record;
|
|
8714
|
-
const
|
|
8568
|
+
const profile = parseSimplexProfile(raw.profile);
|
|
8715
8569
|
registry[alias] = {
|
|
8716
8570
|
contactId: raw.contactId,
|
|
8717
8571
|
addedAt: raw.addedAt,
|
|
8718
|
-
...
|
|
8719
|
-
...typeof raw.
|
|
8720
|
-
...typeof raw.
|
|
8721
|
-
...typeof raw.org === "string" ? { org: raw.org } : {},
|
|
8722
|
-
...accessHint !== undefined ? { accessHint } : {}
|
|
8572
|
+
...profile !== undefined ? { profile } : {},
|
|
8573
|
+
...typeof raw.profileSyncedAt === "string" ? { profileSyncedAt: raw.profileSyncedAt } : {},
|
|
8574
|
+
...typeof raw.description === "string" ? { description: raw.description } : {}
|
|
8723
8575
|
};
|
|
8724
8576
|
}
|
|
8725
8577
|
}
|
|
@@ -8729,9 +8581,29 @@ function loadSimplexPeerRegistry(workspacePath) {
|
|
|
8729
8581
|
}
|
|
8730
8582
|
}
|
|
8731
8583
|
function saveSimplexPeerRegistry(workspacePath, registry) {
|
|
8732
|
-
const dir =
|
|
8584
|
+
const dir = join19(workspacePath, PEERS_DIR);
|
|
8733
8585
|
mkdirSync10(dir, { recursive: true });
|
|
8734
|
-
writeFileSync9(
|
|
8586
|
+
writeFileSync9(join19(dir, PEERS_FILENAME), JSON.stringify(registry, null, 2), { mode: 384 });
|
|
8587
|
+
}
|
|
8588
|
+
function syncSimplexPeers(workspacePath, contacts, syncedAt = new Date().toISOString()) {
|
|
8589
|
+
const registry = loadSimplexPeerRegistry(workspacePath);
|
|
8590
|
+
const updated = [];
|
|
8591
|
+
const untrusted = [];
|
|
8592
|
+
for (const contact of contacts) {
|
|
8593
|
+
const entry = Object.entries(registry).find(([, peer]) => peer.contactId === contact.contactId);
|
|
8594
|
+
if (entry === undefined) {
|
|
8595
|
+
untrusted.push(contact);
|
|
8596
|
+
continue;
|
|
8597
|
+
}
|
|
8598
|
+
if (contact.profile === undefined)
|
|
8599
|
+
continue;
|
|
8600
|
+
const [alias, peer] = entry;
|
|
8601
|
+
registry[alias] = { ...peer, profile: contact.profile, profileSyncedAt: syncedAt };
|
|
8602
|
+
updated.push(alias);
|
|
8603
|
+
}
|
|
8604
|
+
if (updated.length > 0)
|
|
8605
|
+
saveSimplexPeerRegistry(workspacePath, registry);
|
|
8606
|
+
return { updated, untrusted };
|
|
8735
8607
|
}
|
|
8736
8608
|
function consumeToken(buckets, contactId, quotas) {
|
|
8737
8609
|
const now = Date.now();
|
|
@@ -8961,6 +8833,7 @@ var init_simplex_server = __esm(() => {
|
|
|
8961
8833
|
init_injection_classifier();
|
|
8962
8834
|
init_injection_gate();
|
|
8963
8835
|
init_policy();
|
|
8836
|
+
init_simplex_transport();
|
|
8964
8837
|
init_wire();
|
|
8965
8838
|
PRIVATE_POLICY = {
|
|
8966
8839
|
tier: "private",
|
|
@@ -8975,7 +8848,7 @@ var init_simplex_server = __esm(() => {
|
|
|
8975
8848
|
payload: Type9.Unknown({ description: "PeerQueryRequest or PeerQueryResponse" })
|
|
8976
8849
|
});
|
|
8977
8850
|
TARGET_TOKEN_PATTERN = /[\p{L}\p{N}]+/gu;
|
|
8978
|
-
PEERS_DIR =
|
|
8851
|
+
PEERS_DIR = join19(".autorag", "p2p");
|
|
8979
8852
|
QueueFullError = class QueueFullError extends Error {
|
|
8980
8853
|
constructor(message = "The peer query queue is full.") {
|
|
8981
8854
|
super(message);
|
|
@@ -8999,7 +8872,7 @@ function createRecommendPeerTargetsTool(workspacePath) {
|
|
|
8999
8872
|
return {
|
|
9000
8873
|
alias: match.alias,
|
|
9001
8874
|
matchedTerms: match.matchedTerms,
|
|
9002
|
-
...peer?.displayName !== undefined ? { displayName: peer.displayName } : {},
|
|
8875
|
+
...peer?.profile?.displayName !== undefined ? { displayName: peer.profile.displayName } : {},
|
|
9003
8876
|
...peer?.description !== undefined ? { description: peer.description } : {}
|
|
9004
8877
|
};
|
|
9005
8878
|
});
|
|
@@ -9023,6 +8896,80 @@ var init_peer_target_tool = __esm(() => {
|
|
|
9023
8896
|
});
|
|
9024
8897
|
});
|
|
9025
8898
|
|
|
8899
|
+
// src/agent/refresh-progress.ts
|
|
8900
|
+
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
8901
|
+
import { mkdirSync as mkdirSync11, readFileSync as readFileSync13, renameSync as renameSync7, rmSync as rmSync4, writeFileSync as writeFileSync10 } from "node:fs";
|
|
8902
|
+
import { dirname as dirname12 } from "node:path";
|
|
8903
|
+
function readRefreshProgress(root) {
|
|
8904
|
+
try {
|
|
8905
|
+
const parsed = JSON.parse(readFileSync13(refreshProgressPath(root), "utf8"));
|
|
8906
|
+
return isPersistedRefreshProgress(parsed) ? parsed : undefined;
|
|
8907
|
+
} catch (error) {
|
|
8908
|
+
if (error instanceof SyntaxError || typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT") {
|
|
8909
|
+
return;
|
|
8910
|
+
}
|
|
8911
|
+
throw error;
|
|
8912
|
+
}
|
|
8913
|
+
}
|
|
8914
|
+
function writeRefreshProgress(root, progress) {
|
|
8915
|
+
const path = refreshProgressPath(root);
|
|
8916
|
+
mkdirSync11(dirname12(path), { recursive: true });
|
|
8917
|
+
const temporaryPath = `${path}.${randomUUID6()}.tmp`;
|
|
8918
|
+
try {
|
|
8919
|
+
writeFileSync10(temporaryPath, `${JSON.stringify(progress, null, 2)}
|
|
8920
|
+
`);
|
|
8921
|
+
renameSync7(temporaryPath, path);
|
|
8922
|
+
} finally {
|
|
8923
|
+
rmSync4(temporaryPath, { force: true });
|
|
8924
|
+
}
|
|
8925
|
+
}
|
|
8926
|
+
function updateRefreshProgress(progress, update) {
|
|
8927
|
+
return {
|
|
8928
|
+
...progress,
|
|
8929
|
+
...update,
|
|
8930
|
+
updatedAt: new Date().toISOString()
|
|
8931
|
+
};
|
|
8932
|
+
}
|
|
8933
|
+
function removeRefreshProgress(root) {
|
|
8934
|
+
rmSync4(refreshProgressPath(root), { force: true });
|
|
8935
|
+
}
|
|
8936
|
+
function isRefreshOwnerAlive(progress) {
|
|
8937
|
+
if (progress.state !== "running")
|
|
8938
|
+
return false;
|
|
8939
|
+
try {
|
|
8940
|
+
process.kill(progress.pid, 0);
|
|
8941
|
+
return true;
|
|
8942
|
+
} catch (error) {
|
|
8943
|
+
if (error instanceof Error)
|
|
8944
|
+
return false;
|
|
8945
|
+
throw error;
|
|
8946
|
+
}
|
|
8947
|
+
}
|
|
8948
|
+
function isPersistedRefreshProgress(value) {
|
|
8949
|
+
if (!isRecord13(value))
|
|
8950
|
+
return false;
|
|
8951
|
+
const record = value;
|
|
8952
|
+
return record.version === 1 && typeof record.runId === "string" && typeof record.pid === "number" && Number.isInteger(record.pid) && (record.state === "running" || record.state === "success" || record.state === "failed") && isRefreshProgressPhase(record.phase) && typeof record.startedAt === "string" && typeof record.updatedAt === "string" && (record.finishedAt === undefined || typeof record.finishedAt === "string") && (record.error === undefined || typeof record.error === "string") && isSourceFiles(record.sourceFiles) && isParsedCounts(record.parsedCounts) && isMinsync(record.minsync);
|
|
8953
|
+
}
|
|
8954
|
+
function isRefreshProgressPhase(value) {
|
|
8955
|
+
return value === "parsed" || value === "minsync" || value === "datasources" || value === "jikji" || value === "finalizing";
|
|
8956
|
+
}
|
|
8957
|
+
function isSourceFiles(value) {
|
|
8958
|
+
return value === undefined || isRecord13(value) && typeof value.total === "number" && Number.isInteger(value.total);
|
|
8959
|
+
}
|
|
8960
|
+
function isParsedCounts(value) {
|
|
8961
|
+
return value === undefined || isRecord13(value) && typeof value.scanned === "number" && typeof value.written === "number" && typeof value.deleted === "number" && typeof value.skipped === "number";
|
|
8962
|
+
}
|
|
8963
|
+
function isMinsync(value) {
|
|
8964
|
+
return value === undefined || isRecord13(value) && (value.synced === undefined || typeof value.synced === "number");
|
|
8965
|
+
}
|
|
8966
|
+
function isRecord13(value) {
|
|
8967
|
+
return typeof value === "object" && value !== null;
|
|
8968
|
+
}
|
|
8969
|
+
var init_refresh_progress = __esm(() => {
|
|
8970
|
+
init_paths();
|
|
8971
|
+
});
|
|
8972
|
+
|
|
9026
8973
|
// src/agent/search-documents.ts
|
|
9027
8974
|
function toRetrievalTraceResults(results, limit = 5, excerptChars = 300) {
|
|
9028
8975
|
return results.slice(0, limit).map((result) => ({
|
|
@@ -9622,19 +9569,6 @@ var init_watch_refresh = __esm(() => {
|
|
|
9622
9569
|
EXCLUDED_SEGMENTS = new Set([".autorag", ".git", "node_modules"]);
|
|
9623
9570
|
});
|
|
9624
9571
|
|
|
9625
|
-
// src/parser/index.ts
|
|
9626
|
-
var init_parser = __esm(() => {
|
|
9627
|
-
init_defaults();
|
|
9628
|
-
init_eml();
|
|
9629
|
-
init_errors();
|
|
9630
|
-
init_hwp();
|
|
9631
|
-
init_ocr();
|
|
9632
|
-
init_office();
|
|
9633
|
-
init_opendataloader_pdf();
|
|
9634
|
-
init_plain_text();
|
|
9635
|
-
init_registry();
|
|
9636
|
-
});
|
|
9637
|
-
|
|
9638
9572
|
// src/web/entities.ts
|
|
9639
9573
|
function decodeHtmlEntities(value) {
|
|
9640
9574
|
return value.replace(ENTITY_PATTERN, (match, body) => {
|
|
@@ -9823,7 +9757,7 @@ var init_page_loader = __esm(() => {
|
|
|
9823
9757
|
});
|
|
9824
9758
|
|
|
9825
9759
|
// src/web/fetch/url-target.ts
|
|
9826
|
-
import { extname as
|
|
9760
|
+
import { extname as extname5 } from "node:path";
|
|
9827
9761
|
function repairCollapsedScheme(value) {
|
|
9828
9762
|
const m = value.match(/^(https?):\/(?!\/)/i);
|
|
9829
9763
|
return m ? `${m[1]}://${value.slice(m[0].length)}` : value;
|
|
@@ -9842,7 +9776,7 @@ function getFilenameExtensionHint(filename) {
|
|
|
9842
9776
|
const lower = filename.toLowerCase();
|
|
9843
9777
|
if (lower.endsWith(".tar.gz"))
|
|
9844
9778
|
return ".tar.gz";
|
|
9845
|
-
return
|
|
9779
|
+
return extname5(filename).toLowerCase();
|
|
9846
9780
|
}
|
|
9847
9781
|
function getExtensionHint(url, contentDisposition) {
|
|
9848
9782
|
if (contentDisposition) {
|
|
@@ -9910,9 +9844,9 @@ var init_url_target = __esm(() => {
|
|
|
9910
9844
|
});
|
|
9911
9845
|
|
|
9912
9846
|
// src/web/fetch/convert.ts
|
|
9913
|
-
import { mkdtemp as
|
|
9914
|
-
import { tmpdir as
|
|
9915
|
-
import { join as
|
|
9847
|
+
import { mkdtemp as mkdtemp2, rm as rm3, writeFile as writeFile3 } from "node:fs/promises";
|
|
9848
|
+
import { tmpdir as tmpdir2 } from "node:os";
|
|
9849
|
+
import { join as join20 } from "node:path";
|
|
9916
9850
|
function combineSignals2(signal, timeoutMs) {
|
|
9917
9851
|
if (!signal)
|
|
9918
9852
|
return AbortSignal.timeout(timeoutMs);
|
|
@@ -9988,10 +9922,10 @@ async function convertBinaryPayload(buffer, extension, _finalUrl, signal) {
|
|
|
9988
9922
|
if (!parser) {
|
|
9989
9923
|
return { content: "", ok: false, error: `No parser registered for ${ext}` };
|
|
9990
9924
|
}
|
|
9991
|
-
const tempDir = await
|
|
9992
|
-
const tempPath =
|
|
9925
|
+
const tempDir = await mkdtemp2(join20(tmpdir2(), "autorag-fetch-"));
|
|
9926
|
+
const tempPath = join20(tempDir, `payload${ext}`);
|
|
9993
9927
|
try {
|
|
9994
|
-
await
|
|
9928
|
+
await writeFile3(tempPath, buffer);
|
|
9995
9929
|
const input = {
|
|
9996
9930
|
virtualPath: `payload${ext}`,
|
|
9997
9931
|
sourcePath: tempPath,
|
|
@@ -10008,7 +9942,7 @@ async function convertBinaryPayload(buffer, extension, _finalUrl, signal) {
|
|
|
10008
9942
|
error: err instanceof Error ? err.message : "Conversion failed"
|
|
10009
9943
|
};
|
|
10010
9944
|
} finally {
|
|
10011
|
-
await
|
|
9945
|
+
await rm3(tempDir, { recursive: true, force: true });
|
|
10012
9946
|
}
|
|
10013
9947
|
}
|
|
10014
9948
|
var parserRegistry;
|
|
@@ -10019,7 +9953,7 @@ var init_convert = __esm(() => {
|
|
|
10019
9953
|
});
|
|
10020
9954
|
|
|
10021
9955
|
// src/web/fetch/feeds.ts
|
|
10022
|
-
import { extname as
|
|
9956
|
+
import { extname as extname6 } from "node:path";
|
|
10023
9957
|
import { XMLParser as XMLParser2 } from "fast-xml-parser";
|
|
10024
9958
|
function getHtmlAttribute(tag, attribute) {
|
|
10025
9959
|
const pattern = new RegExp(`\\b${attribute}\\s*=\\s*(?:"([^"]*)"|'([^']*)'|([^\\s"'=<>]+))`, "i");
|
|
@@ -10082,7 +10016,7 @@ function extractDocumentLinks(html, baseUrl) {
|
|
|
10082
10016
|
const href = getHtmlAttribute(tag, "href");
|
|
10083
10017
|
if (!href)
|
|
10084
10018
|
continue;
|
|
10085
|
-
const ext =
|
|
10019
|
+
const ext = extname6(href).toLowerCase();
|
|
10086
10020
|
if (!CONVERTIBLE_EXTENSIONS2.has(ext))
|
|
10087
10021
|
continue;
|
|
10088
10022
|
const resolved = href.startsWith("http") ? href : new URL(href, baseUrl).href;
|
|
@@ -10241,7 +10175,7 @@ function alignmentMarker(cell) {
|
|
|
10241
10175
|
return "--:";
|
|
10242
10176
|
return "---";
|
|
10243
10177
|
}
|
|
10244
|
-
function
|
|
10178
|
+
function renderTable(service, table) {
|
|
10245
10179
|
const rows = descendantElements(table, "TR");
|
|
10246
10180
|
const rendered = [];
|
|
10247
10181
|
for (let rowIndex = 0;rowIndex < rows.length; rowIndex++) {
|
|
@@ -10298,7 +10232,7 @@ ${options.fence}
|
|
|
10298
10232
|
service.addRule("table", {
|
|
10299
10233
|
filter: isHeadingTable,
|
|
10300
10234
|
replacement(_content, node) {
|
|
10301
|
-
return
|
|
10235
|
+
return renderTable(service, node);
|
|
10302
10236
|
}
|
|
10303
10237
|
});
|
|
10304
10238
|
}, gfm = (service) => {
|
|
@@ -15250,9 +15184,9 @@ var init_web_search_tool = __esm(() => {
|
|
|
15250
15184
|
});
|
|
15251
15185
|
|
|
15252
15186
|
// src/agent/agent.ts
|
|
15253
|
-
import { randomUUID as
|
|
15254
|
-
import { existsSync as existsSync17, watch as fsWatch, mkdirSync as
|
|
15255
|
-
import { dirname as
|
|
15187
|
+
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
15188
|
+
import { existsSync as existsSync17, watch as fsWatch, mkdirSync as mkdirSync12, realpathSync as realpathSync4, statSync, writeFileSync as writeFileSync11 } from "node:fs";
|
|
15189
|
+
import { dirname as dirname13, join as join21, resolve as resolve11 } from "node:path";
|
|
15256
15190
|
import { Agent } from "@earendil-works/pi-agent-core";
|
|
15257
15191
|
import { clampThinkingLevel, streamSimple } from "@earendil-works/pi-ai/compat";
|
|
15258
15192
|
|
|
@@ -15294,6 +15228,7 @@ class AutoRAGAgent {
|
|
|
15294
15228
|
};
|
|
15295
15229
|
searchPaths;
|
|
15296
15230
|
configuredSearchPaths;
|
|
15231
|
+
languages;
|
|
15297
15232
|
retrievalScopeBindings;
|
|
15298
15233
|
datasourceVirtualScopePrefixes;
|
|
15299
15234
|
workspaceProjectRoot;
|
|
@@ -15341,10 +15276,11 @@ class AutoRAGAgent {
|
|
|
15341
15276
|
this.startupDiagnostics = options.startupDiagnostics ?? [];
|
|
15342
15277
|
this.datasourceAgentSkills = this.buildAuthorizedDatasourceSkills();
|
|
15343
15278
|
this.configuredSearchPaths = options.searchPaths.map((searchPath) => resolve11(searchPath));
|
|
15279
|
+
this.languages = options.languages ?? DEFAULT_LANGUAGES;
|
|
15344
15280
|
this.searchPaths = options.searchPaths.map(pinSearchRoot);
|
|
15345
15281
|
this.workspaceProjectRoot = options.workspacePath ?? process.cwd();
|
|
15346
15282
|
this.retrievalScopeBindings = buildRetrievalScopeBindings(this.workspaceProjectRoot, this.searchPaths, this.configuredSearchPaths);
|
|
15347
|
-
this.parserOptions = options.parserOptions;
|
|
15283
|
+
this.parserOptions = resolveParserOptions(options.parserOptions, this.languages);
|
|
15348
15284
|
this.dupeyOptions = options.dupey ?? {};
|
|
15349
15285
|
this.excludeExactDuplicates = options.excludeExactDuplicates ?? true;
|
|
15350
15286
|
if (options.minSync !== false) {
|
|
@@ -15368,10 +15304,10 @@ class AutoRAGAgent {
|
|
|
15368
15304
|
});
|
|
15369
15305
|
this.jikjiReady = this.searchPaths.every((searchPath) => this.jikjiClient?.isPrepared(searchPath) === true);
|
|
15370
15306
|
}
|
|
15371
|
-
const memPath = memoryPath ??
|
|
15307
|
+
const memPath = memoryPath ?? join21(resolveAutoRAGHome(), "memory.json");
|
|
15372
15308
|
this.memory = new RetrievalMemory({ storagePath: memPath });
|
|
15373
15309
|
this.memory.load();
|
|
15374
|
-
this.runLogger = new AutoRAGRunLogger(
|
|
15310
|
+
this.runLogger = new AutoRAGRunLogger(join21(dirname13(memPath), "logs", "runs.jsonl"));
|
|
15375
15311
|
const checkMemoryTool = createCheckMemoryTool(this.memory);
|
|
15376
15312
|
const singleDatasourceTools = createSingleDatasourceSearchTools(this, this.singleDatasourceToolSpecs());
|
|
15377
15313
|
this.searchToolNames = new Set([...SEARCH_TOOLS, ...singleDatasourceTools.map((tool) => tool.name)]);
|
|
@@ -15645,7 +15581,7 @@ ${summary}
|
|
|
15645
15581
|
if (this.activeRun) {
|
|
15646
15582
|
throw new Error("AutoRAG agent is busy; await the in-flight searchDocuments() call before starting another");
|
|
15647
15583
|
}
|
|
15648
|
-
const sessionId =
|
|
15584
|
+
const sessionId = randomUUID7();
|
|
15649
15585
|
const trimmedQuery = query.trim();
|
|
15650
15586
|
if (trimmedQuery.length === 0) {
|
|
15651
15587
|
this.lastQuery = trimmedQuery;
|
|
@@ -16148,16 +16084,54 @@ ${initialRetrievalContext ?? "Pending; continue only with a brief progress state
|
|
|
16148
16084
|
const allMethods = methods === undefined;
|
|
16149
16085
|
const wants = (m) => allMethods || methods.includes(m);
|
|
16150
16086
|
const needsParsed = allMethods || wants("parsed") || wants("minsync");
|
|
16087
|
+
const runId = randomUUID7();
|
|
16088
|
+
const startedAt = new Date().toISOString();
|
|
16089
|
+
let progress = {
|
|
16090
|
+
version: 1,
|
|
16091
|
+
runId,
|
|
16092
|
+
pid: process.pid,
|
|
16093
|
+
state: "running",
|
|
16094
|
+
phase: "parsed",
|
|
16095
|
+
startedAt,
|
|
16096
|
+
updatedAt: startedAt
|
|
16097
|
+
};
|
|
16098
|
+
writeRefreshProgress(this.workspaceProjectRoot, progress);
|
|
16151
16099
|
this.refreshState = {
|
|
16152
16100
|
...this.refreshState,
|
|
16153
16101
|
inFlight: true,
|
|
16154
|
-
lastStartedAt:
|
|
16102
|
+
lastStartedAt: startedAt
|
|
16155
16103
|
};
|
|
16156
16104
|
try {
|
|
16157
16105
|
const summary = needsParsed ? await this.syncParsedMirrors(force) : await this.scanMirrorStaleness();
|
|
16106
|
+
progress = updateRefreshProgress(progress, {
|
|
16107
|
+
phase: wants("minsync") ? "minsync" : wants("datasources") ? "datasources" : wants("jikji") ? "jikji" : "finalizing",
|
|
16108
|
+
sourceFiles: { total: summary.scanned },
|
|
16109
|
+
parsedCounts: {
|
|
16110
|
+
scanned: summary.scanned,
|
|
16111
|
+
written: summary.written,
|
|
16112
|
+
deleted: summary.deleted,
|
|
16113
|
+
skipped: summary.skipped
|
|
16114
|
+
}
|
|
16115
|
+
});
|
|
16116
|
+
writeRefreshProgress(this.workspaceProjectRoot, progress);
|
|
16158
16117
|
const minsync = wants("minsync") ? await this.syncMinSync(force) : undefined;
|
|
16118
|
+
if (minsync !== undefined) {
|
|
16119
|
+
progress = updateRefreshProgress(progress, {
|
|
16120
|
+
phase: wants("datasources") ? "datasources" : wants("jikji") ? "jikji" : "finalizing",
|
|
16121
|
+
minsync: { synced: minsync.synced }
|
|
16122
|
+
});
|
|
16123
|
+
writeRefreshProgress(this.workspaceProjectRoot, progress);
|
|
16124
|
+
}
|
|
16159
16125
|
const datasources = wants("datasources") ? await this.indexDatasources() : [];
|
|
16126
|
+
if (wants("datasources")) {
|
|
16127
|
+
progress = updateRefreshProgress(progress, {
|
|
16128
|
+
phase: wants("jikji") || allMethods ? "jikji" : "finalizing"
|
|
16129
|
+
});
|
|
16130
|
+
writeRefreshProgress(this.workspaceProjectRoot, progress);
|
|
16131
|
+
}
|
|
16160
16132
|
const jikji = allMethods || wants("jikji") || wants("minsync") ? await this.executeJikjiPrepare() : undefined;
|
|
16133
|
+
progress = updateRefreshProgress(progress, { phase: "finalizing" });
|
|
16134
|
+
writeRefreshProgress(this.workspaceProjectRoot, progress);
|
|
16161
16135
|
this.retrievalScopeBindings = buildRetrievalScopeBindings(this.workspaceProjectRoot, this.searchPaths, this.configuredSearchPaths);
|
|
16162
16136
|
const jikjiDiagnostics = (jikji ?? []).map((result) => jikjiPrepareDiagnostic(result)).filter((diag) => diag !== undefined);
|
|
16163
16137
|
this.refreshState = {
|
|
@@ -16176,10 +16150,15 @@ ${initialRetrievalContext ?? "Pending; continue only with a brief progress state
|
|
|
16176
16150
|
lastError: undefined
|
|
16177
16151
|
};
|
|
16178
16152
|
if (needsParsed) {
|
|
16179
|
-
|
|
16180
|
-
|
|
16153
|
+
mkdirSync12(dirname13(refreshReadinessPath(this.workspaceProjectRoot)), { recursive: true });
|
|
16154
|
+
writeFileSync11(refreshReadinessPath(this.workspaceProjectRoot), `{"version":1,"completed":true,"parsed":true}
|
|
16181
16155
|
`);
|
|
16182
16156
|
}
|
|
16157
|
+
progress = updateRefreshProgress(progress, {
|
|
16158
|
+
state: "success",
|
|
16159
|
+
finishedAt: new Date().toISOString()
|
|
16160
|
+
});
|
|
16161
|
+
writeRefreshProgress(this.workspaceProjectRoot, progress);
|
|
16183
16162
|
const minsyncDiagnostics = minSyncRefreshDiagnostics(minsync);
|
|
16184
16163
|
const publicMinsync = minsync ? {
|
|
16185
16164
|
ok: minsync.ok,
|
|
@@ -16205,6 +16184,12 @@ ${initialRetrievalContext ?? "Pending; continue only with a brief progress state
|
|
|
16205
16184
|
lastOutcome: "failed",
|
|
16206
16185
|
lastError: error instanceof Error ? `Refresh failed: ${error.name}` : "Refresh failed."
|
|
16207
16186
|
};
|
|
16187
|
+
progress = updateRefreshProgress(progress, {
|
|
16188
|
+
state: "failed",
|
|
16189
|
+
error: this.refreshState.lastError,
|
|
16190
|
+
finishedAt: new Date().toISOString()
|
|
16191
|
+
});
|
|
16192
|
+
writeRefreshProgress(this.workspaceProjectRoot, progress);
|
|
16208
16193
|
throw error;
|
|
16209
16194
|
} finally {
|
|
16210
16195
|
this.refreshState = {
|
|
@@ -16215,6 +16200,7 @@ ${initialRetrievalContext ?? "Pending; continue only with a brief progress state
|
|
|
16215
16200
|
}
|
|
16216
16201
|
}
|
|
16217
16202
|
async getRefreshStatus() {
|
|
16203
|
+
const persistedProgress = readRefreshProgress(this.workspaceProjectRoot);
|
|
16218
16204
|
const staleDiagnostics = await detectMirrorStaleness({
|
|
16219
16205
|
root: this.workspaceProjectRoot,
|
|
16220
16206
|
searchPaths: this.searchPaths,
|
|
@@ -16255,18 +16241,37 @@ ${initialRetrievalContext ?? "Pending; continue only with a brief progress state
|
|
|
16255
16241
|
source: "watch"
|
|
16256
16242
|
});
|
|
16257
16243
|
}
|
|
16258
|
-
const
|
|
16259
|
-
const
|
|
16244
|
+
const persistedRunning = persistedProgress?.state === "running";
|
|
16245
|
+
const ownerAlive = persistedProgress !== undefined && isRefreshOwnerAlive(persistedProgress);
|
|
16246
|
+
const interrupted = persistedRunning && !ownerAlive && !this.refreshState.inFlight;
|
|
16247
|
+
if (interrupted) {
|
|
16248
|
+
diagnostics.push({
|
|
16249
|
+
code: "refresh-interrupted",
|
|
16250
|
+
severity: "error",
|
|
16251
|
+
message: "A previous refresh stopped before it completed.",
|
|
16252
|
+
source: "refresh"
|
|
16253
|
+
});
|
|
16254
|
+
}
|
|
16255
|
+
const state = this.refreshState.inFlight || persistedRunning && ownerAlive ? "indexing" : interrupted ? "failed" : persistedProgress?.state === "success" || persistedProgress?.state === "failed" ? persistedProgress.state : this.refreshState.lastOutcome === "never" ? "idle" : this.refreshState.lastOutcome;
|
|
16256
|
+
const parsedMirrorReady = this.refreshState.lastOutcome === "success" || persistedProgress?.state === "success" || existsSync17(refreshReadinessPath(this.workspaceProjectRoot));
|
|
16257
|
+
const effectiveProgress = this.refreshState.inFlight || persistedRunning ? persistedProgress : undefined;
|
|
16260
16258
|
return {
|
|
16261
16259
|
state,
|
|
16262
16260
|
inFlight: this.refreshState.inFlight,
|
|
16263
|
-
lastStartedAt: this.refreshState.lastStartedAt,
|
|
16264
|
-
lastFinishedAt: this.refreshState.lastFinishedAt,
|
|
16261
|
+
lastStartedAt: this.refreshState.lastStartedAt ?? persistedProgress?.startedAt,
|
|
16262
|
+
lastFinishedAt: this.refreshState.lastFinishedAt ?? persistedProgress?.finishedAt,
|
|
16265
16263
|
counts: this.refreshState.counts,
|
|
16264
|
+
progress: effectiveProgress === undefined ? undefined : {
|
|
16265
|
+
phase: effectiveProgress.phase,
|
|
16266
|
+
sourceFiles: effectiveProgress.sourceFiles,
|
|
16267
|
+
parsedCounts: effectiveProgress.parsedCounts,
|
|
16268
|
+
minsync: effectiveProgress.minsync,
|
|
16269
|
+
ownerAlive
|
|
16270
|
+
},
|
|
16266
16271
|
stale: !parsedMirrorReady || staleDiagnostics.length > 0,
|
|
16267
16272
|
diagnostics,
|
|
16268
16273
|
components: this.refreshComponentStatus(),
|
|
16269
|
-
lastError: this.refreshState.lastError
|
|
16274
|
+
lastError: this.refreshState.lastError ?? (persistedProgress?.state === "failed" ? persistedProgress.error : undefined)
|
|
16270
16275
|
};
|
|
16271
16276
|
}
|
|
16272
16277
|
refreshComponentStatus() {
|
|
@@ -16338,7 +16343,7 @@ ${initialRetrievalContext ?? "Pending; continue only with a brief progress state
|
|
|
16338
16343
|
written: 0,
|
|
16339
16344
|
deleted: 0,
|
|
16340
16345
|
skipped: 0,
|
|
16341
|
-
indexPath:
|
|
16346
|
+
indexPath: join21(this.workspaceProjectRoot, PARSED_MIRROR_SUBDIR),
|
|
16342
16347
|
diagnostics
|
|
16343
16348
|
};
|
|
16344
16349
|
}
|
|
@@ -16698,7 +16703,7 @@ function buildMissingFinalEmitAnswer(query, reason, trace) {
|
|
|
16698
16703
|
const lines = [
|
|
16699
16704
|
`The search run for "${query}" ended without finalized results: the agent ended its run without calling emit_autorag_results, so no curated answer is available within the configured search range.`,
|
|
16700
16705
|
reason === undefined ? "The agent did not record why it stopped." : `The agent's last note before stopping: "${reason.length > 500 ? `${reason.slice(0, 500)}…` : reason}"`,
|
|
16701
|
-
"Next steps: broaden the configured searchPaths, connect additional datasources
|
|
16706
|
+
"Next steps: broaden the configured searchPaths, connect additional datasources via the datasources configuration, or retry with a narrower or different query.",
|
|
16702
16707
|
trace.length > 0 ? "Retrieval candidates gathered before the run ended are attached under `retrievalTrace` for inspection." : "No retrieval candidates were gathered before the run ended."
|
|
16703
16708
|
];
|
|
16704
16709
|
return lines.join(`
|
|
@@ -16802,6 +16807,7 @@ var init_agent = __esm(() => {
|
|
|
16802
16807
|
init_dupey();
|
|
16803
16808
|
init_diagnostics();
|
|
16804
16809
|
init_jikji();
|
|
16810
|
+
init_language();
|
|
16805
16811
|
init_loader();
|
|
16806
16812
|
init_check_memory_tool();
|
|
16807
16813
|
init_memory();
|
|
@@ -16810,6 +16816,7 @@ var init_agent = __esm(() => {
|
|
|
16810
16816
|
init_sync();
|
|
16811
16817
|
init_run_log();
|
|
16812
16818
|
init_injection_classifier();
|
|
16819
|
+
init_parser();
|
|
16813
16820
|
init_engine();
|
|
16814
16821
|
init_merger();
|
|
16815
16822
|
init_scope();
|
|
@@ -16822,6 +16829,7 @@ var init_agent = __esm(() => {
|
|
|
16822
16829
|
init_jikji_find_tool();
|
|
16823
16830
|
init_local_model();
|
|
16824
16831
|
init_peer_target_tool();
|
|
16832
|
+
init_refresh_progress();
|
|
16825
16833
|
init_search_all_tool();
|
|
16826
16834
|
init_search_documents();
|
|
16827
16835
|
init_search_minsync_tool();
|
|
@@ -17002,7 +17010,7 @@ ${this.description}`
|
|
|
17002
17010
|
}
|
|
17003
17011
|
|
|
17004
17012
|
// src/datasource/skills/clawgallery/client.ts
|
|
17005
|
-
import { spawn as
|
|
17013
|
+
import { spawn as spawn8 } from "node:child_process";
|
|
17006
17014
|
import { existsSync as existsSync18 } from "node:fs";
|
|
17007
17015
|
|
|
17008
17016
|
class ClawGalleryClient {
|
|
@@ -17107,7 +17115,7 @@ class ClawGalleryClient {
|
|
|
17107
17115
|
function spawnCli(binary, args, env, options, signal) {
|
|
17108
17116
|
return new Promise((resolve) => {
|
|
17109
17117
|
const portable = portableSpawnCommand(binary, args);
|
|
17110
|
-
const child =
|
|
17118
|
+
const child = spawn8(portable.command, [...portable.args], { env, stdio: ["ignore", "pipe", "pipe"] });
|
|
17111
17119
|
let stdout = "";
|
|
17112
17120
|
let stderr = "";
|
|
17113
17121
|
let settled = false;
|
|
@@ -17626,10 +17634,10 @@ function resolveToken(token, tokenEnv) {
|
|
|
17626
17634
|
var DEFAULT_TIMEOUT_MS6 = 15000;
|
|
17627
17635
|
|
|
17628
17636
|
// src/datasource/skills/cloud-drive/rclone-connector.ts
|
|
17629
|
-
import { spawn as
|
|
17630
|
-
import { mkdirSync as
|
|
17631
|
-
import { readFile as
|
|
17632
|
-
import { dirname as
|
|
17637
|
+
import { spawn as spawn9 } from "node:child_process";
|
|
17638
|
+
import { mkdirSync as mkdirSync13, readFileSync as readFileSync14, renameSync as renameSync8, rmSync as rmSync5, writeFileSync as writeFileSync12 } from "node:fs";
|
|
17639
|
+
import { readFile as readFile4 } from "node:fs/promises";
|
|
17640
|
+
import { dirname as dirname14, join as join22, normalize as normalize3 } from "node:path";
|
|
17633
17641
|
|
|
17634
17642
|
class RcloneConnector {
|
|
17635
17643
|
options;
|
|
@@ -17716,18 +17724,18 @@ class RcloneConnector {
|
|
|
17716
17724
|
return;
|
|
17717
17725
|
const destination = mirrorFilePath(paths.mirrorRoot, entry.path);
|
|
17718
17726
|
const temp = `${destination}.autorag-tmp`;
|
|
17719
|
-
|
|
17727
|
+
mkdirSync13(dirname14(temp), { recursive: true });
|
|
17720
17728
|
let copied;
|
|
17721
17729
|
try {
|
|
17722
17730
|
copied = await this.runner(copyArgs(remote, entry.path, temp, exportFormats, this.options.concurrency, this.options.bandwidthLimit), timeoutMs);
|
|
17723
17731
|
} catch {
|
|
17724
17732
|
copyFailure = { reason: "unavailable", message: "rclone copy failed unexpectedly" };
|
|
17725
|
-
|
|
17733
|
+
rmSync5(temp, { force: true });
|
|
17726
17734
|
return;
|
|
17727
17735
|
}
|
|
17728
17736
|
if (!copied.ok) {
|
|
17729
17737
|
copyFailure = { reason: classifyFailure(copied.stderr), message: shortFailure(copied) };
|
|
17730
|
-
|
|
17738
|
+
rmSync5(temp, { force: true });
|
|
17731
17739
|
return;
|
|
17732
17740
|
}
|
|
17733
17741
|
staged.push({ temp, destination });
|
|
@@ -17737,13 +17745,13 @@ class RcloneConnector {
|
|
|
17737
17745
|
await Promise.all(Array.from({ length: concurrency }, () => copyOne()));
|
|
17738
17746
|
if (copyFailure !== undefined) {
|
|
17739
17747
|
for (const file of staged)
|
|
17740
|
-
|
|
17748
|
+
rmSync5(file.temp, { force: true });
|
|
17741
17749
|
return { ok: false, reason: copyFailure.reason, message: copyFailure.message };
|
|
17742
17750
|
}
|
|
17743
17751
|
for (const file of staged)
|
|
17744
|
-
|
|
17752
|
+
renameSync8(file.temp, file.destination);
|
|
17745
17753
|
for (const entry of deletedEntries)
|
|
17746
|
-
|
|
17754
|
+
rmSync5(mirrorFilePath(paths.mirrorRoot, entry.path), { force: true });
|
|
17747
17755
|
saveManifest(paths.manifestPath, { version: 1, remoteName: remoteName(remote), entries: inventory });
|
|
17748
17756
|
const mirrorWarnings = await loadMirroredDocuments(paths.mirrorRoot, changedEntries, skillName, instanceId, remote, this.options.parserOptions);
|
|
17749
17757
|
const warnings = [
|
|
@@ -17821,12 +17829,12 @@ function sameEntry(previous, current) {
|
|
|
17821
17829
|
return previous?.path === current.path && previous.size === current.size && previous.modTime === current.modTime && previous.remoteId === current.remoteId && JSON.stringify(previous.hashes) === JSON.stringify(current.hashes);
|
|
17822
17830
|
}
|
|
17823
17831
|
function mirrorPaths(workspaceRoot, skillName, instanceId) {
|
|
17824
|
-
const base =
|
|
17825
|
-
return { mirrorRoot:
|
|
17832
|
+
const base = join22(workspaceRoot, ".autorag", "datasources", skillName, instanceId);
|
|
17833
|
+
return { mirrorRoot: join22(base, "mirror"), manifestPath: join22(base, "manifest.json") };
|
|
17826
17834
|
}
|
|
17827
17835
|
function mirrorFilePath(root, path) {
|
|
17828
17836
|
const safe = normalize3(path).replace(/^(\.\.(?:[/\\]|$))+|^[/\\]+/gu, "");
|
|
17829
|
-
return
|
|
17837
|
+
return join22(root, safe);
|
|
17830
17838
|
}
|
|
17831
17839
|
function remoteTarget(remote, path) {
|
|
17832
17840
|
return remote.endsWith(":") || remote.endsWith("/") ? `${remote}${path}` : `${remote}/${path}`;
|
|
@@ -17845,18 +17853,18 @@ function copyArgs(remote, path, destination, exportFormats, concurrency, bandwid
|
|
|
17845
17853
|
}
|
|
17846
17854
|
function loadManifest2(path) {
|
|
17847
17855
|
try {
|
|
17848
|
-
const parsed = JSON.parse(
|
|
17856
|
+
const parsed = JSON.parse(readFileSync14(path, "utf8"));
|
|
17849
17857
|
return parsed.version === 1 && Array.isArray(parsed.entries) ? parsed : undefined;
|
|
17850
17858
|
} catch {
|
|
17851
17859
|
return;
|
|
17852
17860
|
}
|
|
17853
17861
|
}
|
|
17854
17862
|
function saveManifest(path, manifest) {
|
|
17855
|
-
|
|
17863
|
+
mkdirSync13(dirname14(path), { recursive: true });
|
|
17856
17864
|
const temp = `${path}.autorag-tmp`;
|
|
17857
|
-
|
|
17865
|
+
writeFileSync12(temp, `${JSON.stringify(manifest)}
|
|
17858
17866
|
`, "utf8");
|
|
17859
|
-
|
|
17867
|
+
renameSync8(temp, path);
|
|
17860
17868
|
}
|
|
17861
17869
|
async function loadMirroredDocuments(root, entries, skillName, instanceId, remote, parserOptions) {
|
|
17862
17870
|
const documents = [];
|
|
@@ -17869,7 +17877,7 @@ async function loadMirroredDocuments(root, entries, skillName, instanceId, remot
|
|
|
17869
17877
|
const parser = registry.getForVirtualPath(entry.path);
|
|
17870
17878
|
if (parser === undefined)
|
|
17871
17879
|
continue;
|
|
17872
|
-
const bytes = await
|
|
17880
|
+
const bytes = await readFile4(sourcePath);
|
|
17873
17881
|
const parsed = await parser.parse({ virtualPath: entry.path, sourcePath, bytes });
|
|
17874
17882
|
for (const diagnostic of parsed.diagnostics ?? []) {
|
|
17875
17883
|
warnings.push(`${diagnostic.code}: ${diagnostic.message}`);
|
|
@@ -17930,7 +17938,7 @@ function shortFailure(result) {
|
|
|
17930
17938
|
function runBinary(binary, args, timeoutMs, env, cwd) {
|
|
17931
17939
|
return new Promise((resolvePromise) => {
|
|
17932
17940
|
const portable = portableSpawnCommand(binary, args);
|
|
17933
|
-
const child =
|
|
17941
|
+
const child = spawn9(portable.command, [...portable.args], {
|
|
17934
17942
|
...env === undefined ? {} : { env: { ...process.env, ...env } },
|
|
17935
17943
|
...cwd === undefined ? {} : { cwd },
|
|
17936
17944
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -18004,10 +18012,10 @@ function sanitizeIdSegment(value) {
|
|
|
18004
18012
|
var init_connector = () => {};
|
|
18005
18013
|
|
|
18006
18014
|
// src/datasource/chunk-store.ts
|
|
18007
|
-
import { existsSync as existsSync19, mkdirSync as
|
|
18008
|
-
import { dirname as
|
|
18015
|
+
import { existsSync as existsSync19, mkdirSync as mkdirSync14, readFileSync as readFileSync15, writeFileSync as writeFileSync13 } from "node:fs";
|
|
18016
|
+
import { dirname as dirname15, join as join23 } from "node:path";
|
|
18009
18017
|
function datasourceChunkStorePath(workspaceRoot, skillName, instanceId) {
|
|
18010
|
-
return
|
|
18018
|
+
return join23(workspaceRoot, ".autorag", "datasources", sanitizeIdSegment(skillName), sanitizeIdSegment(instanceId), "chunks.json");
|
|
18011
18019
|
}
|
|
18012
18020
|
|
|
18013
18021
|
class DatasourceChunkStore {
|
|
@@ -18046,7 +18054,7 @@ class DatasourceChunkStore {
|
|
|
18046
18054
|
try {
|
|
18047
18055
|
if (!existsSync19(this.storePath))
|
|
18048
18056
|
return false;
|
|
18049
|
-
const parsed = JSON.parse(
|
|
18057
|
+
const parsed = JSON.parse(readFileSync15(this.storePath, "utf8"));
|
|
18050
18058
|
if (parsed.version !== STORE_VERSION || !Array.isArray(parsed.chunks))
|
|
18051
18059
|
return false;
|
|
18052
18060
|
this.chunkList = parsed.chunks.filter((chunk) => typeof chunk?.chunkId === "string" && typeof chunk?.content === "string");
|
|
@@ -18120,7 +18128,7 @@ class DatasourceChunkStore {
|
|
|
18120
18128
|
if (this.storePath === undefined)
|
|
18121
18129
|
return;
|
|
18122
18130
|
try {
|
|
18123
|
-
|
|
18131
|
+
mkdirSync14(dirname15(this.storePath), { recursive: true });
|
|
18124
18132
|
const payload = {
|
|
18125
18133
|
version: STORE_VERSION,
|
|
18126
18134
|
skill: this.skillName,
|
|
@@ -18128,7 +18136,7 @@ class DatasourceChunkStore {
|
|
|
18128
18136
|
updatedAt: Date.now(),
|
|
18129
18137
|
chunks: this.chunkList
|
|
18130
18138
|
};
|
|
18131
|
-
|
|
18139
|
+
writeFileSync13(this.storePath, `${JSON.stringify(payload)}
|
|
18132
18140
|
`, "utf8");
|
|
18133
18141
|
} catch {}
|
|
18134
18142
|
}
|
|
@@ -18543,13 +18551,13 @@ var init_cloud_drive = __esm(() => {
|
|
|
18543
18551
|
});
|
|
18544
18552
|
|
|
18545
18553
|
// src/process/terminate-tree.ts
|
|
18546
|
-
import { spawn as
|
|
18554
|
+
import { spawn as spawn10 } from "node:child_process";
|
|
18547
18555
|
function terminateProcessTree(child, signal = "SIGKILL") {
|
|
18548
18556
|
const pid = child.pid;
|
|
18549
18557
|
if (pid === undefined)
|
|
18550
18558
|
return false;
|
|
18551
18559
|
if (process.platform === "win32") {
|
|
18552
|
-
const killer =
|
|
18560
|
+
const killer = spawn10("taskkill", ["/pid", String(pid), "/t", "/f"], { stdio: "ignore", windowsHide: true });
|
|
18553
18561
|
killer.on("error", () => killDirectChild(child, signal));
|
|
18554
18562
|
killer.on("close", (code) => {
|
|
18555
18563
|
if (code !== 0)
|
|
@@ -18592,9 +18600,9 @@ var init_types4 = __esm(() => {
|
|
|
18592
18600
|
});
|
|
18593
18601
|
|
|
18594
18602
|
// src/datasource/skills/discrawl/client.ts
|
|
18595
|
-
import { spawn as
|
|
18596
|
-
import { mkdirSync as
|
|
18597
|
-
import { dirname as
|
|
18603
|
+
import { spawn as spawn11 } from "node:child_process";
|
|
18604
|
+
import { mkdirSync as mkdirSync15, readFileSync as readFileSync16, writeFileSync as writeFileSync14 } from "node:fs";
|
|
18605
|
+
import { dirname as dirname16 } from "node:path";
|
|
18598
18606
|
|
|
18599
18607
|
class DiscrawlClient {
|
|
18600
18608
|
options;
|
|
@@ -18610,7 +18618,7 @@ class DiscrawlClient {
|
|
|
18610
18618
|
const path = `${workspace}/.autorag/datasources/discrawl/config.toml`;
|
|
18611
18619
|
let existing = "";
|
|
18612
18620
|
try {
|
|
18613
|
-
existing =
|
|
18621
|
+
existing = readFileSync16(path, "utf8");
|
|
18614
18622
|
} catch {}
|
|
18615
18623
|
const managed = existing.startsWith(`# AutoRAG managed discrawl embeddings v1
|
|
18616
18624
|
`);
|
|
@@ -18618,9 +18626,9 @@ class DiscrawlClient {
|
|
|
18618
18626
|
return { configured: false, rebuildRequired: false };
|
|
18619
18627
|
const previous = managed ? parseManagedEmbedding(existing) : undefined;
|
|
18620
18628
|
const config = managedDiscrawlConfig({ ...runtime, baseUrl: nativeGatewayBaseUrl(runtime.baseUrl) });
|
|
18621
|
-
|
|
18629
|
+
mkdirSync15(dirname16(path), { recursive: true });
|
|
18622
18630
|
if (existing !== config)
|
|
18623
|
-
|
|
18631
|
+
writeFileSync14(path, config, "utf8");
|
|
18624
18632
|
return {
|
|
18625
18633
|
configured: true,
|
|
18626
18634
|
rebuildRequired: previous !== undefined && (previous.provider !== runtime.provider || previous.model !== runtime.model || previous.dimensions !== runtime.dimensions)
|
|
@@ -18732,7 +18740,7 @@ function spawnDiscrawl(request) {
|
|
|
18732
18740
|
return new Promise((resolveResult) => {
|
|
18733
18741
|
const { options, args, env, signal } = request;
|
|
18734
18742
|
const portable = portableSpawnCommand(options.binaryPath ?? DEFAULT_DISCRAWL_BINARY, args);
|
|
18735
|
-
const child =
|
|
18743
|
+
const child = spawn11(portable.command, [...portable.args], {
|
|
18736
18744
|
env,
|
|
18737
18745
|
...request.cwd === undefined ? {} : { cwd: request.cwd },
|
|
18738
18746
|
detached: process.platform !== "win32",
|
|
@@ -19642,8 +19650,8 @@ var init_github = __esm(() => {
|
|
|
19642
19650
|
|
|
19643
19651
|
// src/datasource/skills/github-gist/connector.ts
|
|
19644
19652
|
import { execFile as execFile3 } from "node:child_process";
|
|
19645
|
-
import { existsSync as existsSync20, mkdirSync as
|
|
19646
|
-
import { dirname as
|
|
19653
|
+
import { existsSync as existsSync20, mkdirSync as mkdirSync16, readFileSync as readFileSync17, writeFileSync as writeFileSync15 } from "node:fs";
|
|
19654
|
+
import { dirname as dirname17 } from "node:path";
|
|
19647
19655
|
async function defaultGhTokenRunner() {
|
|
19648
19656
|
return new Promise((resolve) => {
|
|
19649
19657
|
execFile3("gh", ["auth", "token"], { timeout: GH_TOKEN_TIMEOUT_MS }, (error, stdout) => {
|
|
@@ -19765,7 +19773,7 @@ class GitHubGistConnector {
|
|
|
19765
19773
|
if (statePath === undefined || !existsSync20(statePath))
|
|
19766
19774
|
return { version: STATE_VERSION, gists: {} };
|
|
19767
19775
|
try {
|
|
19768
|
-
const parsed = JSON.parse(
|
|
19776
|
+
const parsed = JSON.parse(readFileSync17(statePath, "utf8"));
|
|
19769
19777
|
if (parsed.version !== STATE_VERSION || typeof parsed.gists !== "object" || parsed.gists === null) {
|
|
19770
19778
|
return { version: STATE_VERSION, gists: {} };
|
|
19771
19779
|
}
|
|
@@ -19779,8 +19787,8 @@ class GitHubGistConnector {
|
|
|
19779
19787
|
if (statePath === undefined)
|
|
19780
19788
|
return;
|
|
19781
19789
|
try {
|
|
19782
|
-
|
|
19783
|
-
|
|
19790
|
+
mkdirSync16(dirname17(statePath), { recursive: true });
|
|
19791
|
+
writeFileSync15(statePath, `${JSON.stringify(state)}
|
|
19784
19792
|
`, "utf8");
|
|
19785
19793
|
} catch {}
|
|
19786
19794
|
}
|
|
@@ -19825,8 +19833,8 @@ var init_connector3 = () => {};
|
|
|
19825
19833
|
|
|
19826
19834
|
// src/datasource/skills/github-gist/semantic.ts
|
|
19827
19835
|
import { createHash as createHash7 } from "node:crypto";
|
|
19828
|
-
import { existsSync as existsSync21, mkdirSync as
|
|
19829
|
-
import { dirname as
|
|
19836
|
+
import { existsSync as existsSync21, mkdirSync as mkdirSync17, readFileSync as readFileSync18, writeFileSync as writeFileSync16 } from "node:fs";
|
|
19837
|
+
import { dirname as dirname18 } from "node:path";
|
|
19830
19838
|
function contentHash(chunk) {
|
|
19831
19839
|
return createHash7("sha256").update(`${chunk.title ?? ""}
|
|
19832
19840
|
${chunk.content}`).digest("hex");
|
|
@@ -19919,7 +19927,7 @@ ${chunk.content}`));
|
|
|
19919
19927
|
if (this.statePath === undefined || !existsSync21(this.statePath))
|
|
19920
19928
|
return;
|
|
19921
19929
|
try {
|
|
19922
|
-
const parsed = JSON.parse(
|
|
19930
|
+
const parsed = JSON.parse(readFileSync18(this.statePath, "utf8"));
|
|
19923
19931
|
if (parsed.version !== VECTORS_VERSION || typeof parsed.entries !== "object" || parsed.entries === null)
|
|
19924
19932
|
return;
|
|
19925
19933
|
if (typeof parsed.identity?.dimension !== "number")
|
|
@@ -19934,13 +19942,13 @@ ${chunk.content}`));
|
|
|
19934
19942
|
if (this.identity === undefined)
|
|
19935
19943
|
return;
|
|
19936
19944
|
try {
|
|
19937
|
-
|
|
19945
|
+
mkdirSync17(dirname18(this.statePath), { recursive: true });
|
|
19938
19946
|
const payload = {
|
|
19939
19947
|
version: VECTORS_VERSION,
|
|
19940
19948
|
identity: this.identity,
|
|
19941
19949
|
entries: this.entries
|
|
19942
19950
|
};
|
|
19943
|
-
|
|
19951
|
+
writeFileSync16(this.statePath, `${JSON.stringify(payload)}
|
|
19944
19952
|
`, "utf8");
|
|
19945
19953
|
} catch {}
|
|
19946
19954
|
}
|
|
@@ -20074,9 +20082,9 @@ var init_semantic = __esm(() => {
|
|
|
20074
20082
|
});
|
|
20075
20083
|
|
|
20076
20084
|
// src/datasource/skills/github-gist/skill.ts
|
|
20077
|
-
import { join as
|
|
20085
|
+
import { join as join24 } from "node:path";
|
|
20078
20086
|
function gistDatasourceDir(workspaceRoot, skillName, instanceId) {
|
|
20079
|
-
return
|
|
20087
|
+
return join24(workspaceRoot, ".autorag", "datasources", sanitizeIdSegment(skillName), sanitizeIdSegment(instanceId));
|
|
20080
20088
|
}
|
|
20081
20089
|
var GITHUB_GIST_SKILL_DEFINITION, DEFAULT_INSTANCE_ID3 = "default", GitHubGistSkill;
|
|
20082
20090
|
var init_skill5 = __esm(() => {
|
|
@@ -20104,7 +20112,7 @@ var init_skill5 = __esm(() => {
|
|
|
20104
20112
|
constructor(options = {}) {
|
|
20105
20113
|
const { connector, connectorOptions, semantic, ...rest } = options;
|
|
20106
20114
|
const instanceId = options.instanceId ?? DEFAULT_INSTANCE_ID3;
|
|
20107
|
-
const statePath = connectorOptions?.statePath ?? (options.workspaceRoot === undefined ? undefined :
|
|
20115
|
+
const statePath = connectorOptions?.statePath ?? (options.workspaceRoot === undefined ? undefined : join24(gistDatasourceDir(options.workspaceRoot, GITHUB_GIST_SKILL_DEFINITION.skillName, instanceId), "state.json"));
|
|
20108
20116
|
super(GITHUB_GIST_SKILL_DEFINITION, {
|
|
20109
20117
|
...rest,
|
|
20110
20118
|
connector: connector ?? new GitHubGistConnector({
|
|
@@ -20114,7 +20122,7 @@ var init_skill5 = __esm(() => {
|
|
|
20114
20122
|
});
|
|
20115
20123
|
if (semantic?.enabled !== false) {
|
|
20116
20124
|
this.semanticIndex = new GistSemanticIndex({
|
|
20117
|
-
statePath: semantic?.statePath ?? (options.workspaceRoot === undefined ? undefined :
|
|
20125
|
+
statePath: semantic?.statePath ?? (options.workspaceRoot === undefined ? undefined : join24(gistDatasourceDir(options.workspaceRoot, GITHUB_GIST_SKILL_DEFINITION.skillName, instanceId), "vectors.json"))
|
|
20118
20126
|
});
|
|
20119
20127
|
this.semanticEmbedder = semantic?.embedder ?? createGatewayGistEmbedder(semantic?.embedderOptions ?? {});
|
|
20120
20128
|
this.semanticMethod = new GitHubGistSemanticMethod({
|
|
@@ -20164,7 +20172,7 @@ var init_github_gist = __esm(() => {
|
|
|
20164
20172
|
});
|
|
20165
20173
|
|
|
20166
20174
|
// src/datasource/crawler-client.ts
|
|
20167
|
-
import { spawn as
|
|
20175
|
+
import { spawn as spawn12 } from "node:child_process";
|
|
20168
20176
|
|
|
20169
20177
|
class CrawlerCliClient {
|
|
20170
20178
|
profile;
|
|
@@ -20201,7 +20209,7 @@ class CrawlerCliClient {
|
|
|
20201
20209
|
function spawnCrawler(command, args, env, signal, options, cwd) {
|
|
20202
20210
|
return new Promise((resolve) => {
|
|
20203
20211
|
const portable = portableSpawnCommand(command, args);
|
|
20204
|
-
const child =
|
|
20212
|
+
const child = spawn12(portable.command, [...portable.args], {
|
|
20205
20213
|
env,
|
|
20206
20214
|
...cwd === undefined ? {} : { cwd },
|
|
20207
20215
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -20414,7 +20422,7 @@ function parseMessages(stdout) {
|
|
|
20414
20422
|
return;
|
|
20415
20423
|
const hits = [];
|
|
20416
20424
|
for (const row of rows) {
|
|
20417
|
-
if (!
|
|
20425
|
+
if (!isRecord14(row))
|
|
20418
20426
|
return;
|
|
20419
20427
|
const id = scalarString(row.message_id);
|
|
20420
20428
|
const content = scalarString(row.content);
|
|
@@ -20447,9 +20455,9 @@ function parseDocs(stdout) {
|
|
|
20447
20455
|
return;
|
|
20448
20456
|
const hits = [];
|
|
20449
20457
|
for (const row of rows) {
|
|
20450
|
-
if (!
|
|
20458
|
+
if (!isRecord14(row))
|
|
20451
20459
|
return;
|
|
20452
|
-
const meta =
|
|
20460
|
+
const meta = isRecord14(row.result_meta) ? row.result_meta : {};
|
|
20453
20461
|
const token = firstString(meta, ["token", "docs_token"]) ?? firstString(row, ["token", "docs_token"]) ?? tokenFromUrl(firstString(meta, ["url"]));
|
|
20454
20462
|
const content = stripHighlight(firstString(row, ["summary_highlighted", "title_highlighted", "summary", "title"]) ?? "");
|
|
20455
20463
|
if (token === undefined || !isSafeId(token) || content.length === 0)
|
|
@@ -20480,7 +20488,7 @@ function envelopeData(stdout) {
|
|
|
20480
20488
|
} catch {
|
|
20481
20489
|
return;
|
|
20482
20490
|
}
|
|
20483
|
-
if (!
|
|
20491
|
+
if (!isRecord14(parsed) || parsed.ok !== true || !isRecord14(parsed.data))
|
|
20484
20492
|
return;
|
|
20485
20493
|
return parsed.data;
|
|
20486
20494
|
}
|
|
@@ -20513,7 +20521,7 @@ function stripHighlight(value) {
|
|
|
20513
20521
|
function isSafeId(value) {
|
|
20514
20522
|
return value.length > 0 && value !== "." && value !== ".." && !value.includes("#") && !value.includes("/");
|
|
20515
20523
|
}
|
|
20516
|
-
function
|
|
20524
|
+
function isRecord14(value) {
|
|
20517
20525
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
20518
20526
|
}
|
|
20519
20527
|
function isRateLimited(failure) {
|
|
@@ -20828,9 +20836,9 @@ var init_types5 = __esm(() => {
|
|
|
20828
20836
|
});
|
|
20829
20837
|
|
|
20830
20838
|
// src/datasource/skills/lazykatok/client.ts
|
|
20831
|
-
import { spawn as
|
|
20839
|
+
import { spawn as spawn13 } from "node:child_process";
|
|
20832
20840
|
import { existsSync as existsSync22 } from "node:fs";
|
|
20833
|
-
import { delimiter as delimiter4, join as
|
|
20841
|
+
import { delimiter as delimiter4, join as join25 } from "node:path";
|
|
20834
20842
|
|
|
20835
20843
|
class LazykatokClient {
|
|
20836
20844
|
options;
|
|
@@ -20924,7 +20932,7 @@ function spawnLazykatok(request) {
|
|
|
20924
20932
|
return new Promise((resolve) => {
|
|
20925
20933
|
const { options, args, env, signal } = request;
|
|
20926
20934
|
const portable = portableSpawnCommand(commandFor2(options, env), args);
|
|
20927
|
-
const child =
|
|
20935
|
+
const child = spawn13(portable.command, [...portable.args], {
|
|
20928
20936
|
env,
|
|
20929
20937
|
...request.cwd === undefined ? {} : { cwd: request.cwd },
|
|
20930
20938
|
detached: process.platform !== "win32",
|
|
@@ -21014,7 +21022,7 @@ function lookupInPath2(executable, env) {
|
|
|
21014
21022
|
for (const dir of pathEnv.split(delimiter4)) {
|
|
21015
21023
|
if (dir.length === 0)
|
|
21016
21024
|
continue;
|
|
21017
|
-
const candidate =
|
|
21025
|
+
const candidate = join25(dir, executable);
|
|
21018
21026
|
if (existsSync22(candidate))
|
|
21019
21027
|
return candidate;
|
|
21020
21028
|
}
|
|
@@ -21502,8 +21510,8 @@ var init_lazykatok = __esm(() => {
|
|
|
21502
21510
|
});
|
|
21503
21511
|
|
|
21504
21512
|
// src/datasource/skills/mail-export/connector.ts
|
|
21505
|
-
import { readdir as readdir2, readFile as
|
|
21506
|
-
import { basename as
|
|
21513
|
+
import { readdir as readdir2, readFile as readFile5, stat as stat5 } from "node:fs/promises";
|
|
21514
|
+
import { basename as basename9, dirname as dirname19, extname as extname7, join as join26 } from "node:path";
|
|
21507
21515
|
import { simpleParser as simpleParser2 } from "mailparser";
|
|
21508
21516
|
|
|
21509
21517
|
class MailExportConnector {
|
|
@@ -21527,9 +21535,9 @@ class MailExportConnector {
|
|
|
21527
21535
|
for (const entry of entries) {
|
|
21528
21536
|
if (!entry.isFile())
|
|
21529
21537
|
continue;
|
|
21530
|
-
const extension =
|
|
21538
|
+
const extension = extname7(entry.name).toLowerCase();
|
|
21531
21539
|
if (extension === ".eml" || extension === ".mbox") {
|
|
21532
|
-
files.push(
|
|
21540
|
+
files.push(join26(entry.parentPath, entry.name));
|
|
21533
21541
|
}
|
|
21534
21542
|
}
|
|
21535
21543
|
} else if (info.isFile()) {
|
|
@@ -21558,15 +21566,15 @@ class MailExportConnector {
|
|
|
21558
21566
|
skippedLarge += 1;
|
|
21559
21567
|
continue;
|
|
21560
21568
|
}
|
|
21561
|
-
bytes = await
|
|
21569
|
+
bytes = await readFile5(file);
|
|
21562
21570
|
} catch {
|
|
21563
21571
|
parseFailures += 1;
|
|
21564
21572
|
continue;
|
|
21565
21573
|
}
|
|
21566
|
-
const stem =
|
|
21567
|
-
const mailboxDir =
|
|
21574
|
+
const stem = basename9(file, extname7(file));
|
|
21575
|
+
const mailboxDir = basename9(dirname19(file));
|
|
21568
21576
|
const hierarchy = ["mailboxes", mailboxDir, stem];
|
|
21569
|
-
const extension =
|
|
21577
|
+
const extension = extname7(file).toLowerCase();
|
|
21570
21578
|
const rawMessages = extension === ".mbox" ? splitMbox(bytes.toString("utf8")) : [bytes.toString("utf8")];
|
|
21571
21579
|
for (const [index, raw] of rawMessages.entries()) {
|
|
21572
21580
|
if (documents.length >= maxDocuments)
|
|
@@ -21674,21 +21682,21 @@ var init_mail_export = __esm(() => {
|
|
|
21674
21682
|
});
|
|
21675
21683
|
|
|
21676
21684
|
// src/datasource/skills/mailcrawl/config.ts
|
|
21677
|
-
import { chmodSync, mkdirSync as
|
|
21685
|
+
import { chmodSync, mkdirSync as mkdirSync18 } from "node:fs";
|
|
21678
21686
|
function validateMailcrawlInstanceId(instanceId) {
|
|
21679
21687
|
if (!/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/u.test(instanceId)) {
|
|
21680
21688
|
throw new Error("mailcrawl instanceId must be a safe single path segment");
|
|
21681
21689
|
}
|
|
21682
21690
|
}
|
|
21683
21691
|
function ensurePrivateMailcrawlDataDir(path) {
|
|
21684
|
-
|
|
21692
|
+
mkdirSync18(path, { recursive: true, mode: 448 });
|
|
21685
21693
|
if (process.platform !== "win32")
|
|
21686
21694
|
chmodSync(path, 448);
|
|
21687
21695
|
}
|
|
21688
21696
|
var init_config = () => {};
|
|
21689
21697
|
|
|
21690
21698
|
// src/datasource/skills/mailcrawl/client.ts
|
|
21691
|
-
import { spawn as
|
|
21699
|
+
import { spawn as spawn14 } from "node:child_process";
|
|
21692
21700
|
|
|
21693
21701
|
class MailcrawlClient {
|
|
21694
21702
|
options;
|
|
@@ -21808,7 +21816,7 @@ class MailcrawlClient {
|
|
|
21808
21816
|
function spawnMailcrawl(binary, args, env, options, signal, timeoutMs) {
|
|
21809
21817
|
return new Promise((resolveResult) => {
|
|
21810
21818
|
const portable = portableSpawnCommand(binary, args);
|
|
21811
|
-
const child =
|
|
21819
|
+
const child = spawn14(portable.command, portable.args, {
|
|
21812
21820
|
env,
|
|
21813
21821
|
detached: process.platform !== "win32",
|
|
21814
21822
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -22504,7 +22512,7 @@ function parseCount(stdout) {
|
|
|
22504
22512
|
return;
|
|
22505
22513
|
if (Array.isArray(parsed))
|
|
22506
22514
|
return parsed.length;
|
|
22507
|
-
if (!
|
|
22515
|
+
if (!isRecord15(parsed))
|
|
22508
22516
|
return;
|
|
22509
22517
|
for (const key of ["pages", "page_count", "pageCount", "synced", "count"]) {
|
|
22510
22518
|
const value = parsed[key];
|
|
@@ -22519,12 +22527,12 @@ function parseHits(stdout) {
|
|
|
22519
22527
|
return parseTabSeparatedHits(trimmed);
|
|
22520
22528
|
}
|
|
22521
22529
|
const parsed = parseJson4(stdout);
|
|
22522
|
-
const rows = Array.isArray(parsed) ? parsed :
|
|
22530
|
+
const rows = Array.isArray(parsed) ? parsed : isRecord15(parsed) && Array.isArray(parsed.results) ? parsed.results : undefined;
|
|
22523
22531
|
if (rows === undefined)
|
|
22524
22532
|
return;
|
|
22525
22533
|
const hits = [];
|
|
22526
22534
|
for (const [index, row] of rows.entries()) {
|
|
22527
|
-
if (!
|
|
22535
|
+
if (!isRecord15(row))
|
|
22528
22536
|
return;
|
|
22529
22537
|
const id = stringValue2(row, ["page_id", "id"]);
|
|
22530
22538
|
const content = stringValue2(row, ["snippet", "text", "content"]);
|
|
@@ -22588,7 +22596,7 @@ function parseJson4(stdout) {
|
|
|
22588
22596
|
return;
|
|
22589
22597
|
}
|
|
22590
22598
|
}
|
|
22591
|
-
function
|
|
22599
|
+
function isRecord15(value) {
|
|
22592
22600
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
22593
22601
|
}
|
|
22594
22602
|
function stringValue2(record, keys) {
|
|
@@ -22638,15 +22646,15 @@ var init_notion = __esm(() => {
|
|
|
22638
22646
|
});
|
|
22639
22647
|
|
|
22640
22648
|
// src/datasource/skills/obsidian/paths.ts
|
|
22641
|
-
import { join as
|
|
22649
|
+
import { join as join27 } from "node:path";
|
|
22642
22650
|
function obsidianDatasourceRoot(workspaceRoot, instanceId) {
|
|
22643
|
-
return
|
|
22651
|
+
return join27(workspaceRoot, AUTORAG_DIRNAME, DATASOURCES_DIRNAME, OBSIDIAN_DATASOURCE_DIRNAME, instanceId);
|
|
22644
22652
|
}
|
|
22645
22653
|
function obsidianQmdConfigDir(workspaceRoot, instanceId) {
|
|
22646
|
-
return
|
|
22654
|
+
return join27(obsidianDatasourceRoot(workspaceRoot, instanceId), "config");
|
|
22647
22655
|
}
|
|
22648
22656
|
function obsidianQmdCacheDir(workspaceRoot, instanceId) {
|
|
22649
|
-
return
|
|
22657
|
+
return join27(obsidianDatasourceRoot(workspaceRoot, instanceId), "cache");
|
|
22650
22658
|
}
|
|
22651
22659
|
function stripEdgeDashes(value) {
|
|
22652
22660
|
let start = 0;
|
|
@@ -22668,8 +22676,8 @@ var init_paths5 = () => {};
|
|
|
22668
22676
|
var DEFAULT_QMD_BINARY = "qmd", DEFAULT_QMD_TIMEOUT_MS = 60000, DEFAULT_QMD_MAX_BUFFER_BYTES = 1048576;
|
|
22669
22677
|
|
|
22670
22678
|
// src/datasource/skills/obsidian/client.ts
|
|
22671
|
-
import { spawn as
|
|
22672
|
-
import { mkdirSync as
|
|
22679
|
+
import { spawn as spawn15 } from "node:child_process";
|
|
22680
|
+
import { mkdirSync as mkdirSync19, writeFileSync as writeFileSync17 } from "node:fs";
|
|
22673
22681
|
import { isAbsolute as isAbsolute6, resolve as resolve12 } from "node:path";
|
|
22674
22682
|
|
|
22675
22683
|
class QmdClient {
|
|
@@ -22689,10 +22697,10 @@ class QmdClient {
|
|
|
22689
22697
|
const cacheDir = obsidianQmdCacheDir(workspaceRoot, instanceId);
|
|
22690
22698
|
try {
|
|
22691
22699
|
if (this.options.configPath === undefined) {
|
|
22692
|
-
|
|
22693
|
-
|
|
22700
|
+
mkdirSync19(configDir, { recursive: true });
|
|
22701
|
+
writeFileSync17(resolve12(configDir, "index.yml"), renderIndexYaml(collectionName, vaultPath), "utf8");
|
|
22694
22702
|
}
|
|
22695
|
-
|
|
22703
|
+
mkdirSync19(cacheDir, { recursive: true });
|
|
22696
22704
|
} catch (error) {
|
|
22697
22705
|
return failure3("spawn-error", error instanceof Error ? error.message : "failed to write qmd config");
|
|
22698
22706
|
}
|
|
@@ -22793,7 +22801,7 @@ function isAllowedEnvKey2(key) {
|
|
|
22793
22801
|
function spawnQmd(request) {
|
|
22794
22802
|
return new Promise((resolveResult) => {
|
|
22795
22803
|
const portable = portableSpawnCommand(request.binaryPath ?? DEFAULT_QMD_BINARY, request.args);
|
|
22796
|
-
const child =
|
|
22804
|
+
const child = spawn15(portable.command, [...portable.args], {
|
|
22797
22805
|
env: request.env,
|
|
22798
22806
|
...request.cwd === undefined ? {} : { cwd: request.cwd },
|
|
22799
22807
|
detached: process.platform !== "win32",
|
|
@@ -22915,7 +22923,7 @@ ${stderr}`;
|
|
|
22915
22923
|
}
|
|
22916
22924
|
try {
|
|
22917
22925
|
const parsed = JSON.parse(stdout);
|
|
22918
|
-
if (
|
|
22926
|
+
if (isRecord16(parsed)) {
|
|
22919
22927
|
return {
|
|
22920
22928
|
indexed: numberField(parsed, "indexed") ?? numberField(parsed, "new") ?? 0,
|
|
22921
22929
|
updated: numberField(parsed, "updated") ?? 0,
|
|
@@ -22944,7 +22952,7 @@ function parseSearchHits(stdout) {
|
|
|
22944
22952
|
function extractHitRows(parsed) {
|
|
22945
22953
|
if (Array.isArray(parsed))
|
|
22946
22954
|
return parsed;
|
|
22947
|
-
if (!
|
|
22955
|
+
if (!isRecord16(parsed))
|
|
22948
22956
|
return;
|
|
22949
22957
|
for (const key of ["results", "hits", "documents", "items"]) {
|
|
22950
22958
|
const value = parsed[key];
|
|
@@ -22956,7 +22964,7 @@ function extractHitRows(parsed) {
|
|
|
22956
22964
|
return;
|
|
22957
22965
|
}
|
|
22958
22966
|
function normalizeHit3(raw) {
|
|
22959
|
-
if (!
|
|
22967
|
+
if (!isRecord16(raw))
|
|
22960
22968
|
return;
|
|
22961
22969
|
const score = numberField(raw, "score") ?? numberField(raw, "relevance") ?? 0;
|
|
22962
22970
|
const docid = stringField(raw, "docid") ?? stringField(raw, "id");
|
|
@@ -23002,7 +23010,7 @@ function numberField(record, key) {
|
|
|
23002
23010
|
const value = record[key];
|
|
23003
23011
|
return typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
23004
23012
|
}
|
|
23005
|
-
function
|
|
23013
|
+
function isRecord16(value) {
|
|
23006
23014
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
23007
23015
|
}
|
|
23008
23016
|
var SAFE_INHERITED_ENV_KEYS3, SAFE_QMD_ENV_PREFIX = "QMD_";
|
|
@@ -23529,7 +23537,7 @@ function parseCount2(stdout) {
|
|
|
23529
23537
|
return;
|
|
23530
23538
|
if (Array.isArray(parsed))
|
|
23531
23539
|
return parsed.length;
|
|
23532
|
-
if (!
|
|
23540
|
+
if (!isRecord17(parsed))
|
|
23533
23541
|
return;
|
|
23534
23542
|
for (const key of ["messages", "message_count", "messageCount", "synced", "count"]) {
|
|
23535
23543
|
const value = parsed[key];
|
|
@@ -23542,12 +23550,12 @@ function parseHits2(stdout) {
|
|
|
23542
23550
|
const parsed = parseJson5(stdout);
|
|
23543
23551
|
if (parsed === null)
|
|
23544
23552
|
return [];
|
|
23545
|
-
const rows = Array.isArray(parsed) ? parsed :
|
|
23553
|
+
const rows = Array.isArray(parsed) ? parsed : isRecord17(parsed) && Array.isArray(parsed.messages) ? parsed.messages : undefined;
|
|
23546
23554
|
if (rows === undefined)
|
|
23547
23555
|
return;
|
|
23548
23556
|
const hits = [];
|
|
23549
23557
|
for (const [index, row] of rows.entries()) {
|
|
23550
|
-
if (!
|
|
23558
|
+
if (!isRecord17(row))
|
|
23551
23559
|
return;
|
|
23552
23560
|
const workspaceId = stringValue3(row, ["workspace_id"]);
|
|
23553
23561
|
const workspaceName = stringValue3(row, ["workspace_name"]);
|
|
@@ -23602,7 +23610,7 @@ function parseJson5(stdout) {
|
|
|
23602
23610
|
return;
|
|
23603
23611
|
}
|
|
23604
23612
|
}
|
|
23605
|
-
function
|
|
23613
|
+
function isRecord17(value) {
|
|
23606
23614
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
23607
23615
|
}
|
|
23608
23616
|
function stringValue3(record, keys) {
|
|
@@ -23665,10 +23673,10 @@ var init_slack = __esm(() => {
|
|
|
23665
23673
|
});
|
|
23666
23674
|
|
|
23667
23675
|
// src/datasource/skills/spotlight/connector.ts
|
|
23668
|
-
import { spawn as
|
|
23676
|
+
import { spawn as spawn16 } from "node:child_process";
|
|
23669
23677
|
import { createHash as createHash8 } from "node:crypto";
|
|
23670
23678
|
import { readFile as fsReadFile, stat as stat6 } from "node:fs/promises";
|
|
23671
|
-
import { basename as
|
|
23679
|
+
import { basename as basename10, extname as extname8 } from "node:path";
|
|
23672
23680
|
|
|
23673
23681
|
class SpotlightConnector {
|
|
23674
23682
|
options;
|
|
@@ -23752,10 +23760,10 @@ class SpotlightConnector {
|
|
|
23752
23760
|
documents.push({
|
|
23753
23761
|
docId: createHash8("sha256").update(path).digest("hex").slice(0, 16),
|
|
23754
23762
|
hierarchy: ["files"],
|
|
23755
|
-
title:
|
|
23763
|
+
title: basename10(path),
|
|
23756
23764
|
content,
|
|
23757
23765
|
publishedAt: info.mtimeMs,
|
|
23758
|
-
metadata: { path, extension:
|
|
23766
|
+
metadata: { path, extension: extname8(path).toLowerCase() }
|
|
23759
23767
|
});
|
|
23760
23768
|
} catch (error) {
|
|
23761
23769
|
const code = error.code;
|
|
@@ -23784,7 +23792,7 @@ class SpotlightConnector {
|
|
|
23784
23792
|
}
|
|
23785
23793
|
}
|
|
23786
23794
|
var DEFAULT_MAX_RESULTS_PER_QUERY = 100, DEFAULT_MAX_DOCUMENTS5 = 300, DEFAULT_MAX_BYTES_PER_FILE3, DEFAULT_TIMEOUT_MS9 = 15000, MAX_CONTENT_CHARS3 = 1e5, MAX_BUFFER_BYTES, FDA_GUIDANCE = "grant Full Disk Access to the terminal or app running AutoRAG (System Settings -> Privacy & Security -> Full Disk Access), then restart it", spawnRunner = (command, args, timeoutMs) => new Promise((resolve) => {
|
|
23787
|
-
const child =
|
|
23795
|
+
const child = spawn16(command, [...args], { stdio: ["ignore", "pipe", "pipe"] });
|
|
23788
23796
|
let stdout = "";
|
|
23789
23797
|
let stderr = "";
|
|
23790
23798
|
let settled = false;
|
|
@@ -23880,7 +23888,7 @@ function parseCount3(stdout) {
|
|
|
23880
23888
|
return;
|
|
23881
23889
|
if (Array.isArray(parsed))
|
|
23882
23890
|
return parsed.length;
|
|
23883
|
-
if (!
|
|
23891
|
+
if (!isRecord18(parsed))
|
|
23884
23892
|
return;
|
|
23885
23893
|
for (const key of ["messages", "message_count", "messageCount", "imported", "count"]) {
|
|
23886
23894
|
const value = parsed[key];
|
|
@@ -23893,12 +23901,12 @@ function parseHits3(stdout) {
|
|
|
23893
23901
|
const parsed = parseJson6(stdout);
|
|
23894
23902
|
if (parsed === null)
|
|
23895
23903
|
return [];
|
|
23896
|
-
const rows = Array.isArray(parsed) ? parsed :
|
|
23904
|
+
const rows = Array.isArray(parsed) ? parsed : isRecord18(parsed) && Array.isArray(parsed.messages) ? parsed.messages : undefined;
|
|
23897
23905
|
if (rows === undefined)
|
|
23898
23906
|
return;
|
|
23899
23907
|
const hits = [];
|
|
23900
23908
|
for (const [index, row] of rows.entries()) {
|
|
23901
|
-
if (!
|
|
23909
|
+
if (!isRecord18(row))
|
|
23902
23910
|
return;
|
|
23903
23911
|
const id = stringValue4(row, ["message_id", "event_id", "id"]);
|
|
23904
23912
|
const content = stringValue4(row, ["snippet", "text", "content"]);
|
|
@@ -23937,7 +23945,7 @@ function parseJson6(stdout) {
|
|
|
23937
23945
|
return;
|
|
23938
23946
|
}
|
|
23939
23947
|
}
|
|
23940
|
-
function
|
|
23948
|
+
function isRecord18(value) {
|
|
23941
23949
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
23942
23950
|
}
|
|
23943
23951
|
function stringValue4(record, keys) {
|
|
@@ -24000,7 +24008,7 @@ function parseCount4(stdout) {
|
|
|
24000
24008
|
return;
|
|
24001
24009
|
if (Array.isArray(parsed))
|
|
24002
24010
|
return parsed.length;
|
|
24003
|
-
if (!
|
|
24011
|
+
if (!isRecord19(parsed))
|
|
24004
24012
|
return;
|
|
24005
24013
|
for (const key of ["messages", "message_count", "messageCount", "imported", "count"]) {
|
|
24006
24014
|
const value = parsed[key];
|
|
@@ -24013,12 +24021,12 @@ function parseHits4(stdout) {
|
|
|
24013
24021
|
const parsed = parseJson7(stdout);
|
|
24014
24022
|
if (parsed === null)
|
|
24015
24023
|
return [];
|
|
24016
|
-
const rows = Array.isArray(parsed) ? parsed :
|
|
24024
|
+
const rows = Array.isArray(parsed) ? parsed : isRecord19(parsed) && Array.isArray(parsed.messages) ? parsed.messages : undefined;
|
|
24017
24025
|
if (rows === undefined)
|
|
24018
24026
|
return;
|
|
24019
24027
|
const hits = [];
|
|
24020
24028
|
for (const [index, row] of rows.entries()) {
|
|
24021
|
-
if (!
|
|
24029
|
+
if (!isRecord19(row))
|
|
24022
24030
|
return;
|
|
24023
24031
|
const id = stringValue5(row, ["message_id", "event_id", "id"]);
|
|
24024
24032
|
const content = stringValue5(row, ["snippet", "text", "content"]);
|
|
@@ -24055,7 +24063,7 @@ function parseJson7(stdout) {
|
|
|
24055
24063
|
return;
|
|
24056
24064
|
}
|
|
24057
24065
|
}
|
|
24058
|
-
function
|
|
24066
|
+
function isRecord19(value) {
|
|
24059
24067
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
24060
24068
|
}
|
|
24061
24069
|
function stringValue5(record, keys) {
|
|
@@ -24343,9 +24351,9 @@ var init_factory = __esm(() => {
|
|
|
24343
24351
|
});
|
|
24344
24352
|
|
|
24345
24353
|
// src/cli/config.ts
|
|
24346
|
-
import { randomUUID as
|
|
24347
|
-
import { existsSync as existsSync23, mkdirSync as
|
|
24348
|
-
import { basename as
|
|
24354
|
+
import { randomUUID as randomUUID8 } from "node:crypto";
|
|
24355
|
+
import { existsSync as existsSync23, mkdirSync as mkdirSync20, readFileSync as readFileSync19, renameSync as renameSync9, unlinkSync as unlinkSync4, writeFileSync as writeFileSync18 } from "node:fs";
|
|
24356
|
+
import { basename as basename11, dirname as dirname20, isAbsolute as isAbsolute7, join as join28, resolve as resolve13 } from "node:path";
|
|
24349
24357
|
import { findEnvKeys, getEnvApiKey, getModel, getProviders } from "@earendil-works/pi-ai/compat";
|
|
24350
24358
|
function resolveConfigPath(input) {
|
|
24351
24359
|
const flags = input.flags;
|
|
@@ -24360,9 +24368,9 @@ function resolveConfigPath(input) {
|
|
|
24360
24368
|
return { configPath: envConfig, explicit: true };
|
|
24361
24369
|
}
|
|
24362
24370
|
return {
|
|
24363
|
-
configPath:
|
|
24371
|
+
configPath: join28(resolveAutoRAGHome(env), DEFAULT_CONFIG_FILENAME),
|
|
24364
24372
|
explicit: false,
|
|
24365
|
-
legacyPath:
|
|
24373
|
+
legacyPath: join28(cwd, LEGACY_CONFIG_FILENAME)
|
|
24366
24374
|
};
|
|
24367
24375
|
}
|
|
24368
24376
|
function readConfigFile(configPath, explicit) {
|
|
@@ -24380,7 +24388,7 @@ function readConfigFile(configPath, explicit) {
|
|
|
24380
24388
|
}
|
|
24381
24389
|
let text;
|
|
24382
24390
|
try {
|
|
24383
|
-
text =
|
|
24391
|
+
text = readFileSync19(configPath, "utf8");
|
|
24384
24392
|
} catch (err) {
|
|
24385
24393
|
throw new ConfigError(`Failed to read config file: ${err.message}`);
|
|
24386
24394
|
}
|
|
@@ -24418,11 +24426,11 @@ function acquireConfigWriteLock(configPath) {
|
|
|
24418
24426
|
});
|
|
24419
24427
|
}
|
|
24420
24428
|
function replaceFileAtomically(path, contents, assertCommitAllowed) {
|
|
24421
|
-
const temporaryPath =
|
|
24429
|
+
const temporaryPath = join28(dirname20(path), `.${basename11(path)}.${process.pid}.${randomUUID8()}.tmp`);
|
|
24422
24430
|
try {
|
|
24423
|
-
|
|
24431
|
+
writeFileSync18(temporaryPath, contents, { encoding: "utf8", flag: "wx", flush: true, mode: 384 });
|
|
24424
24432
|
assertCommitAllowed?.();
|
|
24425
|
-
|
|
24433
|
+
renameSync9(temporaryPath, path);
|
|
24426
24434
|
} finally {
|
|
24427
24435
|
removeFileIfPresent2(temporaryPath);
|
|
24428
24436
|
}
|
|
@@ -24431,12 +24439,12 @@ function migrateLegacyConfig(configPath, legacyPath) {
|
|
|
24431
24439
|
if (existsSync23(configPath) || !existsSync23(legacyPath))
|
|
24432
24440
|
return;
|
|
24433
24441
|
const legacy = readConfigFile(legacyPath, true);
|
|
24434
|
-
const legacyBytes =
|
|
24435
|
-
const migrated = normalizeLegacyConfigPaths(legacy ?? {},
|
|
24442
|
+
const legacyBytes = readFileSync19(legacyPath);
|
|
24443
|
+
const migrated = normalizeLegacyConfigPaths(legacy ?? {}, dirname20(legacyPath));
|
|
24436
24444
|
const migratedPathsUnchanged = legacy?.workspacePath === migrated.workspacePath && legacy?.memoryPath === migrated.memoryPath && JSON.stringify(legacy?.searchPaths) === JSON.stringify(migrated.searchPaths);
|
|
24437
24445
|
const migratedBytes = migratedPathsUnchanged ? legacyBytes : `${JSON.stringify(migrated, null, 2)}
|
|
24438
24446
|
`;
|
|
24439
|
-
|
|
24447
|
+
mkdirSync20(dirname20(configPath), { recursive: true });
|
|
24440
24448
|
const lock = acquireConfigWriteLock(configPath);
|
|
24441
24449
|
try {
|
|
24442
24450
|
const winner = readConfigFile(configPath, false);
|
|
@@ -24466,7 +24474,7 @@ function resolveConfigFileReadOnly(configPath, explicit, legacyPath) {
|
|
|
24466
24474
|
const legacy = readConfigFile(legacyPath, false);
|
|
24467
24475
|
if (legacy === undefined)
|
|
24468
24476
|
return {};
|
|
24469
|
-
return normalizeLegacyConfigPaths(legacy,
|
|
24477
|
+
return normalizeLegacyConfigPaths(legacy, dirname20(legacyPath));
|
|
24470
24478
|
}
|
|
24471
24479
|
function resolveSearchPaths(searchPaths, origin) {
|
|
24472
24480
|
return searchPaths.map((searchPath) => resolvePersistedPath(searchPath, origin));
|
|
@@ -24501,6 +24509,15 @@ function envString(env, key) {
|
|
|
24501
24509
|
return value;
|
|
24502
24510
|
return;
|
|
24503
24511
|
}
|
|
24512
|
+
function normalizeConfigLanguages(raw) {
|
|
24513
|
+
try {
|
|
24514
|
+
return normalizeLanguages(raw);
|
|
24515
|
+
} catch (error) {
|
|
24516
|
+
if (error instanceof LanguageError)
|
|
24517
|
+
throw new ConfigError(error.message);
|
|
24518
|
+
throw error;
|
|
24519
|
+
}
|
|
24520
|
+
}
|
|
24504
24521
|
function modelReference(value, path) {
|
|
24505
24522
|
if (value === undefined)
|
|
24506
24523
|
return;
|
|
@@ -24666,80 +24683,6 @@ function normalizeEmbedder(raw, path) {
|
|
|
24666
24683
|
}
|
|
24667
24684
|
return out;
|
|
24668
24685
|
}
|
|
24669
|
-
function normalizeUiConfig(raw) {
|
|
24670
|
-
if (raw === undefined || raw === null)
|
|
24671
|
-
return {};
|
|
24672
|
-
if (typeof raw !== "object" || Array.isArray(raw))
|
|
24673
|
-
throw new ConfigError("Config field 'ui' must be an object");
|
|
24674
|
-
const record = raw;
|
|
24675
|
-
const allowed = new Set(["host", "port", "allowRemote", "publicOrigin", "corsOrigins", "tokenEnv"]);
|
|
24676
|
-
for (const key of Object.keys(record)) {
|
|
24677
|
-
if (!allowed.has(key))
|
|
24678
|
-
throw new ConfigError(`ui.${key} is not a recognized field`);
|
|
24679
|
-
}
|
|
24680
|
-
const out = {};
|
|
24681
|
-
if (record.host !== undefined) {
|
|
24682
|
-
if (typeof record.host !== "string" || record.host.trim().length === 0) {
|
|
24683
|
-
throw new ConfigError("ui.host must be a non-empty string");
|
|
24684
|
-
}
|
|
24685
|
-
out.host = record.host.trim();
|
|
24686
|
-
}
|
|
24687
|
-
if (record.port !== undefined) {
|
|
24688
|
-
if (typeof record.port !== "number" || !Number.isInteger(record.port) || record.port < 0 || record.port > 65535) {
|
|
24689
|
-
throw new ConfigError("ui.port must be an integer between 0 and 65535");
|
|
24690
|
-
}
|
|
24691
|
-
out.port = record.port;
|
|
24692
|
-
}
|
|
24693
|
-
if (record.allowRemote !== undefined) {
|
|
24694
|
-
if (typeof record.allowRemote !== "boolean")
|
|
24695
|
-
throw new ConfigError("ui.allowRemote must be a boolean");
|
|
24696
|
-
out.allowRemote = record.allowRemote;
|
|
24697
|
-
}
|
|
24698
|
-
if (record.publicOrigin !== undefined) {
|
|
24699
|
-
if (typeof record.publicOrigin !== "string" || record.publicOrigin.trim().length === 0) {
|
|
24700
|
-
throw new ConfigError("ui.publicOrigin must be a non-empty origin");
|
|
24701
|
-
}
|
|
24702
|
-
let origin;
|
|
24703
|
-
try {
|
|
24704
|
-
origin = new URL(record.publicOrigin);
|
|
24705
|
-
} catch {
|
|
24706
|
-
throw new ConfigError("ui.publicOrigin must be a valid http(s) origin");
|
|
24707
|
-
}
|
|
24708
|
-
if (!["http:", "https:"].includes(origin.protocol) || origin.pathname !== "/" || origin.search || origin.hash) {
|
|
24709
|
-
throw new ConfigError("ui.publicOrigin must be a valid http(s) origin");
|
|
24710
|
-
}
|
|
24711
|
-
out.publicOrigin = origin.origin;
|
|
24712
|
-
}
|
|
24713
|
-
if (record.corsOrigins !== undefined) {
|
|
24714
|
-
if (!Array.isArray(record.corsOrigins))
|
|
24715
|
-
throw new ConfigError("ui.corsOrigins must be an array of origins");
|
|
24716
|
-
const origins = [];
|
|
24717
|
-
for (const value of record.corsOrigins) {
|
|
24718
|
-
if (typeof value !== "string" || value.trim().length === 0) {
|
|
24719
|
-
throw new ConfigError("ui.corsOrigins must contain non-empty origins");
|
|
24720
|
-
}
|
|
24721
|
-
let origin;
|
|
24722
|
-
try {
|
|
24723
|
-
origin = new URL(value);
|
|
24724
|
-
} catch {
|
|
24725
|
-
throw new ConfigError("ui.corsOrigins must contain valid http(s) origins");
|
|
24726
|
-
}
|
|
24727
|
-
if (!["http:", "https:"].includes(origin.protocol) || origin.pathname !== "/" || origin.search || origin.hash) {
|
|
24728
|
-
throw new ConfigError("ui.corsOrigins must contain valid http(s) origins");
|
|
24729
|
-
}
|
|
24730
|
-
if (!origins.includes(origin.origin))
|
|
24731
|
-
origins.push(origin.origin);
|
|
24732
|
-
}
|
|
24733
|
-
out.corsOrigins = origins;
|
|
24734
|
-
}
|
|
24735
|
-
if (record.tokenEnv !== undefined) {
|
|
24736
|
-
if (typeof record.tokenEnv !== "string" || !UI_TOKEN_ENV_PATTERN.test(record.tokenEnv)) {
|
|
24737
|
-
throw new ConfigError("ui.tokenEnv must match /^[A-Za-z_][A-Za-z0-9_]*$/");
|
|
24738
|
-
}
|
|
24739
|
-
out.tokenEnv = record.tokenEnv;
|
|
24740
|
-
}
|
|
24741
|
-
return out;
|
|
24742
|
-
}
|
|
24743
24686
|
function normalizeP2pConfig(raw) {
|
|
24744
24687
|
const out = {};
|
|
24745
24688
|
if (raw === undefined || raw === null) {
|
|
@@ -24911,10 +24854,10 @@ function resolveConfig(input) {
|
|
|
24911
24854
|
const file = readOnly ? resolveConfigFileReadOnly(configPath, explicit, legacyPath) : !explicit && legacyPath ? migrateLegacyConfig(configPath, legacyPath) ?? readConfigFile(configPath, explicit) ?? {} : readConfigFile(configPath, explicit) ?? {};
|
|
24912
24855
|
const defaultSearchPaths = ["."];
|
|
24913
24856
|
const defaultWorkspacePath = cwd;
|
|
24914
|
-
const defaultMemoryPath =
|
|
24857
|
+
const defaultMemoryPath = join28(resolveAutoRAGHome(env), "memory.json");
|
|
24915
24858
|
const flagSearchPaths = parseCsv(flagString(flags, "search-paths"));
|
|
24916
24859
|
const envSearchPaths = parseCsv(envString(env, "AUTORAG_SEARCH_PATHS"));
|
|
24917
|
-
const configOrigin =
|
|
24860
|
+
const configOrigin = dirname20(resolve13(configPath));
|
|
24918
24861
|
const fileWorkspacePath = typeof file.workspacePath === "string" ? resolvePersistedPath(file.workspacePath, configOrigin) : undefined;
|
|
24919
24862
|
const fileSearchPaths = file.searchPaths ? resolveSearchPaths(file.searchPaths, fileWorkspacePath ?? configOrigin) : undefined;
|
|
24920
24863
|
const searchPaths = flagSearchPaths ?? envSearchPaths ?? fileSearchPaths ?? defaultSearchPaths;
|
|
@@ -24925,6 +24868,9 @@ function resolveConfig(input) {
|
|
|
24925
24868
|
const envMemoryPath = envString(env, "AUTORAG_MEMORY_PATH");
|
|
24926
24869
|
const fileMemoryPath = typeof file.memoryPath === "string" ? resolvePersistedPath(file.memoryPath, workspacePath) : undefined;
|
|
24927
24870
|
const memoryPath = flagMemoryPath ?? envMemoryPath ?? fileMemoryPath ?? defaultMemoryPath;
|
|
24871
|
+
const flagLanguages = typeof flags.languages === "string" ? flags.languages : undefined;
|
|
24872
|
+
const envLanguages = env.AUTORAG_LANGUAGES;
|
|
24873
|
+
const languages = flagLanguages !== undefined ? normalizeConfigLanguages(flagLanguages) : envLanguages !== undefined ? normalizeConfigLanguages(envLanguages) : normalizeConfigLanguages(file.languages);
|
|
24928
24874
|
const fileModel = modelReference(file.model, "model");
|
|
24929
24875
|
const flagModelProvider = pickString(flags, env, "model-provider", "AUTORAG_MODEL_PROVIDER", undefined);
|
|
24930
24876
|
const flagModelId = pickString(flags, env, "model-id", "AUTORAG_MODEL_ID", undefined);
|
|
@@ -24932,7 +24878,8 @@ function resolveConfig(input) {
|
|
|
24932
24878
|
const config = {
|
|
24933
24879
|
searchPaths,
|
|
24934
24880
|
workspacePath,
|
|
24935
|
-
memoryPath
|
|
24881
|
+
memoryPath,
|
|
24882
|
+
languages
|
|
24936
24883
|
};
|
|
24937
24884
|
if (model)
|
|
24938
24885
|
config.model = model;
|
|
@@ -24965,8 +24912,6 @@ function resolveConfig(input) {
|
|
|
24965
24912
|
}
|
|
24966
24913
|
config.datasourceAccess = file.datasourceAccess;
|
|
24967
24914
|
}
|
|
24968
|
-
if (file.ui !== undefined)
|
|
24969
|
-
config.ui = normalizeUiConfig(file.ui);
|
|
24970
24915
|
config.p2p = normalizeP2pConfig(file.p2p);
|
|
24971
24916
|
return config;
|
|
24972
24917
|
}
|
|
@@ -25028,7 +24973,8 @@ function buildWebSearchAgentOption(raw) {
|
|
|
25028
24973
|
}
|
|
25029
24974
|
function buildAgentOptions(config) {
|
|
25030
24975
|
const opts = {
|
|
25031
|
-
searchPaths: config.searchPaths
|
|
24976
|
+
searchPaths: config.searchPaths,
|
|
24977
|
+
languages: config.languages
|
|
25032
24978
|
};
|
|
25033
24979
|
if (config.workspacePath)
|
|
25034
24980
|
opts.workspacePath = config.workspacePath;
|
|
@@ -25271,7 +25217,7 @@ function writeConfigObject(path, config) {
|
|
|
25271
25217
|
if (config === null || typeof config !== "object" || Array.isArray(config)) {
|
|
25272
25218
|
throw new ConfigError("Config file must be a JSON object");
|
|
25273
25219
|
}
|
|
25274
|
-
|
|
25220
|
+
mkdirSync20(dirname20(path), { recursive: true });
|
|
25275
25221
|
const contents = `${JSON.stringify(config, null, 2)}
|
|
25276
25222
|
`;
|
|
25277
25223
|
const lock = acquireConfigWriteLock(path);
|
|
@@ -25284,11 +25230,12 @@ function writeConfigObject(path, config) {
|
|
|
25284
25230
|
function writeDefaultConfig(path, partial, opts = {}) {
|
|
25285
25231
|
const cwd = resolve13(opts.cwd ?? process.cwd());
|
|
25286
25232
|
const workspacePath = resolvePersistedPath(partial.workspacePath ?? ".", cwd);
|
|
25287
|
-
const memoryPath = partial.memoryPath === undefined ?
|
|
25233
|
+
const memoryPath = partial.memoryPath === undefined ? join28(resolveAutoRAGHome(opts.env), "memory.json") : resolvePersistedPath(partial.memoryPath, workspacePath);
|
|
25288
25234
|
const full = {
|
|
25289
25235
|
searchPaths: resolveSearchPaths(partial.searchPaths ?? ["."], cwd),
|
|
25290
25236
|
workspacePath,
|
|
25291
|
-
memoryPath
|
|
25237
|
+
memoryPath,
|
|
25238
|
+
languages: normalizeConfigLanguages(partial.languages)
|
|
25292
25239
|
};
|
|
25293
25240
|
if (partial.model)
|
|
25294
25241
|
full.model = partial.model;
|
|
@@ -25301,13 +25248,11 @@ function writeDefaultConfig(path, partial, opts = {}) {
|
|
|
25301
25248
|
full.excludeExactDuplicates = partial.excludeExactDuplicates ?? true;
|
|
25302
25249
|
if (partial.parserOptions)
|
|
25303
25250
|
full.parserOptions = partial.parserOptions;
|
|
25304
|
-
if (partial.ui !== undefined)
|
|
25305
|
-
full.ui = normalizeUiConfig(partial.ui);
|
|
25306
25251
|
if (partial.p2p !== undefined)
|
|
25307
25252
|
full.p2p = normalizeP2pConfig(partial.p2p);
|
|
25308
25253
|
else
|
|
25309
25254
|
full.p2p = { enabled: false };
|
|
25310
|
-
|
|
25255
|
+
mkdirSync20(dirname20(path), { recursive: true });
|
|
25311
25256
|
const contents = `${JSON.stringify(full, null, 2)}
|
|
25312
25257
|
`;
|
|
25313
25258
|
const lock = acquireConfigWriteLock(path);
|
|
@@ -25319,7 +25264,7 @@ function writeDefaultConfig(path, partial, opts = {}) {
|
|
|
25319
25264
|
replaceFileAtomically(path, contents, lock.assertOwned);
|
|
25320
25265
|
else {
|
|
25321
25266
|
lock.assertOwned();
|
|
25322
|
-
|
|
25267
|
+
writeFileSync18(path, contents, { encoding: "utf8", flag: "wx", flush: true, mode: 384 });
|
|
25323
25268
|
}
|
|
25324
25269
|
} catch (error) {
|
|
25325
25270
|
if (!opts.force && isEexistError(error)) {
|
|
@@ -25330,12 +25275,13 @@ function writeDefaultConfig(path, partial, opts = {}) {
|
|
|
25330
25275
|
lock.release();
|
|
25331
25276
|
}
|
|
25332
25277
|
}
|
|
25333
|
-
var DEFAULT_CONFIG_FILENAME = "config.json", LEGACY_CONFIG_FILENAME = "autorag.config.json", CONFIG_LOCK_RETRY_MS = 10, CONFIG_LOCK_TIMEOUT_MS = 1e4, CONFIG_LOCK_STALE_MS = 30000, ConfigError, AGENT_MODEL_APIS, AGENT_MODEL_INPUTS, API_KEY_ENV_PATTERN2, POSITIVE_INT_FIELDS, EMBEDDER_ALLOWLIST, MINSYNC_ALLOWLIST, MINSYNC_LEGACY_IGNORED,
|
|
25278
|
+
var DEFAULT_CONFIG_FILENAME = "config.json", LEGACY_CONFIG_FILENAME = "autorag.config.json", CONFIG_LOCK_RETRY_MS = 10, CONFIG_LOCK_TIMEOUT_MS = 1e4, CONFIG_LOCK_STALE_MS = 30000, ConfigError, AGENT_MODEL_APIS, AGENT_MODEL_INPUTS, API_KEY_ENV_PATTERN2, POSITIVE_INT_FIELDS, EMBEDDER_ALLOWLIST, MINSYNC_ALLOWLIST, MINSYNC_LEGACY_IGNORED, P2P_ALLOWLIST, P2P_QUOTA_ALLOWLIST;
|
|
25334
25279
|
var init_config2 = __esm(() => {
|
|
25335
25280
|
init_local_model();
|
|
25336
25281
|
init_home();
|
|
25337
25282
|
init_factory();
|
|
25338
25283
|
init_file_lock();
|
|
25284
|
+
init_language();
|
|
25339
25285
|
init_types3();
|
|
25340
25286
|
init_home();
|
|
25341
25287
|
ConfigError = class ConfigError extends Error {
|
|
@@ -25376,7 +25322,6 @@ var init_config2 = __esm(() => {
|
|
|
25376
25322
|
"embedder"
|
|
25377
25323
|
]);
|
|
25378
25324
|
MINSYNC_LEGACY_IGNORED = new Set(["binaryPath"]);
|
|
25379
|
-
UI_TOKEN_ENV_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
25380
25325
|
P2P_ALLOWLIST = new Set([
|
|
25381
25326
|
"enabled",
|
|
25382
25327
|
"port",
|
|
@@ -25395,7 +25340,7 @@ var init_config2 = __esm(() => {
|
|
|
25395
25340
|
});
|
|
25396
25341
|
|
|
25397
25342
|
// src/core.ts
|
|
25398
|
-
import { randomUUID as
|
|
25343
|
+
import { randomUUID as randomUUID9 } from "node:crypto";
|
|
25399
25344
|
|
|
25400
25345
|
class AutoRAGLite {
|
|
25401
25346
|
config;
|
|
@@ -25448,7 +25393,7 @@ class AutoRAGLite {
|
|
|
25448
25393
|
return recordStructuredResultsSession(sessionId, query, details, this.sessions, this.memory);
|
|
25449
25394
|
}
|
|
25450
25395
|
recordReport(query, details) {
|
|
25451
|
-
return this.recordStructuredResultsSession(
|
|
25396
|
+
return this.recordStructuredResultsSession(randomUUID9(), query, details);
|
|
25452
25397
|
}
|
|
25453
25398
|
getResultRegistry(sessionId) {
|
|
25454
25399
|
return this.sessions.get(sessionId)?.registry ?? new Map;
|