@equationalapplications/expo-llm-wiki 0.0.0-development

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Equational Applications
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,259 @@
1
+ # expo-llm-wiki
2
+
3
+ Offline-first, SQLite-backed memory for LLM apps built with Expo. Handles FTS5 search, episodic event logging, background fact extraction, and memory healing — bring your own LLM.
4
+
5
+ ## Key Principles
6
+
7
+ - **Bring Your Own Inference (BYOI):** Provide one `generateText` function. The package owns prompt construction, JSON parsing, and database writes.
8
+ - **Namespace Safe:** All tables are prefixed (default: `llm_wiki_`) — no collisions with your existing database.
9
+ - **Multi-Entity:** Multiple independent "brains" in one database via `entityId`.
10
+ - **Offline First:** Reads are fully local via SQLite FTS5, typically under 50ms.
11
+ - **Full Unicode Support:** UTF-8 and UTF-16 (including surrogate pairs for emoji) are fully supported. Chunks are split safely at sentence boundaries; surrogate pairs are never fragmented.
12
+
13
+ ## How It Works
14
+
15
+ ```mermaid
16
+ flowchart LR
17
+ subgraph API
18
+ direction TB
19
+ write["write(event)"]
20
+ ingest["ingestDocument()"]
21
+ librarian["runLibrarian()"]
22
+ heal["runHeal()"]
23
+ end
24
+
25
+ subgraph SQLite
26
+ direction TB
27
+ events[(events)]
28
+ entries[("entries\n(facts)")]
29
+ tasks[(tasks)]
30
+ end
31
+
32
+ LLM["LLMProvider\n.generateText()"]
33
+
34
+ read["read(entityId, query)"]
35
+ FTS5(["FTS5 search"])
36
+ Bundle(["MemoryBundle\nfacts · tasks · events"])
37
+
38
+ write --> events
39
+ events -. "≥ threshold" .-> librarian
40
+ librarian --> LLM
41
+ heal --> LLM
42
+ ingest --> LLM
43
+ LLM --> entries
44
+ LLM --> tasks
45
+
46
+ read --> FTS5
47
+ FTS5 --> entries
48
+ entries --> Bundle
49
+ tasks --> Bundle
50
+ events --> Bundle
51
+ ```
52
+
53
+ ## Installation
54
+
55
+ In your Expo project:
56
+
57
+ ```bash
58
+ npx expo install expo-sqlite
59
+ npm install expo-llm-wiki
60
+ ```
61
+
62
+ Use `npx expo install` for `expo-sqlite` so Expo's version resolver picks the correct native build for your SDK version.
63
+
64
+ ## Setup
65
+
66
+ ```typescript
67
+ import { createWiki } from 'expo-llm-wiki';
68
+ import * as SQLite from 'expo-sqlite';
69
+
70
+ const db = await SQLite.openDatabaseAsync('my-app.db');
71
+
72
+ const wiki = createWiki(db, {
73
+ llmProvider: {
74
+ generateText: async ({ systemPrompt, userPrompt }) => {
75
+ // Connect to OpenAI, Gemini, a local model, etc.
76
+ // Must return a raw string (JSON, optionally in a markdown code fence).
77
+ const response = await openai.chat.completions.create({
78
+ model: 'gpt-4o-mini',
79
+ messages: [
80
+ { role: 'system', content: systemPrompt },
81
+ { role: 'user', content: userPrompt },
82
+ ],
83
+ });
84
+ return response.choices[0].message.content ?? '{}';
85
+ },
86
+ },
87
+ config: {
88
+ tablePrefix: 'llm_wiki_', // optional, default: 'llm_wiki_'
89
+ maxFtsResults: 10, // optional, default: 10
90
+ autoLibrarianThreshold: 20, // optional, default: 20
91
+ maxChunkLength: 6000, // optional, default: 6000 (char count, not bytes)
92
+ },
93
+ });
94
+
95
+ // Create tables and FTS5 indexes (call once on app startup)
96
+ await wiki.setup();
97
+ ```
98
+
99
+ ## Core API
100
+
101
+ ### Read
102
+
103
+ FTS5 full-text search over facts, plus open tasks and recent events:
104
+
105
+ ```typescript
106
+ const { facts, tasks, events } = await wiki.read('entity-123', 'weekend plans');
107
+ // facts: WikiFact[] — matched by FTS5, ranked by confidence + access count
108
+ // tasks: WikiTask[] — pending and in-progress only
109
+ // events: WikiEvent[] — 10 most recent, ascending
110
+ ```
111
+
112
+ Pass an empty string to skip FTS and return the most recently updated facts.
113
+
114
+ ### Write
115
+
116
+ Log an episodic event. Automatically triggers the librarian pass once enough events accumulate:
117
+
118
+ ```typescript
119
+ await wiki.write('entity-123', {
120
+ event_type: 'observation',
121
+ summary: 'User mentioned they love hiking on weekends.',
122
+ });
123
+ // event_type: 'observation' | 'decision' | 'action' | 'outcome'
124
+ ```
125
+
126
+ ### Ingest Document
127
+
128
+ Extract facts from a document (chunked internally). Idempotent — re-calling with the same `sourceRef` replaces the prior extraction. Documents are automatically chunked at sentence boundaries; if a sentence exceeds `maxChunkLength`, it is hard-split.
129
+
130
+ ```typescript
131
+ const result = await wiki.ingestDocument('entity-123', {
132
+ // sourceRef is normalized: only [A-Za-z0-9._\- ] are kept, all other characters
133
+ // (including `/`) are stripped. Use underscores or dots as path separators to
134
+ // avoid accidental collisions (e.g. 'docs_preferences.md' not 'docs/preferences.md').
135
+ sourceRef: 'preferences.md', // stable identifier
136
+ sourceHash: sha256(content), // for change detection
137
+ documentChunk: content,
138
+ maxChunkLength: 6000, // optional, character count
139
+ });
140
+ // result: { truncated: boolean; chunks: number }
141
+ // truncated: true if at least one hard-split was required (no sentence boundary)
142
+ // chunks: number of LLM calls made
143
+ ```
144
+
145
+ ### Background Maintenance
146
+
147
+ ```typescript
148
+ // Consolidate recent events into durable facts (auto-triggered by write, or call manually)
149
+ await wiki.runLibrarian('entity-123');
150
+
151
+ // Resolve contradictions, downgrade stale claims, remove obsolete facts
152
+ await wiki.runHeal('entity-123');
153
+ ```
154
+
155
+ ### Forget
156
+
157
+ ```typescript
158
+ const result = await wiki.forget('entity-123', { entryId: 'fact_abc' }); // single fact
159
+ // result: { deleted: { entries: number; tasks: number } }
160
+
161
+ await wiki.forget('entity-123', { taskId: 'task_xyz' }); // single task
162
+ // sourceRef is normalized the same way as in ingestDocument (slashes stripped)
163
+ await wiki.forget('entity-123', { sourceRef: 'x.md' }); // all facts from a document
164
+ await wiki.forget('entity-123', { clearAll: true }); // wipe entity
165
+ ```
166
+
167
+ Throws `Error` if `sourceRef` or `sourceHash` is provided but invalid. Soft-deletes are idempotent — calling again with the same parameters returns `{ deleted: { entries: 0; tasks: 0 } }`.
168
+
169
+ ---
170
+
171
+ ## React / Expo Component API
172
+
173
+ Import from `expo-llm-wiki/react`. This entry point is separate so non-React consumers do not transitively import React.
174
+
175
+ ### Provider
176
+
177
+ Wrap once at app root (or any subtree that needs memory access):
178
+
179
+ ```typescript
180
+ import { WikiProvider } from 'expo-llm-wiki/react';
181
+ import { createWiki } from 'expo-llm-wiki';
182
+
183
+ const wiki = createWiki(db, { llmProvider });
184
+
185
+ export default function App() {
186
+ return (
187
+ <WikiProvider wiki={wiki}>
188
+ <YourApp />
189
+ </WikiProvider>
190
+ );
191
+ }
192
+ ```
193
+
194
+ ### `useMemoryRead(entityId, query)`
195
+
196
+ Reactive read. Fetches on mount and whenever `entityId` or `query` changes. In-flight results always land before a queued re-fetch starts — results are never silently discarded.
197
+
198
+ ```typescript
199
+ const { data, isPending, error, refetch } = useMemoryRead('entity-123', 'weekend plans');
200
+ // data: MemoryBundle | null
201
+ ```
202
+
203
+ ### `useWikiWrite()`
204
+
205
+ ```typescript
206
+ const { execute, isPending, error } = useWikiWrite();
207
+
208
+ await execute('entity-123', {
209
+ event_type: 'observation',
210
+ summary: 'User mentioned they love hiking.',
211
+ });
212
+ ```
213
+
214
+ ### `useWikiMaintenance()`
215
+
216
+ Shared `isPending` — true if either operation is in-flight:
217
+
218
+ ```typescript
219
+ const { runLibrarian, runHeal, isPending, error } = useWikiMaintenance();
220
+
221
+ await runLibrarian('entity-123');
222
+ await runHeal('entity-123');
223
+ ```
224
+
225
+ ### `useWikiIngest()`
226
+
227
+ ```typescript
228
+ const { execute, lastResult, isPending, error } = useWikiIngest();
229
+ // lastResult: { truncated: boolean; chunks: number } | null
230
+
231
+ const result = await execute('entity-123', {
232
+ sourceRef: 'preferences.md', // slashes are stripped by normalizeSourceRef
233
+ sourceHash: sha256(content),
234
+ documentChunk: content,
235
+ });
236
+ // result.truncated — true if any hard-splits were required
237
+ // result.chunks — number of LLM calls made
238
+ ```
239
+
240
+ ### `useWikiForget()`
241
+
242
+ ```typescript
243
+ const { execute, lastResult, isPending, error } = useWikiForget();
244
+ // lastResult: { deleted: { entries: number; tasks: number } } | null
245
+
246
+ const result = await execute('entity-123', { entryId: 'fact_abc' });
247
+ // result.deleted.entries — rows soft-deleted
248
+ ```
249
+
250
+ All mutation hooks follow the same pattern (`TResult` is specific per hook):
251
+
252
+ ```typescript
253
+ {
254
+ execute: (...args) => Promise<TResult>;
255
+ lastResult: TResult | null; // result of the last successful call; null before first call or after an error
256
+ isPending: boolean;
257
+ error: Error | null; // cleared on the next execute call
258
+ }
259
+ ```
@@ -0,0 +1,118 @@
1
+ import * as SQLite from 'expo-sqlite';
2
+
3
+ interface WikiConfig {
4
+ tablePrefix?: string;
5
+ maxFtsResults?: number;
6
+ pruneEventsAfter?: number;
7
+ autoLibrarianThreshold?: number;
8
+ autoHealThreshold?: number;
9
+ orphanAfterDays?: number | null;
10
+ staleInferredAfterDays?: number | null;
11
+ maxChunkBytes?: number;
12
+ }
13
+ interface WikiFact {
14
+ id: string;
15
+ entity_id: string;
16
+ title: string;
17
+ body: string;
18
+ tags: string[];
19
+ confidence: 'certain' | 'inferred' | 'tentative';
20
+ source_type: 'user_stated' | 'agent_inferred' | 'user_confirmed' | 'user_document';
21
+ source_hash: string | null;
22
+ source_ref: string | null;
23
+ created_at: number;
24
+ updated_at: number;
25
+ last_accessed_at: number | null;
26
+ access_count: number;
27
+ deleted_at: number | null;
28
+ }
29
+ interface WikiTask {
30
+ id: string;
31
+ entity_id: string;
32
+ description: string;
33
+ status: 'pending' | 'in_progress' | 'done' | 'abandoned';
34
+ priority: number;
35
+ created_at: number;
36
+ updated_at: number;
37
+ resolved_at: number | null;
38
+ deleted_at: number | null;
39
+ }
40
+ interface WikiEvent {
41
+ id: string;
42
+ entity_id: string;
43
+ event_type: 'observation' | 'decision' | 'action' | 'outcome';
44
+ summary: string;
45
+ related_entry_id?: string | null;
46
+ created_at: number;
47
+ }
48
+ interface WikiCheckpoint {
49
+ entity_id: string;
50
+ heal_checkpoint: number;
51
+ memory_checkpoint: number;
52
+ }
53
+ interface ExtractedFact {
54
+ title: string;
55
+ body: string;
56
+ tags: string[];
57
+ confidence: 'certain' | 'inferred' | 'tentative';
58
+ }
59
+ interface ExtractedTask {
60
+ description: string;
61
+ priority: number;
62
+ }
63
+ interface LLMProvider {
64
+ /**
65
+ * Generates text using the developer's LLM of choice.
66
+ * Expected to return the raw text response (typically a JSON string).
67
+ */
68
+ generateText: (params: {
69
+ systemPrompt: string;
70
+ userPrompt: string;
71
+ }) => Promise<string>;
72
+ }
73
+ interface WikiOptions {
74
+ config?: WikiConfig;
75
+ llmProvider: LLMProvider;
76
+ }
77
+ interface MemoryBundle {
78
+ facts: WikiFact[];
79
+ tasks: WikiTask[];
80
+ events: WikiEvent[];
81
+ }
82
+
83
+ declare class WikiMemory {
84
+ private db;
85
+ private prefix;
86
+ private options;
87
+ constructor(db: SQLite.SQLiteDatabase, options: WikiOptions);
88
+ setup(): Promise<void>;
89
+ private formatSearchQuery;
90
+ read(entityId: string, query: string): Promise<MemoryBundle>;
91
+ write(entityId: string, event: Omit<WikiEvent, 'id' | 'entity_id' | 'created_at'>): Promise<void>;
92
+ private runLibrarianThenMaybeHeal;
93
+ runLibrarian(entityId: string): Promise<void>;
94
+ runHeal(entityId: string): Promise<void>;
95
+ forget(entityId: string, params: {
96
+ entryId?: string;
97
+ taskId?: string;
98
+ sourceRef?: string;
99
+ sourceHash?: string;
100
+ clearAll?: boolean;
101
+ }): Promise<{
102
+ deleted: {
103
+ entries: number;
104
+ tasks: number;
105
+ };
106
+ }>;
107
+ ingestDocument(entityId: string, params: {
108
+ sourceRef: string;
109
+ sourceHash: string;
110
+ documentChunk: string;
111
+ maxChunkBytes?: number;
112
+ }): Promise<{
113
+ truncated: boolean;
114
+ chunks: number;
115
+ }>;
116
+ }
117
+
118
+ export { type ExtractedFact as E, type LLMProvider as L, type MemoryBundle as M, type WikiOptions as W, WikiMemory as a, type ExtractedTask as b, type WikiCheckpoint as c, type WikiConfig as d, type WikiEvent as e, type WikiFact as f, type WikiTask as g };
@@ -0,0 +1,118 @@
1
+ import * as SQLite from 'expo-sqlite';
2
+
3
+ interface WikiConfig {
4
+ tablePrefix?: string;
5
+ maxFtsResults?: number;
6
+ pruneEventsAfter?: number;
7
+ autoLibrarianThreshold?: number;
8
+ autoHealThreshold?: number;
9
+ orphanAfterDays?: number | null;
10
+ staleInferredAfterDays?: number | null;
11
+ maxChunkBytes?: number;
12
+ }
13
+ interface WikiFact {
14
+ id: string;
15
+ entity_id: string;
16
+ title: string;
17
+ body: string;
18
+ tags: string[];
19
+ confidence: 'certain' | 'inferred' | 'tentative';
20
+ source_type: 'user_stated' | 'agent_inferred' | 'user_confirmed' | 'user_document';
21
+ source_hash: string | null;
22
+ source_ref: string | null;
23
+ created_at: number;
24
+ updated_at: number;
25
+ last_accessed_at: number | null;
26
+ access_count: number;
27
+ deleted_at: number | null;
28
+ }
29
+ interface WikiTask {
30
+ id: string;
31
+ entity_id: string;
32
+ description: string;
33
+ status: 'pending' | 'in_progress' | 'done' | 'abandoned';
34
+ priority: number;
35
+ created_at: number;
36
+ updated_at: number;
37
+ resolved_at: number | null;
38
+ deleted_at: number | null;
39
+ }
40
+ interface WikiEvent {
41
+ id: string;
42
+ entity_id: string;
43
+ event_type: 'observation' | 'decision' | 'action' | 'outcome';
44
+ summary: string;
45
+ related_entry_id?: string | null;
46
+ created_at: number;
47
+ }
48
+ interface WikiCheckpoint {
49
+ entity_id: string;
50
+ heal_checkpoint: number;
51
+ memory_checkpoint: number;
52
+ }
53
+ interface ExtractedFact {
54
+ title: string;
55
+ body: string;
56
+ tags: string[];
57
+ confidence: 'certain' | 'inferred' | 'tentative';
58
+ }
59
+ interface ExtractedTask {
60
+ description: string;
61
+ priority: number;
62
+ }
63
+ interface LLMProvider {
64
+ /**
65
+ * Generates text using the developer's LLM of choice.
66
+ * Expected to return the raw text response (typically a JSON string).
67
+ */
68
+ generateText: (params: {
69
+ systemPrompt: string;
70
+ userPrompt: string;
71
+ }) => Promise<string>;
72
+ }
73
+ interface WikiOptions {
74
+ config?: WikiConfig;
75
+ llmProvider: LLMProvider;
76
+ }
77
+ interface MemoryBundle {
78
+ facts: WikiFact[];
79
+ tasks: WikiTask[];
80
+ events: WikiEvent[];
81
+ }
82
+
83
+ declare class WikiMemory {
84
+ private db;
85
+ private prefix;
86
+ private options;
87
+ constructor(db: SQLite.SQLiteDatabase, options: WikiOptions);
88
+ setup(): Promise<void>;
89
+ private formatSearchQuery;
90
+ read(entityId: string, query: string): Promise<MemoryBundle>;
91
+ write(entityId: string, event: Omit<WikiEvent, 'id' | 'entity_id' | 'created_at'>): Promise<void>;
92
+ private runLibrarianThenMaybeHeal;
93
+ runLibrarian(entityId: string): Promise<void>;
94
+ runHeal(entityId: string): Promise<void>;
95
+ forget(entityId: string, params: {
96
+ entryId?: string;
97
+ taskId?: string;
98
+ sourceRef?: string;
99
+ sourceHash?: string;
100
+ clearAll?: boolean;
101
+ }): Promise<{
102
+ deleted: {
103
+ entries: number;
104
+ tasks: number;
105
+ };
106
+ }>;
107
+ ingestDocument(entityId: string, params: {
108
+ sourceRef: string;
109
+ sourceHash: string;
110
+ documentChunk: string;
111
+ maxChunkBytes?: number;
112
+ }): Promise<{
113
+ truncated: boolean;
114
+ chunks: number;
115
+ }>;
116
+ }
117
+
118
+ export { type ExtractedFact as E, type LLMProvider as L, type MemoryBundle as M, type WikiOptions as W, WikiMemory as a, type ExtractedTask as b, type WikiCheckpoint as c, type WikiConfig as d, type WikiEvent as e, type WikiFact as f, type WikiTask as g };
@@ -0,0 +1,121 @@
1
+ import * as SQLite from 'expo-sqlite';
2
+
3
+ interface WikiConfig {
4
+ tablePrefix?: string;
5
+ maxFtsResults?: number;
6
+ pruneEventsAfter?: number;
7
+ autoLibrarianThreshold?: number;
8
+ autoHealThreshold?: number;
9
+ orphanAfterDays?: number | null;
10
+ staleInferredAfterDays?: number | null;
11
+ maxChunkLength?: number;
12
+ }
13
+ interface WikiFact {
14
+ id: string;
15
+ entity_id: string;
16
+ title: string;
17
+ body: string;
18
+ tags: string[];
19
+ confidence: 'certain' | 'inferred' | 'tentative';
20
+ source_type: 'user_stated' | 'agent_inferred' | 'user_confirmed' | 'user_document';
21
+ source_hash: string | null;
22
+ source_ref: string | null;
23
+ created_at: number;
24
+ updated_at: number;
25
+ last_accessed_at: number | null;
26
+ access_count: number;
27
+ deleted_at: number | null;
28
+ }
29
+ interface WikiTask {
30
+ id: string;
31
+ entity_id: string;
32
+ description: string;
33
+ status: 'pending' | 'in_progress' | 'done' | 'abandoned';
34
+ priority: number;
35
+ created_at: number;
36
+ updated_at: number;
37
+ resolved_at: number | null;
38
+ deleted_at: number | null;
39
+ }
40
+ interface WikiEvent {
41
+ id: string;
42
+ entity_id: string;
43
+ event_type: 'observation' | 'decision' | 'action' | 'outcome';
44
+ summary: string;
45
+ related_entry_id?: string | null;
46
+ created_at: number;
47
+ }
48
+ interface WikiCheckpoint {
49
+ entity_id: string;
50
+ heal_checkpoint: number;
51
+ memory_checkpoint: number;
52
+ }
53
+ interface ExtractedFact {
54
+ title: string;
55
+ body: string;
56
+ tags: string[];
57
+ confidence: 'certain' | 'inferred' | 'tentative';
58
+ }
59
+ interface ExtractedTask {
60
+ description: string;
61
+ priority: number;
62
+ }
63
+ interface LLMProvider {
64
+ /**
65
+ * Generates text using the developer's LLM of choice.
66
+ * Expected to return the raw text response (typically a JSON string).
67
+ */
68
+ generateText: (params: {
69
+ systemPrompt: string;
70
+ userPrompt: string;
71
+ }) => Promise<string>;
72
+ }
73
+ interface WikiOptions {
74
+ config?: WikiConfig;
75
+ llmProvider: LLMProvider;
76
+ }
77
+ interface MemoryBundle {
78
+ facts: WikiFact[];
79
+ tasks: WikiTask[];
80
+ events: WikiEvent[];
81
+ }
82
+
83
+ declare class WikiMemory {
84
+ private db;
85
+ private prefix;
86
+ private options;
87
+ private activeMaintenanceJobs;
88
+ constructor(db: SQLite.SQLiteDatabase, options: WikiOptions);
89
+ setup(): Promise<void>;
90
+ private formatSearchQuery;
91
+ read(entityId: string, query: string): Promise<MemoryBundle>;
92
+ write(entityId: string, event: Omit<WikiEvent, 'id' | 'entity_id' | 'created_at'>): Promise<void>;
93
+ private runLibrarianThenMaybeHeal;
94
+ private _doRunLibrarian;
95
+ private _doRunHeal;
96
+ runLibrarian(entityId: string): Promise<void>;
97
+ runHeal(entityId: string): Promise<void>;
98
+ forget(entityId: string, params: {
99
+ entryId?: string;
100
+ taskId?: string;
101
+ sourceRef?: string;
102
+ sourceHash?: string;
103
+ clearAll?: boolean;
104
+ }): Promise<{
105
+ deleted: {
106
+ entries: number;
107
+ tasks: number;
108
+ };
109
+ }>;
110
+ ingestDocument(entityId: string, params: {
111
+ sourceRef: string;
112
+ sourceHash: string;
113
+ documentChunk: string;
114
+ maxChunkLength?: number;
115
+ }): Promise<{
116
+ truncated: boolean;
117
+ chunks: number;
118
+ }>;
119
+ }
120
+
121
+ export { type ExtractedFact as E, type LLMProvider as L, type MemoryBundle as M, type WikiOptions as W, WikiMemory as a, type ExtractedTask as b, type WikiCheckpoint as c, type WikiConfig as d, type WikiEvent as e, type WikiFact as f, type WikiTask as g };