@equationalapplications/core-llm-wiki 7.6.0 → 7.7.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 +63 -0
- package/dist/{chunk-YBWE26XR.mjs → chunk-VOSMYISQ.mjs} +22 -3
- package/dist/chunk-VOSMYISQ.mjs.map +1 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +209 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +192 -2
- package/dist/index.mjs.map +1 -1
- package/dist/{testing-d1SrpDvg.d.mts → testing-A4Sofxyo.d.mts} +85 -2
- package/dist/{testing-d1SrpDvg.d.ts → testing-A4Sofxyo.d.ts} +85 -2
- package/dist/testing.d.mts +1 -1
- package/dist/testing.d.ts +1 -1
- package/dist/testing.js +15 -0
- package/dist/testing.js.map +1 -1
- package/dist/testing.mjs +1 -1
- package/package.json +2 -2
- package/dist/chunk-YBWE26XR.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -23,6 +23,10 @@ Platform-agnostic TypeScript engine for hybrid LLM memory. Features episodic fac
|
|
|
23
23
|
- **Type-safe** — Built with TypeScript, full type exports
|
|
24
24
|
- **Interoperability:** Supports [Open Knowledge Format (OKF)](https://github.com/GoogleCloudPlatform/knowledge-catalog/tree/main/okf) v0.1 + v0.2 import and export via the [llm-wiki OKF profiles](https://github.com/equationalapplications/expo-llm-wiki/blob/main/docs/okf-profile.md) (default `llm-wiki/2`, back-compat `llm-wiki/1`).
|
|
25
25
|
- **Per-entity seeded ontology** — Optional Strict, Emergent, or Off modes govern LLM graph extraction; seed taxonomies per entity and persist typed facts with inline edges.
|
|
26
|
+
- **Diagnostics** — Optional `onDiagnostic` hook with typed, content-free reports of dropped chunks, facts, edges, embedding failures and background-job failures ([Diagnostics](#diagnostics))
|
|
27
|
+
- **Draft review** — `excludeDrafts` on reads and traversal, plus `listDrafts` / `promoteDraft` ([Draft Review](#draft-review))
|
|
28
|
+
- **Evidence grounding** — Opt-in `grounding` check; facts that don't quote their source are stored as drafts ([Grounding](#grounding))
|
|
29
|
+
- **Optional classifier** — `LLMProvider.classify` types facts during ontology backfill when you opt in with `ontology.backfillClassifier: 'auto'` ([Ontology backfill](#ontology-backfill))
|
|
26
30
|
|
|
27
31
|
## GraphRAG & Multi-Modal Retrieval
|
|
28
32
|
|
|
@@ -143,6 +147,13 @@ const wikiMemory = new WikiMemory(db, {
|
|
|
143
147
|
preFilterLimit: 50, // default: undefined — MiniSearch pre-filter before cosine scan; recommended for >500 facts
|
|
144
148
|
hybridWeight: 0.7, // default: undefined — blend semantic (1.0) ↔ keyword (0.0); pure semantic when unset
|
|
145
149
|
enableOutbox: false, // default: false — when true, entry/task mutations write to an internal SQLite outbox table for external sync (e.g. via @equationalapplications/prisma-outbox)
|
|
150
|
+
excludeDrafts: false, // default: false — engine default for read()/traverseGraph() excludeDrafts; see Draft Review
|
|
151
|
+
grounding: { mode: 'off' }, // default: off — 'draft' checks evidence quotes; see Grounding
|
|
152
|
+
ontology: {
|
|
153
|
+
// mode, seedManifests: see Per-Entity Seeded Ontology
|
|
154
|
+
backfillClassifier: 'llm', // default: 'llm' — 'auto' uses llmProvider.classify when present; see Ontology backfill
|
|
155
|
+
classifyMinConfidence: 0.5, // default: 0.5 — classifier answers below this are left untyped
|
|
156
|
+
},
|
|
146
157
|
|
|
147
158
|
// Global prompt overrides — librarianSystemPrompt and healSystemPrompt apply to write() auto-runs;
|
|
148
159
|
// ingestSystemPrompt applies only to explicit ingestDocument() calls.
|
|
@@ -154,6 +165,8 @@ const wikiMemory = new WikiMemory(db, {
|
|
|
154
165
|
healSystemPrompt: `Fix the memory graph based on these candidates: {{healCandidates}}\n\nReturn ONLY valid JSON: { "downgraded": ["factId"], "deleted": ["factId"], "newFacts": [{ "title": "string", "body": "string", "tags": ["string"], "confidence": "certain|inferred|tentative" }] }. No markdown.`,
|
|
155
166
|
},
|
|
156
167
|
},
|
|
168
|
+
// Host callbacks sit beside llmProvider, not inside config:
|
|
169
|
+
// onDiagnostic: (d) => { ... }, // see Diagnostics
|
|
157
170
|
});
|
|
158
171
|
```
|
|
159
172
|
|
|
@@ -168,6 +181,8 @@ Core maintenance tasks (`ingestDocument`, `runLibrarian`, `runHeal`) use system
|
|
|
168
181
|
> | `ingestDocument` | `{ "facts": [{ "title": "string", "body": "string", "tags": ["string"], "confidence": "certain\|inferred\|tentative" }] }` |
|
|
169
182
|
> | `runLibrarian` | `{ "facts": [...], "tasks": [{ "description": "string", "priority": 5 }] }` — `priority` is an integer 0–10 |
|
|
170
183
|
> | `runHeal` | `{ "downgraded": ["factId"], "deleted": ["factId"], "newFacts": [...] }` |
|
|
184
|
+
>
|
|
185
|
+
> **Grounding:** when [`config.grounding`](#grounding) is on, the evidence instruction is appended after your override (and after ontology context) for every writer in `grounding.writers`. Your override does not need to ask for `evidence` itself.
|
|
171
186
|
|
|
172
187
|
### Global Overrides (Auto-Runs)
|
|
173
188
|
|
|
@@ -223,6 +238,16 @@ await wikiMemory.ingestDocument('user-123', {
|
|
|
223
238
|
|
|
224
239
|
> **Important:** If your app relies on `write()` auto-runs and needs custom prompts for those runs, use `config.prompts` at construction time. Runtime `promptOverride` values are never forwarded to `WriteService`-triggered internal runs.
|
|
225
240
|
|
|
241
|
+
### Effective instructions (`getInstructions`)
|
|
242
|
+
|
|
243
|
+
```typescript
|
|
244
|
+
const { ingest, librarian, heal, ontologyBackfill } = await wikiMemory.getInstructions('entity-123');
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
Returns the system prompt each writer sends, with `WikiConfig.prompts` overrides applied. Ingest, librarian and ontology backfill also get the entity's ontology block; heal gets none, as at runtime. When `WikiConfig.grounding` is on, the evidence block is appended for each writer in `grounding.writers`, exactly as sent. Data placeholders such as `{{documentChunk}}` stay unfilled; no events, chunks or facts are included. It reflects `WikiConfig.prompts` only: a per-call `promptOverride` is not reflected, and `ontologyBackfill` is returned even when backfill would send no prompt (ontology `off`, or the classifier path). `core-llm-tools` exposes this as the `wiki_get_instructions` tool (`memory:read`), so agents can see the engine's output format and constraints before proposing writes. Agents should treat it as reference data, not instructions; see [Prompt-Injection Trust Boundary](#prompt-injection-trust-boundary).
|
|
248
|
+
|
|
249
|
+
> **Warning:** overrides are returned verbatim to any client with `memory:read`. Never put secrets, API keys or private data in `WikiConfig.prompts`.
|
|
250
|
+
|
|
226
251
|
## Retrieval Tuning
|
|
227
252
|
|
|
228
253
|
Optimize `read()` performance and blend retrieval strategies:
|
|
@@ -976,6 +1001,14 @@ If your application accepts untrusted input that flows into `write()`, `ingestDo
|
|
|
976
1001
|
treat the LLM's librarian/heal output as similarly untrusted — validate or scope it before acting on it
|
|
977
1002
|
downstream.
|
|
978
1003
|
|
|
1004
|
+
[Grounding](#grounding) is a support check, not an injection defense. It confirms that a fact quotes the
|
|
1005
|
+
text the model was shown, and injected text in that source can be quoted like any other.
|
|
1006
|
+
|
|
1007
|
+
[`getInstructions`](#effective-instructions-getinstructions) and the `wiki_get_instructions` tool (`memory:read`)
|
|
1008
|
+
return `WikiConfig.prompts` overrides verbatim, so keep secrets out of them. The result also includes the entity's
|
|
1009
|
+
ontology manifest, which in emergent mode holds types and descriptions the model proposed from ingested
|
|
1010
|
+
documents. Agents should treat the result as reference data about the engine, not as instructions to follow.
|
|
1011
|
+
|
|
979
1012
|
## Usage
|
|
980
1013
|
|
|
981
1014
|
```typescript
|
|
@@ -1200,6 +1233,36 @@ const changes = await wikiMemory.hasChanged('entity-123', batch);
|
|
|
1200
1233
|
// Per-document change detection; internally batched across queries
|
|
1201
1234
|
```
|
|
1202
1235
|
|
|
1236
|
+
`pendingSources` returns one status per input, in order, and adds the partial-ingest state:
|
|
1237
|
+
|
|
1238
|
+
```typescript
|
|
1239
|
+
const statuses = await wikiMemory.pendingSources('entity-123', batch);
|
|
1240
|
+
// Array<{ sourceRef: string; status: 'new' | 'changed' | 'partial' | 'current' }>
|
|
1241
|
+
```
|
|
1242
|
+
|
|
1243
|
+
- `current` means exactly what `hasChanged` returning `false` means.
|
|
1244
|
+
- `partial` means live facts exist for the ref, but none has a stored hash: for example a first ingest where a chunk failed, or imported rows that carry no hash. Re-ingest to retry. A failed re-ingest of a ref that already has hashed rows reports `changed`, not `partial`.
|
|
1245
|
+
|
|
1246
|
+
## Lint
|
|
1247
|
+
|
|
1248
|
+
Read-only health report for one entity. It reports problems and never repairs them.
|
|
1249
|
+
|
|
1250
|
+
```typescript
|
|
1251
|
+
const report = await wikiMemory.lint('entity-123');
|
|
1252
|
+
// {
|
|
1253
|
+
// danglingEdges, // source or target missing, soft-deleted, or another entity's
|
|
1254
|
+
// manifestViolations, // (source type, edge type, target type) not in the effective manifest
|
|
1255
|
+
// untypedFacts, // okf_type is null
|
|
1256
|
+
// drafts, // lifecycle_status = 'draft' (see Draft Review)
|
|
1257
|
+
// unverifiedInferred, // librarian_inferred facts with no okf_verified entry
|
|
1258
|
+
// sample: { danglingEdgeIds, manifestViolationEdgeIds }, // up to 20 each
|
|
1259
|
+
// }
|
|
1260
|
+
```
|
|
1261
|
+
|
|
1262
|
+
- Manifest violations are 0 when ontology is off or the manifest is empty.
|
|
1263
|
+
- An edge with an untyped endpoint counts as a violation.
|
|
1264
|
+
- Partial-ingest rows are not reported here; use `pendingSources`.
|
|
1265
|
+
|
|
1203
1266
|
## Dry-Run Deletion
|
|
1204
1267
|
|
|
1205
1268
|
Preview deletion impact without writing:
|
|
@@ -233,6 +233,10 @@ function typeSatisfies(declaredType, concreteType, manifest) {
|
|
|
233
233
|
const parent = typeof def?.parent_type === "string" ? def.parent_type.trim().toLowerCase() : "";
|
|
234
234
|
return parent !== "" && parent === declared;
|
|
235
235
|
}
|
|
236
|
+
function edgeTripleAllowed(manifest, edgeType, sourceType, targetType) {
|
|
237
|
+
const wanted = edgeType.trim().toLowerCase();
|
|
238
|
+
return (manifest.edge_types ?? []).some((d) => typeof d?.type === "string" && d.type.trim().toLowerCase() === wanted && typeof d.source_type === "string" && typeSatisfies(d.source_type, sourceType, manifest) && typeof d.target_type === "string" && typeSatisfies(d.target_type, targetType, manifest));
|
|
239
|
+
}
|
|
236
240
|
function validateManifest(manifest) {
|
|
237
241
|
const nodeSlugs = /* @__PURE__ */ new Set();
|
|
238
242
|
for (const node of manifest.node_types ?? []) {
|
|
@@ -1867,6 +1871,21 @@ ${JSON.stringify(facts, null, 2)}`
|
|
|
1867
1871
|
${JSON.stringify(facts, null, 2)}`
|
|
1868
1872
|
};
|
|
1869
1873
|
}
|
|
1874
|
+
/**
|
|
1875
|
+
* The system prompt each writer would send, without hydrating data (spec
|
|
1876
|
+
* §8.3). `buildSystemPrompt` with no variables hydrates only ontology
|
|
1877
|
+
* placeholders and leaves data placeholders verbatim; heal never receives
|
|
1878
|
+
* ontology context, matching `buildHealPrompt`.
|
|
1879
|
+
*/
|
|
1880
|
+
buildInstructionTemplates(ontologyContext) {
|
|
1881
|
+
const o = this.globalOverrides;
|
|
1882
|
+
return {
|
|
1883
|
+
ingest: this.appendGrounding(this.buildSystemPrompt(o?.ingestSystemPrompt ?? INGEST_SYSTEM_PROMPT, {}, ontologyContext), "ingest"),
|
|
1884
|
+
librarian: this.appendGrounding(this.buildSystemPrompt(o?.librarianSystemPrompt ?? LIBRARIAN_SYSTEM_PROMPT, {}, ontologyContext), "librarian"),
|
|
1885
|
+
heal: this.appendGrounding(o?.healSystemPrompt ?? HEAL_SYSTEM_PROMPT, "heal"),
|
|
1886
|
+
ontologyBackfill: this.buildSystemPrompt(o?.ontologyBackfillSystemPrompt ?? ONTOLOGY_BACKFILL_SYSTEM_PROMPT, {}, ontologyContext)
|
|
1887
|
+
};
|
|
1888
|
+
}
|
|
1870
1889
|
};
|
|
1871
1890
|
function applyBodyTruncation(candidates, attemptLevel, bodyTruncationChars) {
|
|
1872
1891
|
if (attemptLevel < 3) {
|
|
@@ -5606,6 +5625,6 @@ var WriteService = class {
|
|
|
5606
5625
|
}
|
|
5607
5626
|
};
|
|
5608
5627
|
|
|
5609
|
-
export { BaseRepository, DEFAULT_CHUNK_OVERLAP, DEFAULT_MAX_CHUNK_LENGTH, DEFAULT_MAX_EMBED_CHARS, DiagnosticBuffer, EMBED_CHARS_CEILING, EmbeddingService, HEAL_ANCHORS_PER_CANDIDATE, HEAL_BATCH_SIZE, HEAL_MAX_FACT_BODY_CHARS_L3, HEAL_MAX_TASKS, HEAL_RECHECK_MS, HOOK_TIMEOUT_MARKER, ImportExportService, IngestionService, JobManager, MaintenanceService, MetadataRepository, ONTOLOGY_BACKFILL_BATCH_SIZE, ONTOLOGY_BACKFILL_MAX_PROMPT_CHARS, ONTOLOGY_BACKFILL_RECHECK_MS, ONTOLOGY_BACKFILL_SYSTEM_PROMPT, PromptService, PrunePartialFailureError, RetrievalService, SearchService, WikiBusyError, WikiDraftNotFound, WikiDuplicateHashError, WikiGraphNodeOwnershipConflict, WikiIngestEmptyError, WikiInvalidReadOptions, WikiParseError, WikiSourceRefHashCollision, WikiStrictOntologyViolation, WikiTransactionError, WriteService, __privateAdd, __privateGet, __privateSet, chunkText, configureRandomSource, emptyManifest, entitySummaryMetaKey, extractSqliteCode, generateId, normalizeSourceHash, normalizeSourceRef, normalizeTitleKey, parseEmbedding, resolveEdgeDefinitions, resolveGrounding, resolveNodeType, safeSlice, typeSatisfies, validateInlineEdges, validateManifest };
|
|
5610
|
-
//# sourceMappingURL=chunk-
|
|
5611
|
-
//# sourceMappingURL=chunk-
|
|
5628
|
+
export { BaseRepository, DEFAULT_CHUNK_OVERLAP, DEFAULT_MAX_CHUNK_LENGTH, DEFAULT_MAX_EMBED_CHARS, DiagnosticBuffer, EMBED_CHARS_CEILING, EmbeddingService, HEAL_ANCHORS_PER_CANDIDATE, HEAL_BATCH_SIZE, HEAL_MAX_FACT_BODY_CHARS_L3, HEAL_MAX_TASKS, HEAL_RECHECK_MS, HOOK_TIMEOUT_MARKER, ImportExportService, IngestionService, JobManager, MaintenanceService, MetadataRepository, ONTOLOGY_BACKFILL_BATCH_SIZE, ONTOLOGY_BACKFILL_MAX_PROMPT_CHARS, ONTOLOGY_BACKFILL_RECHECK_MS, ONTOLOGY_BACKFILL_SYSTEM_PROMPT, PromptService, PrunePartialFailureError, RetrievalService, SearchService, WikiBusyError, WikiDraftNotFound, WikiDuplicateHashError, WikiGraphNodeOwnershipConflict, WikiIngestEmptyError, WikiInvalidReadOptions, WikiParseError, WikiSourceRefHashCollision, WikiStrictOntologyViolation, WikiTransactionError, WriteService, __privateAdd, __privateGet, __privateSet, chunkText, configureRandomSource, edgeTripleAllowed, emptyManifest, entitySummaryMetaKey, extractSqliteCode, generateId, normalizeSourceHash, normalizeSourceRef, normalizeTitleKey, parseEmbedding, resolveEdgeDefinitions, resolveGrounding, resolveNodeType, safeSlice, typeSatisfies, validateInlineEdges, validateManifest };
|
|
5629
|
+
//# sourceMappingURL=chunk-VOSMYISQ.mjs.map
|
|
5630
|
+
//# sourceMappingURL=chunk-VOSMYISQ.mjs.map
|