@aeriondyseti/vector-memory-mcp 0.5.0 ā 0.8.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 +30 -22
- package/hooks/session-start.ts +100 -0
- package/package.json +14 -3
- package/scripts/publish.ts +61 -0
- package/scripts/warmup.ts +1 -2
- package/src/config/index.ts +52 -14
- package/src/db/memory.repository.ts +21 -0
- package/src/db/schema.ts +1 -0
- package/src/http/mcp-transport.ts +255 -0
- package/src/http/server.ts +56 -39
- package/src/index.ts +39 -6
- package/src/mcp/handlers.ts +169 -33
- package/src/mcp/server.ts +1 -1
- package/src/mcp/tools.ts +164 -59
- package/src/services/embeddings.service.ts +5 -3
- package/src/services/memory.service.ts +109 -31
- package/src/types/memory.ts +0 -4
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
A production-ready MCP (Model Context Protocol) server that provides semantic memory storage for AI assistants. Uses local embeddings and vector search to automatically retrieve relevant context without cloud dependencies.
|
|
6
6
|
|
|
7
|
-
**Perfect for:** Software teams maintaining architectural knowledge, developers juggling multiple projects, and anyone building with AI assistants
|
|
7
|
+
**Perfect for:** Software teams maintaining architectural knowledge, developers juggling multiple projects, and anyone building with MCP-compatible AI assistants.
|
|
8
8
|
|
|
9
9
|
[](https://opensource.org/licenses/MIT)
|
|
10
10
|
[](https://www.typescriptlang.org/)
|
|
@@ -36,9 +36,7 @@ A production-ready MCP (Model Context Protocol) server that provides semantic me
|
|
|
36
36
|
- CPU-optimized local embeddings (no GPU required)
|
|
37
37
|
|
|
38
38
|
### š **MCP Native Integration**
|
|
39
|
-
-
|
|
40
|
-
- Session hooks for automatic context injection
|
|
41
|
-
- Standard MCP protocol (compatible with future clients)
|
|
39
|
+
- Standard MCP protocol (compatible with any client)
|
|
42
40
|
|
|
43
41
|
### š ļø **Developer-Friendly**
|
|
44
42
|
- Zero-configuration setup
|
|
@@ -53,7 +51,7 @@ A production-ready MCP (Model Context Protocol) server that provides semantic me
|
|
|
53
51
|
### Prerequisites
|
|
54
52
|
|
|
55
53
|
- [Bun](https://bun.sh/) 1.0+
|
|
56
|
-
-
|
|
54
|
+
- An MCP-compatible client
|
|
57
55
|
|
|
58
56
|
> **Note:** This server requires Bun to run.
|
|
59
57
|
|
|
@@ -68,7 +66,7 @@ bun install -g @aeriondyseti/vector-memory-mcp
|
|
|
68
66
|
|
|
69
67
|
> **Note:** The installation automatically downloads ML models (~90MB) and verifies native dependencies. This may take a minute on first install.
|
|
70
68
|
|
|
71
|
-
**Configure
|
|
69
|
+
**Configure your MCP client** (example config for clients that use `~/.claude/config.json`):
|
|
72
70
|
```json
|
|
73
71
|
{
|
|
74
72
|
"mcpServers": {
|
|
@@ -94,7 +92,7 @@ cd vector-memory-mcp
|
|
|
94
92
|
bun install
|
|
95
93
|
```
|
|
96
94
|
|
|
97
|
-
**Configure
|
|
95
|
+
**Configure your MCP client** (example config for clients that use `~/.claude/config.json`):
|
|
98
96
|
```json
|
|
99
97
|
{
|
|
100
98
|
"mcpServers": {
|
|
@@ -119,11 +117,14 @@ bun install
|
|
|
119
117
|
|
|
120
118
|
### Start Using It
|
|
121
119
|
|
|
122
|
-
That's it! Restart
|
|
123
|
-
- `
|
|
120
|
+
That's it! Restart your MCP client and you'll have access to memory tools:
|
|
121
|
+
- `store_memories` - Save memories for later recall (always pass array)
|
|
124
122
|
- `search_memories` - Find relevant memories semantically
|
|
125
|
-
- `
|
|
126
|
-
- `
|
|
123
|
+
- `get_memories` - Retrieve memories by ID (always pass array)
|
|
124
|
+
- `update_memories` - Update existing memories in place
|
|
125
|
+
- `delete_memories` - Remove memories (always pass array of IDs)
|
|
126
|
+
- `store_handoff` - Store a handoff-style project snapshot
|
|
127
|
+
- `get_handoff` - Retrieve the latest handoff (includes referenced memories)
|
|
127
128
|
|
|
128
129
|
---
|
|
129
130
|
|
|
@@ -131,14 +132,14 @@ That's it! Restart Claude Code and you'll have access to memory tools:
|
|
|
131
132
|
|
|
132
133
|
### Storing Memories
|
|
133
134
|
|
|
134
|
-
Ask
|
|
135
|
+
Ask your MCP client/agent to remember things for you:
|
|
135
136
|
|
|
136
137
|
```
|
|
137
138
|
You: "Remember that we use Drizzle ORM for database access"
|
|
138
|
-
Claude: [calls
|
|
139
|
+
Claude: [calls store_memories tool]
|
|
139
140
|
```
|
|
140
141
|
|
|
141
|
-
Or
|
|
142
|
+
Or your MCP client/agent can store memories directly:
|
|
142
143
|
```json
|
|
143
144
|
{
|
|
144
145
|
"content": "Use Drizzle ORM for type-safe database access",
|
|
@@ -151,7 +152,7 @@ Or Claude Code can store memories directly:
|
|
|
151
152
|
|
|
152
153
|
### Searching Memories
|
|
153
154
|
|
|
154
|
-
|
|
155
|
+
Your MCP client/agent can automatically search memories when relevant, or you can ask:
|
|
155
156
|
|
|
156
157
|
```
|
|
157
158
|
You: "What did we decide about the database?"
|
|
@@ -223,7 +224,7 @@ vector-memory-mcp/
|
|
|
223
224
|
### 1. Memory Storage
|
|
224
225
|
|
|
225
226
|
```
|
|
226
|
-
|
|
227
|
+
An MCP client calls store_memories tool
|
|
227
228
|
ā
|
|
228
229
|
Content ā @huggingface/transformers ā 384d vector
|
|
229
230
|
ā
|
|
@@ -235,7 +236,7 @@ Store in LanceDB with metadata
|
|
|
235
236
|
### 2. Memory Retrieval
|
|
236
237
|
|
|
237
238
|
```
|
|
238
|
-
|
|
239
|
+
An MCP client calls search_memories
|
|
239
240
|
ā
|
|
240
241
|
Query ā @huggingface/transformers ā 384d vector
|
|
241
242
|
ā
|
|
@@ -252,7 +253,9 @@ Return top N relevant memories
|
|
|
252
253
|
|
|
253
254
|
The server uses environment variables for configuration:
|
|
254
255
|
|
|
255
|
-
- `VECTOR_MEMORY_DB_PATH` - Custom database path (default:
|
|
256
|
+
- `VECTOR_MEMORY_DB_PATH` - Custom database path (default: `./.claude/vector-memories.db`)
|
|
257
|
+
|
|
258
|
+
> Note: if you point multiple projects at the same DB path, `store_handoff` uses UUID.ZERO and will overwrite the previous handoff (by design).
|
|
256
259
|
- `VECTOR_MEMORY_MODEL` - Embedding model to use (default: `Xenova/all-MiniLM-L6-v2`)
|
|
257
260
|
|
|
258
261
|
Example:
|
|
@@ -261,7 +264,7 @@ export VECTOR_MEMORY_DB_PATH="/path/to/custom/memories.db"
|
|
|
261
264
|
export VECTOR_MEMORY_MODEL="Xenova/all-MiniLM-L6-v2"
|
|
262
265
|
```
|
|
263
266
|
|
|
264
|
-
Or in your
|
|
267
|
+
Or in your MCP client config:
|
|
265
268
|
```json
|
|
266
269
|
{
|
|
267
270
|
"mcpServers": {
|
|
@@ -282,7 +285,10 @@ Or in your Claude Code config:
|
|
|
282
285
|
### Running Tests
|
|
283
286
|
|
|
284
287
|
```bash
|
|
285
|
-
# Run all tests
|
|
288
|
+
# Run all tests (recommended - includes model preload)
|
|
289
|
+
bun run test
|
|
290
|
+
|
|
291
|
+
# Run tests directly (skips 19 embedding tests, faster)
|
|
286
292
|
bun test
|
|
287
293
|
|
|
288
294
|
# Run with coverage
|
|
@@ -292,6 +298,8 @@ bun test --coverage
|
|
|
292
298
|
bun run typecheck
|
|
293
299
|
```
|
|
294
300
|
|
|
301
|
+
> **Note:** `bun run test` uses a wrapper that preloads the embedding model, running all 98 tests. `bun test` directly is faster but skips embedding-specific tests.
|
|
302
|
+
|
|
295
303
|
### Development Mode
|
|
296
304
|
|
|
297
305
|
```bash
|
|
@@ -387,7 +395,7 @@ MIT License - see [LICENSE](LICENSE) for details.
|
|
|
387
395
|
## š Related Projects
|
|
388
396
|
|
|
389
397
|
- [Model Context Protocol](https://modelcontextprotocol.io) - Official MCP specification
|
|
390
|
-
-
|
|
398
|
+
- Any MCP-compatible client
|
|
391
399
|
- [LanceDB](https://lancedb.com/) - Fast, local vector search
|
|
392
400
|
- [Transformers.js](https://huggingface.co/docs/transformers.js) - Run transformers in JavaScript
|
|
393
401
|
|
|
@@ -408,7 +416,7 @@ MIT License - see [LICENSE](LICENSE) for details.
|
|
|
408
416
|
```
|
|
409
417
|
You: "Remember that we decided to use Drizzle ORM for type-safe database access"
|
|
410
418
|
Claude: I'll store that for you.
|
|
411
|
-
[Calls
|
|
419
|
+
[Calls store_memories tool with content and metadata]
|
|
412
420
|
ā Memory stored successfully
|
|
413
421
|
```
|
|
414
422
|
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/**
|
|
3
|
+
* SessionStart hook for Claude Code
|
|
4
|
+
*
|
|
5
|
+
* Fetches config from the running vector-memory server's /health endpoint,
|
|
6
|
+
* then retrieves and outputs the latest handoff.
|
|
7
|
+
*
|
|
8
|
+
* Requires the server to be running with HTTP enabled.
|
|
9
|
+
*
|
|
10
|
+
* Usage in ~/.claude/settings.json:
|
|
11
|
+
* {
|
|
12
|
+
* "hooks": {
|
|
13
|
+
* "SessionStart": [{
|
|
14
|
+
* "hooks": [{
|
|
15
|
+
* "type": "command",
|
|
16
|
+
* "command": "bun /path/to/vector-memory-mcp/hooks/session-start.ts"
|
|
17
|
+
* }]
|
|
18
|
+
* }]
|
|
19
|
+
* }
|
|
20
|
+
* }
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import { existsSync } from "fs";
|
|
24
|
+
import { connectToDatabase } from "../src/db/connection.js";
|
|
25
|
+
import { MemoryRepository } from "../src/db/memory.repository.js";
|
|
26
|
+
import { EmbeddingsService } from "../src/services/embeddings.service.js";
|
|
27
|
+
import { MemoryService } from "../src/services/memory.service.js";
|
|
28
|
+
|
|
29
|
+
const VECTOR_MEMORY_URL = process.env.VECTOR_MEMORY_URL ?? "http://127.0.0.1:3271";
|
|
30
|
+
|
|
31
|
+
interface HealthResponse {
|
|
32
|
+
status: string;
|
|
33
|
+
config: {
|
|
34
|
+
dbPath: string;
|
|
35
|
+
embeddingModel: string;
|
|
36
|
+
embeddingDimension: number;
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async function main() {
|
|
41
|
+
// Get config from running server
|
|
42
|
+
let health: HealthResponse;
|
|
43
|
+
try {
|
|
44
|
+
const response = await fetch(`${VECTOR_MEMORY_URL}/health`);
|
|
45
|
+
if (!response.ok) {
|
|
46
|
+
throw new Error(`Server returned ${response.status}`);
|
|
47
|
+
}
|
|
48
|
+
health = await response.json();
|
|
49
|
+
} catch (error) {
|
|
50
|
+
if (error instanceof Error && error.message.includes("ECONNREFUSED")) {
|
|
51
|
+
console.log("Vector memory server not running. Starting fresh session.");
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
throw error;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const { dbPath, embeddingModel, embeddingDimension } = health.config;
|
|
58
|
+
|
|
59
|
+
// Check if DB exists
|
|
60
|
+
if (!existsSync(dbPath)) {
|
|
61
|
+
console.log("Vector memory database not found. Starting fresh session.");
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const db = await connectToDatabase(dbPath);
|
|
66
|
+
const repository = new MemoryRepository(db);
|
|
67
|
+
const embeddings = new EmbeddingsService(embeddingModel, embeddingDimension);
|
|
68
|
+
const service = new MemoryService(repository, embeddings);
|
|
69
|
+
|
|
70
|
+
const handoff = await service.getLatestHandoff();
|
|
71
|
+
|
|
72
|
+
if (!handoff) {
|
|
73
|
+
console.log("No handoff found. Starting fresh session.");
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Fetch referenced memories if any
|
|
78
|
+
const memoryIds = (handoff.metadata.memory_ids as string[] | undefined) ?? [];
|
|
79
|
+
let memoriesSection = "";
|
|
80
|
+
|
|
81
|
+
if (memoryIds.length > 0) {
|
|
82
|
+
const memories: string[] = [];
|
|
83
|
+
for (const id of memoryIds) {
|
|
84
|
+
const memory = await service.get(id);
|
|
85
|
+
if (memory) {
|
|
86
|
+
memories.push(`### Memory: ${id}\n${memory.content}`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
if (memories.length > 0) {
|
|
90
|
+
memoriesSection = `\n\n## Referenced Memories\n\n${memories.join("\n\n")}`;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
console.log(handoff.content + memoriesSection);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
main().catch((err) => {
|
|
98
|
+
console.error("Error loading handoff:", err.message);
|
|
99
|
+
process.exit(1);
|
|
100
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aeriondyseti/vector-memory-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "A zero-configuration RAG memory server for MCP clients",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.ts",
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"files": [
|
|
11
11
|
"src",
|
|
12
12
|
"scripts",
|
|
13
|
+
"hooks",
|
|
13
14
|
"README.md",
|
|
14
15
|
"LICENSE"
|
|
15
16
|
],
|
|
@@ -25,6 +26,7 @@
|
|
|
25
26
|
"scripts": {
|
|
26
27
|
"start": "bun run src/index.ts",
|
|
27
28
|
"dev": "bun --watch run src/index.ts",
|
|
29
|
+
"build": "bun run typecheck",
|
|
28
30
|
"typecheck": "bunx tsc --noEmit",
|
|
29
31
|
"test": "bun run scripts/test-runner.ts",
|
|
30
32
|
"test:raw": "bun test --preload ./tests/preload.ts",
|
|
@@ -32,14 +34,23 @@
|
|
|
32
34
|
"test:coverage": "bun test --preload ./tests/preload.ts --coverage",
|
|
33
35
|
"test:preload": "bun run tests/preload.ts",
|
|
34
36
|
"warmup": "bun run scripts/warmup.ts",
|
|
35
|
-
"postinstall": "bun run scripts/warmup.ts"
|
|
37
|
+
"postinstall": "bun run scripts/warmup.ts",
|
|
38
|
+
"publish:check": "bun run scripts/publish.ts --dry-run",
|
|
39
|
+
"publish:npm": "bun run scripts/publish.ts"
|
|
36
40
|
},
|
|
37
|
-
"keywords": [
|
|
41
|
+
"keywords": [
|
|
42
|
+
"mcp",
|
|
43
|
+
"memory",
|
|
44
|
+
"rag",
|
|
45
|
+
"embeddings",
|
|
46
|
+
"lancedb"
|
|
47
|
+
],
|
|
38
48
|
"license": "MIT",
|
|
39
49
|
"dependencies": {
|
|
40
50
|
"@huggingface/transformers": "^3.8.0",
|
|
41
51
|
"@lancedb/lancedb": "^0.22.3",
|
|
42
52
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
53
|
+
"arg": "^5.0.2",
|
|
43
54
|
"hono": "^4.11.3"
|
|
44
55
|
},
|
|
45
56
|
"devDependencies": {
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/**
|
|
3
|
+
* Publish script for vector-memory-mcp
|
|
4
|
+
*
|
|
5
|
+
* Prerequisites:
|
|
6
|
+
* 1. Create a granular access token at https://www.npmjs.com/settings/tokens
|
|
7
|
+
* 2. Store it: npm config set //registry.npmjs.org/:_authToken=npm_YOUR_TOKEN
|
|
8
|
+
* Or set NPM_TOKEN environment variable
|
|
9
|
+
*
|
|
10
|
+
* Usage: bun run scripts/publish.ts [--dry-run]
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { $ } from "bun";
|
|
14
|
+
|
|
15
|
+
const dryRun = process.argv.includes("--dry-run");
|
|
16
|
+
|
|
17
|
+
async function main() {
|
|
18
|
+
// Check for authentication
|
|
19
|
+
console.log("š Checking NPM authentication...");
|
|
20
|
+
try {
|
|
21
|
+
const whoami = await $`npm whoami`.text();
|
|
22
|
+
console.log(`ā
Authenticated as: ${whoami.trim()}`);
|
|
23
|
+
} catch {
|
|
24
|
+
console.error("ā Not authenticated with NPM.");
|
|
25
|
+
console.error(" Option 1: npm login");
|
|
26
|
+
console.error(" Option 2: npm config set //registry.npmjs.org/:_authToken=npm_YOUR_TOKEN");
|
|
27
|
+
console.error(" Option 3: Set NPM_TOKEN environment variable");
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Run tests
|
|
32
|
+
console.log("š§Ŗ Running tests...");
|
|
33
|
+
const testResult = await $`bun run test`.quiet();
|
|
34
|
+
if (testResult.exitCode !== 0) {
|
|
35
|
+
console.error("ā Tests failed. Aborting publish.");
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
console.log("ā
Tests passed");
|
|
39
|
+
|
|
40
|
+
// Build
|
|
41
|
+
console.log("šØ Building...");
|
|
42
|
+
await $`bun run build`;
|
|
43
|
+
console.log("ā
Build complete");
|
|
44
|
+
|
|
45
|
+
// Get version info
|
|
46
|
+
const pkg = await Bun.file("package.json").json();
|
|
47
|
+
console.log(`\nš¦ Publishing ${pkg.name}@${pkg.version}...`);
|
|
48
|
+
|
|
49
|
+
if (dryRun) {
|
|
50
|
+
console.log("š Dry run - would publish:");
|
|
51
|
+
await $`npm publish --dry-run`;
|
|
52
|
+
} else {
|
|
53
|
+
await $`npm publish --access public`;
|
|
54
|
+
console.log(`\nā
Published ${pkg.name}@${pkg.version}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
main().catch((err) => {
|
|
59
|
+
console.error("ā Publish failed:", err.message);
|
|
60
|
+
process.exit(1);
|
|
61
|
+
});
|
package/scripts/warmup.ts
CHANGED
|
@@ -52,8 +52,7 @@ async function warmup(): Promise<void> {
|
|
|
52
52
|
console.log();
|
|
53
53
|
console.log(`ā
Warmup complete! (${duration}s)`);
|
|
54
54
|
console.log();
|
|
55
|
-
console.log("Ready to use! Configure
|
|
56
|
-
console.log("See: https://github.com/AerionDyseti/vector-memory-mcp#configure-claude-code");
|
|
55
|
+
console.log("Ready to use! Configure your MCP client and restart to get started.");
|
|
57
56
|
console.log();
|
|
58
57
|
} catch (error) {
|
|
59
58
|
console.error();
|
package/src/config/index.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import arg from "arg";
|
|
1
2
|
import { join } from "path";
|
|
2
|
-
|
|
3
|
+
|
|
4
|
+
export type TransportMode = "stdio" | "http" | "both";
|
|
3
5
|
|
|
4
6
|
export interface Config {
|
|
5
7
|
dbPath: string;
|
|
@@ -8,30 +10,66 @@ export interface Config {
|
|
|
8
10
|
httpPort: number;
|
|
9
11
|
httpHost: string;
|
|
10
12
|
enableHttp: boolean;
|
|
13
|
+
transportMode: TransportMode;
|
|
11
14
|
}
|
|
12
15
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
);
|
|
16
|
+
export interface ConfigOverrides {
|
|
17
|
+
dbPath?: string;
|
|
18
|
+
httpPort?: number;
|
|
19
|
+
enableHttp?: boolean;
|
|
20
|
+
transportMode?: TransportMode;
|
|
21
|
+
}
|
|
20
22
|
|
|
23
|
+
// Defaults - always use repo-local .vector-memory folder
|
|
24
|
+
const DEFAULT_DB_PATH = join(process.cwd(), ".vector-memory", "memories.db");
|
|
21
25
|
const DEFAULT_EMBEDDING_MODEL = "Xenova/all-MiniLM-L6-v2";
|
|
22
26
|
const DEFAULT_EMBEDDING_DIMENSION = 384;
|
|
23
27
|
const DEFAULT_HTTP_PORT = 3271;
|
|
24
28
|
const DEFAULT_HTTP_HOST = "127.0.0.1";
|
|
25
29
|
|
|
26
|
-
|
|
30
|
+
function resolvePath(path: string): string {
|
|
31
|
+
return path.startsWith("/") ? path : join(process.cwd(), path);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function loadConfig(overrides: ConfigOverrides = {}): Config {
|
|
35
|
+
const transportMode = overrides.transportMode ?? "stdio";
|
|
36
|
+
// HTTP enabled by default (needed for hooks), can disable with --no-http
|
|
37
|
+
const enableHttp = overrides.enableHttp ?? true;
|
|
38
|
+
|
|
27
39
|
return {
|
|
28
|
-
dbPath:
|
|
29
|
-
embeddingModel:
|
|
40
|
+
dbPath: resolvePath(overrides.dbPath ?? DEFAULT_DB_PATH),
|
|
41
|
+
embeddingModel: DEFAULT_EMBEDDING_MODEL,
|
|
30
42
|
embeddingDimension: DEFAULT_EMBEDDING_DIMENSION,
|
|
31
|
-
httpPort:
|
|
32
|
-
httpHost:
|
|
33
|
-
enableHttp
|
|
43
|
+
httpPort: overrides.httpPort ?? DEFAULT_HTTP_PORT,
|
|
44
|
+
httpHost: DEFAULT_HTTP_HOST,
|
|
45
|
+
enableHttp,
|
|
46
|
+
transportMode,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Parse CLI arguments into config overrides.
|
|
52
|
+
*/
|
|
53
|
+
export function parseCliArgs(argv: string[]): ConfigOverrides {
|
|
54
|
+
const args = arg(
|
|
55
|
+
{
|
|
56
|
+
"--db-file": String,
|
|
57
|
+
"--port": Number,
|
|
58
|
+
"--no-http": Boolean,
|
|
59
|
+
|
|
60
|
+
// Aliases
|
|
61
|
+
"-d": "--db-file",
|
|
62
|
+
"-p": "--port",
|
|
63
|
+
},
|
|
64
|
+
{ argv, permissive: true }
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
return {
|
|
68
|
+
dbPath: args["--db-file"],
|
|
69
|
+
httpPort: args["--port"],
|
|
70
|
+
enableHttp: args["--no-http"] ? false : undefined,
|
|
34
71
|
};
|
|
35
72
|
}
|
|
36
73
|
|
|
74
|
+
// Default config for imports that don't use CLI args
|
|
37
75
|
export const config = loadConfig();
|
|
@@ -33,6 +33,27 @@ export class MemoryRepository {
|
|
|
33
33
|
]);
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
async upsert(memory: Memory): Promise<void> {
|
|
37
|
+
const table = await this.getTable();
|
|
38
|
+
const existing = await table.query().where(`id = '${memory.id}'`).limit(1).toArray();
|
|
39
|
+
|
|
40
|
+
if (existing.length === 0) {
|
|
41
|
+
return await this.insert(memory);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
await table.update({
|
|
45
|
+
where: `id = '${memory.id}'`,
|
|
46
|
+
values: {
|
|
47
|
+
vector: memory.embedding,
|
|
48
|
+
content: memory.content,
|
|
49
|
+
metadata: JSON.stringify(memory.metadata),
|
|
50
|
+
created_at: memory.createdAt.getTime(),
|
|
51
|
+
updated_at: memory.updatedAt.getTime(),
|
|
52
|
+
superseded_by: memory.supersededBy,
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
36
57
|
async findById(id: string): Promise<Memory | null> {
|
|
37
58
|
const table = await this.getTable();
|
|
38
59
|
const results = await table.query().where(`id = '${id}'`).limit(1).toArray();
|
package/src/db/schema.ts
CHANGED