@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 +2 -4
- package/package.json +1 -1
- package/src/db.test.ts +12 -0
- package/src/db.ts +28 -6
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; //
|
|
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
|
|
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
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
|
-
|
|
127
|
+
`${PACKAGE_NAME}: configured SQLite dylib does not exist: ${candidate}`,
|
|
120
128
|
);
|
|
121
129
|
}
|
|
122
130
|
|
|
123
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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)}`,
|