@melandlabs/memory-store 0.2.7 → 0.3.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.
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { mkdirSync } from 'fs';
3
- import { homedir } from 'os';
4
- import { join, dirname } from 'path';
3
+ import { dirname } from 'path';
4
+ import { getOpenContextPath } from '@melandlabs/env-config';
5
5
  import { SQLiteRawMessageManager } from '@melandlabs/sqlite';
6
6
  import '@melandlabs/ai/memory';
7
7
  import '@melandlabs/rag';
@@ -34,11 +34,10 @@ function isRawMessageChromaEnabled() {
34
34
 
35
35
  // src/storage/sqlite-raw-message-store.ts
36
36
  var manager = null;
37
- var DEFAULT_SQLITE_PATH = join(homedir(), ".opencontext", "memory", "store.db");
38
37
  function resolveSQLiteRawMessageDbPath(dbPath) {
39
38
  if (dbPath && dbPath.length > 0) return dbPath;
40
39
  const fromEnv = process.env.MEMORY_STORE_DB_PATH?.trim();
41
- return fromEnv && fromEnv.length > 0 ? fromEnv : DEFAULT_SQLITE_PATH;
40
+ return fromEnv && fromEnv.length > 0 ? fromEnv : getOpenContextPath("memory", "store.db");
42
41
  }
43
42
  async function getSQLiteRawMessageManager(options = {}) {
44
43
  if (!manager) {
@@ -61,7 +60,7 @@ async function closeSQLiteRawMessageManager() {
61
60
  }
62
61
 
63
62
  // src/storage/raw-message-store.ts
64
- function resolveBackend(env) {
63
+ function resolveBackend(_env) {
65
64
  const explicit = process.env.OPENCONTEXT_MEMORY_STORE_BACKEND?.trim().toLowerCase();
66
65
  if (explicit === "postgres") return "postgres";
67
66
  return "sqlite";
@@ -281,6 +280,9 @@ async function buildUnified(args) {
281
280
  } else if (args.memoryBackend === "chroma") {
282
281
  if (!args.chromaUrl)
283
282
  throw new Error("--memory-backend=chroma requires --chroma-url <url> (or CHROMA_URL env)");
283
+ if (!aiRag) {
284
+ throw new Error("ai-rag modules not loaded");
285
+ }
284
286
  const store = new aiRag.ChromaVectorStore({
285
287
  url: args.chromaUrl,
286
288
  collectionName: "opencontext_raw_messages"
@@ -319,6 +321,9 @@ async function buildUnified(args) {
319
321
  throw new Error("--insights-backend=chroma requires --chroma-url <url> (or CHROMA_URL env)");
320
322
  if (!unified.embedQuery)
321
323
  throw new Error("--insights-backend=chroma requires --embedding-provider local|openrouter");
324
+ if (!aiRag) {
325
+ throw new Error("ai-rag modules not loaded");
326
+ }
322
327
  const store = new aiRag.ChromaVectorStore({
323
328
  url: args.chromaUrl,
324
329
  collectionName: args.insightsCollection
@@ -336,6 +341,9 @@ async function buildUnified(args) {
336
341
  throw new Error("--knowledge-backend=chroma requires --chroma-url <url> (or CHROMA_URL env)");
337
342
  if (!unified.embedQuery)
338
343
  throw new Error("--knowledge-backend=chroma requires --embedding-provider local|openrouter");
344
+ if (!aiRag) {
345
+ throw new Error("ai-rag modules not loaded");
346
+ }
339
347
  const store = new aiRag.ChromaVectorStore({
340
348
  url: args.chromaUrl,
341
349
  collectionName: args.knowledgeCollection
@@ -1,4 +1,4 @@
1
- import { b as MemoryStoreEnv } from '../config-Ll6ktm4D.js';
1
+ import { i as MemoryStoreEnv } from '../config-2Q092MUz.js';
2
2
 
3
3
  /**
4
4
  * Lazy registration slot for the host's Postgres-backed raw message
@@ -1,5 +1,5 @@
1
1
  import { RawMessageStorageManager } from '@melandlabs/indexeddb/storage';
2
- import { b as MemoryStoreEnv, M as MemoryStoreConfig } from '../config-Ll6ktm4D.js';
2
+ import { i as MemoryStoreEnv, M as MemoryStoreConfig } from '../config-2Q092MUz.js';
3
3
 
4
4
  /**
5
5
  * Top-level raw-message store facade.
@@ -1,6 +1,6 @@
1
1
  import { mkdirSync } from 'fs';
2
- import { homedir } from 'os';
3
- import { join, dirname } from 'path';
2
+ import { dirname } from 'path';
3
+ import { getOpenContextPath } from '@melandlabs/env-config';
4
4
  import { SQLiteRawMessageManager } from '@melandlabs/sqlite';
5
5
  import '@melandlabs/ai/memory';
6
6
  import '@melandlabs/rag';
@@ -33,11 +33,10 @@ function isRawMessageChromaEnabled() {
33
33
 
34
34
  // src/storage/sqlite-raw-message-store.ts
35
35
  var manager = null;
36
- var DEFAULT_SQLITE_PATH = join(homedir(), ".opencontext", "memory", "store.db");
37
36
  function resolveSQLiteRawMessageDbPath(dbPath) {
38
37
  if (dbPath && dbPath.length > 0) return dbPath;
39
38
  const fromEnv = process.env.MEMORY_STORE_DB_PATH?.trim();
40
- return fromEnv && fromEnv.length > 0 ? fromEnv : DEFAULT_SQLITE_PATH;
39
+ return fromEnv && fromEnv.length > 0 ? fromEnv : getOpenContextPath("memory", "store.db");
41
40
  }
42
41
  async function getSQLiteRawMessageManager(options = {}) {
43
42
  if (!manager) {
@@ -60,7 +59,7 @@ async function closeSQLiteRawMessageManager() {
60
59
  }
61
60
 
62
61
  // src/storage/raw-message-store.ts
63
- function resolveBackend(env) {
62
+ function resolveBackend(_env) {
64
63
  const explicit = process.env.OPENCONTEXT_MEMORY_STORE_BACKEND?.trim().toLowerCase();
65
64
  if (explicit === "postgres") return "postgres";
66
65
  return "sqlite";
@@ -1,5 +1,5 @@
1
1
  import { SQLiteRawMessageManager } from '@melandlabs/sqlite';
2
- import { b as MemoryStoreEnv } from '../config-Ll6ktm4D.js';
2
+ import { i as MemoryStoreEnv } from '../config-2Q092MUz.js';
3
3
 
4
4
  /**
5
5
  * SQLite-backed raw message store.
@@ -1,6 +1,6 @@
1
1
  import { mkdirSync } from 'fs';
2
- import { homedir } from 'os';
3
- import { join, dirname } from 'path';
2
+ import { dirname } from 'path';
3
+ import { getOpenContextPath } from '@melandlabs/env-config';
4
4
  import { SQLiteRawMessageManager } from '@melandlabs/sqlite';
5
5
  import '@melandlabs/ai/memory';
6
6
  import '@melandlabs/rag';
@@ -26,11 +26,10 @@ function isRawMessageChromaEnabled() {
26
26
 
27
27
  // src/storage/sqlite-raw-message-store.ts
28
28
  var manager = null;
29
- var DEFAULT_SQLITE_PATH = join(homedir(), ".opencontext", "memory", "store.db");
30
29
  function resolveSQLiteRawMessageDbPath(dbPath) {
31
30
  if (dbPath && dbPath.length > 0) return dbPath;
32
31
  const fromEnv = process.env.MEMORY_STORE_DB_PATH?.trim();
33
- return fromEnv && fromEnv.length > 0 ? fromEnv : DEFAULT_SQLITE_PATH;
32
+ return fromEnv && fromEnv.length > 0 ? fromEnv : getOpenContextPath("memory", "store.db");
34
33
  }
35
34
  function isSQLiteRawMessageStorageAvailable(_env) {
36
35
  return true;
@@ -1,5 +1,5 @@
1
1
  import { VectorSearchResult } from '@melandlabs/rag/vector-service';
2
- import { b as MemoryStoreEnv } from '../config-Ll6ktm4D.js';
2
+ import { i as MemoryStoreEnv } from '../config-2Q092MUz.js';
3
3
 
4
4
  /**
5
5
  * SQLite-vec-backed raw-message + insight vector index.
@@ -1,6 +1,6 @@
1
1
  import 'fs';
2
- import { homedir } from 'os';
3
- import { join } from 'path';
2
+ import 'path';
3
+ import { getOpenContextPath } from '@melandlabs/env-config';
4
4
  import '@melandlabs/sqlite';
5
5
  import '@melandlabs/ai/memory';
6
6
  import '@melandlabs/rag';
@@ -8,10 +8,9 @@ import '@melandlabs/rag';
8
8
  // src/storage/sqlite-raw-message-store.ts
9
9
 
10
10
  // src/storage/sqlite-raw-message-store.ts
11
- var DEFAULT_SQLITE_PATH = join(homedir(), ".opencontext", "memory", "store.db");
12
11
  function resolveSQLiteRawMessageDbPath(dbPath) {
13
12
  const fromEnv = process.env.MEMORY_STORE_DB_PATH?.trim();
14
- return fromEnv && fromEnv.length > 0 ? fromEnv : DEFAULT_SQLITE_PATH;
13
+ return fromEnv && fromEnv.length > 0 ? fromEnv : getOpenContextPath("memory", "store.db");
15
14
  }
16
15
 
17
16
  // src/storage/sqlite-vector-index.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@melandlabs/memory-store",
3
- "version": "0.2.7",
3
+ "version": "0.3.1",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist",
@@ -60,14 +60,15 @@
60
60
  "@modelcontextprotocol/sdk": "^1.25.3",
61
61
  "hono": "^4.6.14",
62
62
  "zod": "^4.3.6",
63
- "@melandlabs/ai": "0.2.1",
64
- "@melandlabs/sqlite": "0.2.1",
65
- "@melandlabs/shared": "0.2.1",
66
- "@melandlabs/rag": "0.2.1"
63
+ "@melandlabs/ai": "0.3.1",
64
+ "@melandlabs/env-config": "0.4.0",
65
+ "@melandlabs/rag": "0.2.2",
66
+ "@melandlabs/sqlite": "0.3.0",
67
+ "@melandlabs/shared": "0.3.0"
67
68
  },
68
69
  "peerDependencies": {
69
- "@melandlabs/ai-rag": "0.2.3",
70
- "@melandlabs/indexeddb": "0.2.1"
70
+ "@melandlabs/ai-rag": "0.2.4",
71
+ "@melandlabs/indexeddb": "0.3.0"
71
72
  },
72
73
  "peerDependenciesMeta": {
73
74
  "@melandlabs/ai-rag": {
@@ -80,8 +81,8 @@
80
81
  "devDependencies": {
81
82
  "@types/node": "^22.13.10",
82
83
  "typescript": "^5.6.3",
83
- "@melandlabs/config": "0.2.1",
84
- "@melandlabs/ai-rag": "0.2.3"
84
+ "@melandlabs/ai-rag": "0.2.4",
85
+ "@melandlabs/config": "0.3.0"
85
86
  },
86
87
  "scripts": {
87
88
  "build": "tsup",
@@ -89,6 +90,7 @@
89
90
  "lint": "biome check .",
90
91
  "lint:fix": "biome check --write .",
91
92
  "test": "vitest run",
93
+ "test:integration": "vitest run --config vitest.integration.config.ts",
92
94
  "test:watch": "vitest"
93
95
  }
94
96
  }
@@ -1,183 +0,0 @@
1
- /**
2
- * Memory store configuration — injected by the host application.
3
- *
4
- * The memory-store package is intentionally decoupled from the
5
- * opencontext web app's database layer. Each consumer wires up its own
6
- * implementation of the `db` contract.
7
- *
8
- * Backend selection is env-var driven, not host-injected:
9
- * - Default: local SQLite at `~/.opencontext/memory/store.db`
10
- * (override with `MEMORY_STORE_DB_PATH`).
11
- * - Set `OPENCONTEXT_MEMORY_STORE_BACKEND=postgres` to opt into the
12
- * host's registered Postgres factory (call `registerPostgresFactory`
13
- * at startup). SQLite stays as the default in every other case.
14
- *
15
- * Required for raw-message persistence:
16
- * - `db.getDb()` — returns a Drizzle DB handle (Postgres path only)
17
- *
18
- * Required for vector indexing:
19
- * - one of `vector.sqlite-vec.dbPath` or `vector.chroma.url`
20
- *
21
- * Required for unified semantic search:
22
- * - `unified.embedQuery` — the embedding provider's query embedder
23
- *
24
- * Optional for cross-source unified search:
25
- * - `unified.searchKnowledge` — RAG over uploaded documents
26
- * - `unified.searchInsights` — over extracted insights
27
- *
28
- * If `unified.*` are absent, the SDK still works but the corresponding
29
- * sources in `searchUnifiedMemory` will return empty results with a
30
- * warning — fine for a standalone memory daemon.
31
- */
32
-
33
- interface MemoryStoreDb {
34
- /** Resolve the active Drizzle DB handle. Must be server-side. */
35
- getDb(): unknown;
36
- /** Whether the DB has finished initializing (optional, for startup gating). */
37
- isDbInitialized?(): boolean;
38
- /** Initialize the DB (optional, called by `createMemoryStore` if present). */
39
- initDb?(): unknown;
40
- /**
41
- * Drizzle table references for the postgres backend. Required when
42
- * running outside Tauri mode without a registered factory. The host
43
- * application owns the actual schema.
44
- */
45
- tables?: {
46
- rawMessages?: unknown;
47
- memorySummaries?: unknown;
48
- };
49
- }
50
- /**
51
- * Placeholder for the historical host-injected environment. The fields
52
- * it used to expose (`isTauriMode`, `getTauriDbPath`, `getTauriDataDir`)
53
- * were Tauri-specific and have been removed. Backend selection is now
54
- * driven entirely by the `OPENCONTEXT_MEMORY_STORE_BACKEND` env var.
55
- *
56
- * The interface is kept (empty) so existing `env?: MemoryStoreEnv`
57
- * parameters on the public surface still type-check, but new code
58
- * should not need to construct a value of this type.
59
- */
60
- interface MemoryStoreEnv {
61
- }
62
- type VectorBackend = "sqlite-vec" | "chroma";
63
- interface MemoryStoreVectorConfig {
64
- /** Active backend selector. Defaults to env-based detection. */
65
- backend?: VectorBackend;
66
- /** SQLite-vec options (used when backend === "sqlite-vec"). */
67
- sqliteVec?: {
68
- dbPath?: string;
69
- insightsCollection?: string;
70
- };
71
- /** Chroma options (used when backend === "chroma"). */
72
- chroma?: {
73
- url?: string;
74
- rawMessagesCollection?: string;
75
- insightsCollection?: string;
76
- };
77
- }
78
- type EmbedQueryFn = (input: {
79
- userId: string;
80
- query: string;
81
- authToken?: string;
82
- }) => Promise<number[]>;
83
- interface UnifiedSearchKnowledgeResult {
84
- chunkId: string;
85
- documentId: string;
86
- documentName: string;
87
- content: string;
88
- similarity: number;
89
- chunkIndex: number;
90
- }
91
- interface UnifiedSearchInsightsResult {
92
- id: string;
93
- content: string;
94
- similarity: number;
95
- metadata: Record<string, unknown>;
96
- }
97
- interface UnifiedSearchDeps {
98
- /** Embed a query string using the active user's provider. */
99
- embedQuery?: EmbedQueryFn;
100
- /**
101
- * Postgres-side ANN search over `raw_messages`. Used when chroma is
102
- * not enabled but the host has a postgres-backed manager. If both
103
- * chroma and this are absent, the memory source will return empty
104
- * (with a warning) in standalone mode.
105
- */
106
- searchRawMessagesAnn?: (input: {
107
- userId: string;
108
- queryEmbedding: number[];
109
- limit: number;
110
- threshold: number;
111
- botId?: string;
112
- }) => Promise<Array<{
113
- id: string;
114
- content: string;
115
- similarity: number;
116
- metadata: Record<string, unknown>;
117
- }>>;
118
- /** RAG over uploaded knowledge documents. Returns a list of chunk hits. */
119
- searchKnowledge?: (input: {
120
- userId: string;
121
- query: string;
122
- options: {
123
- limit: number;
124
- threshold: number;
125
- documentIds?: string[];
126
- };
127
- authToken?: string;
128
- }) => Promise<UnifiedSearchKnowledgeResult[]>;
129
- /** Semantic search over extracted insights. */
130
- searchInsights?: (input: {
131
- userId: string;
132
- query: string;
133
- limit: number;
134
- threshold: number;
135
- botIds?: string[];
136
- includeArchived?: boolean;
137
- authToken?: string;
138
- }) => Promise<UnifiedSearchInsightsResult[]>;
139
- /**
140
- * Optional BM25 (lexical) sub-query for the memory source. Mirrors the
141
- * `searchRawMessagesAnn` shape but operates on FTS5 keywords instead of
142
- * dense embeddings. When absent, the unified pipeline skips the lexical
143
- * path and emits a `memory_lexical_search_not_configured` warning.
144
- */
145
- searchRawMessagesLexical?: (input: {
146
- userId: string;
147
- keywords: string[];
148
- limit: number;
149
- botId?: string;
150
- }) => Promise<Array<{
151
- id: string;
152
- content: string;
153
- similarity: number;
154
- metadata: Record<string, unknown>;
155
- }>>;
156
- }
157
- interface MemoryStoreConfig {
158
- /**
159
- * Database handle factory. Required for the Postgres backend
160
- * (`OPENCONTEXT_MEMORY_STORE_BACKEND=postgres`).
161
- */
162
- db?: MemoryStoreDb;
163
- /**
164
- * Custom SQLite database file path for the default SQLite backend.
165
- *
166
- * If provided, this takes precedence over the `MEMORY_STORE_DB_PATH`
167
- * environment variable and the default `~/.opencontext/memory/store.db`.
168
- *
169
- * For backward compatibility with early tutorials, `db.path` is also
170
- * honoured when `db` is supplied as `{ type, path }`.
171
- */
172
- dbPath?: string;
173
- /** Environment helpers. Defaults to a process.env-only stub if omitted. */
174
- env?: MemoryStoreEnv;
175
- /** Vector backend config. Defaults to env-based detection. */
176
- vector?: MemoryStoreVectorConfig;
177
- /** Optional cross-source search providers. */
178
- unified?: UnifiedSearchDeps;
179
- /** Optional logger. Defaults to console. */
180
- logger?: Pick<Console, "log" | "warn" | "error">;
181
- }
182
-
183
- export type { EmbedQueryFn as E, MemoryStoreConfig as M, UnifiedSearchInsightsResult as U, VectorBackend as V, MemoryStoreDb as a, MemoryStoreEnv as b, UnifiedSearchKnowledgeResult as c, UnifiedSearchDeps as d };