@equationalapplications/core-llm-wiki 7.1.2 → 7.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/README.md +36 -3
- package/dist/{chunk-ZU7K6NAU.mjs → chunk-TTECJ3S3.mjs} +59 -3
- package/dist/chunk-TTECJ3S3.mjs.map +1 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +113 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +58 -5
- package/dist/index.mjs.map +1 -1
- package/dist/{testing-CA7723qk.d.mts → testing-DYeMd9d1.d.mts} +110 -1
- package/dist/{testing-CA7723qk.d.ts → testing-DYeMd9d1.d.ts} +110 -1
- package/dist/testing.d.mts +1 -1
- package/dist/testing.d.ts +1 -1
- package/dist/testing.js +56 -0
- package/dist/testing.js.map +1 -1
- package/dist/testing.mjs +1 -1
- package/package.json +2 -2
- package/dist/chunk-ZU7K6NAU.mjs.map +0 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { M as MemoryBundle, F as FormatContextOptions, G as GraphNeighborhood, a as MemoryDump, b as FormattedMemoryDump, O as OntologyManifest, R as ReadOptions, S as SQLiteAdapter, W as WikiOptions, c as WikiMemory } from './testing-
|
|
2
|
-
export { C as ChunkFailure, D as DegradedRecord, E as EmbedFactResult, d as EmbedFailureKind, e as EmbeddingMarkerKind, f as EntityStatus, g as ExtractedFact, h as ExtractedFactEdge, i as ExtractedFactWithOntology, j as ExtractedTask, k as GraphTraversalOptions, H as HEAL_BATCH_SIZE, l as HEAL_RECHECK_MS, m as HOOK_TIMEOUT_MARKER, n as HealResult, I as IngestDocumentResult, L as LLMProvider, o as ONTOLOGY_BACKFILL_BATCH_SIZE, p as ONTOLOGY_BACKFILL_MAX_PROMPT_CHARS, q as ONTOLOGY_BACKFILL_RECHECK_MS, r as OntologyBackfillResult, s as OntologyConfig, t as OntologyEdgeType, u as OntologyMode, v as OntologyNodeType, w as OntologyPromptContext, x as OntologyUpdates, P as PromptOverrides, y as PromptService, z as PrunePartialFailureError, A as ReembedResult, V as VectorRanker, B as VectorRankerFallback, J as VectorRankerRankArgs, K as VectorRankerSemanticResult, N as WikiBusyError, Q as WikiBusyOperation, T as WikiCheckpoint, U as WikiConfig, X as WikiDuplicateHashError, Y as WikiEdge, Z as WikiEvent, _ as WikiFact, $ as
|
|
1
|
+
import { M as MemoryBundle, F as FormatContextOptions, G as GraphNeighborhood, a as MemoryDump, b as FormattedMemoryDump, O as OntologyManifest, R as ReadOptions, S as SQLiteAdapter, W as WikiOptions, c as WikiMemory } from './testing-DYeMd9d1.mjs';
|
|
2
|
+
export { C as ChunkFailure, D as DegradedRecord, E as EmbedFactResult, d as EmbedFailureKind, e as EmbeddingMarkerKind, f as EntityStatus, g as ExtractedFact, h as ExtractedFactEdge, i as ExtractedFactWithOntology, j as ExtractedTask, k as GraphTraversalOptions, H as HEAL_BATCH_SIZE, l as HEAL_RECHECK_MS, m as HOOK_TIMEOUT_MARKER, n as HealResult, I as IngestDocumentResult, L as LLMProvider, o as ONTOLOGY_BACKFILL_BATCH_SIZE, p as ONTOLOGY_BACKFILL_MAX_PROMPT_CHARS, q as ONTOLOGY_BACKFILL_RECHECK_MS, r as OntologyBackfillResult, s as OntologyConfig, t as OntologyEdgeType, u as OntologyMode, v as OntologyNodeType, w as OntologyPromptContext, x as OntologyUpdates, P as PromptOverrides, y as PromptService, z as PrunePartialFailureError, A as ReembedResult, V as VectorRanker, B as VectorRankerFallback, J as VectorRankerRankArgs, K as VectorRankerSemanticResult, N as WikiBusyError, Q as WikiBusyOperation, T as WikiCheckpoint, U as WikiConfig, X as WikiDuplicateHashError, Y as WikiEdge, Z as WikiEvent, _ as WikiFact, $ as WikiGraphNodeOwnershipConflict, a0 as WikiIngestEmptyError, a1 as WikiInvalidReadOptions, a2 as WikiMemoryTestAccess, a3 as WikiOutboxEvent, a4 as WikiParseError, a5 as WikiSourceRefHashCollision, a6 as WikiStrictOntologyViolation, a7 as WikiTask, a8 as WikiTransactionError } from './testing-DYeMd9d1.mjs';
|
|
3
3
|
import { OkfFile } from '@equationalapplications/core-okf';
|
|
4
4
|
import 'minisearch';
|
|
5
5
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { M as MemoryBundle, F as FormatContextOptions, G as GraphNeighborhood, a as MemoryDump, b as FormattedMemoryDump, O as OntologyManifest, R as ReadOptions, S as SQLiteAdapter, W as WikiOptions, c as WikiMemory } from './testing-
|
|
2
|
-
export { C as ChunkFailure, D as DegradedRecord, E as EmbedFactResult, d as EmbedFailureKind, e as EmbeddingMarkerKind, f as EntityStatus, g as ExtractedFact, h as ExtractedFactEdge, i as ExtractedFactWithOntology, j as ExtractedTask, k as GraphTraversalOptions, H as HEAL_BATCH_SIZE, l as HEAL_RECHECK_MS, m as HOOK_TIMEOUT_MARKER, n as HealResult, I as IngestDocumentResult, L as LLMProvider, o as ONTOLOGY_BACKFILL_BATCH_SIZE, p as ONTOLOGY_BACKFILL_MAX_PROMPT_CHARS, q as ONTOLOGY_BACKFILL_RECHECK_MS, r as OntologyBackfillResult, s as OntologyConfig, t as OntologyEdgeType, u as OntologyMode, v as OntologyNodeType, w as OntologyPromptContext, x as OntologyUpdates, P as PromptOverrides, y as PromptService, z as PrunePartialFailureError, A as ReembedResult, V as VectorRanker, B as VectorRankerFallback, J as VectorRankerRankArgs, K as VectorRankerSemanticResult, N as WikiBusyError, Q as WikiBusyOperation, T as WikiCheckpoint, U as WikiConfig, X as WikiDuplicateHashError, Y as WikiEdge, Z as WikiEvent, _ as WikiFact, $ as
|
|
1
|
+
import { M as MemoryBundle, F as FormatContextOptions, G as GraphNeighborhood, a as MemoryDump, b as FormattedMemoryDump, O as OntologyManifest, R as ReadOptions, S as SQLiteAdapter, W as WikiOptions, c as WikiMemory } from './testing-DYeMd9d1.js';
|
|
2
|
+
export { C as ChunkFailure, D as DegradedRecord, E as EmbedFactResult, d as EmbedFailureKind, e as EmbeddingMarkerKind, f as EntityStatus, g as ExtractedFact, h as ExtractedFactEdge, i as ExtractedFactWithOntology, j as ExtractedTask, k as GraphTraversalOptions, H as HEAL_BATCH_SIZE, l as HEAL_RECHECK_MS, m as HOOK_TIMEOUT_MARKER, n as HealResult, I as IngestDocumentResult, L as LLMProvider, o as ONTOLOGY_BACKFILL_BATCH_SIZE, p as ONTOLOGY_BACKFILL_MAX_PROMPT_CHARS, q as ONTOLOGY_BACKFILL_RECHECK_MS, r as OntologyBackfillResult, s as OntologyConfig, t as OntologyEdgeType, u as OntologyMode, v as OntologyNodeType, w as OntologyPromptContext, x as OntologyUpdates, P as PromptOverrides, y as PromptService, z as PrunePartialFailureError, A as ReembedResult, V as VectorRanker, B as VectorRankerFallback, J as VectorRankerRankArgs, K as VectorRankerSemanticResult, N as WikiBusyError, Q as WikiBusyOperation, T as WikiCheckpoint, U as WikiConfig, X as WikiDuplicateHashError, Y as WikiEdge, Z as WikiEvent, _ as WikiFact, $ as WikiGraphNodeOwnershipConflict, a0 as WikiIngestEmptyError, a1 as WikiInvalidReadOptions, a2 as WikiMemoryTestAccess, a3 as WikiOutboxEvent, a4 as WikiParseError, a5 as WikiSourceRefHashCollision, a6 as WikiStrictOntologyViolation, a7 as WikiTask, a8 as WikiTransactionError } from './testing-DYeMd9d1.js';
|
|
3
3
|
import { OkfFile } from '@equationalapplications/core-okf';
|
|
4
4
|
import 'minisearch';
|
|
5
5
|
|
package/dist/index.js
CHANGED
|
@@ -270,6 +270,21 @@ var WikiSourceRefHashCollision = class extends Error {
|
|
|
270
270
|
this.name = "WikiSourceRefHashCollision";
|
|
271
271
|
}
|
|
272
272
|
};
|
|
273
|
+
var WikiGraphNodeOwnershipConflict = class extends Error {
|
|
274
|
+
/**
|
|
275
|
+
* Privacy-preserving constructor: accepts no arguments, so neither the foreign
|
|
276
|
+
* owner, the conflicting node ID, the stored content, nor any provenance can
|
|
277
|
+
* leak through this error. The fixed message and `code` are the entire signal.
|
|
278
|
+
*
|
|
279
|
+
* @returns a contextless `WikiGraphNodeOwnershipConflict` instance. See the
|
|
280
|
+
* class-level JSDoc for the privacy rationale.
|
|
281
|
+
*/
|
|
282
|
+
constructor() {
|
|
283
|
+
super("Graph write rejected because a node ID is unavailable for this entity.");
|
|
284
|
+
this.code = "WIKI_GRAPH_NODE_OWNERSHIP_CONFLICT";
|
|
285
|
+
this.name = "WikiGraphNodeOwnershipConflict";
|
|
286
|
+
}
|
|
287
|
+
};
|
|
273
288
|
var WikiTransactionError = class extends Error {
|
|
274
289
|
constructor(message, options) {
|
|
275
290
|
super(message, options);
|
|
@@ -764,6 +779,26 @@ var EntryRepository = class extends BaseRepository {
|
|
|
764
779
|
* diagnostic that inflates runReembed's permanentlyFailed counter. A conflict
|
|
765
780
|
* with no blob leaves marker state alone, matching the "absent means don't
|
|
766
781
|
* touch" semantics used for embedding_blob itself.
|
|
782
|
+
*
|
|
783
|
+
* Graph node ownership (spec §2.4 + §3, REQ-OWN-01 + REQ-GRAPH-01): entry
|
|
784
|
+
* IDs share one database-wide namespace, so an ID stays owned by its
|
|
785
|
+
* existing entity for as long as the row exists — soft deletion included.
|
|
786
|
+
* The pre-write lookup already reads the existing row for OKF metadata; we
|
|
787
|
+
* project `entity_id` off that same SELECT and reject the write before
|
|
788
|
+
* any outbox payload construction when the stored owner differs from
|
|
789
|
+
* `fact.entity_id`. Soft-deleted foreign rows keep their IDs reserved;
|
|
790
|
+
* permanent reservation is NOT introduced, so a physically absent ID may
|
|
791
|
+
* still be inserted under the requested entity. The ON CONFLICT UPDATE SET
|
|
792
|
+
* clause carries a final `WHERE entries.entity_id = excluded.entity_id`
|
|
793
|
+
* guard so the database itself refuses a cross-owner row overwrite even if
|
|
794
|
+
* a future caller bypasses the pre-write check. When `runAsync` reports
|
|
795
|
+
* 0 changes (a legitimate conflict-suppressed write, OR an adapter that
|
|
796
|
+
* under-reports a permitted write) we re-read the stored owner; only a
|
|
797
|
+
* foreign owner throws — this is local defensive behavior, not permission
|
|
798
|
+
* for adapters to under-report. The thrown error is
|
|
799
|
+
* `WikiGraphNodeOwnershipConflict` (no owner, node ID, or stored content
|
|
800
|
+
* is disclosed). Upserts that pass both gates retain existing same-entity
|
|
801
|
+
* update + resurrection semantics.
|
|
767
802
|
*/
|
|
768
803
|
async upsert(fact, tx) {
|
|
769
804
|
const executor = this.getExecutor(tx);
|
|
@@ -771,12 +806,15 @@ var EntryRepository = class extends BaseRepository {
|
|
|
771
806
|
const tagsJson = JSON.stringify(fact.tags);
|
|
772
807
|
const embeddingBlob = this.normalizeEmbeddingBlob(fact.embedding_blob);
|
|
773
808
|
const existingRow = await executor.getFirstAsync(
|
|
774
|
-
`SELECT id, lifecycle_status, stale_after, generated_by,
|
|
809
|
+
`SELECT id, entity_id, lifecycle_status, stale_after, generated_by,
|
|
775
810
|
okf_sources, okf_verified, okf_usage_window,
|
|
776
811
|
last_verified_at, last_verified_by
|
|
777
812
|
FROM ${this.prefix}entries WHERE id = ?`,
|
|
778
813
|
[fact.id]
|
|
779
814
|
);
|
|
815
|
+
if (existingRow && existingRow.entity_id !== fact.entity_id) {
|
|
816
|
+
throw new WikiGraphNodeOwnershipConflict();
|
|
817
|
+
}
|
|
780
818
|
const operation = fact.deleted_at ? "DELETE" : existingRow ? "UPDATE" : "INSERT";
|
|
781
819
|
const result = await executor.runAsync(
|
|
782
820
|
`INSERT INTO ${this.prefix}entries (
|
|
@@ -787,7 +825,6 @@ var EntryRepository = class extends BaseRepository {
|
|
|
787
825
|
okf_sources, okf_verified, okf_usage_window
|
|
788
826
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
789
827
|
ON CONFLICT(id) DO UPDATE SET
|
|
790
|
-
entity_id = excluded.entity_id,
|
|
791
828
|
title = excluded.title,
|
|
792
829
|
body = excluded.body,
|
|
793
830
|
tags = excluded.tags,
|
|
@@ -804,7 +841,8 @@ var EntryRepository = class extends BaseRepository {
|
|
|
804
841
|
embedding_failed_at = CASE WHEN excluded.embedding_blob IS NOT NULL THEN NULL ELSE embedding_failed_at END,
|
|
805
842
|
embedding_failure_kind = CASE WHEN excluded.embedding_blob IS NOT NULL THEN NULL ELSE embedding_failure_kind END,
|
|
806
843
|
embedding_attempts = CASE WHEN excluded.embedding_blob IS NOT NULL THEN 0 ELSE embedding_attempts END,
|
|
807
|
-
okf_type = excluded.okf_type
|
|
844
|
+
okf_type = excluded.okf_type
|
|
845
|
+
WHERE ${this.prefix}entries.entity_id = excluded.entity_id`,
|
|
808
846
|
[
|
|
809
847
|
fact.id,
|
|
810
848
|
fact.entity_id,
|
|
@@ -836,6 +874,18 @@ var EntryRepository = class extends BaseRepository {
|
|
|
836
874
|
fact.okf_usage_window ? JSON.stringify(fact.okf_usage_window) : null
|
|
837
875
|
]
|
|
838
876
|
);
|
|
877
|
+
if (result.changes === 0) {
|
|
878
|
+
const stored = await tx.getFirstAsync(
|
|
879
|
+
`SELECT entity_id FROM ${this.prefix}entries WHERE id = ?`,
|
|
880
|
+
[fact.id]
|
|
881
|
+
);
|
|
882
|
+
if (!stored) {
|
|
883
|
+
throw new Error("Entry upsert reported no change and stored no row; the SQLiteAdapter did not perform the write");
|
|
884
|
+
}
|
|
885
|
+
if (stored.entity_id !== fact.entity_id) {
|
|
886
|
+
throw new WikiGraphNodeOwnershipConflict();
|
|
887
|
+
}
|
|
888
|
+
}
|
|
839
889
|
const persistedOkf = existingRow ? {
|
|
840
890
|
lifecycle_status: existingRow.lifecycle_status ?? "stable",
|
|
841
891
|
stale_after: existingRow.stale_after != null ? Number(existingRow.stale_after) : null,
|
|
@@ -4510,6 +4560,36 @@ var IngestionService = class {
|
|
|
4510
4560
|
releaseIngestLocks();
|
|
4511
4561
|
}
|
|
4512
4562
|
}
|
|
4563
|
+
/**
|
|
4564
|
+
* Reject the whole write when any incoming node ID is already owned by a
|
|
4565
|
+
* different entity. Runs entirely inside the supplied `tx`, through the
|
|
4566
|
+
* repository abstraction, and — being the first thing `upsertGraphCore`
|
|
4567
|
+
* does — before ontology resolution, which can itself persist a configured
|
|
4568
|
+
* seed manifest.
|
|
4569
|
+
*
|
|
4570
|
+
* The lookup has no deleted-row filter, so a soft-deleted foreign row keeps
|
|
4571
|
+
* its ID reserved. Only the lookup IDs are deduplicated; `params.nodes` and
|
|
4572
|
+
* the later write loops keep their ordering and counts.
|
|
4573
|
+
*
|
|
4574
|
+
* The error is deliberately contextless — see WikiGraphNodeOwnershipConflict.
|
|
4575
|
+
*
|
|
4576
|
+
* @param entityId - the entity the caller is writing on behalf of. Foreign
|
|
4577
|
+
* rows under a different entity trigger the rejection.
|
|
4578
|
+
* @param nodes - incoming node set; only the IDs are inspected, so callers
|
|
4579
|
+
* may pass the public `params.nodes` shape directly without slicing.
|
|
4580
|
+
* @param tx - the open transaction. Reuses the same handle every later
|
|
4581
|
+
* statement in `upsertGraphCore` runs against, so atomicity is enforced
|
|
4582
|
+
* by the host transaction's commit/rollback, not by this method.
|
|
4583
|
+
*/
|
|
4584
|
+
async assertGraphNodeOwnership(entityId, nodes, tx) {
|
|
4585
|
+
const ids = [...new Set(nodes.map((node) => node.id))];
|
|
4586
|
+
const existing = await this.entryRepo.findExistingMetadataByIds(ids, tx);
|
|
4587
|
+
for (const row of existing) {
|
|
4588
|
+
if (row.entity_id !== entityId) {
|
|
4589
|
+
throw new WikiGraphNodeOwnershipConflict();
|
|
4590
|
+
}
|
|
4591
|
+
}
|
|
4592
|
+
}
|
|
4513
4593
|
/**
|
|
4514
4594
|
* Implements spec §2 data flow steps a–j with the host-facing
|
|
4515
4595
|
* `{sourceRef, sourceHash, nodes, edges}` parameter shape. Shared between
|
|
@@ -4528,8 +4608,19 @@ var IngestionService = class {
|
|
|
4528
4608
|
* @returns Counts: nodesWritten (validated nodes persisted), edgesWritten
|
|
4529
4609
|
* (manifest-valid edges persisted), superseded (prior facts soft-deleted
|
|
4530
4610
|
* plus prior source-ref edges hard-deleted).
|
|
4611
|
+
*
|
|
4612
|
+
* Node-ownership pre-flight (spec §3, REQ-GRAPH-01): the first statement
|
|
4613
|
+
* is `assertGraphNodeOwnership(entityId, params.nodes, tx)`, which runs
|
|
4614
|
+
* before ontology resolution, seed-manifest persistence, and every other
|
|
4615
|
+
* write. A foreign-owned ID throws `WikiGraphNodeOwnershipConflict` with
|
|
4616
|
+
* no disclosed owner, node ID, or content; the caller's transaction
|
|
4617
|
+
* remains open and must be rolled back by the host. Soft-deleted foreign
|
|
4618
|
+
* rows keep their IDs reserved. Duplicate incoming IDs are deduplicated
|
|
4619
|
+
* only for the lookup; `params.nodes` and the write loops keep their
|
|
4620
|
+
* ordering and counts so success counts match the pre-change contract.
|
|
4531
4621
|
*/
|
|
4532
4622
|
async upsertGraphCore(entityId, params, tx, opts) {
|
|
4623
|
+
await this.assertGraphNodeOwnership(entityId, params.nodes, tx);
|
|
4533
4624
|
const now = Date.now();
|
|
4534
4625
|
const ontologyState = await this.ontologyService?.getEffectiveState(entityId, tx) ?? { mode: "off", manifest: { node_types: [], edge_types: [] } };
|
|
4535
4626
|
let { mode, manifest } = ontologyState;
|
|
@@ -7975,6 +8066,11 @@ var WikiMemory = class {
|
|
|
7975
8066
|
return this.maintenanceService.forget(entityId, params, opts);
|
|
7976
8067
|
}
|
|
7977
8068
|
/**
|
|
8069
|
+
* Full and partial ingestion both reject foreign-owned generated fact IDs with
|
|
8070
|
+
* `WikiGraphNodeOwnershipConflict`. Such collisions are unexpected. Ingestion
|
|
8071
|
+
* may already have persisted ontology or other state before rejection; unlike
|
|
8072
|
+
* direct graph preflight, it relies on transaction rollback for atomicity.
|
|
8073
|
+
*
|
|
7978
8074
|
* @param params.promptOverride - Overrides the system prompt for this ingest call only.
|
|
7979
8075
|
* For persistent customization, set `options.config.prompts.ingestSystemPrompt` at
|
|
7980
8076
|
* WikiMemory construction time.
|
|
@@ -8006,6 +8102,19 @@ var WikiMemory = class {
|
|
|
8006
8102
|
* or edge `type` throws `WikiStrictOntologyViolation` (pre-flight,
|
|
8007
8103
|
* all-or-nothing — NONE written on failure).
|
|
8008
8104
|
*
|
|
8105
|
+
* Entry IDs share one database-wide namespace. Existing rows, including
|
|
8106
|
+
* soft-deleted rows, reserve their IDs for their entity; same-entity updates
|
|
8107
|
+
* and resurrection remain supported. Hosts authenticate callers and select
|
|
8108
|
+
* the authorized entity ID; entity-qualified IDs are optional, not required.
|
|
8109
|
+
* After the live-only C2 probe above, a foreign node ID throws the fixed,
|
|
8110
|
+
* privacy-preserving `WikiGraphNodeOwnershipConflict` before persistent writes
|
|
8111
|
+
* (including seed manifests). Deleted source mappings do not trigger C2.
|
|
8112
|
+
*
|
|
8113
|
+
* Propagate later failures to roll back the host transaction. In particular,
|
|
8114
|
+
* foreign edge-ID collisions remain late bare `Error`s: the foreign edge is
|
|
8115
|
+
* not overwritten, but catching and committing can retain earlier writes.
|
|
8116
|
+
* This method neither commits nor rolls back the caller's transaction.
|
|
8117
|
+
*
|
|
8009
8118
|
* @returns Counts: nodesWritten (validated nodes persisted), edgesWritten
|
|
8010
8119
|
* (manifest-valid edges persisted), superseded (prior facts soft-deleted
|
|
8011
8120
|
* plus prior source-ref edges hard-deleted).
|
|
@@ -9100,6 +9209,7 @@ exports.PromptService = PromptService;
|
|
|
9100
9209
|
exports.PrunePartialFailureError = PrunePartialFailureError;
|
|
9101
9210
|
exports.WikiBusyError = WikiBusyError;
|
|
9102
9211
|
exports.WikiDuplicateHashError = WikiDuplicateHashError;
|
|
9212
|
+
exports.WikiGraphNodeOwnershipConflict = WikiGraphNodeOwnershipConflict;
|
|
9103
9213
|
exports.WikiIngestEmptyError = WikiIngestEmptyError;
|
|
9104
9214
|
exports.WikiInvalidReadOptions = WikiInvalidReadOptions;
|
|
9105
9215
|
exports.WikiMemory = WikiMemory;
|