wiki-graph-sdk 0.7.0 → 0.8.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.
@@ -35,7 +35,7 @@ __export(default_worker_exports, {
35
35
  runWikiGraphQueueWorker: () => runWikiGraphQueueWorker
36
36
  });
37
37
  module.exports = __toCommonJS(default_worker_exports);
38
- var import_wiki_graph_core5 = require("wiki-graph-core");
38
+ var import_wiki_graph_core8 = require("wiki-graph-core");
39
39
  var import_worker3 = require("wiki-graph-core/worker");
40
40
 
41
41
  // src/embedding.ts
@@ -303,6 +303,14 @@ function decodeNodeResourceIdentity(identity, kind) {
303
303
  return void 0;
304
304
  }
305
305
  }
306
+ function getNodeResourcePath(resource) {
307
+ const brandedPath = getBrandedNodeResourcePath(resource, resource.kind);
308
+ if (brandedPath !== void 0) return brandedPath;
309
+ if (typeof resource === "object" && resource !== null && "path" in resource && typeof resource.path === "string") {
310
+ return resource.path;
311
+ }
312
+ throw new TypeError("Expected a Node File or Directory resource");
313
+ }
306
314
  function assertChildName(name) {
307
315
  if (name.length === 0 || name === "." || name === ".." || pathModule.isAbsolute(name) || name.includes("/") || name.includes("\\")) {
308
316
  throw new TypeError(`Directory child must be a relative name: ${name}`);
@@ -314,42 +322,42 @@ var NodeDatabaseConnection = class {
314
322
  }
315
323
  database;
316
324
  async close() {
317
- await new Promise((resolve2, reject) => {
325
+ await new Promise((resolve4, reject) => {
318
326
  this.database.close((error) => {
319
327
  if (error) reject(error);
320
- else resolve2();
328
+ else resolve4();
321
329
  });
322
330
  });
323
331
  }
324
332
  async execute(sql) {
325
- await new Promise((resolve2, reject) => {
333
+ await new Promise((resolve4, reject) => {
326
334
  this.database.exec(sql, (error) => {
327
335
  if (error) reject(error);
328
- else resolve2();
336
+ else resolve4();
329
337
  });
330
338
  });
331
339
  }
332
340
  async queryAll(sql, params = []) {
333
- return await new Promise((resolve2, reject) => {
341
+ return await new Promise((resolve4, reject) => {
334
342
  this.database.all(sql, [...params], (error, rows) => {
335
343
  if (error) reject(error);
336
- else resolve2(rows);
344
+ else resolve4(rows);
337
345
  });
338
346
  });
339
347
  }
340
348
  async queryOne(sql, params = []) {
341
- return await new Promise((resolve2, reject) => {
349
+ return await new Promise((resolve4, reject) => {
342
350
  this.database.get(sql, [...params], (error, row) => {
343
351
  if (error) reject(error);
344
- else resolve2(row);
352
+ else resolve4(row);
345
353
  });
346
354
  });
347
355
  }
348
356
  async run(sql, params = []) {
349
- await new Promise((resolve2, reject) => {
357
+ await new Promise((resolve4, reject) => {
350
358
  this.database.run(sql, [...params], (error) => {
351
359
  if (error) reject(error);
352
- else resolve2();
360
+ else resolve4();
353
361
  });
354
362
  });
355
363
  }
@@ -363,10 +371,10 @@ async function openNativeNodeDatabase(file, flags) {
363
371
  if (path === void 0) {
364
372
  throw new TypeError("The Node database adapter requires a NodeFile");
365
373
  }
366
- return await new Promise((resolve2, reject) => {
374
+ return await new Promise((resolve4, reject) => {
367
375
  const database = new nodeSqlite3.Database(path, flags, (error) => {
368
376
  if (error) reject(error);
369
- else resolve2(database);
377
+ else resolve4(database);
370
378
  });
371
379
  });
372
380
  }
@@ -375,19 +383,19 @@ async function openNodeZip(file) {
375
383
  if (path === void 0) {
376
384
  throw new TypeError("The Node ZIP adapter requires a NodeFile");
377
385
  }
378
- const zipFile = await new Promise((resolve2, reject) => {
386
+ const zipFile = await new Promise((resolve4, reject) => {
379
387
  yauzl.open(
380
388
  path,
381
389
  { autoClose: false, lazyEntries: true },
382
390
  (error, opened) => {
383
391
  if (error || opened === void 0)
384
392
  reject(error ?? new Error("Cannot open ZIP"));
385
- else resolve2(opened);
393
+ else resolve4(opened);
386
394
  }
387
395
  );
388
396
  });
389
397
  const entries = await new Promise(
390
- (resolve2, reject) => {
398
+ (resolve4, reject) => {
391
399
  const discovered = /* @__PURE__ */ new Map();
392
400
  const rejectAndClose = (error) => {
393
401
  zipFile.close();
@@ -397,7 +405,7 @@ async function openNodeZip(file) {
397
405
  };
398
406
  const resolveEntries = () => {
399
407
  zipFile.off("error", rejectAndClose);
400
- resolve2(discovered);
408
+ resolve4(discovered);
401
409
  };
402
410
  zipFile.on("entry", (entry) => {
403
411
  if (!entry.fileName.endsWith("/")) {
@@ -507,12 +515,12 @@ async function collectDecodedNodeStreamRange(input, offset, length) {
507
515
  return Buffer.concat(chunks, collected);
508
516
  }
509
517
  async function openNodeZipEntryStream(zipFile, entry, options) {
510
- return await new Promise((resolve2, reject) => {
518
+ return await new Promise((resolve4, reject) => {
511
519
  const callback = (error, opened) => {
512
520
  if (error || opened === void 0) {
513
521
  reject(error ?? new Error(`Cannot read ZIP entry: ${entry.fileName}`));
514
522
  } else {
515
- resolve2(opened);
523
+ resolve4(opened);
516
524
  }
517
525
  };
518
526
  if (options === void 0) zipFile.openReadStream(entry, callback);
@@ -643,11 +651,11 @@ async function writeNodeStream(input, writer) {
643
651
  );
644
652
  }
645
653
  async function collectNodeStream(input) {
646
- return await new Promise((resolve2, reject) => {
654
+ return await new Promise((resolve4, reject) => {
647
655
  const chunks = [];
648
656
  input.on("data", (chunk) => chunks.push(chunk));
649
657
  input.once("error", reject);
650
- input.once("end", () => resolve2(Buffer.concat(chunks)));
658
+ input.once("end", () => resolve4(Buffer.concat(chunks)));
651
659
  });
652
660
  }
653
661
  var nodeWikiGraphPlatform = {
@@ -1389,12 +1397,13 @@ var DEFAULT_GENERATION_JOB_CONCURRENCY = 3;
1389
1397
  // src/wikispine.ts
1390
1398
  var import_child_process = require("child_process");
1391
1399
  var nodeWikispineCommandRunner = {
1392
- run: async ({ args, command, input, onStdout, signal }) => await new Promise((resolve2, reject) => {
1400
+ run: async ({ args, command, input, onStdout, signal }) => await new Promise((resolve4, reject) => {
1393
1401
  signal?.throwIfAborted();
1394
1402
  const child = (0, import_child_process.spawn)(command, [...args], {
1395
1403
  stdio: ["pipe", "pipe", "pipe"]
1396
1404
  });
1397
1405
  const stderr = [];
1406
+ let stdoutQueue = Promise.resolve();
1398
1407
  let settled = false;
1399
1408
  const settle = (operation) => {
1400
1409
  if (settled) return;
@@ -1410,14 +1419,15 @@ var nodeWikispineCommandRunner = {
1410
1419
  child.stdout.setEncoding("utf8");
1411
1420
  child.stdout.on("data", (chunk) => {
1412
1421
  if (settled) return;
1413
- try {
1414
- onStdout(chunk);
1415
- } catch (error) {
1422
+ child.stdout.pause();
1423
+ stdoutQueue = stdoutQueue.then(async () => await onStdout(chunk)).then(() => {
1424
+ child.stdout.resume();
1425
+ }).catch((error) => {
1416
1426
  child.kill();
1417
1427
  settle(
1418
1428
  () => reject(error instanceof Error ? error : new Error(String(error)))
1419
1429
  );
1420
- }
1430
+ });
1421
1431
  });
1422
1432
  child.stderr.on("data", (chunk) => stderr.push(chunk));
1423
1433
  child.on("error", (error) => {
@@ -1428,12 +1438,14 @@ var nodeWikispineCommandRunner = {
1428
1438
  );
1429
1439
  });
1430
1440
  child.on("close", (exitCode) => {
1431
- settle(
1432
- () => resolve2({
1433
- exitCode,
1434
- stderr: Buffer.concat(stderr).toString("utf8")
1435
- })
1436
- );
1441
+ void stdoutQueue.then(() => {
1442
+ settle(
1443
+ () => resolve4({
1444
+ exitCode,
1445
+ stderr: Buffer.concat(stderr).toString("utf8")
1446
+ })
1447
+ );
1448
+ });
1437
1449
  });
1438
1450
  child.stdin.end(input);
1439
1451
  })
@@ -1444,6 +1456,221 @@ function abortError(signal) {
1444
1456
 
1445
1457
  // src/worker.ts
1446
1458
  var import_worker = require("wiki-graph-core/worker");
1459
+ var import_wiki_graph_core7 = require("wiki-graph-core");
1460
+
1461
+ // src/archive/target.ts
1462
+ var import_promises2 = require("fs/promises");
1463
+ var import_path3 = require("path");
1464
+ var import_wiki_graph_core5 = require("wiki-graph-core");
1465
+
1466
+ // src/runtime-path.ts
1467
+ var import_os2 = require("os");
1468
+ var import_path2 = require("path");
1469
+ function resolveWikiGraphRuntimePath(path) {
1470
+ const context = getWikiGraphSDKRuntimeContext();
1471
+ const environmentHome = context.env.HOME?.trim();
1472
+ const home = environmentHome === void 0 || environmentHome === "" ? (0, import_os2.homedir)() : environmentHome;
1473
+ if (path === "~") return home;
1474
+ if (path.startsWith("~/")) return (0, import_path2.resolve)(home, path.slice(2));
1475
+ return (0, import_path2.isAbsolute)(path) ? path : (0, import_path2.resolve)(context.cwd, path);
1476
+ }
1477
+
1478
+ // src/archive/target.ts
1479
+ var WikiGraphArchiveOwnershipError = class extends Error {
1480
+ code = "WIKI_GRAPH_ARCHIVE_OWNERSHIP_MISMATCH";
1481
+ constructor(message) {
1482
+ super(message);
1483
+ this.name = "WikiGraphArchiveOwnershipError";
1484
+ }
1485
+ };
1486
+ async function resolveWikiGraphArchiveLocation(target) {
1487
+ if (target.kind === "standalone") {
1488
+ return await resolveStandaloneLocation(target);
1489
+ }
1490
+ return await resolveLibraryLocation(target);
1491
+ }
1492
+ async function assertStandaloneWikiGraphArchivePath(inputPath) {
1493
+ const path = resolveWikiGraphRuntimePath(inputPath);
1494
+ const candidate = await canonicalPath(path);
1495
+ const candidateIdentity = await readFileIdentity(path);
1496
+ const libraries = await (0, import_wiki_graph_core5.listWikiGraphLibraries)();
1497
+ const matches = await findMatchingMembers(
1498
+ libraries,
1499
+ candidate,
1500
+ candidateIdentity
1501
+ );
1502
+ if (matches.length > 0) {
1503
+ const match = requireUnambiguousManagedMatch(path, matches);
1504
+ throw new WikiGraphArchiveOwnershipError(
1505
+ `Standalone archive path belongs to registered library ${(0, import_wiki_graph_core5.formatWikiGraphLibraryUri)(
1506
+ match.library.isDefault ? void 0 : match.library.publicId
1507
+ )}: ${path}. Use the library UUID URI ${match.archive.uri} instead.`
1508
+ );
1509
+ }
1510
+ for (const library of libraries) {
1511
+ const rootPath = getNodeResourcePath(library.folder);
1512
+ const root = await canonicalPath(rootPath);
1513
+ if (!isWithin(root, candidate)) continue;
1514
+ throw new WikiGraphArchiveOwnershipError(
1515
+ `Standalone archive path belongs to registered library ${(0, import_wiki_graph_core5.formatWikiGraphLibraryUri)(
1516
+ library.isDefault ? void 0 : library.publicId
1517
+ )}: ${path}. Scan the library, then address the archive by its library UUID URI.`
1518
+ );
1519
+ }
1520
+ return path;
1521
+ }
1522
+ async function resolveWikiGraphArchiveTarget(file) {
1523
+ const path = getNodeResourcePath(file);
1524
+ const candidate = await canonicalPath(path);
1525
+ const candidateIdentity = await readFileIdentity(path);
1526
+ const matches = await findMatchingMembers(
1527
+ await (0, import_wiki_graph_core5.listWikiGraphLibraries)(),
1528
+ candidate,
1529
+ candidateIdentity
1530
+ );
1531
+ if (matches.length > 0) {
1532
+ const match = requireUnambiguousManagedMatch(path, matches);
1533
+ return { kind: "library", uri: match.archive.uri };
1534
+ }
1535
+ return { kind: "standalone", path: getNodeResourcePath(file) };
1536
+ }
1537
+ async function resolveStandaloneLocation(target) {
1538
+ if (target.path.startsWith("wikg://lib/")) {
1539
+ throw new WikiGraphArchiveOwnershipError(
1540
+ `A library archive URI cannot be used as a standalone path: ${target.path}`
1541
+ );
1542
+ }
1543
+ const path = await assertStandaloneWikiGraphArchivePath(target.path);
1544
+ const normalized = {
1545
+ kind: "standalone",
1546
+ path,
1547
+ ...target.objectUri === void 0 ? {} : { objectUri: target.objectUri }
1548
+ };
1549
+ return {
1550
+ archiveFile: new NodeFile(path),
1551
+ archiveKey: path,
1552
+ archivePath: path,
1553
+ indexScope: { archiveKey: path, archivePath: path, kind: "archive-index" },
1554
+ locatedUri: (0, import_wiki_graph_core5.formatLocatedWikiGraphUri)(path, target.objectUri),
1555
+ target: normalized
1556
+ };
1557
+ }
1558
+ async function resolveLibraryLocation(target) {
1559
+ const parsedLocated = (0, import_wiki_graph_core5.parseLocatedWikiGraphUri)(target.uri);
1560
+ const archiveUri = parsedLocated.archivePath ?? target.uri;
1561
+ const parsed = (0, import_wiki_graph_core5.parseWikiGraphLibraryUri)(archiveUri);
1562
+ if (parsed?.kind !== "archive") {
1563
+ throw new WikiGraphArchiveOwnershipError(
1564
+ `Library archive target must be a UUID archive URI: ${target.uri}`
1565
+ );
1566
+ }
1567
+ await (0, import_wiki_graph_core5.resolveWikiGraphLibrary)(parsed);
1568
+ const archiveFile = await (0, import_wiki_graph_core5.resolveWikiGraphLibraryArchiveFile)(archiveUri);
1569
+ const normalized = {
1570
+ kind: "library",
1571
+ uri: target.uri
1572
+ };
1573
+ return {
1574
+ archiveFile,
1575
+ archiveKey: archiveUri,
1576
+ archivePath: archiveUri,
1577
+ indexScope: {
1578
+ archiveKey: archiveUri,
1579
+ archivePath: archiveUri,
1580
+ kind: "archive-index"
1581
+ },
1582
+ libraryArchiveTarget: parsed,
1583
+ locatedUri: target.uri,
1584
+ publicArchiveUri: archiveUri,
1585
+ target: normalized
1586
+ };
1587
+ }
1588
+ async function canonicalPath(path) {
1589
+ try {
1590
+ return await (0, import_promises2.realpath)(path);
1591
+ } catch {
1592
+ const absolute = (0, import_path3.resolve)(path);
1593
+ const parent = (0, import_path3.dirname)(absolute);
1594
+ return parent === absolute ? absolute : (0, import_path3.join)(await canonicalPath(parent), (0, import_path3.basename)(absolute));
1595
+ }
1596
+ }
1597
+ function isWithin(root, candidate) {
1598
+ const child = (0, import_path3.relative)(root, candidate);
1599
+ return child === "" || !child.startsWith("..") && !(0, import_path3.isAbsolute)(child);
1600
+ }
1601
+ async function findMatchingMembers(libraries, candidate, candidateIdentity) {
1602
+ const members = [];
1603
+ for (const library of libraries) {
1604
+ const archives = await (0, import_wiki_graph_core5.listWikiGraphLibraryArchives)({
1605
+ isDefault: library.isDefault,
1606
+ kind: "scope",
1607
+ ...library.isDefault ? {} : { publicId: library.publicId }
1608
+ });
1609
+ for (const archive of archives) {
1610
+ if (archive.file === void 0) continue;
1611
+ members.push({
1612
+ archive,
1613
+ library,
1614
+ memberPath: getNodeResourcePath(archive.file)
1615
+ });
1616
+ }
1617
+ }
1618
+ const exact = [];
1619
+ for (const member of members) {
1620
+ if (await canonicalPath(member.memberPath) === candidate) {
1621
+ exact.push(member);
1622
+ }
1623
+ }
1624
+ if (exact.length > 0 || candidateIdentity === void 0) return exact;
1625
+ const identityMatches = [];
1626
+ for (const member of members) {
1627
+ if (await readFileIdentity(member.memberPath) === candidateIdentity) {
1628
+ identityMatches.push(member);
1629
+ }
1630
+ }
1631
+ return identityMatches;
1632
+ }
1633
+ function requireUnambiguousManagedMatch(path, matches) {
1634
+ if (matches.length === 1) return matches[0];
1635
+ throw new WikiGraphArchiveOwnershipError(
1636
+ `Archive file identity is ambiguous across managed archives: ${path}. Use an explicit library UUID URI (${matches.map((match) => match.archive.uri).join(", ")}).`
1637
+ );
1638
+ }
1639
+ async function readFileIdentity(path) {
1640
+ try {
1641
+ const value = await (0, import_promises2.stat)(path);
1642
+ return `${value.dev}:${value.ino}`;
1643
+ } catch {
1644
+ return void 0;
1645
+ }
1646
+ }
1647
+
1648
+ // src/archive/write.ts
1649
+ var import_wiki_graph_core6 = require("wiki-graph-core");
1650
+ async function writeWikiGraphArchiveLocation(location, operation, options = {}) {
1651
+ const cacheOnly = options.searchIndexWritebackPolicy === "cache";
1652
+ const write = async (archiveFile = location.archiveFile) => await new import_wiki_graph_core6.WikiGraphArchiveFile(archiveFile).write(operation, {
1653
+ ...cacheOnly ? {} : { derivedStateKeys: [location.archiveKey, location.archivePath] },
1654
+ ...options.invalidateContinuationCursors === void 0 ? {} : {
1655
+ invalidateContinuationCursors: options.invalidateContinuationCursors
1656
+ },
1657
+ ...options.searchIndexWritebackPolicy === void 0 ? {} : { searchIndexWritebackPolicy: options.searchIndexWritebackPolicy }
1658
+ });
1659
+ if (location.libraryArchiveTarget === void 0 || cacheOnly || options.refreshLibraryIndex === false) {
1660
+ return await write();
1661
+ }
1662
+ return await (0, import_wiki_graph_core6.writeWikiGraphLibraryArchive)({
1663
+ additionalDerivedStateKeys: [location.archiveKey, location.archivePath],
1664
+ ...options.invalidateContinuationCursors === void 0 ? {} : {
1665
+ invalidateContinuationCursors: options.invalidateContinuationCursors
1666
+ },
1667
+ ...options.onIndexSyncError === void 0 ? {} : { onIndexSyncError: options.onIndexSyncError },
1668
+ operation: async (archiveFile) => await write(archiveFile),
1669
+ target: location.libraryArchiveTarget
1670
+ });
1671
+ }
1672
+
1673
+ // src/worker.ts
1447
1674
  var import_worker2 = require("wiki-graph-core/worker");
1448
1675
  async function runBuildJobWorker(options) {
1449
1676
  installNodeWikiGraphPlatform();
@@ -1460,7 +1687,7 @@ async function runWikiGraphQueueWorker(options = {}) {
1460
1687
  await runBuildJobWorker({
1461
1688
  concurrency: config.concurrent?.job ?? DEFAULT_GENERATION_JOB_CONCURRENCY,
1462
1689
  executeJob: async (job, reporter, context) => {
1463
- await (0, import_wiki_graph_core5.withLoggingContext)(
1690
+ await (0, import_wiki_graph_core8.withLoggingContext)(
1464
1691
  { logDirectory: job.log, operation: "build-job" },
1465
1692
  async () => await executeBuildJob(job, reporter, context)
1466
1693
  );
@@ -1483,7 +1710,7 @@ async function executeBuildJob(job, reporter, context) {
1483
1710
  let stage = await readChapterStage(job);
1484
1711
  if (stage === "sourced") {
1485
1712
  await executeStep(job, "reading-graph", execution, reporter, context, {
1486
- ...execution.extractionPrompt === void 0 ? {} : { extractionPrompt: execution.extractionPrompt }
1713
+ ...execution.extractionPrompt === void 0 ? {} : { prompt: execution.extractionPrompt }
1487
1714
  });
1488
1715
  stage = await readChapterStage(job);
1489
1716
  }
@@ -1516,8 +1743,8 @@ async function executeBuildJob(job, reporter, context) {
1516
1743
  }
1517
1744
  }
1518
1745
  await executeStep(job, job.target, execution, reporter, context, {
1519
- ...job.target === "reading-graph" ? { extractionPrompt: execution.extractionPrompt } : {},
1520
- ...job.target === "knowledge-graph" ? { policyPrompt: execution.knowledgeGraphPrompt } : {}
1746
+ ...job.target === "reading-graph" ? { prompt: execution.extractionPrompt } : {},
1747
+ ...job.target === "knowledge-graph" ? { prompt: execution.knowledgeGraphPrompt } : {}
1521
1748
  });
1522
1749
  } finally {
1523
1750
  await execution.close();
@@ -1532,9 +1759,9 @@ async function executeStep(job, kind, execution, reporter, context, inputOptions
1532
1759
  const stepWorkspace = await resetStepWorkspace(job.workspace, kind);
1533
1760
  const inputFile = await stepWorkspace.createFile("input.jsonl");
1534
1761
  const outputWorkspace = await stepWorkspace.createDirectory("output");
1535
- const revision = await new import_wiki_graph_core5.WikiGraphArchiveFile(job.archive).readDocument(
1762
+ const revision = await new import_wiki_graph_core8.WikiGraphArchiveFile(job.archive).readDocument(
1536
1763
  async (document) => {
1537
- await (0, import_wiki_graph_core5.getChapterDetails)(document, job.chapterId);
1764
+ await (0, import_wiki_graph_core8.getChapterDetails)(document, job.chapterId);
1538
1765
  return await (0, import_worker3.writeChapterJobInputFile)(
1539
1766
  document,
1540
1767
  job.chapterId,
@@ -1544,7 +1771,7 @@ async function executeStep(job, kind, execution, reporter, context, inputOptions
1544
1771
  );
1545
1772
  }
1546
1773
  );
1547
- await (0, import_wiki_graph_core5.recordBuildJobInputRevision)({
1774
+ await (0, import_wiki_graph_core8.recordBuildJobInputRevision)({
1548
1775
  currentRevision: revision,
1549
1776
  jobId: job.jobId,
1550
1777
  ownerId: requireRunningJobOwnerId(job)
@@ -1574,16 +1801,23 @@ async function executeStep(job, kind, execution, reporter, context, inputOptions
1574
1801
  total: 1,
1575
1802
  unit: "item"
1576
1803
  });
1577
- await new import_wiki_graph_core5.WikiGraphArchiveFile(job.archive).write(async (document) => {
1578
- assertJobStillRunning(await (0, import_wiki_graph_core5.getBuildJob)(job.jobId));
1579
- await (0, import_worker3.applyChapterJobArtifactFile)(
1580
- document,
1581
- job.chapterId,
1582
- kind,
1583
- revision,
1584
- result.artifactFile
1585
- );
1586
- });
1804
+ const target = await resolveWikiGraphArchiveTarget(job.archive);
1805
+ const resolvedLocation = await resolveWikiGraphArchiveLocation(target);
1806
+ const location = target.kind === "standalone" ? { ...resolvedLocation, archiveFile: job.archive } : resolvedLocation;
1807
+ await writeWikiGraphArchiveLocation(
1808
+ location,
1809
+ async (document) => {
1810
+ assertJobStillRunning(await (0, import_wiki_graph_core8.getBuildJob)(job.jobId));
1811
+ await (0, import_worker3.applyChapterJobArtifactFile)(
1812
+ document,
1813
+ job.chapterId,
1814
+ kind,
1815
+ revision,
1816
+ result.artifactFile
1817
+ );
1818
+ },
1819
+ { invalidateContinuationCursors: true }
1820
+ );
1587
1821
  await reporter.updatePhase({
1588
1822
  done: 1,
1589
1823
  phase: "committing",
@@ -1591,7 +1825,7 @@ async function executeStep(job, kind, execution, reporter, context, inputOptions
1591
1825
  unit: "item"
1592
1826
  });
1593
1827
  await reporter.stepCompleted(kind);
1594
- assertJobStillRunning(await (0, import_wiki_graph_core5.getBuildJob)(job.jobId));
1828
+ assertJobStillRunning(await (0, import_wiki_graph_core8.getBuildJob)(job.jobId));
1595
1829
  }
1596
1830
  async function openJobExecutor(job, config, signal, reporter) {
1597
1831
  const generation = !job.target.startsWith("index-");
@@ -1610,18 +1844,22 @@ async function openJobExecutor(job, config, signal, reporter) {
1610
1844
  const request = llm === void 0 ? void 0 : async (messages, index, maxRetries) => await llm.request(messages, {
1611
1845
  retryIndex: index,
1612
1846
  retryMax: maxRetries,
1613
- scope: import_wiki_graph_core5.WikiGraphScope.ReaderExtraction,
1847
+ scope: import_wiki_graph_core8.WikiGraphScope.ReaderExtraction,
1614
1848
  signal
1615
1849
  });
1616
1850
  if (request !== void 0 && llm !== void 0) {
1617
1851
  request.lazy = async (operation) => await llm.request(async () => await operation(request));
1618
1852
  }
1619
- const wikimediaResolver = job.target !== "knowledge-graph" ? void 0 : await (0, import_wiki_graph_core5.openWikimediaResolver)(
1853
+ const wikimediaResolver = job.target !== "knowledge-graph" ? void 0 : await (0, import_wiki_graph_core8.openWikimediaResolver)(
1620
1854
  config.wikimedia === void 0 ? {
1621
1855
  kind: "local",
1622
1856
  llmRequest: requireValue(
1623
1857
  request,
1624
1858
  "Local Wikimedia resolution requires an LLM."
1859
+ ),
1860
+ llmModelId: requireValue(
1861
+ stageConfig?.llm?.model,
1862
+ "Local Wikimedia resolution requires an LLM model."
1625
1863
  )
1626
1864
  } : {
1627
1865
  endpoint: config.wikimedia.endpoint,
@@ -1659,12 +1897,12 @@ async function resetStepWorkspace(workspace, kind) {
1659
1897
  return await workspace.createDirectory(name);
1660
1898
  }
1661
1899
  async function readChapterStage(job) {
1662
- return await new import_wiki_graph_core5.WikiGraphArchiveFile(job.archive).readDocument(
1663
- async (document) => (await (0, import_wiki_graph_core5.getChapterDetails)(document, job.chapterId)).stage
1900
+ return await new import_wiki_graph_core8.WikiGraphArchiveFile(job.archive).readDocument(
1901
+ async (document) => (await (0, import_wiki_graph_core8.getChapterDetails)(document, job.chapterId)).stage
1664
1902
  );
1665
1903
  }
1666
1904
  async function assertCurrentFtsArtifact(job) {
1667
- await new import_wiki_graph_core5.WikiGraphArchiveFile(job.archive).readDocument(async (document) => {
1905
+ await new import_wiki_graph_core8.WikiGraphArchiveFile(job.archive).readDocument(async (document) => {
1668
1906
  const revision = await document.serials.getRevision(job.chapterId);
1669
1907
  const artifact = await document.indexArtifacts.get(job.chapterId, "fts");
1670
1908
  if (artifact?.sourceRevision !== revision) {