@equationalapplications/core-llm-wiki 4.18.1 → 4.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { __privateAdd, EmbeddingService, SearchService, JobManager, PromptService, IngestionService, MaintenanceService, ImportExportService, RetrievalService, WriteService, __privateGet, __privateSet, normalizeSourceRef, normalizeSourceHash, generateId, validateManifest, emptyManifest, mergeOntologyUpdates, resolveNodeType, validateInlineEdges, resolveEdgeDefinition, normalizeTitleKey } from './chunk-V7QNRQFK.mjs';
2
- export { HOOK_TIMEOUT_MARKER, PromptService, PrunePartialFailureError, WikiBusyError, configureRandomSource, parseEmbedding } from './chunk-V7QNRQFK.mjs';
1
+ import { __privateAdd, MetadataRepository, EmbeddingService, SearchService, JobManager, PromptService, IngestionService, MaintenanceService, ImportExportService, RetrievalService, WriteService, __privateGet, __privateSet, normalizeSourceRef, normalizeSourceHash, entitySummaryMetaKey, generateId, BaseRepository, emptyManifest, resolveNodeType, validateInlineEdges, resolveEdgeDefinition, normalizeTitleKey, WikiTransactionError, extractSqliteCode } from './chunk-HKB5FEJG.mjs';
2
+ export { HOOK_TIMEOUT_MARKER, PromptService, PrunePartialFailureError, WikiBusyError, WikiTransactionError, configureRandomSource, parseEmbedding } from './chunk-HKB5FEJG.mjs';
3
3
  import { appendRelatedSection, buildConceptDocument, buildLogMd, buildEntityIndexMd, buildRootIndexMd, isAllowedOkfPath, parseRootIndexMd, parseEntityIndexMd, parseConcept, splitRelatedSection, extractMarkdownLinks, parseLogMd, parseEventIdComment, appendEventIdComment } from '@equationalapplications/core-okf';
4
4
 
5
5
  // src/db/schema.ts
@@ -104,6 +104,50 @@ async function setupDatabase(db, prefix) {
104
104
  `);
105
105
  }
106
106
 
107
+ // src/db/serializedAdapter.ts
108
+ function isDriverError(err) {
109
+ return extractSqliteCode(err) !== void 0;
110
+ }
111
+ function withOverrides(target, overrides) {
112
+ return new Proxy(target, {
113
+ get(obj, prop, receiver) {
114
+ if (prop in overrides) return Reflect.get(overrides, prop, receiver);
115
+ const value = Reflect.get(obj, prop, obj);
116
+ return typeof value === "function" ? value.bind(obj) : value;
117
+ }
118
+ });
119
+ }
120
+ function guardReentrancy(tx) {
121
+ return withOverrides(tx, {
122
+ withTransactionAsync() {
123
+ throw new Error(
124
+ "Nested withTransactionAsync is not supported: you are already inside a transaction. Pass the current `tx` down instead of opening a new transaction."
125
+ );
126
+ }
127
+ });
128
+ }
129
+ var DEADLOCK_WARN_MS = 1e4;
130
+ function withSerializedTransactions(db) {
131
+ let queue = Promise.resolve();
132
+ return withOverrides(db, {
133
+ withTransactionAsync(fn) {
134
+ const warn = setTimeout(() => {
135
+ console.warn(
136
+ "[core-llm-wiki] Transaction queued >10s \u2014 possible deadlock. Inside a transaction callback, use the `tx` parameter, never the outer database handle."
137
+ );
138
+ }, DEADLOCK_WARN_MS);
139
+ const run = queue.catch(() => void 0).then(() => {
140
+ clearTimeout(warn);
141
+ return db.withTransactionAsync((tx) => fn(guardReentrancy(tx ?? db)));
142
+ }).catch((e) => {
143
+ throw isDriverError(e) ? new WikiTransactionError("Transaction failed", { cause: e }) : e;
144
+ });
145
+ queue = run;
146
+ return run;
147
+ }
148
+ });
149
+ }
150
+
107
151
  // src/db/migrations.ts
108
152
  var MIGRATIONS = [
109
153
  {
@@ -215,21 +259,6 @@ for (let i = 1; i < MIGRATIONS.length; i++) {
215
259
  }
216
260
  var CURRENT_SCHEMA_VERSION = MIGRATIONS.length > 0 ? MIGRATIONS[MIGRATIONS.length - 1].version : 0;
217
261
 
218
- // src/repositories/BaseRepository.ts
219
- var BaseRepository = class {
220
- constructor(db, prefix) {
221
- this.db = db;
222
- this.prefix = prefix;
223
- }
224
- /**
225
- * Return the DB executor for a given transaction handle.
226
- * If tx is provided, use it; otherwise fall back to this.db.
227
- */
228
- getExecutor(tx) {
229
- return tx ?? this.db;
230
- }
231
- };
232
-
233
262
  // src/repositories/EntryRepository.ts
234
263
  function mapRowToFact(row) {
235
264
  const tags = (() => {
@@ -1520,144 +1549,6 @@ function mapRowToEdge(row) {
1520
1549
  };
1521
1550
  }
1522
1551
 
1523
- // src/repositories/MetadataRepository.ts
1524
- var MetadataRepository = class extends BaseRepository {
1525
- // CHECKPOINTS TABLE METHODS
1526
- async getCheckpoint(entityId, tx) {
1527
- const executor = this.getExecutor(tx);
1528
- const row = await executor.getFirstAsync(
1529
- `SELECT memory_checkpoint, heal_checkpoint FROM ${this.prefix}checkpoints WHERE entity_id = ?`,
1530
- [entityId]
1531
- );
1532
- if (!row) return {};
1533
- return {
1534
- memory: row.memory_checkpoint ?? void 0,
1535
- heal: row.heal_checkpoint ?? void 0
1536
- };
1537
- }
1538
- async updateCheckpoint(entityId, updates, tx) {
1539
- const fields = [];
1540
- const values = [];
1541
- if (updates.memory !== void 0) {
1542
- fields.push("memory_checkpoint = ?");
1543
- values.push(updates.memory);
1544
- }
1545
- if (updates.heal !== void 0) {
1546
- fields.push("heal_checkpoint = ?");
1547
- values.push(updates.heal);
1548
- }
1549
- if (fields.length === 0) return;
1550
- const executor = this.getExecutor(tx);
1551
- await executor.runAsync(
1552
- `INSERT INTO ${this.prefix}checkpoints (entity_id, memory_checkpoint, heal_checkpoint)
1553
- VALUES (?, ?, ?)
1554
- ON CONFLICT(entity_id) DO UPDATE SET ${fields.join(", ")}`,
1555
- [entityId, updates.memory ?? 0, updates.heal ?? 0, ...values]
1556
- );
1557
- }
1558
- async deleteCheckpoint(entityId, tx) {
1559
- const executor = this.getExecutor(tx);
1560
- await executor.runAsync(
1561
- `DELETE FROM ${this.prefix}checkpoints WHERE entity_id = ?`,
1562
- [entityId]
1563
- );
1564
- }
1565
- // META TABLE METHODS
1566
- async getMeta(key, tx) {
1567
- const executor = this.getExecutor(tx);
1568
- const row = await executor.getFirstAsync(
1569
- `SELECT value FROM ${this.prefix}meta WHERE key = ?`,
1570
- [key]
1571
- );
1572
- return row ? row.value : null;
1573
- }
1574
- async setMeta(key, value, tx) {
1575
- const executor = this.getExecutor(tx);
1576
- await executor.runAsync(
1577
- `INSERT INTO ${this.prefix}meta (key, value) VALUES (?, ?)
1578
- ON CONFLICT(key) DO UPDATE SET value = excluded.value`,
1579
- [key, value]
1580
- );
1581
- }
1582
- async clearDimensionMismatch(tx) {
1583
- const executor = this.getExecutor(tx);
1584
- await executor.runAsync(
1585
- `DELETE FROM ${this.prefix}meta WHERE key = 'embedding_dimension_mismatch'`
1586
- );
1587
- }
1588
- async tableExists(tableName, tx) {
1589
- const executor = this.getExecutor(tx);
1590
- const row = await executor.getFirstAsync(
1591
- `SELECT name FROM sqlite_master WHERE type='table' AND name=?`,
1592
- [tableName]
1593
- );
1594
- return row != null;
1595
- }
1596
- async getTableDdl(tableName, tx) {
1597
- const executor = this.getExecutor(tx);
1598
- const row = await executor.getFirstAsync(
1599
- `SELECT sql FROM sqlite_master WHERE type='table' AND name=?`,
1600
- [tableName]
1601
- );
1602
- return row?.sql ?? null;
1603
- }
1604
- async vacuum() {
1605
- await this.db.execAsync(`PRAGMA wal_checkpoint(TRUNCATE)`);
1606
- await this.db.execAsync(`VACUUM`);
1607
- }
1608
- async getDistinctEntityIds(tx) {
1609
- const executor = this.getExecutor(tx);
1610
- const rows = await executor.getAllAsync(
1611
- `SELECT DISTINCT entity_id FROM (
1612
- SELECT entity_id FROM ${this.prefix}entries WHERE deleted_at IS NULL
1613
- UNION
1614
- SELECT entity_id FROM ${this.prefix}tasks WHERE deleted_at IS NULL
1615
- UNION
1616
- SELECT entity_id FROM ${this.prefix}events
1617
- ) ORDER BY entity_id`
1618
- );
1619
- return rows.map((r) => r.entity_id);
1620
- }
1621
- async getManifest(entityId, tx) {
1622
- const executor = this.getExecutor(tx);
1623
- const row = await executor.getFirstAsync(`SELECT mode, manifest_json FROM ${this.prefix}entity_manifests WHERE entity_id = ?`, [entityId]);
1624
- if (!row) return null;
1625
- if (row.mode !== "off" && row.mode !== "strict" && row.mode !== "emergent") {
1626
- throw new Error(`Invalid ontology mode for entity ${entityId}: ${JSON.stringify(row.mode)}`);
1627
- }
1628
- let manifest;
1629
- try {
1630
- manifest = JSON.parse(row.manifest_json);
1631
- } catch (error) {
1632
- throw new Error(`Invalid manifest_json for entity ${entityId}: ${error.message}`);
1633
- }
1634
- validateManifest(manifest);
1635
- return {
1636
- mode: row.mode,
1637
- manifest
1638
- };
1639
- }
1640
- async setManifest(entityId, data, tx) {
1641
- validateManifest(data.manifest);
1642
- const executor = this.getExecutor(tx);
1643
- await executor.runAsync(
1644
- `INSERT INTO ${this.prefix}entity_manifests (entity_id, mode, manifest_json, updated_at)
1645
- VALUES (?, ?, ?, ?)
1646
- ON CONFLICT(entity_id) DO UPDATE SET mode = excluded.mode, manifest_json = excluded.manifest_json, updated_at = excluded.updated_at`,
1647
- [entityId, data.mode, JSON.stringify(data.manifest), Date.now()]
1648
- );
1649
- }
1650
- async mergeManifestUpdates(entityId, updates, tx) {
1651
- const current = await this.getManifest(entityId, tx) ?? {
1652
- mode: "emergent",
1653
- manifest: emptyManifest()
1654
- };
1655
- const merged = mergeOntologyUpdates(current.manifest, updates);
1656
- await this.setManifest(entityId, { mode: current.mode, manifest: merged }, tx);
1657
- return merged;
1658
- }
1659
- };
1660
-
1661
1552
  // src/prompts/ontology.ts
1662
1553
  var FACT_ONTOLOGY_FIELDS = `
1663
1554
  Each fact may optionally include:
@@ -1804,7 +1695,7 @@ var WikiMemory = class {
1804
1695
  constructor(db, options) {
1805
1696
  /** Emits `__testAccess` console warning at most once per instance when NODE_ENV ≠ "test". */
1806
1697
  __privateAdd(this, _testAccessNonTestEnvWarned, false);
1807
- this.db = db;
1698
+ this.db = withSerializedTransactions(db);
1808
1699
  this.options = options;
1809
1700
  this.prefix = options.config?.tablePrefix ?? "llm_wiki_";
1810
1701
  if (!TABLE_PREFIX_PATTERN.test(this.prefix)) {
@@ -1812,12 +1703,12 @@ var WikiMemory = class {
1812
1703
  `Invalid tablePrefix: ${JSON.stringify(this.prefix)}. Must match ${TABLE_PREFIX_PATTERN} (letter, then alphanumeric/underscore, ending in "_", max 32 chars total).`
1813
1704
  );
1814
1705
  }
1815
- this.outboxRepo = new OutboxRepository(db, this.prefix, !!options.config?.enableOutbox);
1816
- this.entryRepo = new EntryRepository(db, this.prefix, this.outboxRepo);
1817
- this.taskRepo = new TaskRepository(db, this.prefix, this.outboxRepo);
1818
- this.eventRepo = new EventRepository(db, this.prefix);
1819
- this.edgeRepo = new EdgeRepository(db, this.prefix);
1820
- this.metadataRepo = new MetadataRepository(db, this.prefix);
1706
+ this.outboxRepo = new OutboxRepository(this.db, this.prefix, !!options.config?.enableOutbox);
1707
+ this.entryRepo = new EntryRepository(this.db, this.prefix, this.outboxRepo);
1708
+ this.taskRepo = new TaskRepository(this.db, this.prefix, this.outboxRepo);
1709
+ this.eventRepo = new EventRepository(this.db, this.prefix);
1710
+ this.edgeRepo = new EdgeRepository(this.db, this.prefix);
1711
+ this.metadataRepo = new MetadataRepository(this.db, this.prefix);
1821
1712
  this.ontologyService = new OntologyService(
1822
1713
  this.metadataRepo,
1823
1714
  this.edgeRepo,
@@ -2016,6 +1907,10 @@ var WikiMemory = class {
2016
1907
  async exportDump(entityIds) {
2017
1908
  return this.importExportService.exportDump(entityIds);
2018
1909
  }
1910
+ /** Entity summary prose persisted from an OKF profile ≥ 1 import; null when none stored. */
1911
+ async getEntitySummary(entityId) {
1912
+ return this.metadataRepo.getMeta(entitySummaryMetaKey(entityId));
1913
+ }
2019
1914
  async importDump(dump, opts) {
2020
1915
  return this.importExportService.importDump(dump, opts);
2021
1916
  }