@equationalapplications/core-llm-wiki 7.7.2 → 7.7.4

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/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { __privateAdd, MetadataRepository, EmbeddingService, SearchService, JobManager, PromptService, resolveGrounding, IngestionService, MaintenanceService, ImportExportService, RetrievalService, WriteService, __privateGet, __privateSet, normalizeSourceRef, normalizeSourceHash, entitySummaryMetaKey, WikiSourceRefHashCollision, DiagnosticBuffer, validateManifest, WikiDraftNotFound, generateId, BaseRepository, WikiGraphNodeOwnershipConflict, emptyManifest, resolveNodeType, WikiStrictOntologyViolation, validateInlineEdges, resolveEdgeDefinitions, typeSatisfies, normalizeTitleKey, edgeTripleAllowed, WikiTransactionError, extractSqliteCode } from './chunk-NWODQRSM.mjs';
2
- export { DEFAULT_CHUNK_OVERLAP, DEFAULT_MAX_CHUNK_LENGTH, DEFAULT_MAX_EMBED_CHARS, EMBED_CHARS_CEILING, HEAL_ANCHORS_PER_CANDIDATE, HEAL_BATCH_SIZE, HEAL_MAX_FACT_BODY_CHARS_L3, HEAL_MAX_TASKS, HEAL_RECHECK_MS, HOOK_TIMEOUT_MARKER, ONTOLOGY_BACKFILL_BATCH_SIZE, ONTOLOGY_BACKFILL_MAX_PROMPT_CHARS, ONTOLOGY_BACKFILL_RECHECK_MS, ONTOLOGY_BACKFILL_SYSTEM_PROMPT, PromptService, PrunePartialFailureError, WikiBusyError, WikiDraftNotFound, WikiDuplicateHashError, WikiGraphNodeOwnershipConflict, WikiIngestEmptyError, WikiInvalidReadOptions, WikiParseError, WikiSourceRefHashCollision, WikiStrictOntologyViolation, WikiTransactionError, chunkText, configureRandomSource, parseEmbedding, safeSlice, validateManifest } from './chunk-NWODQRSM.mjs';
1
+ import { __privateAdd, MetadataRepository, EmbeddingService, SearchService, JobManager, PromptService, resolveGrounding, IngestionService, MaintenanceService, ImportExportService, RetrievalService, WriteService, __privateGet, __privateSet, normalizeSourceRef, normalizeSourceHash, entitySummaryMetaKey, WikiSourceRefHashCollision, DiagnosticBuffer, validateManifest, WikiDraftNotFound, generateId, BaseRepository, WikiGraphNodeOwnershipConflict, emptyManifest, resolveNodeType, WikiStrictOntologyViolation, validateInlineEdges, resolveEdgeDefinitions, typeSatisfies, normalizeTitleKey, edgeTripleAllowed, WikiTransactionError, extractSqliteCode } from './chunk-JV2OQ5CM.mjs';
2
+ export { DEFAULT_CHUNK_OVERLAP, DEFAULT_MAX_CHUNK_LENGTH, DEFAULT_MAX_EMBED_CHARS, EMBED_CHARS_CEILING, HEAL_ANCHORS_PER_CANDIDATE, HEAL_BATCH_SIZE, HEAL_MAX_FACT_BODY_CHARS_L3, HEAL_MAX_TASKS, HEAL_RECHECK_MS, HOOK_TIMEOUT_MARKER, ONTOLOGY_BACKFILL_BATCH_SIZE, ONTOLOGY_BACKFILL_MAX_PROMPT_CHARS, ONTOLOGY_BACKFILL_RECHECK_MS, ONTOLOGY_BACKFILL_SYSTEM_PROMPT, PromptService, PrunePartialFailureError, WikiBusyError, WikiDraftNotFound, WikiDuplicateHashError, WikiGraphNodeOwnershipConflict, WikiIngestEmptyError, WikiInvalidReadOptions, WikiParseError, WikiSourceRefHashCollision, WikiStrictOntologyViolation, WikiTransactionError, chunkText, configureRandomSource, parseEmbedding, safeSlice, validateManifest } from './chunk-JV2OQ5CM.mjs';
3
3
  import { appendRelatedSection, buildConceptDocument, buildLogMd, buildEntityIndexMd, buildRootIndexMd, isAllowedOkfPath, parseRootIndexMd, parseEntityIndexMd, parseConcept, splitRelatedSection, extractMarkdownLinks, parseLogMd, parseEventIdComment, latestVerified, formatSourcesJson, appendEventIdComment, parseVerifiedFlexible, parseCitationsList, deriveTrustTier, isStaleAfter } from '@equationalapplications/core-okf';
4
4
 
5
5
  // src/db/schema.ts
@@ -1889,6 +1889,17 @@ declare class DiagnosticBuffer {
1889
1889
  push(input: WikiDiagnosticInput): void;
1890
1890
  get size(): number;
1891
1891
  flush(options: DiagnosticTarget): void;
1892
+ /**
1893
+ * Emit only the buffered diagnostics whose code is in `codes` and discard
1894
+ * the rest. The buffer is empty afterwards either way.
1895
+ *
1896
+ * For an operation that did real work before its write was rolled back:
1897
+ * some buffered diagnostics describe that work and are still true, while
1898
+ * others describe rows that no longer exist (anything carrying a `factId`
1899
+ * minted inside the aborted transaction). `flush` would emit both and
1900
+ * `discard` would drop both; this emits the first set only.
1901
+ */
1902
+ flushOnly(options: DiagnosticTarget, codes: readonly WikiDiagnosticCode[]): void;
1892
1903
  discard(): void;
1893
1904
  }
1894
1905
 
@@ -1889,6 +1889,17 @@ declare class DiagnosticBuffer {
1889
1889
  push(input: WikiDiagnosticInput): void;
1890
1890
  get size(): number;
1891
1891
  flush(options: DiagnosticTarget): void;
1892
+ /**
1893
+ * Emit only the buffered diagnostics whose code is in `codes` and discard
1894
+ * the rest. The buffer is empty afterwards either way.
1895
+ *
1896
+ * For an operation that did real work before its write was rolled back:
1897
+ * some buffered diagnostics describe that work and are still true, while
1898
+ * others describe rows that no longer exist (anything carrying a `factId`
1899
+ * minted inside the aborted transaction). `flush` would emit both and
1900
+ * `discard` would drop both; this emits the first set only.
1901
+ */
1902
+ flushOnly(options: DiagnosticTarget, codes: readonly WikiDiagnosticCode[]): void;
1892
1903
  discard(): void;
1893
1904
  }
1894
1905
 
@@ -1,3 +1,3 @@
1
- export { aq as EmbeddingService, ar as ImportExportService, as as IngestionService, at as JobManager, at as JobManagerType, au as MaintenanceService, av as RetrievalService, aw as SearchService, aw as SearchServiceType, ai as WikiMemoryTestAccess, ax as WriteService } from './testing-A4Sofxyo.mjs';
1
+ export { aq as EmbeddingService, ar as ImportExportService, as as IngestionService, at as JobManager, at as JobManagerType, au as MaintenanceService, av as RetrievalService, aw as SearchService, aw as SearchServiceType, ai as WikiMemoryTestAccess, ax as WriteService } from './testing-CH_Kk34-.mjs';
2
2
  import '@equationalapplications/core-okf';
3
3
  import 'minisearch';
package/dist/testing.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- export { aq as EmbeddingService, ar as ImportExportService, as as IngestionService, at as JobManager, at as JobManagerType, au as MaintenanceService, av as RetrievalService, aw as SearchService, aw as SearchServiceType, ai as WikiMemoryTestAccess, ax as WriteService } from './testing-A4Sofxyo.js';
1
+ export { aq as EmbeddingService, ar as ImportExportService, as as IngestionService, at as JobManager, at as JobManagerType, au as MaintenanceService, av as RetrievalService, aw as SearchService, aw as SearchServiceType, ai as WikiMemoryTestAccess, ax as WriteService } from './testing-CH_Kk34-.js';
2
2
  import '@equationalapplications/core-okf';
3
3
  import 'minisearch';
package/dist/testing.js CHANGED
@@ -755,6 +755,23 @@ var DiagnosticBuffer = class {
755
755
  this.items = [];
756
756
  for (const input of pending) emitDiagnostic(options, input);
757
757
  }
758
+ /**
759
+ * Emit only the buffered diagnostics whose code is in `codes` and discard
760
+ * the rest. The buffer is empty afterwards either way.
761
+ *
762
+ * For an operation that did real work before its write was rolled back:
763
+ * some buffered diagnostics describe that work and are still true, while
764
+ * others describe rows that no longer exist (anything carrying a `factId`
765
+ * minted inside the aborted transaction). `flush` would emit both and
766
+ * `discard` would drop both; this emits the first set only.
767
+ */
768
+ flushOnly(options, codes) {
769
+ const pending = this.items;
770
+ this.items = [];
771
+ for (const input of pending) {
772
+ if (codes.includes(input.code)) emitDiagnostic(options, input);
773
+ }
774
+ }
758
775
  discard() {
759
776
  this.items = [];
760
777
  }
@@ -1839,6 +1856,16 @@ var DEFAULT_MAX_CHUNK_LENGTH = 12e3;
1839
1856
  var DEFAULT_CHUNK_OVERLAP = 400;
1840
1857
 
1841
1858
  // src/services/IngestionService.ts
1859
+ var LLM_PASS_DIAGNOSTIC_CODES = ["ingest_chunk_failed", "fact_rejected", "fact_deduplicated"];
1860
+ function dedupDiagnostic(entityId, sourceRef, locator) {
1861
+ return {
1862
+ entityId,
1863
+ operation: "ingest",
1864
+ trigger: "call",
1865
+ code: "fact_deduplicated",
1866
+ detail: locator ? { sourceRef, chunkIndex: locator.chunkIndex, itemIndex: locator.itemIndex, reason: "exact_title" } : { sourceRef, reason: "exact_title" }
1867
+ };
1868
+ }
1842
1869
  function zeroChunkResult(duplicateOf) {
1843
1870
  const result = {
1844
1871
  truncated: false,
@@ -1975,11 +2002,7 @@ var IngestionService = class {
1975
2002
  const diagBuffer = new DiagnosticBuffer();
1976
2003
  const diagBase = { entityId, operation: "ingest", trigger: "call" };
1977
2004
  const pushDeduplicated = (chunkIndex, itemIndex) => {
1978
- diagBuffer.push({
1979
- ...diagBase,
1980
- code: "fact_deduplicated",
1981
- detail: { sourceRef, chunkIndex, itemIndex, reason: "exact_title" }
1982
- });
2005
+ diagBuffer.push(dedupDiagnostic(entityId, sourceRef, { chunkIndex, itemIndex }));
1983
2006
  };
1984
2007
  for (const [chunkIndex, slot] of chunkResults.entries()) {
1985
2008
  if (slot.status === "failed") {
@@ -2006,7 +2029,7 @@ var IngestionService = class {
2006
2029
  });
2007
2030
  }
2008
2031
  const orderedChunkFacts = [];
2009
- const groundingLedger = /* @__PURE__ */ new Map();
2032
+ const factLedger = /* @__PURE__ */ new Map();
2010
2033
  for (const [chunkIndex, slot] of chunkResults.entries()) {
2011
2034
  if (slot.status === "failed") continue;
2012
2035
  const keptFacts = [];
@@ -2014,7 +2037,11 @@ var IngestionService = class {
2014
2037
  const winner = winners.get(normalizeTitleKey(fact.title));
2015
2038
  if (winner?.chunkIndex !== chunkIndex || winner.k !== k) return;
2016
2039
  keptFacts.push(fact);
2017
- if (ingestGrounding) groundingLedger.set(fact, { verdict: slot.verdicts[k], chunkIndex, itemIndex: winner.itemIndex });
2040
+ factLedger.set(fact, {
2041
+ verdict: ingestGrounding ? slot.verdicts[k] : null,
2042
+ chunkIndex,
2043
+ itemIndex: winner.itemIndex
2044
+ });
2018
2045
  });
2019
2046
  orderedChunkFacts.push({ facts: keptFacts, ontology_updates: slot.ontology_updates });
2020
2047
  }
@@ -2044,7 +2071,7 @@ var IngestionService = class {
2044
2071
  try {
2045
2072
  if (failedChunks === 0) {
2046
2073
  const fullResult = await this.db.withTransactionAsync(async (tx) => {
2047
- return await this.runFullUpsertGraph(entityId, sourceRef, sourceHash, orderedChunkFacts, tx, diagBuffer, groundingLedger);
2074
+ return await this.runFullUpsertGraph(entityId, sourceRef, sourceHash, orderedChunkFacts, tx, diagBuffer, factLedger);
2048
2075
  });
2049
2076
  deletedSourceFactIds.push(...fullResult.deletedSourceFactIds);
2050
2077
  insertedFacts.push(...fullResult.insertedFacts);
@@ -2052,13 +2079,14 @@ var IngestionService = class {
2052
2079
  const partialResult = await this.db.withTransactionAsync(async (tx) => {
2053
2080
  const flat = [];
2054
2081
  for (const slot of orderedChunkFacts) flat.push(...slot.facts);
2055
- return await this.appendPartialFacts(entityId, sourceRef, flat, tx, diagBuffer, groundingLedger);
2082
+ return await this.appendPartialFacts(entityId, sourceRef, flat, tx, diagBuffer, factLedger);
2056
2083
  });
2057
2084
  insertedFacts.push(...partialResult.insertedDescriptors);
2058
2085
  }
2059
2086
  } catch (err) {
2060
2087
  const sqliteCode = err instanceof WikiTransactionError ? err.sqliteErrorCode : extractSqliteCode(err);
2061
2088
  if (sqliteCode !== "SQLITE_CONSTRAINT_UNIQUE") throw err;
2089
+ diagBuffer.flushOnly(this.options, LLM_PASS_DIAGNOSTIC_CODES);
2062
2090
  const canonical = await this.sourceRefIndexRepo.findActiveByEntityAndHash(entityId, sourceHash);
2063
2091
  if (canonical === null) throw err;
2064
2092
  if (onDuplicateHash === "throw" || onDuplicateHash === "ingest") {
@@ -2286,7 +2314,7 @@ var IngestionService = class {
2286
2314
  * On the partial path the caller never invokes this method; the empty
2287
2315
  * arrays stay empty.
2288
2316
  */
2289
- async runFullUpsertGraph(entityId, sourceRef, sourceHash, orderedChunkFacts, tx, diagBuffer, groundingLedger = /* @__PURE__ */ new Map()) {
2317
+ async runFullUpsertGraph(entityId, sourceRef, sourceHash, orderedChunkFacts, tx, diagBuffer, factLedger = /* @__PURE__ */ new Map()) {
2290
2318
  const deletedSourceFactIds = [];
2291
2319
  const insertedFacts = [];
2292
2320
  const nodeTrust = /* @__PURE__ */ new Map();
@@ -2333,9 +2361,9 @@ var IngestionService = class {
2333
2361
  tags: fact.tags,
2334
2362
  confidence: fact.confidence
2335
2363
  });
2336
- const grounding = groundingLedger.get(fact);
2337
- if (grounding) {
2338
- const outcome = groundingOutcome(grounding.verdict, now);
2364
+ const locator = factLedger.get(fact);
2365
+ if (locator?.verdict) {
2366
+ const outcome = groundingOutcome(locator.verdict, now);
2339
2367
  nodeTrust.set(id, outcome.trust);
2340
2368
  if (outcome.diagnostic) {
2341
2369
  diagBuffer.push({
@@ -2343,7 +2371,7 @@ var IngestionService = class {
2343
2371
  operation: "ingest",
2344
2372
  trigger: "call",
2345
2373
  code: outcome.diagnostic.code,
2346
- detail: { factId: id, sourceRef, chunkIndex: grounding.chunkIndex, itemIndex: grounding.itemIndex, reason: outcome.diagnostic.reason }
2374
+ detail: { factId: id, sourceRef, chunkIndex: locator.chunkIndex, itemIndex: locator.itemIndex, reason: outcome.diagnostic.reason }
2347
2375
  });
2348
2376
  }
2349
2377
  }
@@ -2402,7 +2430,7 @@ var IngestionService = class {
2402
2430
  * Runs INSIDE the caller's `tx`. Does not open a nested transaction.
2403
2431
  * Returns `{ inserted, skippedDuplicate }` for observability.
2404
2432
  */
2405
- async appendPartialFacts(entityId, sourceRef, dedupedFacts, tx, diagBuffer, groundingLedger = /* @__PURE__ */ new Map()) {
2433
+ async appendPartialFacts(entityId, sourceRef, dedupedFacts, tx, diagBuffer, factLedger = /* @__PURE__ */ new Map()) {
2406
2434
  const liveIds = await this.entryRepo.findIdsBySource(entityId, sourceRef, null, tx, false);
2407
2435
  const liveFacts = liveIds.length === 0 ? [] : await this.entryRepo.findByIds(liveIds, void 0, tx);
2408
2436
  const liveTitles = new Set(liveFacts.map((f) => normalizeTitleKey(f.title)));
@@ -2412,28 +2440,22 @@ var IngestionService = class {
2412
2440
  const insertedDescriptors = [];
2413
2441
  for (const fact of dedupedFacts) {
2414
2442
  const normalizedTitle = normalizeTitleKey(fact.title);
2443
+ const locator = factLedger.get(fact);
2415
2444
  if (liveTitles.has(normalizedTitle)) {
2416
- diagBuffer.push({
2417
- entityId,
2418
- operation: "ingest",
2419
- trigger: "call",
2420
- code: "fact_deduplicated",
2421
- detail: { sourceRef, reason: "exact_title" }
2422
- });
2445
+ diagBuffer.push(dedupDiagnostic(entityId, sourceRef, locator));
2423
2446
  skippedDuplicate++;
2424
2447
  continue;
2425
2448
  }
2426
2449
  liveTitles.add(normalizedTitle);
2427
2450
  const id = generateId("fact_");
2428
- const grounding = groundingLedger.get(fact);
2429
- const outcome = grounding ? groundingOutcome(grounding.verdict, now) : null;
2430
- if (grounding && outcome?.diagnostic) {
2451
+ const outcome = locator?.verdict ? groundingOutcome(locator.verdict, now) : null;
2452
+ if (locator?.verdict && outcome?.diagnostic) {
2431
2453
  diagBuffer.push({
2432
2454
  entityId,
2433
2455
  operation: "ingest",
2434
2456
  trigger: "call",
2435
2457
  code: outcome.diagnostic.code,
2436
- detail: { factId: id, sourceRef, chunkIndex: grounding.chunkIndex, itemIndex: grounding.itemIndex, reason: outcome.diagnostic.reason }
2458
+ detail: { factId: id, sourceRef, chunkIndex: locator.chunkIndex, itemIndex: locator.itemIndex, reason: outcome.diagnostic.reason }
2437
2459
  });
2438
2460
  }
2439
2461
  const wikiFact = {