@equationalapplications/core-llm-wiki 5.1.1 → 5.2.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/{chunk-YKXCMOHH.mjs → chunk-J3N3WRK7.mjs} +84 -7
- package/dist/chunk-J3N3WRK7.mjs.map +1 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +304 -22
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +224 -20
- package/dist/index.mjs.map +1 -1
- package/dist/{testing-DCRNie7k.d.mts → testing-DyXISRwS.d.mts} +137 -1
- package/dist/{testing-DCRNie7k.d.ts → testing-DyXISRwS.d.ts} +137 -1
- package/dist/testing.d.mts +1 -1
- package/dist/testing.d.ts +1 -1
- package/dist/testing.js +81 -4
- package/dist/testing.js.map +1 -1
- package/dist/testing.mjs +1 -1
- package/package.json +2 -2
- package/dist/chunk-YKXCMOHH.mjs.map +0 -1
|
@@ -544,6 +544,22 @@ declare class WikiBusyError extends Error {
|
|
|
544
544
|
readonly entityId: string;
|
|
545
545
|
constructor(operation: WikiBusyOperation, entityId: string);
|
|
546
546
|
}
|
|
547
|
+
/**
|
|
548
|
+
* Thrown by `ingestDocument({ onDuplicateHash: 'throw' })` when a different
|
|
549
|
+
* source_ref in the same entity already holds the supplied source_hash against
|
|
550
|
+
* a live row. Mirrors {@link WikiBusyError}'s anchoring of canonical metadata
|
|
551
|
+
* on the error instance for stable observability.
|
|
552
|
+
*/
|
|
553
|
+
declare class WikiDuplicateHashError extends Error {
|
|
554
|
+
readonly canonical: string;
|
|
555
|
+
readonly sourceHash: string;
|
|
556
|
+
readonly entityId: string;
|
|
557
|
+
constructor(params: {
|
|
558
|
+
canonical: string;
|
|
559
|
+
sourceHash: string;
|
|
560
|
+
entityId: string;
|
|
561
|
+
});
|
|
562
|
+
}
|
|
547
563
|
/**
|
|
548
564
|
* Thrown by the serialized transaction wrapper when a SQLite driver error
|
|
549
565
|
* escapes a transaction callback (nested BEGIN, SQLITE_BUSY, constraint
|
|
@@ -796,6 +812,59 @@ declare class EntryRepository extends BaseRepository {
|
|
|
796
812
|
}>>;
|
|
797
813
|
updateSourceRefByRowid(rowid: number, sourceRef: string | null, tx: SQLiteAdapter): Promise<void>;
|
|
798
814
|
findLatestSourceHash(entityId: string, sourceRef: string, tx?: SQLiteAdapter): Promise<string | null>;
|
|
815
|
+
/**
|
|
816
|
+
* Batch version of {@link findLatestSourceHash}. Returns a Map covering every
|
|
817
|
+
* requested ref, where the value is the source_hash from the row with the
|
|
818
|
+
* most-recently-updated live fact for that ref, or null when no live row exists.
|
|
819
|
+
*
|
|
820
|
+
* The SQL uses ROW_NUMBER() OVER (PARTITION BY source_ref ORDER BY updated_at
|
|
821
|
+
* DESC, id ASC) — NOT MAX(source_hash). Aggregation with MAX(source_hash) is
|
|
822
|
+
* wrong because MAX computes independently across grouped rows; the hash must
|
|
823
|
+
* come from the exact row that wins MAX(updated_at). The `id ASC` tie-break
|
|
824
|
+
* keeps selection deterministic when two live rows share `updated_at`.
|
|
825
|
+
*
|
|
826
|
+
* Source refs are de-duplicated and processed in chunks so the per-query bind
|
|
827
|
+
* parameter count stays under SQLite's `SQLITE_MAX_VARIABLE_NUMBER` (default
|
|
828
|
+
* 999, leaving one slot for `entity_id`).
|
|
829
|
+
*
|
|
830
|
+
* Empty input is a synchronous early return with zero SQL calls.
|
|
831
|
+
*/
|
|
832
|
+
findLatestSourceHashes(entityId: string, sourceRefs: readonly string[], tx?: SQLiteAdapter): Promise<Map<string, string | null>>;
|
|
833
|
+
/**
|
|
834
|
+
* Return the live source_refs for an entity that hold the given source_hash.
|
|
835
|
+
* Used by the ingestDocument duplicate-hash guard and by hosts auditing
|
|
836
|
+
* duplicate-content collisions. Sorted `COLLATE BINARY` so the canonical
|
|
837
|
+
* ref (the code-unit-minimum of the set) is stable across deploys.
|
|
838
|
+
*/
|
|
839
|
+
findSourceRefsByHash(entityId: string, sourceHash: string, tx?: SQLiteAdapter): Promise<string[]>;
|
|
840
|
+
/**
|
|
841
|
+
* Per-sourceRef rollup for an entity: one row per live source_ref, with the
|
|
842
|
+
* most-recently-updated live hash (NOT the lexically-max hash) and a live
|
|
843
|
+
* fact count.
|
|
844
|
+
*
|
|
845
|
+
* The hash comes from the same row that wins ROW_NUMBER() over updated_at
|
|
846
|
+
* DESC, so a ref with multiple live hashes (e.g. from import) reports the
|
|
847
|
+
* latest one — matching single-doc `findLatestSourceHash` semantics.
|
|
848
|
+
*
|
|
849
|
+
* Sort is COLLATE BINARY: locale-dependent ordering re-mints identity on
|
|
850
|
+
* every deploy, which is the bug this whole section exists to prevent.
|
|
851
|
+
*/
|
|
852
|
+
listSourceRefs(entityId: string, tx?: SQLiteAdapter): Promise<Array<{
|
|
853
|
+
sourceRef: string;
|
|
854
|
+
sourceHash: string | null;
|
|
855
|
+
factCount: number;
|
|
856
|
+
lastIngestedAt: number;
|
|
857
|
+
}>>;
|
|
858
|
+
/**
|
|
859
|
+
* Count live entries for an entity across all source_refs/source_hashes.
|
|
860
|
+
* Used by forget({ dryRun, clearAll: true }).
|
|
861
|
+
*/
|
|
862
|
+
countLiveByEntityId(entityId: string, tx?: SQLiteAdapter): Promise<number>;
|
|
863
|
+
/**
|
|
864
|
+
* Count live entries matching a source filter (either or both may be null).
|
|
865
|
+
* Used by forget({ dryRun: true }) with sourceRef/sourceHash.
|
|
866
|
+
*/
|
|
867
|
+
countLiveBySource(entityId: string, sourceRef: string | null, sourceHash: string | null, tx?: SQLiteAdapter): Promise<number>;
|
|
799
868
|
findMetadataByIds(ids: readonly string[], tx?: SQLiteAdapter): Promise<EntryRowMetadata[]>;
|
|
800
869
|
findWithEmbeddingsByIds(ids: readonly string[], tx?: SQLiteAdapter): Promise<EntryRowWithEmbeddings[]>;
|
|
801
870
|
findMetadataByEntityIds(entityIds: readonly string[], tx?: SQLiteAdapter): Promise<EntryRowMetadata[]>;
|
|
@@ -1169,9 +1238,12 @@ declare class IngestionService {
|
|
|
1169
1238
|
chunkOverlap?: number;
|
|
1170
1239
|
chunkConcurrency?: number;
|
|
1171
1240
|
promptOverride?: string;
|
|
1241
|
+
}, opts?: {
|
|
1242
|
+
onDuplicateHash?: 'ingest' | 'skip' | 'throw';
|
|
1172
1243
|
}): Promise<{
|
|
1173
1244
|
truncated: boolean;
|
|
1174
1245
|
chunks: number;
|
|
1246
|
+
duplicateOf?: string;
|
|
1175
1247
|
}>;
|
|
1176
1248
|
}
|
|
1177
1249
|
|
|
@@ -1230,6 +1302,10 @@ declare class TaskRepository extends BaseRepository {
|
|
|
1230
1302
|
* `tx` is REQUIRED.
|
|
1231
1303
|
*/
|
|
1232
1304
|
bulkSoftDeleteByEntityId(entityId: string, tx: SQLiteAdapter): Promise<number>;
|
|
1305
|
+
/**
|
|
1306
|
+
* Count live tasks for an entity. Used by forget({ dryRun, clearAll: true }).
|
|
1307
|
+
*/
|
|
1308
|
+
countLiveByEntityId(entityId: string, tx?: SQLiteAdapter): Promise<number>;
|
|
1233
1309
|
}
|
|
1234
1310
|
|
|
1235
1311
|
declare class EventRepository extends BaseRepository {
|
|
@@ -1328,12 +1404,28 @@ declare class MaintenanceService {
|
|
|
1328
1404
|
sourceRef?: string;
|
|
1329
1405
|
sourceHash?: string;
|
|
1330
1406
|
clearAll?: boolean;
|
|
1407
|
+
}, opts?: {
|
|
1408
|
+
dryRun?: boolean;
|
|
1331
1409
|
}): Promise<{
|
|
1332
1410
|
deleted: {
|
|
1333
1411
|
entries: number;
|
|
1334
1412
|
tasks: number;
|
|
1335
1413
|
};
|
|
1414
|
+
metadataReset?: boolean;
|
|
1336
1415
|
}>;
|
|
1416
|
+
/**
|
|
1417
|
+
* Read-only dry-run preview of {@link forget}. Returns the same shape as a
|
|
1418
|
+
* real call would, without acquiring the lock, opening a transaction, staging
|
|
1419
|
+
* outbox events, or firing embedding hooks. Counts may be off-by-N during a
|
|
1420
|
+
* concurrent real forget — this is accepted, not considered a bug.
|
|
1421
|
+
*
|
|
1422
|
+
* `metadataReset` mirrors the real call: only `clearAll: true` returns true,
|
|
1423
|
+
* because only `clearAll` actually resets the metadata checkpoint.
|
|
1424
|
+
* `standard` (sourceRef/sourceHash) returns no metadataReset field, just like
|
|
1425
|
+
* the real call. `entryId`/`taskId` selectors are rejected with a clear error
|
|
1426
|
+
* (the spec keeps dry-run narrow).
|
|
1427
|
+
*/
|
|
1428
|
+
private forgetDryRun;
|
|
1337
1429
|
/** Core librarian pass (locks handled by {@link runLibrarian}). Package-internal orchestration hook. */
|
|
1338
1430
|
doRunLibrarian(entityId: string, promptOverride?: string): Promise<void>;
|
|
1339
1431
|
/**
|
|
@@ -1523,6 +1615,44 @@ declare class WikiMemory {
|
|
|
1523
1615
|
get __testAccess(): WikiMemoryTestAccess;
|
|
1524
1616
|
setup(): Promise<void>;
|
|
1525
1617
|
hasChanged(entityId: string, sourceRef: string, sourceHash: string): Promise<boolean>;
|
|
1618
|
+
/**
|
|
1619
|
+
* Batched overload.
|
|
1620
|
+
*
|
|
1621
|
+
* `duplicateOf`, when present, is the canonical stored DIFFERENT `source_ref`
|
|
1622
|
+
* holding the same hash — never the incoming ref itself (the incoming ref is
|
|
1623
|
+
* excluded from the canonical-sort set so a self-reference is impossible).
|
|
1624
|
+
* `duplicateOf` reflects the *DB-side* normalized spelling; `sourceRef` in
|
|
1625
|
+
* each result echoes the raw caller value. Hosts should not compare these
|
|
1626
|
+
* two fields directly to infer canonical status.
|
|
1627
|
+
*/
|
|
1628
|
+
hasChanged(entityId: string, entries: Array<{
|
|
1629
|
+
sourceRef: string;
|
|
1630
|
+
sourceHash: string;
|
|
1631
|
+
}>): Promise<Array<{
|
|
1632
|
+
sourceRef: string;
|
|
1633
|
+
changed: boolean;
|
|
1634
|
+
duplicateOf?: string;
|
|
1635
|
+
}>>;
|
|
1636
|
+
/**
|
|
1637
|
+
* Returns the live source_refs for an entity, one row per ref, with the most
|
|
1638
|
+
* recently-updated live `source_hash` and a live fact count. Refs are sorted
|
|
1639
|
+
* `COLLATE BINARY` (no locale dependency). Used by hosts to reconcile stored
|
|
1640
|
+
* state against a live source, or audit duplicate-hash collisions via
|
|
1641
|
+
* `findSourceRefsByHash`.
|
|
1642
|
+
*/
|
|
1643
|
+
listSourceRefs(entityId: string): Promise<Array<{
|
|
1644
|
+
sourceRef: string;
|
|
1645
|
+
sourceHash: string | null;
|
|
1646
|
+
factCount: number;
|
|
1647
|
+
lastIngestedAt: number;
|
|
1648
|
+
}>>;
|
|
1649
|
+
/**
|
|
1650
|
+
* Returns the live source_refs for an entity that hold the given source_hash,
|
|
1651
|
+
* sorted `COLLATE BINARY` ascending. The first element is the canonical ref
|
|
1652
|
+
* under the code-unit-minimum rule (no locale dependency). Used by the
|
|
1653
|
+
* ingestDocument guard and by hosts auditing duplicate-content collisions.
|
|
1654
|
+
*/
|
|
1655
|
+
findSourceRefsByHash(entityId: string, sourceHash: string): Promise<string[]>;
|
|
1526
1656
|
runPrune(entityId: string, options?: {
|
|
1527
1657
|
retainSoftDeletedFor?: number | null;
|
|
1528
1658
|
retainEventsFor?: number | null;
|
|
@@ -1609,11 +1739,14 @@ declare class WikiMemory {
|
|
|
1609
1739
|
sourceRef?: string;
|
|
1610
1740
|
sourceHash?: string;
|
|
1611
1741
|
clearAll?: boolean;
|
|
1742
|
+
}, opts?: {
|
|
1743
|
+
dryRun?: boolean;
|
|
1612
1744
|
}): Promise<{
|
|
1613
1745
|
deleted: {
|
|
1614
1746
|
entries: number;
|
|
1615
1747
|
tasks: number;
|
|
1616
1748
|
};
|
|
1749
|
+
metadataReset?: boolean;
|
|
1617
1750
|
}>;
|
|
1618
1751
|
/**
|
|
1619
1752
|
* @param params.promptOverride - Overrides the system prompt for this ingest call only.
|
|
@@ -1628,9 +1761,12 @@ declare class WikiMemory {
|
|
|
1628
1761
|
chunkOverlap?: number;
|
|
1629
1762
|
chunkConcurrency?: number;
|
|
1630
1763
|
promptOverride?: string;
|
|
1764
|
+
}, opts?: {
|
|
1765
|
+
onDuplicateHash?: 'ingest' | 'skip' | 'throw';
|
|
1631
1766
|
}): Promise<{
|
|
1632
1767
|
truncated: boolean;
|
|
1633
1768
|
chunks: number;
|
|
1769
|
+
duplicateOf?: string;
|
|
1634
1770
|
}>;
|
|
1635
1771
|
/**
|
|
1636
1772
|
* Returns up to `limit` unprocessed outbox events, oldest first.
|
|
@@ -1660,4 +1796,4 @@ declare class WikiMemory {
|
|
|
1660
1796
|
}): Promise<void>;
|
|
1661
1797
|
}
|
|
1662
1798
|
|
|
1663
|
-
export {
|
|
1799
|
+
export { JobManager as $, WikiBusyError as A, type WikiBusyOperation as B, type WikiCheckpoint as C, type WikiConfig as D, type EntityStatus as E, type FormatContextOptions as F, type GraphNeighborhood as G, HEAL_BATCH_SIZE as H, WikiDuplicateHashError as I, type WikiEdge as J, type WikiEvent as K, type LLMProvider as L, type MemoryBundle as M, type WikiFact as N, type OntologyManifest as O, type PromptOverrides as P, type WikiMemoryTestAccess as Q, type ReadOptions as R, type SQLiteAdapter as S, type WikiOutboxEvent as T, type WikiTask as U, type VectorRanker as V, type WikiOptions as W, WikiTransactionError as X, EmbeddingService as Y, ImportExportService as Z, IngestionService as _, type MemoryDump as a, MaintenanceService as a0, RetrievalService as a1, SearchService as a2, WriteService as a3, type FormattedMemoryDump as b, WikiMemory as c, type ExtractedFact as d, type ExtractedFactEdge as e, type ExtractedFactWithOntology as f, type ExtractedTask as g, type GraphTraversalOptions as h, HEAL_RECHECK_MS as i, HOOK_TIMEOUT_MARKER as j, type HealResult as k, ONTOLOGY_BACKFILL_BATCH_SIZE as l, ONTOLOGY_BACKFILL_MAX_PROMPT_CHARS as m, ONTOLOGY_BACKFILL_RECHECK_MS as n, type OntologyBackfillResult as o, type OntologyConfig as p, type OntologyEdgeType as q, type OntologyMode as r, type OntologyNodeType as s, type OntologyPromptContext as t, type OntologyUpdates as u, PromptService as v, PrunePartialFailureError as w, type VectorRankerFallback as x, type VectorRankerRankArgs as y, type VectorRankerSemanticResult as z };
|
|
@@ -544,6 +544,22 @@ declare class WikiBusyError extends Error {
|
|
|
544
544
|
readonly entityId: string;
|
|
545
545
|
constructor(operation: WikiBusyOperation, entityId: string);
|
|
546
546
|
}
|
|
547
|
+
/**
|
|
548
|
+
* Thrown by `ingestDocument({ onDuplicateHash: 'throw' })` when a different
|
|
549
|
+
* source_ref in the same entity already holds the supplied source_hash against
|
|
550
|
+
* a live row. Mirrors {@link WikiBusyError}'s anchoring of canonical metadata
|
|
551
|
+
* on the error instance for stable observability.
|
|
552
|
+
*/
|
|
553
|
+
declare class WikiDuplicateHashError extends Error {
|
|
554
|
+
readonly canonical: string;
|
|
555
|
+
readonly sourceHash: string;
|
|
556
|
+
readonly entityId: string;
|
|
557
|
+
constructor(params: {
|
|
558
|
+
canonical: string;
|
|
559
|
+
sourceHash: string;
|
|
560
|
+
entityId: string;
|
|
561
|
+
});
|
|
562
|
+
}
|
|
547
563
|
/**
|
|
548
564
|
* Thrown by the serialized transaction wrapper when a SQLite driver error
|
|
549
565
|
* escapes a transaction callback (nested BEGIN, SQLITE_BUSY, constraint
|
|
@@ -796,6 +812,59 @@ declare class EntryRepository extends BaseRepository {
|
|
|
796
812
|
}>>;
|
|
797
813
|
updateSourceRefByRowid(rowid: number, sourceRef: string | null, tx: SQLiteAdapter): Promise<void>;
|
|
798
814
|
findLatestSourceHash(entityId: string, sourceRef: string, tx?: SQLiteAdapter): Promise<string | null>;
|
|
815
|
+
/**
|
|
816
|
+
* Batch version of {@link findLatestSourceHash}. Returns a Map covering every
|
|
817
|
+
* requested ref, where the value is the source_hash from the row with the
|
|
818
|
+
* most-recently-updated live fact for that ref, or null when no live row exists.
|
|
819
|
+
*
|
|
820
|
+
* The SQL uses ROW_NUMBER() OVER (PARTITION BY source_ref ORDER BY updated_at
|
|
821
|
+
* DESC, id ASC) — NOT MAX(source_hash). Aggregation with MAX(source_hash) is
|
|
822
|
+
* wrong because MAX computes independently across grouped rows; the hash must
|
|
823
|
+
* come from the exact row that wins MAX(updated_at). The `id ASC` tie-break
|
|
824
|
+
* keeps selection deterministic when two live rows share `updated_at`.
|
|
825
|
+
*
|
|
826
|
+
* Source refs are de-duplicated and processed in chunks so the per-query bind
|
|
827
|
+
* parameter count stays under SQLite's `SQLITE_MAX_VARIABLE_NUMBER` (default
|
|
828
|
+
* 999, leaving one slot for `entity_id`).
|
|
829
|
+
*
|
|
830
|
+
* Empty input is a synchronous early return with zero SQL calls.
|
|
831
|
+
*/
|
|
832
|
+
findLatestSourceHashes(entityId: string, sourceRefs: readonly string[], tx?: SQLiteAdapter): Promise<Map<string, string | null>>;
|
|
833
|
+
/**
|
|
834
|
+
* Return the live source_refs for an entity that hold the given source_hash.
|
|
835
|
+
* Used by the ingestDocument duplicate-hash guard and by hosts auditing
|
|
836
|
+
* duplicate-content collisions. Sorted `COLLATE BINARY` so the canonical
|
|
837
|
+
* ref (the code-unit-minimum of the set) is stable across deploys.
|
|
838
|
+
*/
|
|
839
|
+
findSourceRefsByHash(entityId: string, sourceHash: string, tx?: SQLiteAdapter): Promise<string[]>;
|
|
840
|
+
/**
|
|
841
|
+
* Per-sourceRef rollup for an entity: one row per live source_ref, with the
|
|
842
|
+
* most-recently-updated live hash (NOT the lexically-max hash) and a live
|
|
843
|
+
* fact count.
|
|
844
|
+
*
|
|
845
|
+
* The hash comes from the same row that wins ROW_NUMBER() over updated_at
|
|
846
|
+
* DESC, so a ref with multiple live hashes (e.g. from import) reports the
|
|
847
|
+
* latest one — matching single-doc `findLatestSourceHash` semantics.
|
|
848
|
+
*
|
|
849
|
+
* Sort is COLLATE BINARY: locale-dependent ordering re-mints identity on
|
|
850
|
+
* every deploy, which is the bug this whole section exists to prevent.
|
|
851
|
+
*/
|
|
852
|
+
listSourceRefs(entityId: string, tx?: SQLiteAdapter): Promise<Array<{
|
|
853
|
+
sourceRef: string;
|
|
854
|
+
sourceHash: string | null;
|
|
855
|
+
factCount: number;
|
|
856
|
+
lastIngestedAt: number;
|
|
857
|
+
}>>;
|
|
858
|
+
/**
|
|
859
|
+
* Count live entries for an entity across all source_refs/source_hashes.
|
|
860
|
+
* Used by forget({ dryRun, clearAll: true }).
|
|
861
|
+
*/
|
|
862
|
+
countLiveByEntityId(entityId: string, tx?: SQLiteAdapter): Promise<number>;
|
|
863
|
+
/**
|
|
864
|
+
* Count live entries matching a source filter (either or both may be null).
|
|
865
|
+
* Used by forget({ dryRun: true }) with sourceRef/sourceHash.
|
|
866
|
+
*/
|
|
867
|
+
countLiveBySource(entityId: string, sourceRef: string | null, sourceHash: string | null, tx?: SQLiteAdapter): Promise<number>;
|
|
799
868
|
findMetadataByIds(ids: readonly string[], tx?: SQLiteAdapter): Promise<EntryRowMetadata[]>;
|
|
800
869
|
findWithEmbeddingsByIds(ids: readonly string[], tx?: SQLiteAdapter): Promise<EntryRowWithEmbeddings[]>;
|
|
801
870
|
findMetadataByEntityIds(entityIds: readonly string[], tx?: SQLiteAdapter): Promise<EntryRowMetadata[]>;
|
|
@@ -1169,9 +1238,12 @@ declare class IngestionService {
|
|
|
1169
1238
|
chunkOverlap?: number;
|
|
1170
1239
|
chunkConcurrency?: number;
|
|
1171
1240
|
promptOverride?: string;
|
|
1241
|
+
}, opts?: {
|
|
1242
|
+
onDuplicateHash?: 'ingest' | 'skip' | 'throw';
|
|
1172
1243
|
}): Promise<{
|
|
1173
1244
|
truncated: boolean;
|
|
1174
1245
|
chunks: number;
|
|
1246
|
+
duplicateOf?: string;
|
|
1175
1247
|
}>;
|
|
1176
1248
|
}
|
|
1177
1249
|
|
|
@@ -1230,6 +1302,10 @@ declare class TaskRepository extends BaseRepository {
|
|
|
1230
1302
|
* `tx` is REQUIRED.
|
|
1231
1303
|
*/
|
|
1232
1304
|
bulkSoftDeleteByEntityId(entityId: string, tx: SQLiteAdapter): Promise<number>;
|
|
1305
|
+
/**
|
|
1306
|
+
* Count live tasks for an entity. Used by forget({ dryRun, clearAll: true }).
|
|
1307
|
+
*/
|
|
1308
|
+
countLiveByEntityId(entityId: string, tx?: SQLiteAdapter): Promise<number>;
|
|
1233
1309
|
}
|
|
1234
1310
|
|
|
1235
1311
|
declare class EventRepository extends BaseRepository {
|
|
@@ -1328,12 +1404,28 @@ declare class MaintenanceService {
|
|
|
1328
1404
|
sourceRef?: string;
|
|
1329
1405
|
sourceHash?: string;
|
|
1330
1406
|
clearAll?: boolean;
|
|
1407
|
+
}, opts?: {
|
|
1408
|
+
dryRun?: boolean;
|
|
1331
1409
|
}): Promise<{
|
|
1332
1410
|
deleted: {
|
|
1333
1411
|
entries: number;
|
|
1334
1412
|
tasks: number;
|
|
1335
1413
|
};
|
|
1414
|
+
metadataReset?: boolean;
|
|
1336
1415
|
}>;
|
|
1416
|
+
/**
|
|
1417
|
+
* Read-only dry-run preview of {@link forget}. Returns the same shape as a
|
|
1418
|
+
* real call would, without acquiring the lock, opening a transaction, staging
|
|
1419
|
+
* outbox events, or firing embedding hooks. Counts may be off-by-N during a
|
|
1420
|
+
* concurrent real forget — this is accepted, not considered a bug.
|
|
1421
|
+
*
|
|
1422
|
+
* `metadataReset` mirrors the real call: only `clearAll: true` returns true,
|
|
1423
|
+
* because only `clearAll` actually resets the metadata checkpoint.
|
|
1424
|
+
* `standard` (sourceRef/sourceHash) returns no metadataReset field, just like
|
|
1425
|
+
* the real call. `entryId`/`taskId` selectors are rejected with a clear error
|
|
1426
|
+
* (the spec keeps dry-run narrow).
|
|
1427
|
+
*/
|
|
1428
|
+
private forgetDryRun;
|
|
1337
1429
|
/** Core librarian pass (locks handled by {@link runLibrarian}). Package-internal orchestration hook. */
|
|
1338
1430
|
doRunLibrarian(entityId: string, promptOverride?: string): Promise<void>;
|
|
1339
1431
|
/**
|
|
@@ -1523,6 +1615,44 @@ declare class WikiMemory {
|
|
|
1523
1615
|
get __testAccess(): WikiMemoryTestAccess;
|
|
1524
1616
|
setup(): Promise<void>;
|
|
1525
1617
|
hasChanged(entityId: string, sourceRef: string, sourceHash: string): Promise<boolean>;
|
|
1618
|
+
/**
|
|
1619
|
+
* Batched overload.
|
|
1620
|
+
*
|
|
1621
|
+
* `duplicateOf`, when present, is the canonical stored DIFFERENT `source_ref`
|
|
1622
|
+
* holding the same hash — never the incoming ref itself (the incoming ref is
|
|
1623
|
+
* excluded from the canonical-sort set so a self-reference is impossible).
|
|
1624
|
+
* `duplicateOf` reflects the *DB-side* normalized spelling; `sourceRef` in
|
|
1625
|
+
* each result echoes the raw caller value. Hosts should not compare these
|
|
1626
|
+
* two fields directly to infer canonical status.
|
|
1627
|
+
*/
|
|
1628
|
+
hasChanged(entityId: string, entries: Array<{
|
|
1629
|
+
sourceRef: string;
|
|
1630
|
+
sourceHash: string;
|
|
1631
|
+
}>): Promise<Array<{
|
|
1632
|
+
sourceRef: string;
|
|
1633
|
+
changed: boolean;
|
|
1634
|
+
duplicateOf?: string;
|
|
1635
|
+
}>>;
|
|
1636
|
+
/**
|
|
1637
|
+
* Returns the live source_refs for an entity, one row per ref, with the most
|
|
1638
|
+
* recently-updated live `source_hash` and a live fact count. Refs are sorted
|
|
1639
|
+
* `COLLATE BINARY` (no locale dependency). Used by hosts to reconcile stored
|
|
1640
|
+
* state against a live source, or audit duplicate-hash collisions via
|
|
1641
|
+
* `findSourceRefsByHash`.
|
|
1642
|
+
*/
|
|
1643
|
+
listSourceRefs(entityId: string): Promise<Array<{
|
|
1644
|
+
sourceRef: string;
|
|
1645
|
+
sourceHash: string | null;
|
|
1646
|
+
factCount: number;
|
|
1647
|
+
lastIngestedAt: number;
|
|
1648
|
+
}>>;
|
|
1649
|
+
/**
|
|
1650
|
+
* Returns the live source_refs for an entity that hold the given source_hash,
|
|
1651
|
+
* sorted `COLLATE BINARY` ascending. The first element is the canonical ref
|
|
1652
|
+
* under the code-unit-minimum rule (no locale dependency). Used by the
|
|
1653
|
+
* ingestDocument guard and by hosts auditing duplicate-content collisions.
|
|
1654
|
+
*/
|
|
1655
|
+
findSourceRefsByHash(entityId: string, sourceHash: string): Promise<string[]>;
|
|
1526
1656
|
runPrune(entityId: string, options?: {
|
|
1527
1657
|
retainSoftDeletedFor?: number | null;
|
|
1528
1658
|
retainEventsFor?: number | null;
|
|
@@ -1609,11 +1739,14 @@ declare class WikiMemory {
|
|
|
1609
1739
|
sourceRef?: string;
|
|
1610
1740
|
sourceHash?: string;
|
|
1611
1741
|
clearAll?: boolean;
|
|
1742
|
+
}, opts?: {
|
|
1743
|
+
dryRun?: boolean;
|
|
1612
1744
|
}): Promise<{
|
|
1613
1745
|
deleted: {
|
|
1614
1746
|
entries: number;
|
|
1615
1747
|
tasks: number;
|
|
1616
1748
|
};
|
|
1749
|
+
metadataReset?: boolean;
|
|
1617
1750
|
}>;
|
|
1618
1751
|
/**
|
|
1619
1752
|
* @param params.promptOverride - Overrides the system prompt for this ingest call only.
|
|
@@ -1628,9 +1761,12 @@ declare class WikiMemory {
|
|
|
1628
1761
|
chunkOverlap?: number;
|
|
1629
1762
|
chunkConcurrency?: number;
|
|
1630
1763
|
promptOverride?: string;
|
|
1764
|
+
}, opts?: {
|
|
1765
|
+
onDuplicateHash?: 'ingest' | 'skip' | 'throw';
|
|
1631
1766
|
}): Promise<{
|
|
1632
1767
|
truncated: boolean;
|
|
1633
1768
|
chunks: number;
|
|
1769
|
+
duplicateOf?: string;
|
|
1634
1770
|
}>;
|
|
1635
1771
|
/**
|
|
1636
1772
|
* Returns up to `limit` unprocessed outbox events, oldest first.
|
|
@@ -1660,4 +1796,4 @@ declare class WikiMemory {
|
|
|
1660
1796
|
}): Promise<void>;
|
|
1661
1797
|
}
|
|
1662
1798
|
|
|
1663
|
-
export {
|
|
1799
|
+
export { JobManager as $, WikiBusyError as A, type WikiBusyOperation as B, type WikiCheckpoint as C, type WikiConfig as D, type EntityStatus as E, type FormatContextOptions as F, type GraphNeighborhood as G, HEAL_BATCH_SIZE as H, WikiDuplicateHashError as I, type WikiEdge as J, type WikiEvent as K, type LLMProvider as L, type MemoryBundle as M, type WikiFact as N, type OntologyManifest as O, type PromptOverrides as P, type WikiMemoryTestAccess as Q, type ReadOptions as R, type SQLiteAdapter as S, type WikiOutboxEvent as T, type WikiTask as U, type VectorRanker as V, type WikiOptions as W, WikiTransactionError as X, EmbeddingService as Y, ImportExportService as Z, IngestionService as _, type MemoryDump as a, MaintenanceService as a0, RetrievalService as a1, SearchService as a2, WriteService as a3, type FormattedMemoryDump as b, WikiMemory as c, type ExtractedFact as d, type ExtractedFactEdge as e, type ExtractedFactWithOntology as f, type ExtractedTask as g, type GraphTraversalOptions as h, HEAL_RECHECK_MS as i, HOOK_TIMEOUT_MARKER as j, type HealResult as k, ONTOLOGY_BACKFILL_BATCH_SIZE as l, ONTOLOGY_BACKFILL_MAX_PROMPT_CHARS as m, ONTOLOGY_BACKFILL_RECHECK_MS as n, type OntologyBackfillResult as o, type OntologyConfig as p, type OntologyEdgeType as q, type OntologyMode as r, type OntologyNodeType as s, type OntologyPromptContext as t, type OntologyUpdates as u, PromptService as v, PrunePartialFailureError as w, type VectorRankerFallback as x, type VectorRankerRankArgs as y, type VectorRankerSemanticResult as z };
|
package/dist/testing.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { Y as EmbeddingService, Z as ImportExportService, _ as IngestionService, $ as JobManager, $ as JobManagerType, a0 as MaintenanceService, a1 as RetrievalService, a2 as SearchService, a2 as SearchServiceType, Q as WikiMemoryTestAccess, a3 as WriteService } from './testing-DyXISRwS.mjs';
|
|
2
2
|
import 'minisearch';
|
package/dist/testing.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { Y as EmbeddingService, Z as ImportExportService, _ as IngestionService, $ as JobManager, $ as JobManagerType, a0 as MaintenanceService, a1 as RetrievalService, a2 as SearchService, a2 as SearchServiceType, Q as WikiMemoryTestAccess, a3 as WriteService } from './testing-DyXISRwS.js';
|
|
2
2
|
import 'minisearch';
|
package/dist/testing.js
CHANGED
|
@@ -15,6 +15,15 @@ var WikiBusyError = class extends Error {
|
|
|
15
15
|
this.entityId = entityId;
|
|
16
16
|
}
|
|
17
17
|
};
|
|
18
|
+
var WikiDuplicateHashError = class extends Error {
|
|
19
|
+
constructor(params) {
|
|
20
|
+
super(`Duplicate source hash for entity ${params.entityId}; another ref already holds this content`);
|
|
21
|
+
this.name = "WikiDuplicateHashError";
|
|
22
|
+
this.canonical = params.canonical;
|
|
23
|
+
this.sourceHash = params.sourceHash;
|
|
24
|
+
this.entityId = params.entityId;
|
|
25
|
+
}
|
|
26
|
+
};
|
|
18
27
|
var PrunePartialFailureError = class extends Error {
|
|
19
28
|
constructor(deleted, failedAt, remaining, cause, deletedTasks = 0, deletedEvents = 0) {
|
|
20
29
|
super(`Prune partially failed: deleted ${deleted}, failed at ${failedAt}, ${remaining} remaining`);
|
|
@@ -574,6 +583,15 @@ var ImportExportService = class {
|
|
|
574
583
|
const safeTitle = clip(String(fact.title ?? ""), IMPORT_TITLE_MAX);
|
|
575
584
|
const safeBody = clip(String(fact.body ?? ""), IMPORT_BODY_MAX);
|
|
576
585
|
clippedTextByFactId.set(fact.id, { title: safeTitle, body: safeBody });
|
|
586
|
+
let normalizedSourceRef = null;
|
|
587
|
+
if (fact.source_ref !== null && fact.source_ref !== void 0) {
|
|
588
|
+
normalizedSourceRef = normalizeSourceRef(fact.source_ref);
|
|
589
|
+
if (normalizedSourceRef === null) {
|
|
590
|
+
throw new Error(
|
|
591
|
+
`importDump: invalid source_ref ${JSON.stringify(fact.source_ref)} for entity "${entityId}" fact "${fact.id}" (must normalize to a non-empty string; see ingestDocument's sourceRef validation)`
|
|
592
|
+
);
|
|
593
|
+
}
|
|
594
|
+
}
|
|
577
595
|
const factObj = {
|
|
578
596
|
id: fact.id,
|
|
579
597
|
entity_id: entityId,
|
|
@@ -583,7 +601,7 @@ var ImportExportService = class {
|
|
|
583
601
|
confidence: fact.confidence,
|
|
584
602
|
source_type: sourceType,
|
|
585
603
|
source_hash: fact.source_hash,
|
|
586
|
-
source_ref:
|
|
604
|
+
source_ref: normalizedSourceRef,
|
|
587
605
|
created_at: fact.created_at,
|
|
588
606
|
updated_at: safeUpdatedAt,
|
|
589
607
|
last_accessed_at: fact.last_accessed_at,
|
|
@@ -986,11 +1004,23 @@ var IngestionService = class {
|
|
|
986
1004
|
this.ontologyService = ontologyService;
|
|
987
1005
|
this.promptService = promptService ?? new PromptService(this.options.config?.prompts);
|
|
988
1006
|
}
|
|
989
|
-
async ingestDocument(entityId, params) {
|
|
1007
|
+
async ingestDocument(entityId, params, opts) {
|
|
990
1008
|
const sourceRef = normalizeSourceRef(params.sourceRef);
|
|
991
1009
|
if (!sourceRef) throw new Error("Invalid sourceRef");
|
|
992
1010
|
const sourceHash = normalizeSourceHash(params.sourceHash);
|
|
993
1011
|
if (!sourceHash) throw new Error("Invalid sourceHash (must be 64-char hex string)");
|
|
1012
|
+
const onDuplicateHash = opts?.onDuplicateHash ?? "ingest";
|
|
1013
|
+
if (onDuplicateHash !== "ingest") {
|
|
1014
|
+
const refs = await this.entryRepo.findSourceRefsByHash(entityId, sourceHash);
|
|
1015
|
+
const others = refs.filter((r) => r !== sourceRef);
|
|
1016
|
+
if (others.length > 0) {
|
|
1017
|
+
const canonical = others[0];
|
|
1018
|
+
if (onDuplicateHash === "throw") {
|
|
1019
|
+
throw new WikiDuplicateHashError({ canonical, sourceHash, entityId });
|
|
1020
|
+
}
|
|
1021
|
+
return { truncated: false, chunks: 0, duplicateOf: canonical };
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
994
1024
|
const maxChunkLength = params.maxChunkLength ?? this.options.config?.maxChunkLength ?? DEFAULT_MAX_CHUNK_LENGTH;
|
|
995
1025
|
const rawOverlap = params.chunkOverlap ?? this.options.config?.chunkOverlap ?? DEFAULT_CHUNK_OVERLAP;
|
|
996
1026
|
const chunkOverlap = Math.min(
|
|
@@ -1431,10 +1461,13 @@ var MaintenanceService = class {
|
|
|
1431
1461
|
this.jobManager.releaseLock(op, entityId ?? "*");
|
|
1432
1462
|
}
|
|
1433
1463
|
}
|
|
1434
|
-
async forget(entityId, params) {
|
|
1464
|
+
async forget(entityId, params, opts) {
|
|
1435
1465
|
if (params.clearAll && (params.entryId !== void 0 || params.taskId !== void 0 || params.sourceRef !== void 0 || params.sourceHash !== void 0)) {
|
|
1436
1466
|
throw new Error("forget() clearAll is mutually exclusive with entryId, taskId, sourceRef, and sourceHash");
|
|
1437
1467
|
}
|
|
1468
|
+
if (opts?.dryRun === true) {
|
|
1469
|
+
return this.forgetDryRun(entityId, params);
|
|
1470
|
+
}
|
|
1438
1471
|
this.jobManager.acquireLock("forget", entityId);
|
|
1439
1472
|
try {
|
|
1440
1473
|
const now = Date.now();
|
|
@@ -1495,11 +1528,42 @@ var MaintenanceService = class {
|
|
|
1495
1528
|
throw new Error(`forget(${entityId}/${factId}) failed: ANN cleanup hook rejected`, { cause: this._sanitizeRankerError(hookErr) });
|
|
1496
1529
|
}
|
|
1497
1530
|
}
|
|
1498
|
-
return { deleted: { entries: deletedEntries, tasks: deletedTasks } };
|
|
1531
|
+
return params.clearAll ? { deleted: { entries: deletedEntries, tasks: deletedTasks }, metadataReset: true } : { deleted: { entries: deletedEntries, tasks: deletedTasks } };
|
|
1499
1532
|
} finally {
|
|
1500
1533
|
this.jobManager.releaseLock("forget", entityId);
|
|
1501
1534
|
}
|
|
1502
1535
|
}
|
|
1536
|
+
/**
|
|
1537
|
+
* Read-only dry-run preview of {@link forget}. Returns the same shape as a
|
|
1538
|
+
* real call would, without acquiring the lock, opening a transaction, staging
|
|
1539
|
+
* outbox events, or firing embedding hooks. Counts may be off-by-N during a
|
|
1540
|
+
* concurrent real forget — this is accepted, not considered a bug.
|
|
1541
|
+
*
|
|
1542
|
+
* `metadataReset` mirrors the real call: only `clearAll: true` returns true,
|
|
1543
|
+
* because only `clearAll` actually resets the metadata checkpoint.
|
|
1544
|
+
* `standard` (sourceRef/sourceHash) returns no metadataReset field, just like
|
|
1545
|
+
* the real call. `entryId`/`taskId` selectors are rejected with a clear error
|
|
1546
|
+
* (the spec keeps dry-run narrow).
|
|
1547
|
+
*/
|
|
1548
|
+
async forgetDryRun(entityId, params) {
|
|
1549
|
+
if (params.entryId !== void 0 || params.taskId !== void 0) {
|
|
1550
|
+
throw new Error("forget({ dryRun: true }) does not support entryId/taskId selectors; use sourceRef/sourceHash or clearAll");
|
|
1551
|
+
}
|
|
1552
|
+
if (params.clearAll) {
|
|
1553
|
+
const entries2 = await this.entryRepo.countLiveByEntityId(entityId);
|
|
1554
|
+
const tasks = await this.taskRepo.countLiveByEntityId(entityId);
|
|
1555
|
+
return { deleted: { entries: entries2, tasks }, metadataReset: true };
|
|
1556
|
+
}
|
|
1557
|
+
const sourceRef = params.sourceRef !== void 0 ? normalizeSourceRef(params.sourceRef) : null;
|
|
1558
|
+
if (params.sourceRef !== void 0 && !sourceRef) throw new Error("Invalid sourceRef");
|
|
1559
|
+
const sourceHash = params.sourceHash !== void 0 ? normalizeSourceHash(params.sourceHash) : null;
|
|
1560
|
+
if (params.sourceHash !== void 0 && !sourceHash) throw new Error("Invalid sourceHash (must be 64-char hex string)");
|
|
1561
|
+
if (sourceRef === null && sourceHash === null) {
|
|
1562
|
+
return { deleted: { entries: 0, tasks: 0 } };
|
|
1563
|
+
}
|
|
1564
|
+
const entries = await this.entryRepo.countLiveBySource(entityId, sourceRef, sourceHash);
|
|
1565
|
+
return { deleted: { entries, tasks: 0 } };
|
|
1566
|
+
}
|
|
1503
1567
|
/** Core librarian pass (locks handled by {@link runLibrarian}). Package-internal orchestration hook. */
|
|
1504
1568
|
async doRunLibrarian(entityId, promptOverride) {
|
|
1505
1569
|
const events = await this.eventRepo.getRecent(entityId, 50);
|
|
@@ -3018,6 +3082,19 @@ var JobManager = class {
|
|
|
3018
3082
|
return this.activeMaintenanceJobs.has(this.lockKeyFns[operation](entityId)) || this.activeMaintenanceJobs.has(this._pruneKey(entityId)) || this._isReembedActive(entityId) || this._isImportActiveFor(entityId) || this._isForgetActiveFor(entityId);
|
|
3019
3083
|
case "prune":
|
|
3020
3084
|
return this.activeMaintenanceJobs.has(this._pruneKey(entityId)) || this.activeMaintenanceJobs.has(this._librarianKey(entityId)) || this.activeMaintenanceJobs.has(this._healKey(entityId)) || this.activeMaintenanceJobs.has(this._ontologyBackfillKey(entityId)) || this._isReembedActive(entityId) || this._isIngestActiveFor(entityId) || this._isImportActiveFor(entityId) || this._isForgetActiveFor(entityId);
|
|
3085
|
+
case "reembed":
|
|
3086
|
+
return this.activeMaintenanceJobs.has(this._reembedKey(entityId)) || this.activeMaintenanceJobs.has(this._globalReembedKey()) || this.activeMaintenanceJobs.has(this._pruneKey(entityId)) || this.activeMaintenanceJobs.has(this._librarianKey(entityId)) || this.activeMaintenanceJobs.has(this._healKey(entityId)) || this.activeMaintenanceJobs.has(this._ontologyBackfillKey(entityId)) || this._isIngestActiveFor(entityId) || this._isImportActiveFor(entityId) || this._isForgetActiveFor(entityId);
|
|
3087
|
+
case "global_reembed":
|
|
3088
|
+
return this.activeMaintenanceJobs.has(this._globalReembedKey()) || this._isAnyMaintenanceActiveWithSuffix(":reembed") || this._isAnyMaintenanceActiveWithSuffix(":prune") || this._isAnyMaintenanceActiveWithSuffix(":librarian") || this._isAnyMaintenanceActiveWithSuffix(":heal") || this._isAnyMaintenanceActiveWithSuffix(":ontologyBackfill") || this.activeIngestJobs.size > 0 || this._isAnyMaintenanceActiveWithSuffix(":import") || this._isAnyMaintenanceActiveWithSuffix(":forget");
|
|
3089
|
+
case "import":
|
|
3090
|
+
case "forget": {
|
|
3091
|
+
const selfKey = operation === "import" ? this._importKey(entityId) : this._forgetKey(entityId);
|
|
3092
|
+
return this.activeMaintenanceJobs.has(selfKey) || this.activeMaintenanceJobs.has(this._librarianKey(entityId)) || this.activeMaintenanceJobs.has(this._healKey(entityId)) || this.activeMaintenanceJobs.has(this._ontologyBackfillKey(entityId)) || this.activeMaintenanceJobs.has(this._pruneKey(entityId)) || this._isReembedActive(entityId) || this._isIngestActiveFor(entityId) || this._isImportActiveFor(entityId) || this._isForgetActiveFor(entityId);
|
|
3093
|
+
}
|
|
3094
|
+
case "global_import":
|
|
3095
|
+
return this.activeMaintenanceJobs.has(this._globalImportKey());
|
|
3096
|
+
case "ingest":
|
|
3097
|
+
return this._hasIngestJob(entityId) || this.activeMaintenanceJobs.has(this._pruneKey(entityId)) || this._isReembedActive(entityId) || this._isImportActiveFor(entityId) || this._isForgetActiveFor(entityId);
|
|
3021
3098
|
default:
|
|
3022
3099
|
return false;
|
|
3023
3100
|
}
|