@equationalapplications/core-llm-wiki 4.5.0 → 4.5.1
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 +27 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,7 +9,9 @@ Pure TypeScript business logic for LLM Wiki Memory.
|
|
|
9
9
|
- **Platform-agnostic** — Zero runtime dependencies; works with any SQLite driver via the `SQLiteAdapter` interface
|
|
10
10
|
- **Semantic search** — Vector embeddings via your LLM's `embed` function, ranked by cosine similarity
|
|
11
11
|
- **Keyword fallback** — MiniSearch in-memory index for offline/degraded scenarios when embeddings unavailable
|
|
12
|
-
- **Retrieval tuning** — Per-call overrides for `maxResults`, `preFilterLimit`, and `
|
|
12
|
+
- **Retrieval tuning** — Per-call overrides for `maxResults`, `preFilterLimit`, `hybridWeight`, `tierWeights`, and `includeZeroWeightEntities`
|
|
13
|
+
- **Multi-entity reads** — Search across multiple `entity_id` namespaces in one pass with per-entity score multipliers (`tierWeights`); optional `factScores` and `metadata` for explainability
|
|
14
|
+
- **Immutable vs mutable facts** — Use `WikiFact.source_type` to distinguish document-sourced facts (`immutable_document`) from derived or user-provided facts (`librarian_inferred`, `user_stated`, `user_confirmed`). Immutable document facts are not rewritten by `runLibrarian()` or `runHeal()` and can only be removed by `forget()` or re-ingesting.
|
|
13
15
|
- **Full-featured memory** — Facts, tasks, events, maintenance jobs (librarian, heal, reembed, prune)
|
|
14
16
|
- **Type-safe** — Built with TypeScript, full type exports
|
|
15
17
|
|
|
@@ -121,6 +123,19 @@ const memory = await wikiMemory.read('user-123', 'my preferences', {
|
|
|
121
123
|
preFilterLimit: 20,
|
|
122
124
|
hybridWeight: 0.5,
|
|
123
125
|
});
|
|
126
|
+
|
|
127
|
+
// Multi-entity with tier weights
|
|
128
|
+
const multiMemory = await wikiMemory.read(['tier_wisdom', 'tier_fact', 'tier_working'], 'my preferences', {
|
|
129
|
+
maxResults: 8,
|
|
130
|
+
tierWeights: {
|
|
131
|
+
tier_wisdom: 2, // high-confidence curated notes boosted 2×
|
|
132
|
+
tier_fact: 1, // neutral baseline
|
|
133
|
+
tier_working: 0.25, // recent but unvetted context downranked
|
|
134
|
+
},
|
|
135
|
+
// includeZeroWeightEntities: true — include 0-weight entities as bottom-ranked filler
|
|
136
|
+
});
|
|
137
|
+
// multiMemory.factScores — optional Record<factId, weightedScore> for returned facts; may be absent/undefined
|
|
138
|
+
// multiMemory.metadata — optional { query, entityIds, tierWeights }; may be absent/undefined
|
|
124
139
|
```
|
|
125
140
|
|
|
126
141
|
**Hybrid scoring blends:**
|
|
@@ -130,6 +145,15 @@ const memory = await wikiMemory.read('user-123', 'my preferences', {
|
|
|
130
145
|
|
|
131
146
|
True cosine-range pure semantic ranking (including negative cosine values) is used when `hybridWeight` is left `undefined`.
|
|
132
147
|
|
|
148
|
+
**Tier weights:**
|
|
149
|
+
- `tierWeights` applies a per-entity multiplier after semantic/keyword scoring: `finalScore = retrievalScore × weight`
|
|
150
|
+
- Missing weights default to `1.0`. Negative weights clamp to `0`. Non-finite weights default to `1.0`.
|
|
151
|
+
- `tierWeights[entity] = 0` skips that entity's scored retrieval branch (no compute cost).
|
|
152
|
+
- `includeZeroWeightEntities: true` includes zero-weight entities as bottom-ranked filler instead of skipping them.
|
|
153
|
+
- `factScores` is present for array-shaped `entityId` calls only when the query is non-empty and at least one fact is scored; empty-query ("recent facts") reads leave it absent even when `entityId` is an array. Plain string calls never expose it. `metadata` is present for all array-shaped calls regardless of query.
|
|
154
|
+
- `maxResults` applies globally across all requested entities.
|
|
155
|
+
- Tasks are capped at `min(20 × entityCount, 200)`; events at `min(10 × entityCount, 100)` for multi-entity reads.
|
|
156
|
+
|
|
133
157
|
**Pre-filtering optimization:**
|
|
134
158
|
When `preFilterLimit: 50` is set with 1000 facts, cosine similarity is computed only for the top 50 MiniSearch keyword matches, reducing O(N) scoring to O(50).
|
|
135
159
|
|
|
@@ -418,7 +442,7 @@ console.log(memory.factScores);
|
|
|
418
442
|
|
|
419
443
|
### Librarian prompt override contract
|
|
420
444
|
|
|
421
|
-
Core
|
|
445
|
+
Core exports prompt utilities for weighted retrieval-based synthesis. Use `mapLibrarianOptionsToReadOptions()` to map `entityWeights` to `tierWeights`, then hydrate a prompt with `query`, `context`, and `tasks`.
|
|
422
446
|
|
|
423
447
|
```ts
|
|
424
448
|
import {
|
|
@@ -553,7 +577,7 @@ const adapter: SQLiteAdapter = {
|
|
|
553
577
|
|
|
554
578
|
```mermaid
|
|
555
579
|
flowchart TD
|
|
556
|
-
A["read(entityId, query)"] --> B{hybridWeight = 0?}
|
|
580
|
+
A["read(entityId | entityId[], query, options?)"] --> B{hybridWeight = 0?}
|
|
557
581
|
B -->|Yes| C["MiniSearch only<br/>(skip embed)"]
|
|
558
582
|
B -->|No| D{embed available?}
|
|
559
583
|
D -->|No| C
|