wiki-graph-sdk 0.7.1 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -1
- package/dist/archives.cjs +494 -656
- package/dist/archives.cjs.map +1 -1
- package/dist/archives.d.ts +48 -80
- package/dist/archives.js +431 -585
- package/dist/archives.js.map +1 -1
- package/dist/conversions.cjs +183 -33
- package/dist/conversions.cjs.map +1 -1
- package/dist/conversions.d.ts +8 -1
- package/dist/conversions.js +188 -29
- package/dist/conversions.js.map +1 -1
- package/dist/default-worker.cjs +322 -62
- package/dist/default-worker.cjs.map +1 -1
- package/dist/default-worker.d.ts +1 -0
- package/dist/default-worker.js +336 -60
- package/dist/default-worker.js.map +1 -1
- package/dist/embedding.cjs +2 -1
- package/dist/embedding.cjs.map +1 -1
- package/dist/embedding.d.ts +4 -4
- package/dist/embedding.js +2 -1
- package/dist/embedding.js.map +1 -1
- package/dist/index.cjs +1295 -949
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +58 -24
- package/dist/index.js +1164 -805
- package/dist/index.js.map +1 -1
- package/dist/{jobs-Dd5PMSId.d.ts → jobs-CRK-DZ40.d.ts} +27 -14
- package/dist/local-config.cjs +2 -1
- package/dist/local-config.cjs.map +1 -1
- package/dist/local-config.js +2 -1
- package/dist/local-config.js.map +1 -1
- package/dist/maintenance.cjs +140 -30
- package/dist/maintenance.cjs.map +1 -1
- package/dist/maintenance.d.ts +5 -1
- package/dist/maintenance.js +145 -26
- package/dist/maintenance.js.map +1 -1
- package/dist/runtime-config.cjs +4 -3
- package/dist/runtime-config.cjs.map +1 -1
- package/dist/runtime-config.d.ts +4 -1
- package/dist/runtime-config.js +4 -3
- package/dist/runtime-config.js.map +1 -1
- package/dist/stage-BnWI3Rqt.d.ts +33 -0
- package/dist/stage.cjs +22 -12
- package/dist/stage.cjs.map +1 -1
- package/dist/stage.d.ts +2 -14
- package/dist/stage.js +22 -12
- package/dist/stage.js.map +1 -1
- package/dist/target-CZ7elwmj.d.ts +14 -0
- package/dist/wikispine.cjs +14 -10
- package/dist/wikispine.cjs.map +1 -1
- package/dist/wikispine.js +14 -10
- package/dist/wikispine.js.map +1 -1
- package/dist/worker.cjs +295 -25
- package/dist/worker.cjs.map +1 -1
- package/dist/worker.d.ts +28 -5
- package/dist/worker.js +313 -28
- package/dist/worker.js.map +1 -1
- package/package.json +2 -2
package/dist/archives.js
CHANGED
|
@@ -4,20 +4,20 @@ globalThis.__WIKIGRAPH_DATA_DIR__ ??= __WIKIGRAPH_RESOLVE__(__WIKIGRAPH_FILE_URL
|
|
|
4
4
|
|
|
5
5
|
// src/archive/archive.ts
|
|
6
6
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
7
|
-
import { link, mkdtemp, rename as rename2, rm as rm3, stat as
|
|
7
|
+
import { link, mkdtemp, rename as rename2, rm as rm3, stat as stat3 } from "fs/promises";
|
|
8
8
|
import { tmpdir } from "os";
|
|
9
|
-
import { basename as
|
|
9
|
+
import { basename as basename4, dirname as dirname3, join as join4 } from "path";
|
|
10
10
|
import { Readable as Readable2 } from "stream";
|
|
11
11
|
import {
|
|
12
12
|
addChapter,
|
|
13
13
|
applyChapterTree,
|
|
14
|
+
assertArchiveIndexArtifactsReady,
|
|
14
15
|
assertNoActiveBuildJobConflicts,
|
|
15
16
|
assertNoActiveBuildJobs,
|
|
16
17
|
deleteArchiveSearchSessions,
|
|
17
18
|
DirectoryDocument,
|
|
18
|
-
finalizeWikiGraphLibraryArchiveWrite,
|
|
19
19
|
findArchiveObjects,
|
|
20
|
-
formatLocatedWikiGraphUri,
|
|
20
|
+
formatLocatedWikiGraphUri as formatLocatedWikiGraphUri2,
|
|
21
21
|
isArchiveSearchIndexCurrent as isArchiveSearchIndexCurrent2,
|
|
22
22
|
isSourceLocatorScopeUri,
|
|
23
23
|
listArchiveCollection,
|
|
@@ -28,23 +28,19 @@ import {
|
|
|
28
28
|
listRelatedArchiveObjects,
|
|
29
29
|
moveChapter,
|
|
30
30
|
packArchiveContext,
|
|
31
|
-
parseLocatedWikiGraphUri,
|
|
32
|
-
parseWikiGraphLibraryUri,
|
|
31
|
+
parseLocatedWikiGraphUri as parseLocatedWikiGraphUri2,
|
|
33
32
|
readArchivePage,
|
|
34
33
|
readSearchIndexCapabilityStatus,
|
|
35
|
-
readWikiGraphLibraryIndexState,
|
|
36
34
|
rebuildArchiveSearchIndex,
|
|
37
|
-
rebuildWikiGraphLibraryIndex,
|
|
38
35
|
removeChapter,
|
|
39
36
|
resetChapter,
|
|
40
37
|
resolveChapterPathReadonly,
|
|
41
|
-
resolveWikiGraphLibraryArchiveFile,
|
|
42
38
|
setChapterSource,
|
|
43
39
|
setChapterSummary,
|
|
44
40
|
setChapterTitle,
|
|
45
41
|
getChapterTree,
|
|
46
42
|
WikiGraph as WikiGraph2,
|
|
47
|
-
WikiGraphArchiveFile,
|
|
43
|
+
WikiGraphArchiveFile as WikiGraphArchiveFile2,
|
|
48
44
|
TOC_FILE_VERSION,
|
|
49
45
|
writeWikgArchive,
|
|
50
46
|
ObjectMetadataKind
|
|
@@ -54,7 +50,7 @@ import {
|
|
|
54
50
|
import { createHash } from "crypto";
|
|
55
51
|
import { createReadStream } from "fs";
|
|
56
52
|
import { rm as rm2 } from "fs/promises";
|
|
57
|
-
import { basename as
|
|
53
|
+
import { basename as basename3 } from "path";
|
|
58
54
|
import {
|
|
59
55
|
WikiGraph
|
|
60
56
|
} from "wiki-graph-core";
|
|
@@ -383,42 +379,42 @@ var NodeDatabaseConnection = class {
|
|
|
383
379
|
}
|
|
384
380
|
database;
|
|
385
381
|
async close() {
|
|
386
|
-
await new Promise((
|
|
382
|
+
await new Promise((resolve4, reject) => {
|
|
387
383
|
this.database.close((error) => {
|
|
388
384
|
if (error) reject(error);
|
|
389
|
-
else
|
|
385
|
+
else resolve4();
|
|
390
386
|
});
|
|
391
387
|
});
|
|
392
388
|
}
|
|
393
389
|
async execute(sql) {
|
|
394
|
-
await new Promise((
|
|
390
|
+
await new Promise((resolve4, reject) => {
|
|
395
391
|
this.database.exec(sql, (error) => {
|
|
396
392
|
if (error) reject(error);
|
|
397
|
-
else
|
|
393
|
+
else resolve4();
|
|
398
394
|
});
|
|
399
395
|
});
|
|
400
396
|
}
|
|
401
397
|
async queryAll(sql, params = []) {
|
|
402
|
-
return await new Promise((
|
|
398
|
+
return await new Promise((resolve4, reject) => {
|
|
403
399
|
this.database.all(sql, [...params], (error, rows) => {
|
|
404
400
|
if (error) reject(error);
|
|
405
|
-
else
|
|
401
|
+
else resolve4(rows);
|
|
406
402
|
});
|
|
407
403
|
});
|
|
408
404
|
}
|
|
409
405
|
async queryOne(sql, params = []) {
|
|
410
|
-
return await new Promise((
|
|
406
|
+
return await new Promise((resolve4, reject) => {
|
|
411
407
|
this.database.get(sql, [...params], (error, row) => {
|
|
412
408
|
if (error) reject(error);
|
|
413
|
-
else
|
|
409
|
+
else resolve4(row);
|
|
414
410
|
});
|
|
415
411
|
});
|
|
416
412
|
}
|
|
417
413
|
async run(sql, params = []) {
|
|
418
|
-
await new Promise((
|
|
414
|
+
await new Promise((resolve4, reject) => {
|
|
419
415
|
this.database.run(sql, [...params], (error) => {
|
|
420
416
|
if (error) reject(error);
|
|
421
|
-
else
|
|
417
|
+
else resolve4();
|
|
422
418
|
});
|
|
423
419
|
});
|
|
424
420
|
}
|
|
@@ -432,10 +428,10 @@ async function openNativeNodeDatabase(file, flags) {
|
|
|
432
428
|
if (path === void 0) {
|
|
433
429
|
throw new TypeError("The Node database adapter requires a NodeFile");
|
|
434
430
|
}
|
|
435
|
-
return await new Promise((
|
|
431
|
+
return await new Promise((resolve4, reject) => {
|
|
436
432
|
const database = new nodeSqlite3.Database(path, flags, (error) => {
|
|
437
433
|
if (error) reject(error);
|
|
438
|
-
else
|
|
434
|
+
else resolve4(database);
|
|
439
435
|
});
|
|
440
436
|
});
|
|
441
437
|
}
|
|
@@ -444,19 +440,19 @@ async function openNodeZip(file) {
|
|
|
444
440
|
if (path === void 0) {
|
|
445
441
|
throw new TypeError("The Node ZIP adapter requires a NodeFile");
|
|
446
442
|
}
|
|
447
|
-
const zipFile = await new Promise((
|
|
443
|
+
const zipFile = await new Promise((resolve4, reject) => {
|
|
448
444
|
yauzl.open(
|
|
449
445
|
path,
|
|
450
446
|
{ autoClose: false, lazyEntries: true },
|
|
451
447
|
(error, opened) => {
|
|
452
448
|
if (error || opened === void 0)
|
|
453
449
|
reject(error ?? new Error("Cannot open ZIP"));
|
|
454
|
-
else
|
|
450
|
+
else resolve4(opened);
|
|
455
451
|
}
|
|
456
452
|
);
|
|
457
453
|
});
|
|
458
454
|
const entries = await new Promise(
|
|
459
|
-
(
|
|
455
|
+
(resolve4, reject) => {
|
|
460
456
|
const discovered = /* @__PURE__ */ new Map();
|
|
461
457
|
const rejectAndClose = (error) => {
|
|
462
458
|
zipFile.close();
|
|
@@ -466,7 +462,7 @@ async function openNodeZip(file) {
|
|
|
466
462
|
};
|
|
467
463
|
const resolveEntries = () => {
|
|
468
464
|
zipFile.off("error", rejectAndClose);
|
|
469
|
-
|
|
465
|
+
resolve4(discovered);
|
|
470
466
|
};
|
|
471
467
|
zipFile.on("entry", (entry) => {
|
|
472
468
|
if (!entry.fileName.endsWith("/")) {
|
|
@@ -576,12 +572,12 @@ async function collectDecodedNodeStreamRange(input, offset, length) {
|
|
|
576
572
|
return Buffer.concat(chunks, collected);
|
|
577
573
|
}
|
|
578
574
|
async function openNodeZipEntryStream(zipFile, entry, options) {
|
|
579
|
-
return await new Promise((
|
|
575
|
+
return await new Promise((resolve4, reject) => {
|
|
580
576
|
const callback = (error, opened) => {
|
|
581
577
|
if (error || opened === void 0) {
|
|
582
578
|
reject(error ?? new Error(`Cannot read ZIP entry: ${entry.fileName}`));
|
|
583
579
|
} else {
|
|
584
|
-
|
|
580
|
+
resolve4(opened);
|
|
585
581
|
}
|
|
586
582
|
};
|
|
587
583
|
if (options === void 0) zipFile.openReadStream(entry, callback);
|
|
@@ -712,11 +708,11 @@ async function writeNodeStream(input, writer) {
|
|
|
712
708
|
);
|
|
713
709
|
}
|
|
714
710
|
async function collectNodeStream(input) {
|
|
715
|
-
return await new Promise((
|
|
711
|
+
return await new Promise((resolve4, reject) => {
|
|
716
712
|
const chunks = [];
|
|
717
713
|
input.on("data", (chunk) => chunks.push(chunk));
|
|
718
714
|
input.once("error", reject);
|
|
719
|
-
input.once("end", () =>
|
|
715
|
+
input.once("end", () => resolve4(Buffer.concat(chunks)));
|
|
720
716
|
});
|
|
721
717
|
}
|
|
722
718
|
var nodeWikiGraphPlatform = {
|
|
@@ -837,12 +833,16 @@ function getWikiGraphSDKRuntimeContext() {
|
|
|
837
833
|
return runtimeContext.getStore() ?? {
|
|
838
834
|
cwd: process.cwd(),
|
|
839
835
|
env: process.env,
|
|
840
|
-
envPolicy: "production"
|
|
836
|
+
envPolicy: "production",
|
|
837
|
+
providers: {}
|
|
841
838
|
};
|
|
842
839
|
}
|
|
843
840
|
function getWikiGraphSDKStateDir() {
|
|
844
841
|
return getWikiGraphSDKRuntimeContext().stateDir;
|
|
845
842
|
}
|
|
843
|
+
function getWikiGraphSDKProviders() {
|
|
844
|
+
return getWikiGraphSDKRuntimeContext().providers ?? {};
|
|
845
|
+
}
|
|
846
846
|
|
|
847
847
|
// src/local-config.ts
|
|
848
848
|
import { join as join2 } from "path";
|
|
@@ -1060,8 +1060,8 @@ var inlineLLMConfigSchema = z.object({
|
|
|
1060
1060
|
});
|
|
1061
1061
|
async function loadWikiGraphRuntimeConfig(options) {
|
|
1062
1062
|
const [embedding, localLLM, concurrent, wikimedia, wikispine] = await Promise.all([
|
|
1063
|
-
readLocalConfigSection("embeddings"),
|
|
1064
|
-
readLocalConfigSection("llm"),
|
|
1063
|
+
options?.skipEmbeddingConfig === true ? Promise.resolve({}) : readLocalConfigSection("embeddings"),
|
|
1064
|
+
options?.skipLLMConfig === true ? Promise.resolve({}) : readLocalConfigSection("llm"),
|
|
1065
1065
|
readLocalConfigSection("concurrent"),
|
|
1066
1066
|
readLocalConfigSection("wikimedia"),
|
|
1067
1067
|
readLocalConfigSection("wikispine")
|
|
@@ -1257,6 +1257,14 @@ function formatError2(error) {
|
|
|
1257
1257
|
return error instanceof Error ? error.message : String(error);
|
|
1258
1258
|
}
|
|
1259
1259
|
|
|
1260
|
+
// src/providers.ts
|
|
1261
|
+
function resolveWikiGraphLLMJSON(options) {
|
|
1262
|
+
if (options.llm !== void 0 && options.llmJSON !== void 0) {
|
|
1263
|
+
throw new Error("Pass either llm or llmJSON, not both.");
|
|
1264
|
+
}
|
|
1265
|
+
return options.llm === void 0 ? options.llmJSON : JSON.stringify(options.llm);
|
|
1266
|
+
}
|
|
1267
|
+
|
|
1260
1268
|
// src/runtime-path.ts
|
|
1261
1269
|
import { homedir as homedir3 } from "os";
|
|
1262
1270
|
import { isAbsolute as isAbsolute2, resolve as resolve2 } from "path";
|
|
@@ -1269,6 +1277,173 @@ function resolveWikiGraphRuntimePath(path) {
|
|
|
1269
1277
|
return isAbsolute2(path) ? path : resolve2(context.cwd, path);
|
|
1270
1278
|
}
|
|
1271
1279
|
|
|
1280
|
+
// src/archive/target.ts
|
|
1281
|
+
import { realpath, stat as stat2 } from "fs/promises";
|
|
1282
|
+
import { basename as basename2, dirname as dirname2, isAbsolute as isAbsolute3, join as join3, relative, resolve as resolve3 } from "path";
|
|
1283
|
+
import {
|
|
1284
|
+
formatLocatedWikiGraphUri,
|
|
1285
|
+
formatWikiGraphLibraryUri,
|
|
1286
|
+
listWikiGraphLibraries,
|
|
1287
|
+
listWikiGraphLibraryArchives,
|
|
1288
|
+
parseLocatedWikiGraphUri,
|
|
1289
|
+
parseWikiGraphLibraryUri,
|
|
1290
|
+
resolveWikiGraphLibrary,
|
|
1291
|
+
resolveWikiGraphLibraryArchiveFile
|
|
1292
|
+
} from "wiki-graph-core";
|
|
1293
|
+
var WikiGraphArchiveOwnershipError = class extends Error {
|
|
1294
|
+
code = "WIKI_GRAPH_ARCHIVE_OWNERSHIP_MISMATCH";
|
|
1295
|
+
constructor(message) {
|
|
1296
|
+
super(message);
|
|
1297
|
+
this.name = "WikiGraphArchiveOwnershipError";
|
|
1298
|
+
}
|
|
1299
|
+
};
|
|
1300
|
+
async function resolveWikiGraphArchiveLocation(target) {
|
|
1301
|
+
if (target.kind === "standalone") {
|
|
1302
|
+
return await resolveStandaloneLocation(target);
|
|
1303
|
+
}
|
|
1304
|
+
return await resolveLibraryLocation(target);
|
|
1305
|
+
}
|
|
1306
|
+
async function assertStandaloneWikiGraphArchivePath(inputPath) {
|
|
1307
|
+
const path = resolveWikiGraphRuntimePath(inputPath);
|
|
1308
|
+
const candidate = await canonicalPath(path);
|
|
1309
|
+
const candidateIdentity = await readFileIdentity(path);
|
|
1310
|
+
const libraries = await listWikiGraphLibraries();
|
|
1311
|
+
const matches = await findMatchingMembers(
|
|
1312
|
+
libraries,
|
|
1313
|
+
candidate,
|
|
1314
|
+
candidateIdentity
|
|
1315
|
+
);
|
|
1316
|
+
if (matches.length > 0) {
|
|
1317
|
+
const match = requireUnambiguousManagedMatch(path, matches);
|
|
1318
|
+
throw new WikiGraphArchiveOwnershipError(
|
|
1319
|
+
`Standalone archive path belongs to registered library ${formatWikiGraphLibraryUri(
|
|
1320
|
+
match.library.isDefault ? void 0 : match.library.publicId
|
|
1321
|
+
)}: ${path}. Use the library UUID URI ${match.archive.uri} instead.`
|
|
1322
|
+
);
|
|
1323
|
+
}
|
|
1324
|
+
for (const library of libraries) {
|
|
1325
|
+
const rootPath = getNodeResourcePath(library.folder);
|
|
1326
|
+
const root = await canonicalPath(rootPath);
|
|
1327
|
+
if (!isWithin(root, candidate)) continue;
|
|
1328
|
+
throw new WikiGraphArchiveOwnershipError(
|
|
1329
|
+
`Standalone archive path belongs to registered library ${formatWikiGraphLibraryUri(
|
|
1330
|
+
library.isDefault ? void 0 : library.publicId
|
|
1331
|
+
)}: ${path}. Scan the library, then address the archive by its library UUID URI.`
|
|
1332
|
+
);
|
|
1333
|
+
}
|
|
1334
|
+
return path;
|
|
1335
|
+
}
|
|
1336
|
+
async function resolveStandaloneLocation(target) {
|
|
1337
|
+
if (target.path.startsWith("wikg://lib/")) {
|
|
1338
|
+
throw new WikiGraphArchiveOwnershipError(
|
|
1339
|
+
`A library archive URI cannot be used as a standalone path: ${target.path}`
|
|
1340
|
+
);
|
|
1341
|
+
}
|
|
1342
|
+
const path = await assertStandaloneWikiGraphArchivePath(target.path);
|
|
1343
|
+
const normalized = {
|
|
1344
|
+
kind: "standalone",
|
|
1345
|
+
path,
|
|
1346
|
+
...target.objectUri === void 0 ? {} : { objectUri: target.objectUri }
|
|
1347
|
+
};
|
|
1348
|
+
return {
|
|
1349
|
+
archiveFile: new NodeFile(path),
|
|
1350
|
+
archiveKey: path,
|
|
1351
|
+
archivePath: path,
|
|
1352
|
+
indexScope: { archiveKey: path, archivePath: path, kind: "archive-index" },
|
|
1353
|
+
locatedUri: formatLocatedWikiGraphUri(path, target.objectUri),
|
|
1354
|
+
target: normalized
|
|
1355
|
+
};
|
|
1356
|
+
}
|
|
1357
|
+
async function resolveLibraryLocation(target) {
|
|
1358
|
+
const parsedLocated = parseLocatedWikiGraphUri(target.uri);
|
|
1359
|
+
const archiveUri = parsedLocated.archivePath ?? target.uri;
|
|
1360
|
+
const parsed = parseWikiGraphLibraryUri(archiveUri);
|
|
1361
|
+
if (parsed?.kind !== "archive") {
|
|
1362
|
+
throw new WikiGraphArchiveOwnershipError(
|
|
1363
|
+
`Library archive target must be a UUID archive URI: ${target.uri}`
|
|
1364
|
+
);
|
|
1365
|
+
}
|
|
1366
|
+
await resolveWikiGraphLibrary(parsed);
|
|
1367
|
+
const archiveFile = await resolveWikiGraphLibraryArchiveFile(archiveUri);
|
|
1368
|
+
const normalized = {
|
|
1369
|
+
kind: "library",
|
|
1370
|
+
uri: target.uri
|
|
1371
|
+
};
|
|
1372
|
+
return {
|
|
1373
|
+
archiveFile,
|
|
1374
|
+
archiveKey: archiveUri,
|
|
1375
|
+
archivePath: archiveUri,
|
|
1376
|
+
indexScope: {
|
|
1377
|
+
archiveKey: archiveUri,
|
|
1378
|
+
archivePath: archiveUri,
|
|
1379
|
+
kind: "archive-index"
|
|
1380
|
+
},
|
|
1381
|
+
libraryArchiveTarget: parsed,
|
|
1382
|
+
locatedUri: target.uri,
|
|
1383
|
+
publicArchiveUri: archiveUri,
|
|
1384
|
+
target: normalized
|
|
1385
|
+
};
|
|
1386
|
+
}
|
|
1387
|
+
async function canonicalPath(path) {
|
|
1388
|
+
try {
|
|
1389
|
+
return await realpath(path);
|
|
1390
|
+
} catch {
|
|
1391
|
+
const absolute = resolve3(path);
|
|
1392
|
+
const parent = dirname2(absolute);
|
|
1393
|
+
return parent === absolute ? absolute : join3(await canonicalPath(parent), basename2(absolute));
|
|
1394
|
+
}
|
|
1395
|
+
}
|
|
1396
|
+
function isWithin(root, candidate) {
|
|
1397
|
+
const child = relative(root, candidate);
|
|
1398
|
+
return child === "" || !child.startsWith("..") && !isAbsolute3(child);
|
|
1399
|
+
}
|
|
1400
|
+
async function findMatchingMembers(libraries, candidate, candidateIdentity) {
|
|
1401
|
+
const members = [];
|
|
1402
|
+
for (const library of libraries) {
|
|
1403
|
+
const archives = await listWikiGraphLibraryArchives({
|
|
1404
|
+
isDefault: library.isDefault,
|
|
1405
|
+
kind: "scope",
|
|
1406
|
+
...library.isDefault ? {} : { publicId: library.publicId }
|
|
1407
|
+
});
|
|
1408
|
+
for (const archive of archives) {
|
|
1409
|
+
if (archive.file === void 0) continue;
|
|
1410
|
+
members.push({
|
|
1411
|
+
archive,
|
|
1412
|
+
library,
|
|
1413
|
+
memberPath: getNodeResourcePath(archive.file)
|
|
1414
|
+
});
|
|
1415
|
+
}
|
|
1416
|
+
}
|
|
1417
|
+
const exact = [];
|
|
1418
|
+
for (const member of members) {
|
|
1419
|
+
if (await canonicalPath(member.memberPath) === candidate) {
|
|
1420
|
+
exact.push(member);
|
|
1421
|
+
}
|
|
1422
|
+
}
|
|
1423
|
+
if (exact.length > 0 || candidateIdentity === void 0) return exact;
|
|
1424
|
+
const identityMatches = [];
|
|
1425
|
+
for (const member of members) {
|
|
1426
|
+
if (await readFileIdentity(member.memberPath) === candidateIdentity) {
|
|
1427
|
+
identityMatches.push(member);
|
|
1428
|
+
}
|
|
1429
|
+
}
|
|
1430
|
+
return identityMatches;
|
|
1431
|
+
}
|
|
1432
|
+
function requireUnambiguousManagedMatch(path, matches) {
|
|
1433
|
+
if (matches.length === 1) return matches[0];
|
|
1434
|
+
throw new WikiGraphArchiveOwnershipError(
|
|
1435
|
+
`Archive file identity is ambiguous across managed archives: ${path}. Use an explicit library UUID URI (${matches.map((match) => match.archive.uri).join(", ")}).`
|
|
1436
|
+
);
|
|
1437
|
+
}
|
|
1438
|
+
async function readFileIdentity(path) {
|
|
1439
|
+
try {
|
|
1440
|
+
const value = await stat2(path);
|
|
1441
|
+
return `${value.dev}:${value.ino}`;
|
|
1442
|
+
} catch {
|
|
1443
|
+
return void 0;
|
|
1444
|
+
}
|
|
1445
|
+
}
|
|
1446
|
+
|
|
1272
1447
|
// src/conversions.ts
|
|
1273
1448
|
var WikiGraphConversionManager = class {
|
|
1274
1449
|
#runtime;
|
|
@@ -1293,23 +1468,33 @@ var WikiGraphConversionManager = class {
|
|
|
1293
1468
|
}
|
|
1294
1469
|
const requiresDigest = options.input.format !== "wikg";
|
|
1295
1470
|
const requiresLLM = requiresDigest && targetStage !== "planned" && targetStage !== "sourced";
|
|
1471
|
+
const llmJSON = resolveWikiGraphLLMJSON(options);
|
|
1472
|
+
const injectedLLM = llmJSON === void 0 ? getWikiGraphSDKProviders().llm : void 0;
|
|
1296
1473
|
const config = await loadWikiGraphRuntimeConfig({
|
|
1297
|
-
...
|
|
1474
|
+
...llmJSON === void 0 ? {} : { llmJSON },
|
|
1475
|
+
...injectedLLM === void 0 ? {} : { skipLLMConfig: true },
|
|
1476
|
+
...getWikiGraphSDKProviders().embedding === void 0 ? {} : { skipEmbeddingConfig: true }
|
|
1298
1477
|
});
|
|
1299
1478
|
const app = new WikiGraph({
|
|
1300
1479
|
...options.verbose === true ? { verbose: true } : {},
|
|
1301
|
-
...requiresLLM ? {
|
|
1480
|
+
...requiresLLM ? {
|
|
1481
|
+
llm: injectedLLM === void 0 ? buildWikiGraphLLMOptions(config) : { streamProvider: injectedLLM }
|
|
1482
|
+
} : {}
|
|
1302
1483
|
});
|
|
1303
1484
|
const documentDirectory = await prepareDigestDirectory(
|
|
1304
1485
|
options.digestDirectory,
|
|
1305
1486
|
requiresDigest
|
|
1306
1487
|
);
|
|
1307
1488
|
let chapterCount;
|
|
1489
|
+
let chapterPaths;
|
|
1308
1490
|
const write = async (archive) => {
|
|
1309
1491
|
if (requiresDigest) await options.onSourceImported?.();
|
|
1310
1492
|
if (typeof archive.readToc === "function") {
|
|
1311
1493
|
const toc = await archive.readToc();
|
|
1312
1494
|
chapterCount = toc === void 0 ? void 0 : countTocChapters(toc.items);
|
|
1495
|
+
if (options.output.format === "wikg") {
|
|
1496
|
+
chapterPaths = toc === void 0 ? [] : collectTocChapterPaths(toc.items);
|
|
1497
|
+
}
|
|
1313
1498
|
}
|
|
1314
1499
|
await writeArchive(archive, options.output.path, options.output.format);
|
|
1315
1500
|
};
|
|
@@ -1318,7 +1503,9 @@ var WikiGraphConversionManager = class {
|
|
|
1318
1503
|
throw new Error("wikg input requires a file path.");
|
|
1319
1504
|
}
|
|
1320
1505
|
await app.openSession(
|
|
1321
|
-
new NodeFile(
|
|
1506
|
+
new NodeFile(
|
|
1507
|
+
await assertStandaloneWikiGraphArchivePath(options.input.path)
|
|
1508
|
+
),
|
|
1322
1509
|
write
|
|
1323
1510
|
);
|
|
1324
1511
|
} else if ("stream" in options.input) {
|
|
@@ -1361,6 +1548,7 @@ var WikiGraphConversionManager = class {
|
|
|
1361
1548
|
const sourceArtifact = await resolveSourceArtifact(options.input);
|
|
1362
1549
|
return {
|
|
1363
1550
|
...chapterCount === void 0 ? {} : { chapterCount },
|
|
1551
|
+
...chapterPaths === void 0 ? {} : { chapterPaths },
|
|
1364
1552
|
inputFormat: options.input.format,
|
|
1365
1553
|
outputFormat: options.output.format,
|
|
1366
1554
|
outputPath: options.output.path,
|
|
@@ -1377,7 +1565,8 @@ async function prepareDigestDirectory(path, required) {
|
|
|
1377
1565
|
return new NodeDirectory(resolved);
|
|
1378
1566
|
}
|
|
1379
1567
|
async function writeArchive(archive, path, format) {
|
|
1380
|
-
const
|
|
1568
|
+
const outputPath = format === "wikg" ? await assertStandaloneWikiGraphArchivePath(path) : resolveWikiGraphRuntimePath(path);
|
|
1569
|
+
const file = new NodeFile(outputPath);
|
|
1381
1570
|
if (format === "epub") await archive.exportEpub(file);
|
|
1382
1571
|
else if (format === "wikg") await archive.saveAs(file);
|
|
1383
1572
|
else if (format === "pcex") throw new Error("pcex output is not supported.");
|
|
@@ -1406,7 +1595,7 @@ async function resolveSourceArtifact(input) {
|
|
|
1406
1595
|
return {
|
|
1407
1596
|
digest: hash.digest("hex"),
|
|
1408
1597
|
mediaType: "application/epub+zip",
|
|
1409
|
-
name:
|
|
1598
|
+
name: basename3(path)
|
|
1410
1599
|
};
|
|
1411
1600
|
}
|
|
1412
1601
|
function isNodeErrorCode(error, code) {
|
|
@@ -1422,6 +1611,21 @@ function countTocChapters(items) {
|
|
|
1422
1611
|
}
|
|
1423
1612
|
return count;
|
|
1424
1613
|
}
|
|
1614
|
+
function collectTocChapterPaths(items, ancestorKeys = []) {
|
|
1615
|
+
const paths = [];
|
|
1616
|
+
for (const item of items) {
|
|
1617
|
+
const key = item.key ?? `chapter-${item.serialId ?? "group"}`;
|
|
1618
|
+
const chapterPath = [...ancestorKeys, key];
|
|
1619
|
+
if (item.serialId !== void 0) paths.push(chapterPath.join("/"));
|
|
1620
|
+
paths.push(
|
|
1621
|
+
...collectTocChapterPaths(
|
|
1622
|
+
item.children,
|
|
1623
|
+
chapterPath
|
|
1624
|
+
)
|
|
1625
|
+
);
|
|
1626
|
+
}
|
|
1627
|
+
return paths;
|
|
1628
|
+
}
|
|
1425
1629
|
|
|
1426
1630
|
// src/query-runtime.ts
|
|
1427
1631
|
import {
|
|
@@ -1565,6 +1769,8 @@ function createOpenAICompatibleName2(baseURL) {
|
|
|
1565
1769
|
|
|
1566
1770
|
// src/query-runtime.ts
|
|
1567
1771
|
async function createConfiguredEmbeddingProvider() {
|
|
1772
|
+
const injected = getWikiGraphSDKProviders().embedding;
|
|
1773
|
+
if (injected !== void 0) return injected;
|
|
1568
1774
|
const config = await readWikiGraphEmbeddingConfig();
|
|
1569
1775
|
if (config.provider === void 0 || config.model === void 0 || config.provider === "openai-compatible" && config.baseURL === void 0 || config.provider === "openai" && config.baseURL !== void 0) {
|
|
1570
1776
|
return void 0;
|
|
@@ -1593,489 +1799,130 @@ import {
|
|
|
1593
1799
|
isArchiveSearchIndexCurrent,
|
|
1594
1800
|
listChapters
|
|
1595
1801
|
} from "wiki-graph-core";
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
var DEFAULT_GENERATION_REQUEST_CONCURRENCY = 6;
|
|
1600
|
-
function planGenerationTask(task, words, chapters, concurrent, model) {
|
|
1601
|
-
const profile = getGenerationPlanningProfile(task);
|
|
1602
|
-
const calls = Math.max(chapters, Math.ceil(words / profile.wordsPerCall));
|
|
1603
|
-
const effectiveConcurrency = Math.max(
|
|
1604
|
-
1,
|
|
1605
|
-
task === "reading-graph" ? 1 : concurrent.request
|
|
1606
|
-
);
|
|
1607
|
-
const callBatches = Math.ceil(calls / effectiveConcurrency);
|
|
1608
|
-
const wordSeconds = words * profile.secondsPerWord;
|
|
1609
|
-
return {
|
|
1610
|
-
model,
|
|
1611
|
-
timeSeconds: {
|
|
1612
|
-
max: Math.ceil(callBatches * profile.maxSecondsPerCall + wordSeconds),
|
|
1613
|
-
min: Math.ceil(callBatches * profile.minSecondsPerCall + wordSeconds)
|
|
1614
|
-
},
|
|
1615
|
-
tokens: {
|
|
1616
|
-
cacheableInput: Math.ceil(words * profile.cacheableInputTokenPerWord),
|
|
1617
|
-
input: Math.ceil(words * profile.inputTokenPerWord),
|
|
1618
|
-
output: Math.ceil(words * profile.outputTokenPerWord)
|
|
1619
|
-
}
|
|
1620
|
-
};
|
|
1621
|
-
}
|
|
1622
|
-
function createGenerationPerformanceHints(input) {
|
|
1623
|
-
if (!input.hasJobWork) {
|
|
1624
|
-
return [];
|
|
1625
|
-
}
|
|
1626
|
-
const hints = [];
|
|
1627
|
-
const recommendedRequest = input.concurrent.request < 4 ? DEFAULT_GENERATION_REQUEST_CONCURRENCY : input.concurrent.request < 8 ? 8 : void 0;
|
|
1628
|
-
if (input.hasRequestWork && recommendedRequest !== void 0) {
|
|
1629
|
-
hints.push({
|
|
1630
|
-
configKey: "request",
|
|
1631
|
-
configValue: recommendedRequest,
|
|
1632
|
-
current: input.concurrent.request,
|
|
1633
|
-
kind: "request",
|
|
1634
|
-
message: "LLM request concurrency can often be higher. Use at least 4; 6-8 is usually faster when the provider allows it.",
|
|
1635
|
-
recommended: recommendedRequest
|
|
1636
|
-
});
|
|
1637
|
-
}
|
|
1638
|
-
if (input.concurrent.job < 4 && input.chapters > 1) {
|
|
1639
|
-
hints.push({
|
|
1640
|
-
configKey: "job",
|
|
1641
|
-
configValue: 4,
|
|
1642
|
-
current: input.concurrent.job,
|
|
1643
|
-
kind: "job",
|
|
1644
|
-
message: "Multiple chapters need work and job concurrency is below 4. Raising it lets chapter jobs run in parallel.",
|
|
1645
|
-
recommended: 4
|
|
1646
|
-
});
|
|
1647
|
-
}
|
|
1648
|
-
return hints;
|
|
1649
|
-
}
|
|
1650
|
-
function formatGenerationPlanningModel(llm) {
|
|
1651
|
-
if (llm?.model === void 0) {
|
|
1652
|
-
return "not configured";
|
|
1653
|
-
}
|
|
1654
|
-
return llm.provider === void 0 ? llm.model : `${llm.provider}/${llm.model}`;
|
|
1655
|
-
}
|
|
1656
|
-
function getGenerationPlanningProfile(task) {
|
|
1657
|
-
switch (task) {
|
|
1658
|
-
case "index-fts":
|
|
1659
|
-
return {
|
|
1660
|
-
cacheableInputTokenPerWord: 0,
|
|
1661
|
-
inputTokenPerWord: 0,
|
|
1662
|
-
maxSecondsPerCall: 1,
|
|
1663
|
-
minSecondsPerCall: 0,
|
|
1664
|
-
outputTokenPerWord: 0,
|
|
1665
|
-
secondsPerWord: 5e-4,
|
|
1666
|
-
wordsPerCall: 1e5
|
|
1667
|
-
};
|
|
1668
|
-
case "index-embedding-source":
|
|
1669
|
-
case "index-embedding-summary":
|
|
1670
|
-
return {
|
|
1671
|
-
cacheableInputTokenPerWord: 0,
|
|
1672
|
-
inputTokenPerWord: 0,
|
|
1673
|
-
maxSecondsPerCall: 10,
|
|
1674
|
-
minSecondsPerCall: 1,
|
|
1675
|
-
outputTokenPerWord: 0,
|
|
1676
|
-
secondsPerWord: 2e-3,
|
|
1677
|
-
wordsPerCall: 1e4
|
|
1678
|
-
};
|
|
1679
|
-
case "knowledge-graph":
|
|
1680
|
-
return {
|
|
1681
|
-
cacheableInputTokenPerWord: 60,
|
|
1682
|
-
inputTokenPerWord: 80,
|
|
1683
|
-
maxSecondsPerCall: 35,
|
|
1684
|
-
minSecondsPerCall: 15,
|
|
1685
|
-
outputTokenPerWord: 25,
|
|
1686
|
-
secondsPerWord: 0.02,
|
|
1687
|
-
wordsPerCall: 35
|
|
1688
|
-
};
|
|
1689
|
-
case "reading-graph":
|
|
1690
|
-
return {
|
|
1691
|
-
cacheableInputTokenPerWord: 20,
|
|
1692
|
-
inputTokenPerWord: 25,
|
|
1693
|
-
maxSecondsPerCall: 45,
|
|
1694
|
-
minSecondsPerCall: 15,
|
|
1695
|
-
outputTokenPerWord: 4,
|
|
1696
|
-
secondsPerWord: 0.01,
|
|
1697
|
-
wordsPerCall: 160
|
|
1698
|
-
};
|
|
1699
|
-
case "reading-summary":
|
|
1700
|
-
return {
|
|
1701
|
-
cacheableInputTokenPerWord: 45,
|
|
1702
|
-
inputTokenPerWord: 55,
|
|
1703
|
-
maxSecondsPerCall: 25,
|
|
1704
|
-
minSecondsPerCall: 10,
|
|
1705
|
-
outputTokenPerWord: 4,
|
|
1706
|
-
secondsPerWord: 0.01,
|
|
1707
|
-
wordsPerCall: 110
|
|
1708
|
-
};
|
|
1709
|
-
}
|
|
1710
|
-
}
|
|
1711
|
-
|
|
1712
|
-
// src/archive/inspect.ts
|
|
1713
|
-
async function createWikiGraphArchiveInspectReport(document, options) {
|
|
1714
|
-
const { archiveUri } = options;
|
|
1715
|
-
const [
|
|
1716
|
-
chapters,
|
|
1717
|
-
summaryWords,
|
|
1718
|
-
indexCacheCurrent,
|
|
1719
|
-
config,
|
|
1720
|
-
ftsArtifactCoverage,
|
|
1721
|
-
sourceEmbeddingArtifactCoverage,
|
|
1722
|
-
summaryEmbeddingArtifactCoverage
|
|
1723
|
-
] = await Promise.all([
|
|
1724
|
-
readInspectChapters(document, options.chapterId),
|
|
1725
|
-
readSummaryWords(document, options.chapterId),
|
|
1802
|
+
async function inspectWikiGraphArchive(document, options) {
|
|
1803
|
+
const [allChapters, indexCacheCurrent, summaryWords, ...coverage] = await Promise.all([
|
|
1804
|
+
listChapters(document),
|
|
1726
1805
|
isArchiveSearchIndexCurrent(document),
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1806
|
+
readSummaryWords(document),
|
|
1807
|
+
document.indexArtifacts.listCoverage("fts"),
|
|
1808
|
+
document.indexArtifacts.listCoverage("embedding-source"),
|
|
1809
|
+
document.indexArtifacts.listCoverage("embedding-summary")
|
|
1731
1810
|
]);
|
|
1732
|
-
const
|
|
1733
|
-
const
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1811
|
+
const chapters = selectChapters(allChapters, options.chapterId);
|
|
1812
|
+
const coverageByKind = {
|
|
1813
|
+
fts: byChapterId(coverage[0]),
|
|
1814
|
+
sourceEmbedding: byChapterId(coverage[1]),
|
|
1815
|
+
summaryEmbedding: byChapterId(coverage[2])
|
|
1737
1816
|
};
|
|
1738
|
-
const
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
(chapter) => createInspectChapterReference(archiveUri, chapter)
|
|
1817
|
+
const inspections = await Promise.all(
|
|
1818
|
+
chapters.map(async (chapter) => {
|
|
1819
|
+
const serial = await document.serials.getById(chapter.chapterId);
|
|
1820
|
+
return {
|
|
1821
|
+
capabilities: {
|
|
1822
|
+
knowledgeGraph: {
|
|
1823
|
+
completed: serial?.knowledgeGraphReady === true
|
|
1824
|
+
},
|
|
1825
|
+
readingGraph: { completed: serial?.topologyReady === true },
|
|
1826
|
+
readingSummary: { completed: chapter.stage === "summarized" }
|
|
1827
|
+
},
|
|
1828
|
+
chapter,
|
|
1829
|
+
indexes: {
|
|
1830
|
+
fts: inspectArtifact(
|
|
1831
|
+
"fts",
|
|
1832
|
+
coverageByKind.fts.get(chapter.chapterId)
|
|
1833
|
+
),
|
|
1834
|
+
sourceEmbedding: inspectArtifact(
|
|
1835
|
+
"embedding-source",
|
|
1836
|
+
coverageByKind.sourceEmbedding.get(chapter.chapterId)
|
|
1837
|
+
),
|
|
1838
|
+
summaryEmbedding: inspectArtifact(
|
|
1839
|
+
"embedding-summary",
|
|
1840
|
+
coverageByKind.summaryEmbedding.get(chapter.chapterId)
|
|
1841
|
+
)
|
|
1842
|
+
},
|
|
1843
|
+
revision: serial?.revision ?? 0,
|
|
1844
|
+
summaryWords: summaryWords.get(chapter.chapterId) ?? 0
|
|
1845
|
+
};
|
|
1846
|
+
})
|
|
1769
1847
|
);
|
|
1770
|
-
const
|
|
1771
|
-
const improvements = createInspectImprovements({
|
|
1772
|
-
concurrent,
|
|
1773
|
-
contentChapters,
|
|
1774
|
-
indexCacheCurrent,
|
|
1775
|
-
planningModel,
|
|
1776
|
-
queryBlockedChapters: queryBlockedContentChapters,
|
|
1777
|
-
summaryCovered,
|
|
1778
|
-
knowledgeGraphCovered,
|
|
1779
|
-
readingGraphCovered
|
|
1780
|
-
});
|
|
1781
|
-
const performanceHints = createGenerationPerformanceHints({
|
|
1782
|
-
chapters: Math.max(
|
|
1783
|
-
0,
|
|
1784
|
-
...improvements.map((improvement) => improvement.missingChapters ?? 0)
|
|
1785
|
-
),
|
|
1786
|
-
concurrent,
|
|
1787
|
-
hasJobWork: improvements.some(
|
|
1788
|
-
(improvement) => improvement.planning !== void 0
|
|
1789
|
-
),
|
|
1790
|
-
hasRequestWork: improvements.some(
|
|
1791
|
-
(improvement) => improvement.planning !== void 0
|
|
1792
|
-
)
|
|
1793
|
-
});
|
|
1848
|
+
const selected = inspections[0];
|
|
1794
1849
|
return {
|
|
1795
|
-
archiveUri,
|
|
1796
|
-
|
|
1850
|
+
archiveUri: options.archiveUri,
|
|
1851
|
+
chapters: inspections,
|
|
1852
|
+
localIndexCache: { current: indexCacheCurrent },
|
|
1797
1853
|
scope: options.chapterId === void 0 ? { type: "archive" } : { chapterId: options.chapterId, type: "chapter" },
|
|
1798
|
-
|
|
1799
|
-
chapters: {
|
|
1800
|
-
content: contentChapters.length,
|
|
1801
|
-
planned: chapters.length - contentChapters.length,
|
|
1802
|
-
total: chapters.length
|
|
1803
|
-
},
|
|
1804
|
-
sourceWords,
|
|
1805
|
-
summaryWords
|
|
1806
|
-
},
|
|
1807
|
-
localIndexCache: {
|
|
1808
|
-
current: indexCacheCurrent,
|
|
1809
|
-
...!queryReady ? {
|
|
1810
|
-
blockedBy: "missing-search-artifacts",
|
|
1811
|
-
impact: "The cache cannot be built until every content chapter has a current FTS or source embedding artifact."
|
|
1812
|
-
} : indexCacheCurrent ? {} : {
|
|
1813
|
-
impact: "The next archive query may need to sync index cache first.",
|
|
1814
|
-
resource: "local CPU/disk time only; no provider calls."
|
|
1815
|
-
},
|
|
1816
|
-
status: !queryReady ? "blocked" : indexCacheCurrent ? "current" : "missing-or-outdated",
|
|
1817
|
-
syncAvailable: queryReady && !indexCacheCurrent
|
|
1818
|
-
},
|
|
1819
|
-
coverage: {
|
|
1820
|
-
ftsIndexArtifact: createInspectCoverage(
|
|
1821
|
-
ftsArtifactCovered,
|
|
1822
|
-
contentChapters
|
|
1823
|
-
),
|
|
1824
|
-
knowledgeGraph: createInspectCoverage(
|
|
1825
|
-
knowledgeGraphCovered,
|
|
1826
|
-
contentChapters
|
|
1827
|
-
),
|
|
1828
|
-
readingGraph: createInspectCoverage(readingGraphCovered, contentChapters),
|
|
1829
|
-
summary: createInspectCoverage(summaryCovered, contentChapters),
|
|
1830
|
-
sourceEmbeddingIndexArtifact: createInspectCoverage(
|
|
1831
|
-
sourceEmbeddingArtifactCovered,
|
|
1832
|
-
contentChapters
|
|
1833
|
-
),
|
|
1834
|
-
summaryEmbeddingIndexArtifact: createInspectCoverage(
|
|
1835
|
-
summaryEmbeddingArtifactCovered,
|
|
1836
|
-
contentChapters
|
|
1837
|
-
)
|
|
1838
|
-
},
|
|
1839
|
-
query: {
|
|
1840
|
-
ready: queryReady
|
|
1841
|
-
},
|
|
1842
|
-
searchArtifacts: {
|
|
1843
|
-
blockedChapters: queryBlockedChapters,
|
|
1844
|
-
...!queryReady ? {
|
|
1845
|
-
resource: "local CPU/disk time only; no provider calls."
|
|
1846
|
-
} : {},
|
|
1847
|
-
ready: queryReady,
|
|
1848
|
-
status: queryReady ? "ready" : "incomplete"
|
|
1849
|
-
},
|
|
1850
|
-
retrievalGuidance: formatRetrievalGuidance({
|
|
1851
|
-
indexCacheCurrent,
|
|
1852
|
-
knowledgeGraphCovered,
|
|
1853
|
-
readingGraphCovered,
|
|
1854
|
-
contentChapters,
|
|
1855
|
-
queryReady,
|
|
1856
|
-
sourceWords
|
|
1857
|
-
}),
|
|
1858
|
-
improvements,
|
|
1859
|
-
performanceHints,
|
|
1860
|
-
summaryCoverageNote: "Summary coverage means a current summary artifact exists for the chapter; it does not guarantee that every source topic is represented in the summary text."
|
|
1854
|
+
uri: selected === void 0 || options.chapterId === void 0 ? options.archiveUri : formatLocatedChapterUri(options.archiveUri, selected.chapter)
|
|
1861
1855
|
};
|
|
1862
1856
|
}
|
|
1863
|
-
function
|
|
1864
|
-
return
|
|
1865
|
-
|
|
1866
|
-
locatedUri: formatInspectLocatedChapterUri(archiveUri, chapter),
|
|
1867
|
-
title: chapter.title,
|
|
1868
|
-
uri: chapter.uri
|
|
1869
|
-
};
|
|
1870
|
-
}
|
|
1871
|
-
function formatInspectLocatedChapterUri(archiveUri, chapter) {
|
|
1872
|
-
return `${archiveUri.replace(/\/+$/u, "")}/${chapter.uri.replace(/^wikg:\/\//u, "")}`;
|
|
1873
|
-
}
|
|
1874
|
-
async function readInspectChapters(document, chapterId) {
|
|
1875
|
-
const chapters = chapterId === void 0 ? await listChapters(document) : (await listChapters(document)).filter(
|
|
1857
|
+
function selectChapters(chapters, chapterId) {
|
|
1858
|
+
if (chapterId === void 0) return chapters;
|
|
1859
|
+
const selected = chapters.filter(
|
|
1876
1860
|
(chapter) => chapter.chapterId === chapterId
|
|
1877
1861
|
);
|
|
1878
|
-
if (
|
|
1862
|
+
if (selected.length === 0) {
|
|
1879
1863
|
throw new Error(`Chapter ${chapterId} does not exist.`);
|
|
1880
1864
|
}
|
|
1881
|
-
return
|
|
1882
|
-
chapters.map(async (chapter) => {
|
|
1883
|
-
const serial = await document.serials.getById(chapter.chapterId);
|
|
1884
|
-
return {
|
|
1885
|
-
...chapter,
|
|
1886
|
-
knowledgeGraphReady: serial?.knowledgeGraphReady === true,
|
|
1887
|
-
readingGraphReady: serial?.topologyReady === true,
|
|
1888
|
-
summaryReady: chapter.stage === "summarized"
|
|
1889
|
-
};
|
|
1890
|
-
})
|
|
1891
|
-
);
|
|
1892
|
-
}
|
|
1893
|
-
async function readSummaryWords(document, chapterId) {
|
|
1894
|
-
return await document.readDatabase(
|
|
1895
|
-
async (database) => await database.queryOne(
|
|
1896
|
-
`
|
|
1897
|
-
SELECT COALESCE(SUM(words_count), 0) AS words
|
|
1898
|
-
FROM text_sentence_records
|
|
1899
|
-
WHERE kind = 2
|
|
1900
|
-
${chapterId === void 0 ? "" : "AND chapter_id = ?"}
|
|
1901
|
-
`,
|
|
1902
|
-
chapterId === void 0 ? void 0 : [chapterId],
|
|
1903
|
-
(row) => Number(row.words)
|
|
1904
|
-
) ?? 0
|
|
1905
|
-
);
|
|
1906
|
-
}
|
|
1907
|
-
async function readIndexArtifactCoverage(document, kind, chapterId) {
|
|
1908
|
-
const coverage = await document.indexArtifacts.listCoverage(kind);
|
|
1909
|
-
return chapterId === void 0 ? coverage : coverage.filter((item) => item.serialId === chapterId);
|
|
1865
|
+
return selected;
|
|
1910
1866
|
}
|
|
1911
|
-
function
|
|
1912
|
-
|
|
1913
|
-
coverage.filter((item) => item.current).map((item) => item.serialId)
|
|
1914
|
-
);
|
|
1915
|
-
return chapters.filter((chapter) => currentChapterIds.has(chapter.chapterId));
|
|
1867
|
+
function byChapterId(coverage) {
|
|
1868
|
+
return new Map(coverage.map((item) => [item.serialId, item]));
|
|
1916
1869
|
}
|
|
1917
|
-
function
|
|
1918
|
-
const coveredWords = sumWords(covered);
|
|
1919
|
-
const totalWords = sumWords(total);
|
|
1870
|
+
function inspectArtifact(kind, coverage) {
|
|
1920
1871
|
return {
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
totalWords
|
|
1872
|
+
current: coverage?.current === true,
|
|
1873
|
+
exists: coverage?.sourceRevision !== void 0,
|
|
1874
|
+
kind,
|
|
1875
|
+
...coverage?.sourceRevision === void 0 ? {} : { sourceRevision: coverage.sourceRevision }
|
|
1926
1876
|
};
|
|
1927
1877
|
}
|
|
1928
|
-
function
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
input.contentChapters
|
|
1943
|
-
)
|
|
1944
|
-
);
|
|
1945
|
-
lines.push(
|
|
1946
|
-
formatObjectSearchGuidance(
|
|
1947
|
-
"Entity/triple retrieval",
|
|
1948
|
-
input.knowledgeGraphCovered,
|
|
1949
|
-
input.contentChapters
|
|
1878
|
+
async function readSummaryWords(document) {
|
|
1879
|
+
const rows = await document.readDatabase(
|
|
1880
|
+
async (database) => await database.queryAll(
|
|
1881
|
+
`
|
|
1882
|
+
SELECT chapter_id, COALESCE(SUM(words_count), 0) AS words
|
|
1883
|
+
FROM text_sentence_records
|
|
1884
|
+
WHERE kind = 2
|
|
1885
|
+
GROUP BY chapter_id
|
|
1886
|
+
`,
|
|
1887
|
+
void 0,
|
|
1888
|
+
(row) => ({
|
|
1889
|
+
chapterId: Number(row.chapter_id),
|
|
1890
|
+
words: Number(row.words)
|
|
1891
|
+
})
|
|
1950
1892
|
)
|
|
1951
1893
|
);
|
|
1952
|
-
return
|
|
1953
|
-
}
|
|
1954
|
-
function formatObjectSearchGuidance(label, covered, total) {
|
|
1955
|
-
const coveredWords = sumWords(covered);
|
|
1956
|
-
const totalWords = sumWords(total);
|
|
1957
|
-
const ratio = totalWords === 0 ? 0 : coveredWords / totalWords;
|
|
1958
|
-
const coverage = formatPercent(coveredWords, totalWords);
|
|
1959
|
-
if (ratio >= 1) {
|
|
1960
|
-
return `${label}: covers all source content; it can represent the full scope for object retrieval.`;
|
|
1961
|
-
}
|
|
1962
|
-
if (ratio >= 0.9) {
|
|
1963
|
-
return `${label}: covers ${coverage}; use it as the main path, but source --query is needed for uncovered content.`;
|
|
1964
|
-
}
|
|
1965
|
-
if (ratio >= 0.5) {
|
|
1966
|
-
return `${label}: covers ${coverage}; use it as leads, not as a full-scope substitute for source --query.`;
|
|
1967
|
-
}
|
|
1968
|
-
return `${label}: covers ${coverage}; build missing graph coverage before relying on object retrieval.`;
|
|
1969
|
-
}
|
|
1970
|
-
function createInspectImprovements(input) {
|
|
1971
|
-
const improvements = [];
|
|
1972
|
-
if (input.contentChapters.length === 0) {
|
|
1973
|
-
improvements.push({
|
|
1974
|
-
kind: "add-source",
|
|
1975
|
-
recommendation: "No source content is available yet; add or import source text before graph or summary generation.",
|
|
1976
|
-
title: "Add source content"
|
|
1977
|
-
});
|
|
1978
|
-
return improvements;
|
|
1979
|
-
}
|
|
1980
|
-
if (input.queryBlockedChapters.length > 0) {
|
|
1981
|
-
improvements.push({
|
|
1982
|
-
kind: "build",
|
|
1983
|
-
missingChapters: input.queryBlockedChapters.length,
|
|
1984
|
-
missingWords: sumWords(input.queryBlockedChapters),
|
|
1985
|
-
recommendation: "Build local FTS artifacts to make this scope queryable. This does not call a provider.",
|
|
1986
|
-
task: "index-fts",
|
|
1987
|
-
title: "Enable query with local FTS"
|
|
1988
|
-
});
|
|
1989
|
-
} else if (!input.indexCacheCurrent) {
|
|
1990
|
-
improvements.push({
|
|
1991
|
-
kind: "sync-index",
|
|
1992
|
-
recommendation: "Sync the index cache from chapter index artifacts so query starts without a lazy cache rebuild.",
|
|
1993
|
-
title: "Sync index cache"
|
|
1994
|
-
});
|
|
1995
|
-
}
|
|
1996
|
-
improvements.push(
|
|
1997
|
-
...createGraphImprovement({
|
|
1998
|
-
concurrent: input.concurrent,
|
|
1999
|
-
covered: input.readingGraphCovered,
|
|
2000
|
-
planningModel: input.planningModel,
|
|
2001
|
-
task: "reading-graph",
|
|
2002
|
-
title: "Complete Reading Graph coverage",
|
|
2003
|
-
total: input.contentChapters
|
|
2004
|
-
})
|
|
2005
|
-
);
|
|
2006
|
-
improvements.push(
|
|
2007
|
-
...createGraphImprovement({
|
|
2008
|
-
concurrent: input.concurrent,
|
|
2009
|
-
covered: input.knowledgeGraphCovered,
|
|
2010
|
-
planningModel: input.planningModel,
|
|
2011
|
-
task: "knowledge-graph",
|
|
2012
|
-
title: "Complete Knowledge Graph coverage",
|
|
2013
|
-
total: input.contentChapters
|
|
2014
|
-
})
|
|
2015
|
-
);
|
|
2016
|
-
improvements.push(
|
|
2017
|
-
...createGraphImprovement({
|
|
2018
|
-
concurrent: input.concurrent,
|
|
2019
|
-
covered: input.summaryCovered,
|
|
2020
|
-
planningModel: input.planningModel,
|
|
2021
|
-
task: "reading-summary",
|
|
2022
|
-
title: "Complete Summary coverage",
|
|
2023
|
-
total: input.contentChapters
|
|
2024
|
-
})
|
|
2025
|
-
);
|
|
2026
|
-
return improvements;
|
|
2027
|
-
}
|
|
2028
|
-
function createGraphImprovement(input) {
|
|
2029
|
-
const coveredIds = new Set(input.covered.map((chapter) => chapter.chapterId));
|
|
2030
|
-
const missing = input.total.filter(
|
|
2031
|
-
(chapter) => !coveredIds.has(chapter.chapterId)
|
|
2032
|
-
);
|
|
2033
|
-
if (missing.length === 0) {
|
|
2034
|
-
return [];
|
|
2035
|
-
}
|
|
2036
|
-
const missingWords = sumWords(missing);
|
|
2037
|
-
return [
|
|
2038
|
-
{
|
|
2039
|
-
kind: "build",
|
|
2040
|
-
missingChapters: missing.length,
|
|
2041
|
-
missingWords,
|
|
2042
|
-
planning: planGenerationTask(
|
|
2043
|
-
input.task,
|
|
2044
|
-
missingWords,
|
|
2045
|
-
missing.length,
|
|
2046
|
-
input.concurrent,
|
|
2047
|
-
input.planningModel
|
|
2048
|
-
),
|
|
2049
|
-
recommendation: formatImprovementRecommendation(
|
|
2050
|
-
input.covered,
|
|
2051
|
-
input.total,
|
|
2052
|
-
missingWords
|
|
2053
|
-
),
|
|
2054
|
-
task: input.task,
|
|
2055
|
-
title: input.title
|
|
2056
|
-
}
|
|
2057
|
-
];
|
|
2058
|
-
}
|
|
2059
|
-
function formatImprovementRecommendation(covered, total, missingWords) {
|
|
2060
|
-
const totalWords = sumWords(total);
|
|
2061
|
-
const coveredWords = sumWords(covered);
|
|
2062
|
-
if (totalWords === 0) {
|
|
2063
|
-
return "No source content is available.";
|
|
2064
|
-
}
|
|
2065
|
-
if (total.length === 1 || coveredWords / totalWords >= 0.9 || missingWords <= 1e3) {
|
|
2066
|
-
return "Queue the full scope to finish the remaining gap.";
|
|
2067
|
-
}
|
|
2068
|
-
return "Queue selected chapters first if only part of the scope matters.";
|
|
1894
|
+
return new Map(rows.map((row) => [row.chapterId, row.words]));
|
|
2069
1895
|
}
|
|
2070
|
-
function
|
|
2071
|
-
return
|
|
1896
|
+
function formatLocatedChapterUri(archiveUri, chapter) {
|
|
1897
|
+
return `${archiveUri.replace(/\/+$/u, "")}/${chapter.uri.replace(/^wikg:\/\//u, "")}`;
|
|
2072
1898
|
}
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
1899
|
+
|
|
1900
|
+
// src/archive/write.ts
|
|
1901
|
+
import {
|
|
1902
|
+
WikiGraphArchiveFile,
|
|
1903
|
+
writeWikiGraphLibraryArchive
|
|
1904
|
+
} from "wiki-graph-core";
|
|
1905
|
+
async function writeWikiGraphArchiveLocation(location, operation, options = {}) {
|
|
1906
|
+
const cacheOnly = options.searchIndexWritebackPolicy === "cache";
|
|
1907
|
+
const write = async (archiveFile = location.archiveFile) => await new WikiGraphArchiveFile(archiveFile).write(operation, {
|
|
1908
|
+
...cacheOnly ? {} : { derivedStateKeys: [location.archiveKey, location.archivePath] },
|
|
1909
|
+
...options.invalidateContinuationCursors === void 0 ? {} : {
|
|
1910
|
+
invalidateContinuationCursors: options.invalidateContinuationCursors
|
|
1911
|
+
},
|
|
1912
|
+
...options.searchIndexWritebackPolicy === void 0 ? {} : { searchIndexWritebackPolicy: options.searchIndexWritebackPolicy }
|
|
1913
|
+
});
|
|
1914
|
+
if (location.libraryArchiveTarget === void 0 || cacheOnly || options.refreshLibraryIndex === false) {
|
|
1915
|
+
return await write();
|
|
2076
1916
|
}
|
|
2077
|
-
|
|
2078
|
-
|
|
1917
|
+
return await writeWikiGraphLibraryArchive({
|
|
1918
|
+
additionalDerivedStateKeys: [location.archiveKey, location.archivePath],
|
|
1919
|
+
...options.invalidateContinuationCursors === void 0 ? {} : {
|
|
1920
|
+
invalidateContinuationCursors: options.invalidateContinuationCursors
|
|
1921
|
+
},
|
|
1922
|
+
...options.onIndexSyncError === void 0 ? {} : { onIndexSyncError: options.onIndexSyncError },
|
|
1923
|
+
operation: async (archiveFile) => await write(archiveFile),
|
|
1924
|
+
target: location.libraryArchiveTarget
|
|
1925
|
+
});
|
|
2079
1926
|
}
|
|
2080
1927
|
|
|
2081
1928
|
// src/archive/archive.ts
|
|
@@ -2095,13 +1942,13 @@ var WikiGraphArchiveManager = class {
|
|
|
2095
1942
|
}
|
|
2096
1943
|
async create(options) {
|
|
2097
1944
|
return await this.#runtime.run(async () => {
|
|
2098
|
-
const path =
|
|
1945
|
+
const path = await assertStandaloneWikiGraphArchivePath(options.path);
|
|
2099
1946
|
if (options.replace !== true && await nodePathExists(path)) {
|
|
2100
1947
|
throw new WikiGraphArchiveExistsError(path);
|
|
2101
1948
|
}
|
|
2102
|
-
const outputPath =
|
|
2103
|
-
|
|
2104
|
-
`.${
|
|
1949
|
+
const outputPath = join4(
|
|
1950
|
+
dirname3(path),
|
|
1951
|
+
`.${basename4(path)}.${randomUUID2()}.tmp.wikg`
|
|
2105
1952
|
);
|
|
2106
1953
|
try {
|
|
2107
1954
|
if (options.importPath === void 0) {
|
|
@@ -2126,15 +1973,15 @@ var WikiGraphArchiveManager = class {
|
|
|
2126
1973
|
throw error;
|
|
2127
1974
|
}
|
|
2128
1975
|
}
|
|
2129
|
-
return { locatedUri:
|
|
1976
|
+
return { locatedUri: formatLocatedWikiGraphUri2(path), path };
|
|
2130
1977
|
} finally {
|
|
2131
1978
|
await rm3(outputPath, { force: true, recursive: true });
|
|
2132
1979
|
}
|
|
2133
1980
|
}, options.signal);
|
|
2134
1981
|
}
|
|
2135
|
-
async open(
|
|
1982
|
+
async open(target, options = {}) {
|
|
2136
1983
|
const location = await this.#runtime.run(
|
|
2137
|
-
async () => await resolveWikiGraphArchiveLocation(
|
|
1984
|
+
async () => await resolveWikiGraphArchiveLocation(target),
|
|
2138
1985
|
options.signal
|
|
2139
1986
|
);
|
|
2140
1987
|
return new WikiGraphArchiveHandle(this.#runtime, location);
|
|
@@ -2157,14 +2004,17 @@ var WikiGraphArchiveHandle = class {
|
|
|
2157
2004
|
return this.#location.locatedUri;
|
|
2158
2005
|
}
|
|
2159
2006
|
get objectUri() {
|
|
2160
|
-
return
|
|
2007
|
+
return parseLocatedWikiGraphUri2(this.#location.locatedUri).objectUri ?? "wikg://";
|
|
2161
2008
|
}
|
|
2162
2009
|
get path() {
|
|
2163
2010
|
return this.#location.archivePath;
|
|
2164
2011
|
}
|
|
2012
|
+
get target() {
|
|
2013
|
+
return this.#location.target;
|
|
2014
|
+
}
|
|
2165
2015
|
async inspect(options = {}) {
|
|
2166
2016
|
return await this.#readDocument(
|
|
2167
|
-
async (document) => await
|
|
2017
|
+
async (document) => await inspectWikiGraphArchive(document, {
|
|
2168
2018
|
archiveUri: this.#location.publicArchiveUri ?? this.locatedUri,
|
|
2169
2019
|
...options.chapterId === void 0 ? {} : { chapterId: options.chapterId }
|
|
2170
2020
|
}),
|
|
@@ -2172,13 +2022,15 @@ var WikiGraphArchiveHandle = class {
|
|
|
2172
2022
|
);
|
|
2173
2023
|
}
|
|
2174
2024
|
async search(query, options = {}) {
|
|
2175
|
-
const embeddingProvider = await this.#
|
|
2176
|
-
|
|
2025
|
+
const embeddingProvider = await this.#resolveQueryEmbeddingProvider(
|
|
2026
|
+
options.queryMode,
|
|
2177
2027
|
options.signal
|
|
2178
2028
|
);
|
|
2179
2029
|
return await this.#writeDocument(
|
|
2180
2030
|
async (document) => {
|
|
2181
|
-
const chapters = await this.#resolveQueryChapters(document, options
|
|
2031
|
+
const chapters = await this.#resolveQueryChapters(document, options, {
|
|
2032
|
+
embeddingProvider
|
|
2033
|
+
});
|
|
2182
2034
|
await ensureArchiveSearchIndex(document, {
|
|
2183
2035
|
...chapters === void 0 ? {} : { chapters },
|
|
2184
2036
|
...embeddingProvider === void 0 ? {} : { embeddingProvider }
|
|
@@ -2465,7 +2317,7 @@ var WikiGraphArchiveHandle = class {
|
|
|
2465
2317
|
objectUri,
|
|
2466
2318
|
async (wikimediaOptions) => await this.#readDocument(
|
|
2467
2319
|
async (document) => await readArchivePage(document, objectUri, {
|
|
2468
|
-
...
|
|
2320
|
+
...options,
|
|
2469
2321
|
...wikimediaOptions
|
|
2470
2322
|
}),
|
|
2471
2323
|
options
|
|
@@ -2476,6 +2328,9 @@ var WikiGraphArchiveHandle = class {
|
|
|
2476
2328
|
}
|
|
2477
2329
|
async related(objectUri = this.objectUri, options = {}) {
|
|
2478
2330
|
if (options.query === void 0) {
|
|
2331
|
+
if (options.queryMode !== void 0) {
|
|
2332
|
+
throw new Error("`queryMode` requires `query`.");
|
|
2333
|
+
}
|
|
2479
2334
|
return await this.#readDocument(async (document) => {
|
|
2480
2335
|
const chapters = await this.#resolveScope(document, {});
|
|
2481
2336
|
return await listRelatedArchiveObjects(document, objectUri, {
|
|
@@ -2484,19 +2339,22 @@ var WikiGraphArchiveHandle = class {
|
|
|
2484
2339
|
});
|
|
2485
2340
|
}, options);
|
|
2486
2341
|
}
|
|
2487
|
-
const embeddingProvider = await this.#
|
|
2488
|
-
|
|
2342
|
+
const embeddingProvider = await this.#resolveQueryEmbeddingProvider(
|
|
2343
|
+
options.queryMode,
|
|
2489
2344
|
options.signal
|
|
2490
2345
|
);
|
|
2491
2346
|
return await this.#writeDocument(
|
|
2492
2347
|
async (document) => {
|
|
2493
|
-
const chapters = await this.#resolveQueryChapters(document, options
|
|
2348
|
+
const chapters = await this.#resolveQueryChapters(document, options, {
|
|
2349
|
+
embeddingProvider
|
|
2350
|
+
});
|
|
2494
2351
|
await ensureArchiveSearchIndex(document, {
|
|
2495
2352
|
...chapters === void 0 ? {} : { chapters },
|
|
2496
2353
|
...embeddingProvider === void 0 ? {} : { embeddingProvider }
|
|
2497
2354
|
});
|
|
2498
2355
|
return await listRelatedArchiveObjects(document, objectUri, {
|
|
2499
2356
|
...withoutOperation(options),
|
|
2357
|
+
...embeddingProvider === void 0 ? {} : { embeddingProvider },
|
|
2500
2358
|
...chapters === void 0 ? {} : { chapters }
|
|
2501
2359
|
});
|
|
2502
2360
|
},
|
|
@@ -2508,6 +2366,9 @@ var WikiGraphArchiveHandle = class {
|
|
|
2508
2366
|
}
|
|
2509
2367
|
async evidence(objectUri = this.objectUri, options = {}) {
|
|
2510
2368
|
if (options.query === void 0) {
|
|
2369
|
+
if (options.queryMode !== void 0) {
|
|
2370
|
+
throw new Error("`queryMode` requires `query`.");
|
|
2371
|
+
}
|
|
2511
2372
|
return await this.#readDocument(async (document) => {
|
|
2512
2373
|
const chapters = await this.#resolveScope(document, {});
|
|
2513
2374
|
return await listArchiveEvidence(document, objectUri, {
|
|
@@ -2516,19 +2377,22 @@ var WikiGraphArchiveHandle = class {
|
|
|
2516
2377
|
});
|
|
2517
2378
|
}, options);
|
|
2518
2379
|
}
|
|
2519
|
-
const embeddingProvider = await this.#
|
|
2520
|
-
|
|
2380
|
+
const embeddingProvider = await this.#resolveQueryEmbeddingProvider(
|
|
2381
|
+
options.queryMode,
|
|
2521
2382
|
options.signal
|
|
2522
2383
|
);
|
|
2523
2384
|
return await this.#writeDocument(
|
|
2524
2385
|
async (document) => {
|
|
2525
|
-
const chapters = await this.#resolveQueryChapters(document, options
|
|
2386
|
+
const chapters = await this.#resolveQueryChapters(document, options, {
|
|
2387
|
+
embeddingProvider
|
|
2388
|
+
});
|
|
2526
2389
|
await ensureArchiveSearchIndex(document, {
|
|
2527
2390
|
...chapters === void 0 ? {} : { chapters },
|
|
2528
2391
|
...embeddingProvider === void 0 ? {} : { embeddingProvider }
|
|
2529
2392
|
});
|
|
2530
2393
|
return await listArchiveEvidence(document, objectUri, {
|
|
2531
2394
|
...withoutOperation(options),
|
|
2395
|
+
...embeddingProvider === void 0 ? {} : { embeddingProvider },
|
|
2532
2396
|
...chapters === void 0 ? {} : { chapters }
|
|
2533
2397
|
});
|
|
2534
2398
|
},
|
|
@@ -2562,6 +2426,24 @@ var WikiGraphArchiveHandle = class {
|
|
|
2562
2426
|
return meta;
|
|
2563
2427
|
}, options);
|
|
2564
2428
|
}
|
|
2429
|
+
async setArchiveTitle(title, options = {}) {
|
|
2430
|
+
const normalized = title?.trim() ?? null;
|
|
2431
|
+
if (title !== null && normalized === "") {
|
|
2432
|
+
throw new Error("Archive title cannot be empty.");
|
|
2433
|
+
}
|
|
2434
|
+
return await this.#writeDocument(async (document) => {
|
|
2435
|
+
if (normalized === null) {
|
|
2436
|
+
await document.metadata.deleteKey("", "title");
|
|
2437
|
+
} else {
|
|
2438
|
+
await document.metadata.put(
|
|
2439
|
+
{ kind: ObjectMetadataKind.Archive, objectPath: "" },
|
|
2440
|
+
"title",
|
|
2441
|
+
normalized
|
|
2442
|
+
);
|
|
2443
|
+
}
|
|
2444
|
+
return normalized;
|
|
2445
|
+
}, options);
|
|
2446
|
+
}
|
|
2565
2447
|
async readCover(options = {}) {
|
|
2566
2448
|
const app = new WikiGraph2({});
|
|
2567
2449
|
return await this.#runtime.run(
|
|
@@ -2611,7 +2493,7 @@ var WikiGraphArchiveHandle = class {
|
|
|
2611
2493
|
}
|
|
2612
2494
|
async #readDocument(operation, options = {}) {
|
|
2613
2495
|
return await this.#runtime.run(
|
|
2614
|
-
async () => await new
|
|
2496
|
+
async () => await new WikiGraphArchiveFile2(this.#location.archiveFile).readDocument(
|
|
2615
2497
|
operation
|
|
2616
2498
|
),
|
|
2617
2499
|
options.signal
|
|
@@ -2619,28 +2501,33 @@ var WikiGraphArchiveHandle = class {
|
|
|
2619
2501
|
}
|
|
2620
2502
|
async #writeDocument(operation, options = {}) {
|
|
2621
2503
|
return await this.#runtime.run(async () => {
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2504
|
+
return await writeWikiGraphArchiveLocation(this.#location, operation, {
|
|
2505
|
+
...options.onIndexSyncError === void 0 ? {} : { onIndexSyncError: options.onIndexSyncError },
|
|
2506
|
+
...options.refreshLibraryIndex === void 0 ? {} : { refreshLibraryIndex: options.refreshLibraryIndex },
|
|
2625
2507
|
...options.searchIndexWritebackPolicy === void 0 ? {} : {
|
|
2626
2508
|
searchIndexWritebackPolicy: options.searchIndexWritebackPolicy
|
|
2627
2509
|
}
|
|
2628
2510
|
});
|
|
2629
|
-
if (options.refreshLibraryIndex !== false) {
|
|
2630
|
-
await this.#refreshLibraryIndex(options.onIndexSyncError);
|
|
2631
|
-
}
|
|
2632
|
-
return result;
|
|
2633
2511
|
}, options.signal);
|
|
2634
2512
|
}
|
|
2635
2513
|
async #resolveScope(document, options) {
|
|
2636
2514
|
if (options.chapters !== void 0) return options.chapters;
|
|
2637
2515
|
return (await resolveArchiveScope(document, this.objectUri, options.depth))?.chapterIds;
|
|
2638
2516
|
}
|
|
2639
|
-
async #resolveQueryChapters(document, options) {
|
|
2517
|
+
async #resolveQueryChapters(document, options, capabilities) {
|
|
2640
2518
|
const chapters = await this.#resolveScope(document, options);
|
|
2641
|
-
|
|
2519
|
+
const coverageOptions = {
|
|
2520
|
+
...chapters === void 0 ? {} : { chapters },
|
|
2521
|
+
...capabilities.embeddingProvider === void 0 ? {} : { embeddingProvider: capabilities.embeddingProvider },
|
|
2522
|
+
requireEmbeddingProvider: true,
|
|
2523
|
+
...options.queryMode === void 0 ? {} : { queryMode: options.queryMode }
|
|
2524
|
+
};
|
|
2525
|
+
if (options.skipUnindexed !== true) {
|
|
2526
|
+
await assertArchiveIndexArtifactsReady(document, coverageOptions);
|
|
2527
|
+
return chapters;
|
|
2528
|
+
}
|
|
2642
2529
|
const queryable = await listArchiveQueryableChapterIds(document, {
|
|
2643
|
-
...
|
|
2530
|
+
...coverageOptions
|
|
2644
2531
|
});
|
|
2645
2532
|
if (queryable.length === 0) {
|
|
2646
2533
|
throw new Error(
|
|
@@ -2649,52 +2536,20 @@ var WikiGraphArchiveHandle = class {
|
|
|
2649
2536
|
}
|
|
2650
2537
|
return queryable;
|
|
2651
2538
|
}
|
|
2652
|
-
async #
|
|
2653
|
-
if (
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
this.#location.libraryDirtyTarget
|
|
2539
|
+
async #resolveQueryEmbeddingProvider(queryMode, signal) {
|
|
2540
|
+
if (queryMode === "fts") return void 0;
|
|
2541
|
+
const provider = await this.#runtime.run(
|
|
2542
|
+
createConfiguredEmbeddingProvider,
|
|
2543
|
+
signal
|
|
2544
|
+
);
|
|
2545
|
+
if (queryMode === "embedding" && provider === void 0) {
|
|
2546
|
+
throw new Error(
|
|
2547
|
+
"Embedding query mode requires embeddings configuration at `wikg://local/config/embeddings`."
|
|
2662
2548
|
);
|
|
2663
|
-
if (state.status !== "missing") {
|
|
2664
|
-
await rebuildWikiGraphLibraryIndex(this.#location.libraryDirtyTarget);
|
|
2665
|
-
}
|
|
2666
|
-
} catch (error) {
|
|
2667
|
-
onError?.(error);
|
|
2668
2549
|
}
|
|
2550
|
+
return provider;
|
|
2669
2551
|
}
|
|
2670
2552
|
};
|
|
2671
|
-
async function resolveWikiGraphArchiveLocation(uriOrPath) {
|
|
2672
|
-
if (!uriOrPath.startsWith("wikg://")) {
|
|
2673
|
-
return createPathLocation(resolveWikiGraphRuntimePath(uriOrPath));
|
|
2674
|
-
}
|
|
2675
|
-
const parsed = parseLocatedWikiGraphUri(uriOrPath);
|
|
2676
|
-
const portableArchiveLocator = parsed.archivePath ?? uriOrPath;
|
|
2677
|
-
const archiveLocator = portableArchiveLocator.startsWith("wikg://lib/") ? portableArchiveLocator : resolveWikiGraphRuntimePath(portableArchiveLocator);
|
|
2678
|
-
const libraryArchiveTarget = archiveLocator.startsWith("wikg://lib/") ? parseWikiGraphLibraryUri(archiveLocator) : void 0;
|
|
2679
|
-
const archiveFile = libraryArchiveTarget?.kind === "archive" ? await resolveWikiGraphLibraryArchiveFile(archiveLocator) : new NodeFile(archiveLocator);
|
|
2680
|
-
const archivePath = getNodeResourcePath(archiveFile);
|
|
2681
|
-
return {
|
|
2682
|
-
archiveFile,
|
|
2683
|
-
archiveKey: archivePath,
|
|
2684
|
-
archivePath,
|
|
2685
|
-
indexScope: { archiveKey: archivePath, archivePath, kind: "archive-index" },
|
|
2686
|
-
...libraryArchiveTarget?.kind === "archive" ? {
|
|
2687
|
-
libraryArchiveTarget,
|
|
2688
|
-
libraryDirtyTarget: {
|
|
2689
|
-
isDefault: libraryArchiveTarget.isDefault,
|
|
2690
|
-
kind: "scope",
|
|
2691
|
-
...libraryArchiveTarget.publicId === void 0 ? {} : { publicId: libraryArchiveTarget.publicId }
|
|
2692
|
-
},
|
|
2693
|
-
publicArchiveUri: portableArchiveLocator
|
|
2694
|
-
} : {},
|
|
2695
|
-
locatedUri: formatLocatedWikiGraphUri(archivePath, parsed.objectUri)
|
|
2696
|
-
};
|
|
2697
|
-
}
|
|
2698
2553
|
async function ensureArchiveSearchIndex(document, options = {}) {
|
|
2699
2554
|
const scope = options.chapters === void 0 ? {} : { chapters: options.chapters };
|
|
2700
2555
|
if (await isArchiveSearchIndexCurrent2(document, scope)) return;
|
|
@@ -2733,18 +2588,9 @@ function selectChapterSubtree(chapters, rootChapterId, depth) {
|
|
|
2733
2588
|
(chapter) => chapter.chapterId === root.chapterId || chapter.path.startsWith(prefix) && (depth === void 0 || chapter.depth - root.depth <= depth)
|
|
2734
2589
|
);
|
|
2735
2590
|
}
|
|
2736
|
-
function createPathLocation(path) {
|
|
2737
|
-
return {
|
|
2738
|
-
archiveFile: new NodeFile(path),
|
|
2739
|
-
archiveKey: path,
|
|
2740
|
-
archivePath: path,
|
|
2741
|
-
indexScope: { archiveKey: path, archivePath: path, kind: "archive-index" },
|
|
2742
|
-
locatedUri: formatLocatedWikiGraphUri(path)
|
|
2743
|
-
};
|
|
2744
|
-
}
|
|
2745
2591
|
async function createEmptyArchiveFile(path) {
|
|
2746
2592
|
const directoryPath = await mkdtemp(
|
|
2747
|
-
|
|
2593
|
+
join4(tmpdir(), "wikigraph-archive-write-")
|
|
2748
2594
|
);
|
|
2749
2595
|
try {
|
|
2750
2596
|
const directory = new NodeDirectory(directoryPath);
|
|
@@ -2766,7 +2612,7 @@ function isNodeEEXISTError(error) {
|
|
|
2766
2612
|
}
|
|
2767
2613
|
async function nodePathExists(path) {
|
|
2768
2614
|
try {
|
|
2769
|
-
await
|
|
2615
|
+
await stat3(path);
|
|
2770
2616
|
return true;
|
|
2771
2617
|
} catch (error) {
|
|
2772
2618
|
if (isNodeENOENTError(error)) return false;
|
|
@@ -2872,7 +2718,7 @@ export {
|
|
|
2872
2718
|
WikiGraphArchiveExistsError,
|
|
2873
2719
|
WikiGraphArchiveHandle,
|
|
2874
2720
|
WikiGraphArchiveManager,
|
|
2875
|
-
|
|
2876
|
-
|
|
2721
|
+
WikiGraphArchiveOwnershipError,
|
|
2722
|
+
inspectWikiGraphArchive
|
|
2877
2723
|
};
|
|
2878
2724
|
//# sourceMappingURL=archives.js.map
|