@equationalapplications/core-llm-wiki 4.7.0 → 4.9.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 CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  Pure TypeScript business logic for LLM Wiki Memory.
4
4
 
5
+ [![npm version](https://img.shields.io/npm/v/%40equationalapplications%2Fcore-llm-wiki?label=core)](https://www.npmjs.com/package/@equationalapplications/core-llm-wiki) [![npm downloads](https://img.shields.io/npm/dm/%40equationalapplications%2Fcore-llm-wiki?label=downloads)](https://www.npmjs.com/package/@equationalapplications/core-llm-wiki)
6
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.x-3178C6?logo=typescript&logoColor=white)](https://www.typescriptlang.org/)
7
+ [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
8
+
5
9
  > Inspired by [Andrej Karpathy's LLM Wiki memory spec](https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f).
6
10
 
7
11
  ## Features
@@ -92,10 +96,87 @@ const wikiMemory = new WikiMemory(db, {
92
96
  staleInferredAfterDays: 60, // default: 60 (days before runHeal downgrades inferred facts; null to disable)
93
97
  preFilterLimit: 50, // default: undefined — MiniSearch pre-filter before cosine scan; recommended for >500 facts
94
98
  hybridWeight: 0.7, // default: undefined — blend semantic (1.0) ↔ keyword (0.0); pure semantic when unset
99
+ 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)
100
+
101
+ // Global prompt overrides — librarianSystemPrompt and healSystemPrompt apply to write() auto-runs;
102
+ // ingestSystemPrompt applies only to explicit ingestDocument() calls.
103
+ // ⚠ Overrides replace the entire default prompt, including the JSON output contract.
104
+ // See "JSON Output Contracts" in the Prompt Management & Overrides section below.
105
+ prompts: {
106
+ ingestSystemPrompt: `Extract core facts from this document: {{documentChunk}}\n\nReturn ONLY valid JSON: { "facts": [{ "title": "string", "body": "string", "tags": ["string"], "confidence": "certain|inferred|tentative" }] }. No markdown.`,
107
+ librarianSystemPrompt: `You are an expert curator. Synthesize these thoughts:\n{{events}}\n\nCurrent Facts:\n{{currentFacts}}\n\nReturn ONLY valid JSON: { "facts": [{ "title": "string", "body": "string", "tags": ["string"], "confidence": "certain|inferred|tentative" }], "tasks": [{ "description": "string", "priority": 0 }] }. No markdown.`,
108
+ 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.`,
109
+ },
110
+ },
111
+ });
112
+ ```
113
+
114
+ ## Prompt Management & Overrides
115
+
116
+ Core maintenance tasks (`ingestDocument`, `runLibrarian`, `runHeal`) use system prompts to instruct the LLM. You can customize these prompts using `{{mustache}}` style variables to inject context dynamically.
117
+
118
+ > **JSON Output Contracts:** Prompt overrides replace the *entire* default system prompt, including the JSON response schema the parser depends on. Your override **must** instruct the LLM to return raw JSON — no markdown. Required shapes:
119
+ >
120
+ > | Operation | Required JSON shape |
121
+ > |-----------|-------------------|
122
+ > | `ingestDocument` | `{ "facts": [{ "title": "string", "body": "string", "tags": ["string"], "confidence": "certain\|inferred\|tentative" }] }` |
123
+ > | `runLibrarian` | `{ "facts": [...], "tasks": [{ "description": "string", "priority": 5 }] }` — `priority` is an integer 0–10 |
124
+ > | `runHeal` | `{ "downgraded": ["factId"], "deleted": ["factId"], "newFacts": [...] }` |
125
+
126
+ ### Global Overrides (Auto-Runs)
127
+
128
+ If your application relies on `write()` to automatically maintain the memory graph in the background (via `autoLibrarianThreshold` and `autoHealThreshold`), configure custom prompts globally at instantiation. This ensures the internal `WriteService` uses your domain-specific instructions when it triggers an auto-run.
129
+
130
+ ```typescript
131
+ const wikiMemory = new WikiMemory(db, {
132
+ llmProvider,
133
+ config: {
134
+ prompts: {
135
+ // Override must include the JSON output contract — it replaces the entire default prompt.
136
+ librarianSystemPrompt: `You are an expert curator. Synthesize these thoughts:\n{{events}}\n\nCurrent Facts:\n{{currentFacts}}\n\nReturn ONLY a valid JSON object: { "facts": [{ "title": "string", "body": "string", "tags": ["string"], "confidence": "certain|inferred|tentative" }], "tasks": [{ "description": "string", "priority": 0 }] }. No markdown.`,
137
+ },
95
138
  },
96
139
  });
140
+
141
+ // WriteService uses the global prompt whenever autoLibrarianThreshold is hit
142
+ await wikiMemory.write('user-123', { event_type: 'observation', summary: '...' });
97
143
  ```
98
144
 
145
+ Available `{{variables}}` per prompt type:
146
+
147
+ | Prompt | Variables |
148
+ |--------|-----------|
149
+ | `ingestSystemPrompt` | `{{documentChunk}}` |
150
+ | `librarianSystemPrompt` | `{{events}}`, `{{currentFacts}}` |
151
+ | `healSystemPrompt` | `{{healCandidates}}`, `{{documentAnchors}}`, `{{allTasks}}`, `{{recentEvents}}` |
152
+
153
+ When a template contains `{{variable}}` tags, the matching data is hydrated directly into `systemPrompt` and a short fixed string is used as `userPrompt`. When a template has no `{{}}` tags, the raw data is appended as `userPrompt` — backward compatible with plain-string overrides.
154
+
155
+ ### Runtime Overrides (Manual Execution)
156
+
157
+ Pass `promptOverride` per-call for one-off instructions. **Runtime overrides apply only to that single call — they do not persist for future auto-runs triggered by `write()`.**
158
+
159
+ ```typescript
160
+ // Override the base default AND global config for this single execution.
161
+ // Each override must include the JSON output contract (replaces the entire default prompt).
162
+ await wikiMemory.runLibrarian('user-123', {
163
+ promptOverride: `One-off extraction task:\n{{events}}\n\nReturn ONLY valid JSON: { "facts": [{ "title": "string", "body": "string", "tags": ["string"], "confidence": "certain|inferred|tentative" }], "tasks": [{ "description": "string", "priority": 0 }] }. No markdown.`,
164
+ });
165
+
166
+ await wikiMemory.runHeal('user-123', {
167
+ promptOverride: `Domain-specific healing: {{healCandidates}}\n\nReturn ONLY valid JSON: { "downgraded": ["factId"], "deleted": ["factId"], "newFacts": [{ "title": "string", "body": "string", "tags": ["string"], "confidence": "certain|inferred|tentative" }] }. No markdown.`,
168
+ });
169
+
170
+ await wikiMemory.ingestDocument('user-123', {
171
+ sourceRef: 'doc-1',
172
+ sourceHash: sha256(content),
173
+ documentChunk: content,
174
+ promptOverride: `Strict technical extraction: {{documentChunk}}\n\nReturn ONLY valid JSON: { "facts": [{ "title": "string", "body": "string", "tags": ["string"], "confidence": "certain|inferred|tentative" }] }. No markdown.`,
175
+ });
176
+ ```
177
+
178
+ > **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.
179
+
99
180
  ## Retrieval Tuning
100
181
 
101
182
  Optimize `read()` performance and blend retrieval strategies: