@dex-ai/memory 0.3.4 → 0.3.5

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
@@ -104,7 +104,7 @@ interface MemoryExtensionOptions {
104
104
  userId: string; // owner for episodic + semantic memory
105
105
 
106
106
  vecPath?: string; // optional explicit sqlite-vec extension path
107
- sqlitePath?: string; // optional SQLite dylib with extension loading enabled
107
+ sqlitePath?: string; // advanced: override auto-detected Homebrew SQLite dylib
108
108
 
109
109
  llm?: { provider?: Provider; model?: string };
110
110
  embed?: (texts: string[]) => Promise<number[][]>; // 384-dim vectors
@@ -143,12 +143,10 @@ This message is **not** persisted to `actx.messages` — it is a per-turn rewrit
143
143
  ## Requirements + gotchas
144
144
 
145
145
  - **sqlite-vec**: loaded via the `sqlite-vec` npm package, which ships prebuilt binaries for macOS, Linux, and Windows. Extension construction throws if the binary is not loadable for your platform.
146
- - **Bun + macOS SQLite**: Bun uses Apple SQLite on macOS by default, and Apple SQLite disables loadable extensions. The extension automatically uses Homebrew SQLite when it exists at `/opt/homebrew/opt/sqlite/lib/libsqlite3.dylib` or `/usr/local/opt/sqlite/lib/libsqlite3.dylib`. If needed, install it with `brew install sqlite`, set `DEX_SQLITE_DYLIB=/path/to/libsqlite3.dylib`, or pass `sqlitePath` to `memoryExtension()`.
146
+ - **Bun + macOS SQLite**: Bun uses Apple SQLite on macOS by default, and Apple SQLite disables loadable extensions. The extension automatically uses Homebrew SQLite when it exists at `/opt/homebrew/opt/sqlite/lib/libsqlite3.dylib` or `/usr/local/opt/sqlite/lib/libsqlite3.dylib`. If needed, install it and restart Dex:
147
147
 
148
148
  ```bash
149
149
  brew install sqlite
150
- export DEX_SQLITE_DYLIB="$(brew --prefix sqlite)/lib/libsqlite3.dylib"
151
- bun test
152
150
  ```
153
151
 
154
152
  - **Transformers.js first-run download**: the default local embedder downloads an ONNX model and caches it in `~/.cache/huggingface`. Initial `embed()` may take 10-30s; subsequent calls are faster.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dex-ai/memory",
3
- "version": "0.3.4",
3
+ "version": "0.3.5",
4
4
  "description": "SQLite-backed memory Extension for @dex-ai/sdk — episodic, semantic, and procedural memory in one package.",
5
5
  "type": "module",
6
6
  "exports": {
package/src/db.test.ts CHANGED
@@ -1,4 +1,6 @@
1
+ import { Database } from 'bun:sqlite';
1
2
  import { describe, expect, test } from 'bun:test';
3
+ import { fileURLToPath } from 'node:url';
2
4
  import { MemoryDb, EMBED_DIMS } from './db';
3
5
 
4
6
  describe('MemoryDb', () => {
@@ -40,6 +42,16 @@ describe('MemoryDb', () => {
40
42
  }
41
43
  });
42
44
 
45
+ test('tolerates SQLite being loaded before custom sqlite configuration', () => {
46
+ const alreadyOpen = new Database(':memory:');
47
+ try {
48
+ const db = new MemoryDb({ path: ':memory:', sqlitePath: fileURLToPath(import.meta.url) });
49
+ db.close();
50
+ } finally {
51
+ alreadyOpen.close();
52
+ }
53
+ });
54
+
43
55
  test('EMBED_DIMS is 384', () => {
44
56
  expect(EMBED_DIMS).toBe(384);
45
57
  });
package/src/db.ts CHANGED
@@ -96,6 +96,7 @@ const MIGRATIONS: Array<{ name: string; sql: string }> = [
96
96
  },
97
97
  ];
98
98
 
99
+ const PACKAGE_NAME = "@dex-ai/memory";
99
100
  const SQLITE_DYLIB_ENV = "DEX_SQLITE_DYLIB";
100
101
 
101
102
  const HOMEBREW_SQLITE_DYLIBS = [
@@ -104,9 +105,16 @@ const HOMEBREW_SQLITE_DYLIBS = [
104
105
  ];
105
106
 
106
107
  let customSqliteConfigured = false;
108
+ let customSqliteAttempted = false;
109
+
110
+ function isSQLiteAlreadyLoadedError(err: unknown): boolean {
111
+ return err instanceof Error && /SQLite already loaded/i.test(err.message);
112
+ }
107
113
 
108
114
  function configureCustomSQLite(sqlitePath?: string): void {
109
115
  if (customSqliteConfigured || platform !== "darwin") return;
116
+ if (sqlitePath === undefined && customSqliteAttempted) return;
117
+ customSqliteAttempted = true;
110
118
 
111
119
  const candidate =
112
120
  sqlitePath ??
@@ -116,23 +124,37 @@ function configureCustomSQLite(sqlitePath?: string): void {
116
124
 
117
125
  if (!existsSync(candidate)) {
118
126
  throw new Error(
119
- `@dex-ai/memory-sqlite: configured SQLite dylib does not exist: ${candidate}`,
127
+ `${PACKAGE_NAME}: configured SQLite dylib does not exist: ${candidate}`,
120
128
  );
121
129
  }
122
130
 
123
- if (!Database.setCustomSQLite(candidate)) {
131
+ try {
132
+ if (!Database.setCustomSQLite(candidate)) {
133
+ throw new Error(`failed to configure custom SQLite dylib: ${candidate}`);
134
+ }
135
+ customSqliteConfigured = true;
136
+ } catch (err) {
137
+ // Bun only allows setCustomSQLite() before SQLite is loaded anywhere in
138
+ // the process. Dex may load another SQLite-backed extension first. In
139
+ // that case, keep using the already-loaded SQLite and let sqlite-vec
140
+ // loading below determine whether the current build supports extensions.
141
+ if (isSQLiteAlreadyLoadedError(err)) return;
124
142
  throw new Error(
125
- `@dex-ai/memory-sqlite: failed to configure custom SQLite dylib: ${candidate}`,
143
+ `${PACKAGE_NAME}: ${err instanceof Error ? err.message : String(err)}`,
126
144
  );
127
145
  }
128
- customSqliteConfigured = true;
129
146
  }
130
147
 
131
148
  function customSQLiteHelp(): string {
132
149
  if (platform !== "darwin") return "";
133
- return ` On macOS, Bun uses Apple SQLite by default, which disables loadable extensions. Install SQLite with \`brew install sqlite\`, then either set ${SQLITE_DYLIB_ENV}=/opt/homebrew/opt/sqlite/lib/libsqlite3.dylib or pass sqlitePath.`;
150
+ return " On macOS, Bun uses Apple SQLite by default, which disables loadable extensions. Install SQLite with `brew install sqlite`, then restart Dex.";
134
151
  }
135
152
 
153
+ // Configure Bun to use Homebrew SQLite as soon as this module is imported.
154
+ // Users should only need to install SQLite; no environment variables are
155
+ // required for the common Homebrew locations.
156
+ configureCustomSQLite();
157
+
136
158
  function applyMigrations(db: Database): void {
137
159
  db.exec(`
138
160
  CREATE TABLE IF NOT EXISTS _schema_migrations (
@@ -179,7 +201,7 @@ export class MemoryDb {
179
201
  } catch (err) {
180
202
  this.db.close();
181
203
  throw new Error(
182
- `@dex-ai/memory-sqlite: failed to load sqlite-vec extension. ` +
204
+ `${PACKAGE_NAME}: failed to load sqlite-vec extension. ` +
183
205
  `Ensure the sqlite-vec npm package's prebuilt binary is available for this platform.` +
184
206
  customSQLiteHelp() +
185
207
  ` Original error: ${err instanceof Error ? err.message : String(err)}`,