memvault 0.0.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.
- package/LICENSE +21 -0
- package/README.md +203 -0
- package/dist/chunk-JJHMEQOW.js +136 -0
- package/dist/chunk-JJHMEQOW.js.map +1 -0
- package/dist/index.d.ts +67 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/integrations/ai-sdk.d.ts +64 -0
- package/dist/integrations/ai-sdk.js +95 -0
- package/dist/integrations/ai-sdk.js.map +1 -0
- package/dist/integrations/anthropic.d.ts +33 -0
- package/dist/integrations/anthropic.js +146 -0
- package/dist/integrations/anthropic.js.map +1 -0
- package/dist/integrations/openai.d.ts +32 -0
- package/dist/integrations/openai.js +159 -0
- package/dist/integrations/openai.js.map +1 -0
- package/dist/types-BbBXYjeB.d.ts +116 -0
- package/package.json +90 -0
- package/prisma/schema.prisma +30 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 iamsaad640
|
|
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,203 @@
|
|
|
1
|
+
# memvault
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/memvault)
|
|
4
|
+
[](https://www.typescriptlang.org/)
|
|
5
|
+
[](https://www.prisma.io/)
|
|
6
|
+
[](https://github.com/iamsaad640/memvault)
|
|
7
|
+
[](https://opensource.org/licenses/MIT)
|
|
8
|
+
[](https://ai-sdk.dev)
|
|
9
|
+
[](https://platform.openai.com)
|
|
10
|
+
[](https://docs.anthropic.com)
|
|
11
|
+
|
|
12
|
+
> Persistent, tenant-isolated memory tools for AI agents. Prisma-powered. Drop-in tools for Vercel AI SDK, OpenAI, and Anthropic.
|
|
13
|
+
|
|
14
|
+
**No cloud. No Neo4j. No $249/mo paywall. Just your PostgreSQL.**
|
|
15
|
+
|
|
16
|
+
## Install
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install memvault
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Setup
|
|
23
|
+
|
|
24
|
+
### 1. Add the model to your Prisma schema
|
|
25
|
+
|
|
26
|
+
```prisma
|
|
27
|
+
model MemvaultMemory {
|
|
28
|
+
id String @id @default(cuid())
|
|
29
|
+
tenantId String
|
|
30
|
+
type String @default("general")
|
|
31
|
+
content String
|
|
32
|
+
metadata Json?
|
|
33
|
+
tags String[]
|
|
34
|
+
createdAt DateTime @default(now())
|
|
35
|
+
updatedAt DateTime @updatedAt
|
|
36
|
+
expiresAt DateTime?
|
|
37
|
+
|
|
38
|
+
@@index([tenantId])
|
|
39
|
+
@@index([tenantId, type])
|
|
40
|
+
@@map("memvault_memories")
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### 2. Run migration
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
npx prisma migrate dev --name add-memvault
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### 3. Create vault instance
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
import { MemVault } from "memvault"
|
|
54
|
+
|
|
55
|
+
const vault = new MemVault({ db: prisma.memvaultMemory })
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Usage with AI SDKs
|
|
59
|
+
|
|
60
|
+
### Vercel AI SDK
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
import { createMemVaultTools } from "memvault/ai-sdk"
|
|
64
|
+
import { generateText } from "ai"
|
|
65
|
+
import { anthropic } from "@ai-sdk/anthropic"
|
|
66
|
+
|
|
67
|
+
const tools = createMemVaultTools({ vault, tenantId: user.id })
|
|
68
|
+
|
|
69
|
+
const result = await generateText({
|
|
70
|
+
model: anthropic("claude-sonnet-4-6"),
|
|
71
|
+
tools,
|
|
72
|
+
prompt: "Help the user with their project"
|
|
73
|
+
})
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### OpenAI SDK
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
import { createMemVaultTools } from "memvault/openai"
|
|
80
|
+
|
|
81
|
+
const { tools, handleToolCall } = createMemVaultTools({ vault, tenantId: user.id })
|
|
82
|
+
|
|
83
|
+
const response = await openai.responses.create({
|
|
84
|
+
model: "gpt-4o",
|
|
85
|
+
tools,
|
|
86
|
+
input: "Help the user..."
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
// Handle tool calls from the response
|
|
90
|
+
for (const output of response.output) {
|
|
91
|
+
if (output.type === "function_call") {
|
|
92
|
+
const result = await handleToolCall(output.name, JSON.parse(output.arguments))
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Anthropic SDK
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
import { createMemVaultTools } from "memvault/anthropic"
|
|
101
|
+
|
|
102
|
+
const { tools, handleToolCall } = createMemVaultTools({ vault, tenantId: user.id })
|
|
103
|
+
|
|
104
|
+
const message = await anthropic.messages.create({
|
|
105
|
+
model: "claude-sonnet-4-6",
|
|
106
|
+
max_tokens: 1024,
|
|
107
|
+
tools,
|
|
108
|
+
messages: [{ role: "user", content: "Help me..." }]
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
// Handle tool calls from the response
|
|
112
|
+
for (const block of message.content) {
|
|
113
|
+
if (block.type === "tool_use") {
|
|
114
|
+
const result = await handleToolCall(block.name, block.input)
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Standalone (no LLM)
|
|
120
|
+
|
|
121
|
+
```typescript
|
|
122
|
+
const tenant = vault.tenant("user-123")
|
|
123
|
+
|
|
124
|
+
await tenant.remember({
|
|
125
|
+
content: "Prefers dark mode",
|
|
126
|
+
type: "preference",
|
|
127
|
+
tags: ["ui", "theme"]
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
const memories = await tenant.recall({ type: "preference" })
|
|
131
|
+
await tenant.update(memoryId, { content: "Switched to light mode" })
|
|
132
|
+
await tenant.forget(memoryId)
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Tools Provided
|
|
136
|
+
|
|
137
|
+
Each SDK integration provides 4 tools:
|
|
138
|
+
|
|
139
|
+
| Tool | Description |
|
|
140
|
+
|------|-------------|
|
|
141
|
+
| `memvault_remember` | Save information to persistent memory |
|
|
142
|
+
| `memvault_recall` | Retrieve relevant memories with filters |
|
|
143
|
+
| `memvault_update` | Update existing memories |
|
|
144
|
+
| `memvault_forget` | Delete a specific memory |
|
|
145
|
+
|
|
146
|
+
The LLM decides when to use each tool based on the built-in descriptions.
|
|
147
|
+
|
|
148
|
+
## Tenant Isolation
|
|
149
|
+
|
|
150
|
+
Every operation is scoped to a `tenantId`. No tenant can read, update, or delete another tenant's memories.
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
const alice = vault.tenant("alice")
|
|
154
|
+
const bob = vault.tenant("bob")
|
|
155
|
+
|
|
156
|
+
await alice.remember({ content: "Alice's secret" })
|
|
157
|
+
await bob.recall() // Returns empty — Bob can't see Alice's memories
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## Memory Types
|
|
161
|
+
|
|
162
|
+
Organize memories by type:
|
|
163
|
+
|
|
164
|
+
- `preference` — User preferences and settings
|
|
165
|
+
- `fact` — Facts about the user
|
|
166
|
+
- `feedback` — User feedback on behavior
|
|
167
|
+
- `project` — Project context and details
|
|
168
|
+
- `reference` — Links and external references
|
|
169
|
+
- `general` — Default catch-all
|
|
170
|
+
- Any custom string
|
|
171
|
+
|
|
172
|
+
## TTL (Time-to-Live)
|
|
173
|
+
|
|
174
|
+
Set temporary memories that auto-expire:
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
await tenant.remember({
|
|
178
|
+
content: "Currently debugging auth flow",
|
|
179
|
+
type: "context",
|
|
180
|
+
ttl: 3600 // expires in 1 hour
|
|
181
|
+
})
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
## API
|
|
185
|
+
|
|
186
|
+
### `MemVault`
|
|
187
|
+
|
|
188
|
+
- `new MemVault({ db })` — Create instance with Prisma delegate
|
|
189
|
+
- `vault.tenant(tenantId)` — Get tenant-scoped vault
|
|
190
|
+
|
|
191
|
+
### `TenantVault`
|
|
192
|
+
|
|
193
|
+
- `tenant.remember(input)` — Save a memory
|
|
194
|
+
- `tenant.recall(filter?)` — Query memories
|
|
195
|
+
- `tenant.get(id)` — Get specific memory
|
|
196
|
+
- `tenant.update(id, input)` — Update a memory
|
|
197
|
+
- `tenant.forget(id)` — Delete a memory
|
|
198
|
+
- `tenant.forgetAll()` — Delete all tenant memories
|
|
199
|
+
- `tenant.count(filter?)` — Count memories
|
|
200
|
+
|
|
201
|
+
## License
|
|
202
|
+
|
|
203
|
+
MIT
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
// src/tenant.ts
|
|
2
|
+
var TenantVault = class {
|
|
3
|
+
constructor(db, tenantId) {
|
|
4
|
+
this.db = db;
|
|
5
|
+
this.tenantId = tenantId;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Save a memory for this tenant.
|
|
9
|
+
*/
|
|
10
|
+
async remember(input) {
|
|
11
|
+
const now = /* @__PURE__ */ new Date();
|
|
12
|
+
const expiresAt = input.ttl != null ? new Date(now.getTime() + input.ttl * 1e3) : null;
|
|
13
|
+
return this.db.create({
|
|
14
|
+
data: {
|
|
15
|
+
tenantId: this.tenantId,
|
|
16
|
+
content: input.content,
|
|
17
|
+
type: input.type ?? "general",
|
|
18
|
+
metadata: input.metadata ?? null,
|
|
19
|
+
tags: input.tags ?? [],
|
|
20
|
+
expiresAt
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Retrieve memories for this tenant, with optional filters.
|
|
26
|
+
* Expired memories are excluded by default.
|
|
27
|
+
*/
|
|
28
|
+
async recall(filter) {
|
|
29
|
+
const where = this.buildWhere(filter);
|
|
30
|
+
return this.db.findMany({
|
|
31
|
+
where,
|
|
32
|
+
orderBy: { createdAt: "desc" },
|
|
33
|
+
take: filter?.limit
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Get a specific memory by ID. Returns null if not found or belongs to another tenant.
|
|
38
|
+
*/
|
|
39
|
+
async get(id) {
|
|
40
|
+
const memory = await this.db.findUnique({ where: { id } });
|
|
41
|
+
if (!memory || memory.tenantId !== this.tenantId) return null;
|
|
42
|
+
return memory;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Update an existing memory. Only updates fields that are provided.
|
|
46
|
+
* Throws if the memory doesn't exist or belongs to another tenant.
|
|
47
|
+
*/
|
|
48
|
+
async update(id, input) {
|
|
49
|
+
const existing = await this.get(id);
|
|
50
|
+
if (!existing) {
|
|
51
|
+
throw new Error(`Memory "${id}" not found for tenant "${this.tenantId}"`);
|
|
52
|
+
}
|
|
53
|
+
const data = {};
|
|
54
|
+
if (input.content !== void 0) data.content = input.content;
|
|
55
|
+
if (input.type !== void 0) data.type = input.type;
|
|
56
|
+
if (input.metadata !== void 0) data.metadata = input.metadata;
|
|
57
|
+
if (input.tags !== void 0) data.tags = input.tags;
|
|
58
|
+
if (input.ttl !== void 0) {
|
|
59
|
+
data.expiresAt = input.ttl === null ? null : new Date(Date.now() + input.ttl * 1e3);
|
|
60
|
+
}
|
|
61
|
+
return this.db.update({ where: { id }, data });
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Delete a specific memory. Silently succeeds if memory doesn't exist.
|
|
65
|
+
*/
|
|
66
|
+
async forget(id) {
|
|
67
|
+
const existing = await this.get(id);
|
|
68
|
+
if (!existing) return;
|
|
69
|
+
await this.db.delete({ where: { id } });
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Delete all memories for this tenant. Returns the count of deleted records.
|
|
73
|
+
*/
|
|
74
|
+
async forgetAll() {
|
|
75
|
+
const result = await this.db.deleteMany({
|
|
76
|
+
where: { tenantId: this.tenantId }
|
|
77
|
+
});
|
|
78
|
+
return result.count;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Count memories for this tenant with optional filters.
|
|
82
|
+
*/
|
|
83
|
+
async count(filter) {
|
|
84
|
+
const where = this.buildWhere(filter);
|
|
85
|
+
return this.db.count({ where });
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Build a Prisma where clause scoped to this tenant.
|
|
89
|
+
*/
|
|
90
|
+
buildWhere(filter) {
|
|
91
|
+
const where = {
|
|
92
|
+
tenantId: this.tenantId
|
|
93
|
+
};
|
|
94
|
+
if (filter?.type) {
|
|
95
|
+
where.type = filter.type;
|
|
96
|
+
}
|
|
97
|
+
if (filter?.tags && filter.tags.length > 0) {
|
|
98
|
+
where.tags = { hasSome: filter.tags };
|
|
99
|
+
}
|
|
100
|
+
if (filter?.search) {
|
|
101
|
+
where.content = { contains: filter.search, mode: "insensitive" };
|
|
102
|
+
}
|
|
103
|
+
if (!filter?.includeExpired) {
|
|
104
|
+
where.OR = [{ expiresAt: null }, { expiresAt: { gt: /* @__PURE__ */ new Date() } }];
|
|
105
|
+
}
|
|
106
|
+
return where;
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
// src/memvault.ts
|
|
111
|
+
var MemVault = class {
|
|
112
|
+
config;
|
|
113
|
+
constructor(config) {
|
|
114
|
+
if (!config.db) {
|
|
115
|
+
throw new Error(
|
|
116
|
+
"MemVault requires a Prisma delegate. Pass { db: prisma.memvaultMemory }"
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
this.config = config;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Get a tenant-scoped vault. All operations are isolated to this tenant.
|
|
123
|
+
*/
|
|
124
|
+
tenant(tenantId) {
|
|
125
|
+
if (!tenantId || typeof tenantId !== "string") {
|
|
126
|
+
throw new Error("tenantId must be a non-empty string");
|
|
127
|
+
}
|
|
128
|
+
return new TenantVault(this.config.db, tenantId);
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
export {
|
|
133
|
+
TenantVault,
|
|
134
|
+
MemVault
|
|
135
|
+
};
|
|
136
|
+
//# sourceMappingURL=chunk-JJHMEQOW.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/tenant.ts","../src/memvault.ts"],"sourcesContent":["import type {\n Memory,\n MemoryInput,\n MemoryUpdate,\n MemoryFilter,\n MemvaultPrismaDelegate,\n TenantVaultInstance,\n} from \"./types.js\";\n\n/**\n * All operations are scoped to a single tenant.\n * No query can ever leak across tenant boundaries.\n */\nexport class TenantVault implements TenantVaultInstance {\n constructor(\n private readonly db: MemvaultPrismaDelegate,\n public readonly tenantId: string,\n ) {}\n\n /**\n * Save a memory for this tenant.\n */\n async remember(input: MemoryInput): Promise<Memory> {\n const now = new Date();\n const expiresAt =\n input.ttl != null ? new Date(now.getTime() + input.ttl * 1000) : null;\n\n return this.db.create({\n data: {\n tenantId: this.tenantId,\n content: input.content,\n type: input.type ?? \"general\",\n metadata: input.metadata ?? null,\n tags: input.tags ?? [],\n expiresAt,\n },\n });\n }\n\n /**\n * Retrieve memories for this tenant, with optional filters.\n * Expired memories are excluded by default.\n */\n async recall(filter?: MemoryFilter): Promise<Memory[]> {\n const where = this.buildWhere(filter);\n\n return this.db.findMany({\n where,\n orderBy: { createdAt: \"desc\" },\n take: filter?.limit,\n });\n }\n\n /**\n * Get a specific memory by ID. Returns null if not found or belongs to another tenant.\n */\n async get(id: string): Promise<Memory | null> {\n const memory = await this.db.findUnique({ where: { id } });\n if (!memory || memory.tenantId !== this.tenantId) return null;\n return memory;\n }\n\n /**\n * Update an existing memory. Only updates fields that are provided.\n * Throws if the memory doesn't exist or belongs to another tenant.\n */\n async update(id: string, input: MemoryUpdate): Promise<Memory> {\n const existing = await this.get(id);\n if (!existing) {\n throw new Error(`Memory \"${id}\" not found for tenant \"${this.tenantId}\"`);\n }\n\n const data: Record<string, unknown> = {};\n if (input.content !== undefined) data.content = input.content;\n if (input.type !== undefined) data.type = input.type;\n if (input.metadata !== undefined) data.metadata = input.metadata;\n if (input.tags !== undefined) data.tags = input.tags;\n if (input.ttl !== undefined) {\n data.expiresAt =\n input.ttl === null\n ? null\n : new Date(Date.now() + input.ttl * 1000);\n }\n\n return this.db.update({ where: { id }, data });\n }\n\n /**\n * Delete a specific memory. Silently succeeds if memory doesn't exist.\n */\n async forget(id: string): Promise<void> {\n const existing = await this.get(id);\n if (!existing) return;\n await this.db.delete({ where: { id } });\n }\n\n /**\n * Delete all memories for this tenant. Returns the count of deleted records.\n */\n async forgetAll(): Promise<number> {\n const result = await this.db.deleteMany({\n where: { tenantId: this.tenantId },\n });\n return result.count;\n }\n\n /**\n * Count memories for this tenant with optional filters.\n */\n async count(filter?: MemoryFilter): Promise<number> {\n const where = this.buildWhere(filter);\n return this.db.count({ where });\n }\n\n /**\n * Build a Prisma where clause scoped to this tenant.\n */\n private buildWhere(filter?: MemoryFilter): Record<string, unknown> {\n const where: Record<string, unknown> = {\n tenantId: this.tenantId,\n };\n\n if (filter?.type) {\n where.type = filter.type;\n }\n\n if (filter?.tags && filter.tags.length > 0) {\n where.tags = { hasSome: filter.tags };\n }\n\n if (filter?.search) {\n where.content = { contains: filter.search, mode: \"insensitive\" };\n }\n\n if (!filter?.includeExpired) {\n where.OR = [{ expiresAt: null }, { expiresAt: { gt: new Date() } }];\n }\n\n return where;\n }\n}\n","import type { MemVaultConfig, MemVaultInstance } from \"./types.js\";\nimport { TenantVault } from \"./tenant.js\";\n\n/**\n * MemVault — persistent, tenant-isolated memory for AI agents.\n *\n * Usage:\n * ```ts\n * const vault = new MemVault({ db: prisma.memvaultMemory })\n * const tenant = vault.tenant(\"user-123\")\n * await tenant.remember({ content: \"Prefers dark mode\", type: \"preference\" })\n * ```\n */\nexport class MemVault implements MemVaultInstance {\n private readonly config: MemVaultConfig;\n\n constructor(config: MemVaultConfig) {\n if (!config.db) {\n throw new Error(\n \"MemVault requires a Prisma delegate. Pass { db: prisma.memvaultMemory }\",\n );\n }\n this.config = config;\n }\n\n /**\n * Get a tenant-scoped vault. All operations are isolated to this tenant.\n */\n tenant(tenantId: string): TenantVault {\n if (!tenantId || typeof tenantId !== \"string\") {\n throw new Error(\"tenantId must be a non-empty string\");\n }\n return new TenantVault(this.config.db, tenantId);\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { T as TenantVaultInstance, M as MemvaultPrismaDelegate, a as MemoryInput, b as Memory, c as MemoryFilter, d as MemoryUpdate, e as MemVaultInstance, f as MemVaultConfig } from './types-BbBXYjeB.js';
|
|
2
|
+
export { g as ToolsConfig } from './types-BbBXYjeB.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* All operations are scoped to a single tenant.
|
|
6
|
+
* No query can ever leak across tenant boundaries.
|
|
7
|
+
*/
|
|
8
|
+
declare class TenantVault implements TenantVaultInstance {
|
|
9
|
+
private readonly db;
|
|
10
|
+
readonly tenantId: string;
|
|
11
|
+
constructor(db: MemvaultPrismaDelegate, tenantId: string);
|
|
12
|
+
/**
|
|
13
|
+
* Save a memory for this tenant.
|
|
14
|
+
*/
|
|
15
|
+
remember(input: MemoryInput): Promise<Memory>;
|
|
16
|
+
/**
|
|
17
|
+
* Retrieve memories for this tenant, with optional filters.
|
|
18
|
+
* Expired memories are excluded by default.
|
|
19
|
+
*/
|
|
20
|
+
recall(filter?: MemoryFilter): Promise<Memory[]>;
|
|
21
|
+
/**
|
|
22
|
+
* Get a specific memory by ID. Returns null if not found or belongs to another tenant.
|
|
23
|
+
*/
|
|
24
|
+
get(id: string): Promise<Memory | null>;
|
|
25
|
+
/**
|
|
26
|
+
* Update an existing memory. Only updates fields that are provided.
|
|
27
|
+
* Throws if the memory doesn't exist or belongs to another tenant.
|
|
28
|
+
*/
|
|
29
|
+
update(id: string, input: MemoryUpdate): Promise<Memory>;
|
|
30
|
+
/**
|
|
31
|
+
* Delete a specific memory. Silently succeeds if memory doesn't exist.
|
|
32
|
+
*/
|
|
33
|
+
forget(id: string): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Delete all memories for this tenant. Returns the count of deleted records.
|
|
36
|
+
*/
|
|
37
|
+
forgetAll(): Promise<number>;
|
|
38
|
+
/**
|
|
39
|
+
* Count memories for this tenant with optional filters.
|
|
40
|
+
*/
|
|
41
|
+
count(filter?: MemoryFilter): Promise<number>;
|
|
42
|
+
/**
|
|
43
|
+
* Build a Prisma where clause scoped to this tenant.
|
|
44
|
+
*/
|
|
45
|
+
private buildWhere;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* MemVault — persistent, tenant-isolated memory for AI agents.
|
|
50
|
+
*
|
|
51
|
+
* Usage:
|
|
52
|
+
* ```ts
|
|
53
|
+
* const vault = new MemVault({ db: prisma.memvaultMemory })
|
|
54
|
+
* const tenant = vault.tenant("user-123")
|
|
55
|
+
* await tenant.remember({ content: "Prefers dark mode", type: "preference" })
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
declare class MemVault implements MemVaultInstance {
|
|
59
|
+
private readonly config;
|
|
60
|
+
constructor(config: MemVaultConfig);
|
|
61
|
+
/**
|
|
62
|
+
* Get a tenant-scoped vault. All operations are isolated to this tenant.
|
|
63
|
+
*/
|
|
64
|
+
tenant(tenantId: string): TenantVault;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export { MemVault, MemVaultConfig, MemVaultInstance, Memory, MemoryFilter, MemoryInput, MemoryUpdate, MemvaultPrismaDelegate, TenantVault, TenantVaultInstance };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import * as ai from 'ai';
|
|
2
|
+
import { g as ToolsConfig } from '../types-BbBXYjeB.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Create drop-in memory tools for the Vercel AI SDK.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { createMemVaultTools } from "memvault/ai-sdk"
|
|
10
|
+
*
|
|
11
|
+
* const tools = createMemVaultTools({ vault, tenantId: user.id })
|
|
12
|
+
*
|
|
13
|
+
* const result = await generateText({
|
|
14
|
+
* model: anthropic("claude-sonnet-4-6"),
|
|
15
|
+
* tools,
|
|
16
|
+
* prompt: "Help the user..."
|
|
17
|
+
* })
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
declare function createMemVaultTools(config: ToolsConfig): {
|
|
21
|
+
memvault_remember: ai.Tool<{
|
|
22
|
+
content: string;
|
|
23
|
+
type?: string | undefined;
|
|
24
|
+
tags?: string[] | undefined;
|
|
25
|
+
ttl?: number | undefined;
|
|
26
|
+
}, {
|
|
27
|
+
success: boolean;
|
|
28
|
+
id: string;
|
|
29
|
+
message: string;
|
|
30
|
+
}>;
|
|
31
|
+
memvault_recall: ai.Tool<{
|
|
32
|
+
type?: string | undefined;
|
|
33
|
+
tags?: string[] | undefined;
|
|
34
|
+
search?: string | undefined;
|
|
35
|
+
limit?: number | undefined;
|
|
36
|
+
}, {
|
|
37
|
+
count: number;
|
|
38
|
+
memories: {
|
|
39
|
+
id: string;
|
|
40
|
+
type: string;
|
|
41
|
+
content: string;
|
|
42
|
+
tags: string[];
|
|
43
|
+
createdAt: string;
|
|
44
|
+
}[];
|
|
45
|
+
}>;
|
|
46
|
+
memvault_forget: ai.Tool<{
|
|
47
|
+
id: string;
|
|
48
|
+
}, {
|
|
49
|
+
success: boolean;
|
|
50
|
+
message: string;
|
|
51
|
+
}>;
|
|
52
|
+
memvault_update: ai.Tool<{
|
|
53
|
+
id: string;
|
|
54
|
+
content?: string | undefined;
|
|
55
|
+
type?: string | undefined;
|
|
56
|
+
tags?: string[] | undefined;
|
|
57
|
+
}, {
|
|
58
|
+
success: boolean;
|
|
59
|
+
id: string;
|
|
60
|
+
message: string;
|
|
61
|
+
}>;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export { createMemVaultTools };
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import "../chunk-JJHMEQOW.js";
|
|
2
|
+
|
|
3
|
+
// src/integrations/ai-sdk.ts
|
|
4
|
+
import { tool } from "ai";
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
function createMemVaultTools(config) {
|
|
7
|
+
const tenant = config.vault.tenant(config.tenantId);
|
|
8
|
+
return {
|
|
9
|
+
memvault_remember: tool({
|
|
10
|
+
description: "Save important information to persistent memory for this user. Use this when the user shares preferences, facts about themselves, project context, feedback, or anything worth remembering across sessions. Memories persist permanently unless given a TTL.",
|
|
11
|
+
inputSchema: z.object({
|
|
12
|
+
content: z.string().describe("The information to remember. Be specific and concise."),
|
|
13
|
+
type: z.string().optional().describe(
|
|
14
|
+
'Category: "preference", "fact", "feedback", "project", "reference", or any custom type. Defaults to "general".'
|
|
15
|
+
),
|
|
16
|
+
tags: z.array(z.string()).optional().describe("Tags for categorization and filtering, e.g. ['ui', 'theme']"),
|
|
17
|
+
ttl: z.number().optional().describe(
|
|
18
|
+
"Time-to-live in seconds. Omit for permanent memory. Use for temporary/session info."
|
|
19
|
+
)
|
|
20
|
+
}),
|
|
21
|
+
execute: async (input) => {
|
|
22
|
+
const memory = await tenant.remember({
|
|
23
|
+
content: input.content,
|
|
24
|
+
type: input.type,
|
|
25
|
+
tags: input.tags,
|
|
26
|
+
ttl: input.ttl
|
|
27
|
+
});
|
|
28
|
+
return {
|
|
29
|
+
success: true,
|
|
30
|
+
id: memory.id,
|
|
31
|
+
message: `Remembered: "${memory.content}" (type: ${memory.type})`
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
}),
|
|
35
|
+
memvault_recall: tool({
|
|
36
|
+
description: "Retrieve memories for this user. Use this BEFORE responding when you need context about the user's preferences, past conversations, project details, or any previously saved information. Always recall relevant memories to personalize your responses.",
|
|
37
|
+
inputSchema: z.object({
|
|
38
|
+
type: z.string().optional().describe("Filter by memory type, e.g. 'preference', 'project'"),
|
|
39
|
+
tags: z.array(z.string()).optional().describe("Filter by tags \u2014 returns memories matching ANY of these tags"),
|
|
40
|
+
search: z.string().optional().describe("Search memory content (case-insensitive substring match)"),
|
|
41
|
+
limit: z.number().optional().describe("Max number of memories to return. Defaults to all.")
|
|
42
|
+
}),
|
|
43
|
+
execute: async (input) => {
|
|
44
|
+
const memories = await tenant.recall({
|
|
45
|
+
type: input.type,
|
|
46
|
+
tags: input.tags,
|
|
47
|
+
search: input.search,
|
|
48
|
+
limit: input.limit
|
|
49
|
+
});
|
|
50
|
+
return {
|
|
51
|
+
count: memories.length,
|
|
52
|
+
memories: memories.map((m) => ({
|
|
53
|
+
id: m.id,
|
|
54
|
+
type: m.type,
|
|
55
|
+
content: m.content,
|
|
56
|
+
tags: m.tags,
|
|
57
|
+
createdAt: m.createdAt.toISOString()
|
|
58
|
+
}))
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
}),
|
|
62
|
+
memvault_forget: tool({
|
|
63
|
+
description: "Delete a specific memory by ID. Use when the user asks to forget something or when information is outdated and should be removed.",
|
|
64
|
+
inputSchema: z.object({
|
|
65
|
+
id: z.string().describe("The memory ID to delete")
|
|
66
|
+
}),
|
|
67
|
+
execute: async (input) => {
|
|
68
|
+
await tenant.forget(input.id);
|
|
69
|
+
return { success: true, message: `Memory ${input.id} deleted.` };
|
|
70
|
+
}
|
|
71
|
+
}),
|
|
72
|
+
memvault_update: tool({
|
|
73
|
+
description: "Update an existing memory. Use when information has changed and the old memory should be corrected rather than deleted and re-created.",
|
|
74
|
+
inputSchema: z.object({
|
|
75
|
+
id: z.string().describe("The memory ID to update"),
|
|
76
|
+
content: z.string().optional().describe("New content to replace the existing memory content"),
|
|
77
|
+
type: z.string().optional().describe("New type for the memory"),
|
|
78
|
+
tags: z.array(z.string()).optional().describe("New tags (replaces existing tags)")
|
|
79
|
+
}),
|
|
80
|
+
execute: async (input) => {
|
|
81
|
+
const { id, ...updates } = input;
|
|
82
|
+
const memory = await tenant.update(id, updates);
|
|
83
|
+
return {
|
|
84
|
+
success: true,
|
|
85
|
+
id: memory.id,
|
|
86
|
+
message: `Updated memory: "${memory.content}"`
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
})
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
export {
|
|
93
|
+
createMemVaultTools
|
|
94
|
+
};
|
|
95
|
+
//# sourceMappingURL=ai-sdk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/integrations/ai-sdk.ts"],"sourcesContent":["import { tool } from \"ai\";\nimport { z } from \"zod\";\nimport { MemVault } from \"../memvault.js\";\nimport type { ToolsConfig } from \"../types.js\";\n\n/**\n * Create drop-in memory tools for the Vercel AI SDK.\n *\n * Usage:\n * ```ts\n * import { createMemVaultTools } from \"memvault/ai-sdk\"\n *\n * const tools = createMemVaultTools({ vault, tenantId: user.id })\n *\n * const result = await generateText({\n * model: anthropic(\"claude-sonnet-4-6\"),\n * tools,\n * prompt: \"Help the user...\"\n * })\n * ```\n */\nexport function createMemVaultTools(config: ToolsConfig) {\n const tenant = config.vault.tenant(config.tenantId);\n\n return {\n memvault_remember: tool({\n description:\n \"Save important information to persistent memory for this user. \" +\n \"Use this when the user shares preferences, facts about themselves, \" +\n \"project context, feedback, or anything worth remembering across sessions. \" +\n \"Memories persist permanently unless given a TTL.\",\n inputSchema: z.object({\n content: z\n .string()\n .describe(\"The information to remember. Be specific and concise.\"),\n type: z\n .string()\n .optional()\n .describe(\n 'Category: \"preference\", \"fact\", \"feedback\", \"project\", \"reference\", or any custom type. Defaults to \"general\".',\n ),\n tags: z\n .array(z.string())\n .optional()\n .describe(\"Tags for categorization and filtering, e.g. ['ui', 'theme']\"),\n ttl: z\n .number()\n .optional()\n .describe(\n \"Time-to-live in seconds. Omit for permanent memory. Use for temporary/session info.\",\n ),\n }),\n execute: async (input) => {\n const memory = await tenant.remember({\n content: input.content,\n type: input.type,\n tags: input.tags,\n ttl: input.ttl,\n });\n return {\n success: true,\n id: memory.id,\n message: `Remembered: \"${memory.content}\" (type: ${memory.type})`,\n };\n },\n }),\n\n memvault_recall: tool({\n description:\n \"Retrieve memories for this user. Use this BEFORE responding when you need \" +\n \"context about the user's preferences, past conversations, project details, \" +\n \"or any previously saved information. Always recall relevant memories to \" +\n \"personalize your responses.\",\n inputSchema: z.object({\n type: z\n .string()\n .optional()\n .describe(\"Filter by memory type, e.g. 'preference', 'project'\"),\n tags: z\n .array(z.string())\n .optional()\n .describe(\"Filter by tags — returns memories matching ANY of these tags\"),\n search: z\n .string()\n .optional()\n .describe(\"Search memory content (case-insensitive substring match)\"),\n limit: z\n .number()\n .optional()\n .describe(\"Max number of memories to return. Defaults to all.\"),\n }),\n execute: async (input) => {\n const memories = await tenant.recall({\n type: input.type,\n tags: input.tags,\n search: input.search,\n limit: input.limit,\n });\n return {\n count: memories.length,\n memories: memories.map((m) => ({\n id: m.id,\n type: m.type,\n content: m.content,\n tags: m.tags,\n createdAt: m.createdAt.toISOString(),\n })),\n };\n },\n }),\n\n memvault_forget: tool({\n description:\n \"Delete a specific memory by ID. Use when the user asks to forget something \" +\n \"or when information is outdated and should be removed.\",\n inputSchema: z.object({\n id: z.string().describe(\"The memory ID to delete\"),\n }),\n execute: async (input) => {\n await tenant.forget(input.id);\n return { success: true, message: `Memory ${input.id} deleted.` };\n },\n }),\n\n memvault_update: tool({\n description:\n \"Update an existing memory. Use when information has changed and the old \" +\n \"memory should be corrected rather than deleted and re-created.\",\n inputSchema: z.object({\n id: z.string().describe(\"The memory ID to update\"),\n content: z\n .string()\n .optional()\n .describe(\"New content to replace the existing memory content\"),\n type: z.string().optional().describe(\"New type for the memory\"),\n tags: z\n .array(z.string())\n .optional()\n .describe(\"New tags (replaces existing tags)\"),\n }),\n execute: async (input) => {\n const { id, ...updates } = input;\n const memory = await tenant.update(id, updates);\n return {\n success: true,\n id: memory.id,\n message: `Updated memory: \"${memory.content}\"`,\n };\n },\n }),\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { g as ToolsConfig } from '../types-BbBXYjeB.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Tool definitions for the Anthropic SDK.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* ```ts
|
|
8
|
+
* import { createMemVaultTools } from "memvault/anthropic"
|
|
9
|
+
*
|
|
10
|
+
* const { tools, handleToolCall } = createMemVaultTools({ vault, tenantId: user.id })
|
|
11
|
+
*
|
|
12
|
+
* const message = await anthropic.messages.create({
|
|
13
|
+
* model: "claude-sonnet-4-6",
|
|
14
|
+
* tools,
|
|
15
|
+
* messages: [{ role: "user", content: "Help me..." }]
|
|
16
|
+
* })
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
interface AnthropicTool {
|
|
20
|
+
name: string;
|
|
21
|
+
description: string;
|
|
22
|
+
input_schema: {
|
|
23
|
+
type: "object";
|
|
24
|
+
properties: Record<string, unknown>;
|
|
25
|
+
required?: string[];
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
declare function createMemVaultTools(config: ToolsConfig): {
|
|
29
|
+
tools: AnthropicTool[];
|
|
30
|
+
handleToolCall: (name: string, input: Record<string, unknown>) => Promise<string>;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export { createMemVaultTools };
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
// src/integrations/anthropic.ts
|
|
2
|
+
function createMemVaultTools(config) {
|
|
3
|
+
const tenant = config.vault.tenant(config.tenantId);
|
|
4
|
+
const tools = [
|
|
5
|
+
{
|
|
6
|
+
name: "memvault_remember",
|
|
7
|
+
description: "Save important information to persistent memory for this user. Use this when the user shares preferences, facts about themselves, project context, feedback, or anything worth remembering across sessions.",
|
|
8
|
+
input_schema: {
|
|
9
|
+
type: "object",
|
|
10
|
+
properties: {
|
|
11
|
+
content: {
|
|
12
|
+
type: "string",
|
|
13
|
+
description: "The information to remember. Be specific and concise."
|
|
14
|
+
},
|
|
15
|
+
type: {
|
|
16
|
+
type: "string",
|
|
17
|
+
description: 'Category: "preference", "fact", "feedback", "project", "reference", or any custom type. Defaults to "general".'
|
|
18
|
+
},
|
|
19
|
+
tags: {
|
|
20
|
+
type: "array",
|
|
21
|
+
items: { type: "string" },
|
|
22
|
+
description: "Tags for categorization and filtering."
|
|
23
|
+
},
|
|
24
|
+
ttl: {
|
|
25
|
+
type: "number",
|
|
26
|
+
description: "Time-to-live in seconds. Omit for permanent memory."
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
required: ["content"]
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
name: "memvault_recall",
|
|
34
|
+
description: "Retrieve memories for this user. Use this BEFORE responding when you need context about the user's preferences, past conversations, or project details.",
|
|
35
|
+
input_schema: {
|
|
36
|
+
type: "object",
|
|
37
|
+
properties: {
|
|
38
|
+
type: {
|
|
39
|
+
type: "string",
|
|
40
|
+
description: "Filter by memory type."
|
|
41
|
+
},
|
|
42
|
+
tags: {
|
|
43
|
+
type: "array",
|
|
44
|
+
items: { type: "string" },
|
|
45
|
+
description: "Filter by tags."
|
|
46
|
+
},
|
|
47
|
+
search: {
|
|
48
|
+
type: "string",
|
|
49
|
+
description: "Search memory content (case-insensitive)."
|
|
50
|
+
},
|
|
51
|
+
limit: {
|
|
52
|
+
type: "number",
|
|
53
|
+
description: "Max number of memories to return."
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
name: "memvault_forget",
|
|
60
|
+
description: "Delete a specific memory by ID. Use when the user asks to forget something.",
|
|
61
|
+
input_schema: {
|
|
62
|
+
type: "object",
|
|
63
|
+
properties: {
|
|
64
|
+
id: { type: "string", description: "The memory ID to delete." }
|
|
65
|
+
},
|
|
66
|
+
required: ["id"]
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
name: "memvault_update",
|
|
71
|
+
description: "Update an existing memory. Use when information has changed.",
|
|
72
|
+
input_schema: {
|
|
73
|
+
type: "object",
|
|
74
|
+
properties: {
|
|
75
|
+
id: { type: "string", description: "The memory ID to update." },
|
|
76
|
+
content: { type: "string", description: "New content." },
|
|
77
|
+
type: { type: "string", description: "New type." },
|
|
78
|
+
tags: {
|
|
79
|
+
type: "array",
|
|
80
|
+
items: { type: "string" },
|
|
81
|
+
description: "New tags."
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
required: ["id"]
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
];
|
|
88
|
+
async function handleToolCall(name, input) {
|
|
89
|
+
switch (name) {
|
|
90
|
+
case "memvault_remember": {
|
|
91
|
+
const memory = await tenant.remember({
|
|
92
|
+
content: input.content,
|
|
93
|
+
type: input.type,
|
|
94
|
+
tags: input.tags,
|
|
95
|
+
ttl: input.ttl
|
|
96
|
+
});
|
|
97
|
+
return JSON.stringify({
|
|
98
|
+
success: true,
|
|
99
|
+
id: memory.id,
|
|
100
|
+
message: `Remembered: "${memory.content}"`
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
case "memvault_recall": {
|
|
104
|
+
const memories = await tenant.recall({
|
|
105
|
+
type: input.type,
|
|
106
|
+
tags: input.tags,
|
|
107
|
+
search: input.search,
|
|
108
|
+
limit: input.limit
|
|
109
|
+
});
|
|
110
|
+
return JSON.stringify({
|
|
111
|
+
count: memories.length,
|
|
112
|
+
memories: memories.map((m) => ({
|
|
113
|
+
id: m.id,
|
|
114
|
+
type: m.type,
|
|
115
|
+
content: m.content,
|
|
116
|
+
tags: m.tags,
|
|
117
|
+
createdAt: m.createdAt.toISOString()
|
|
118
|
+
}))
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
case "memvault_forget": {
|
|
122
|
+
await tenant.forget(input.id);
|
|
123
|
+
return JSON.stringify({
|
|
124
|
+
success: true,
|
|
125
|
+
message: `Memory ${input.id} deleted.`
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
case "memvault_update": {
|
|
129
|
+
const { id, ...updates } = input;
|
|
130
|
+
const memory = await tenant.update(id, updates);
|
|
131
|
+
return JSON.stringify({
|
|
132
|
+
success: true,
|
|
133
|
+
id: memory.id,
|
|
134
|
+
message: `Updated memory: "${memory.content}"`
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
default:
|
|
138
|
+
return JSON.stringify({ error: `Unknown tool: ${name}` });
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return { tools, handleToolCall };
|
|
142
|
+
}
|
|
143
|
+
export {
|
|
144
|
+
createMemVaultTools
|
|
145
|
+
};
|
|
146
|
+
//# sourceMappingURL=anthropic.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/integrations/anthropic.ts"],"sourcesContent":["import type { ToolsConfig, TenantVaultInstance } from \"../types.js\";\n\n/**\n * Tool definitions for the Anthropic SDK.\n *\n * Usage:\n * ```ts\n * import { createMemVaultTools } from \"memvault/anthropic\"\n *\n * const { tools, handleToolCall } = createMemVaultTools({ vault, tenantId: user.id })\n *\n * const message = await anthropic.messages.create({\n * model: \"claude-sonnet-4-6\",\n * tools,\n * messages: [{ role: \"user\", content: \"Help me...\" }]\n * })\n * ```\n */\n\ninterface AnthropicTool {\n name: string;\n description: string;\n input_schema: {\n type: \"object\";\n properties: Record<string, unknown>;\n required?: string[];\n };\n}\n\nexport function createMemVaultTools(config: ToolsConfig) {\n const tenant = config.vault.tenant(config.tenantId);\n\n const tools: AnthropicTool[] = [\n {\n name: \"memvault_remember\",\n description:\n \"Save important information to persistent memory for this user. \" +\n \"Use this when the user shares preferences, facts about themselves, \" +\n \"project context, feedback, or anything worth remembering across sessions.\",\n input_schema: {\n type: \"object\",\n properties: {\n content: {\n type: \"string\",\n description:\n \"The information to remember. Be specific and concise.\",\n },\n type: {\n type: \"string\",\n description:\n 'Category: \"preference\", \"fact\", \"feedback\", \"project\", \"reference\", or any custom type. Defaults to \"general\".',\n },\n tags: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Tags for categorization and filtering.\",\n },\n ttl: {\n type: \"number\",\n description:\n \"Time-to-live in seconds. Omit for permanent memory.\",\n },\n },\n required: [\"content\"],\n },\n },\n {\n name: \"memvault_recall\",\n description:\n \"Retrieve memories for this user. Use this BEFORE responding when you need \" +\n \"context about the user's preferences, past conversations, or project details.\",\n input_schema: {\n type: \"object\",\n properties: {\n type: {\n type: \"string\",\n description: \"Filter by memory type.\",\n },\n tags: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Filter by tags.\",\n },\n search: {\n type: \"string\",\n description: \"Search memory content (case-insensitive).\",\n },\n limit: {\n type: \"number\",\n description: \"Max number of memories to return.\",\n },\n },\n },\n },\n {\n name: \"memvault_forget\",\n description:\n \"Delete a specific memory by ID. Use when the user asks to forget something.\",\n input_schema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"The memory ID to delete.\" },\n },\n required: [\"id\"],\n },\n },\n {\n name: \"memvault_update\",\n description:\n \"Update an existing memory. Use when information has changed.\",\n input_schema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"The memory ID to update.\" },\n content: { type: \"string\", description: \"New content.\" },\n type: { type: \"string\", description: \"New type.\" },\n tags: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"New tags.\",\n },\n },\n required: [\"id\"],\n },\n },\n ];\n\n /**\n * Execute a tool call from the Anthropic API response.\n * Pass the tool name and input object from the tool_use content block.\n */\n async function handleToolCall(\n name: string,\n input: Record<string, unknown>,\n ): Promise<string> {\n switch (name) {\n case \"memvault_remember\": {\n const memory = await tenant.remember({\n content: input.content as string,\n type: input.type as string | undefined,\n tags: input.tags as string[] | undefined,\n ttl: input.ttl as number | undefined,\n });\n return JSON.stringify({\n success: true,\n id: memory.id,\n message: `Remembered: \"${memory.content}\"`,\n });\n }\n case \"memvault_recall\": {\n const memories = await tenant.recall({\n type: input.type as string | undefined,\n tags: input.tags as string[] | undefined,\n search: input.search as string | undefined,\n limit: input.limit as number | undefined,\n });\n return JSON.stringify({\n count: memories.length,\n memories: memories.map((m) => ({\n id: m.id,\n type: m.type,\n content: m.content,\n tags: m.tags,\n createdAt: m.createdAt.toISOString(),\n })),\n });\n }\n case \"memvault_forget\": {\n await tenant.forget(input.id as string);\n return JSON.stringify({\n success: true,\n message: `Memory ${input.id} deleted.`,\n });\n }\n case \"memvault_update\": {\n const { id, ...updates } = input;\n const memory = await tenant.update(id as string, updates);\n return JSON.stringify({\n success: true,\n id: memory.id,\n message: `Updated memory: \"${memory.content}\"`,\n });\n }\n default:\n return JSON.stringify({ error: `Unknown tool: ${name}` });\n }\n }\n\n return { tools, handleToolCall };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { g as ToolsConfig } from '../types-BbBXYjeB.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Tool definitions for the OpenAI SDK (Responses API & Chat Completions).
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* ```ts
|
|
8
|
+
* import { createMemVaultTools, handleToolCall } from "memvault/openai"
|
|
9
|
+
*
|
|
10
|
+
* const { tools, handleToolCall } = createMemVaultTools({ vault, tenantId: user.id })
|
|
11
|
+
*
|
|
12
|
+
* const response = await openai.responses.create({
|
|
13
|
+
* model: "gpt-4o",
|
|
14
|
+
* tools,
|
|
15
|
+
* input: "Help the user..."
|
|
16
|
+
* })
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
interface OpenAIFunctionTool {
|
|
20
|
+
type: "function";
|
|
21
|
+
function: {
|
|
22
|
+
name: string;
|
|
23
|
+
description: string;
|
|
24
|
+
parameters: Record<string, unknown>;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
declare function createMemVaultTools(config: ToolsConfig): {
|
|
28
|
+
tools: OpenAIFunctionTool[];
|
|
29
|
+
handleToolCall: (name: string, args: Record<string, unknown>) => Promise<string>;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export { createMemVaultTools };
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
// src/integrations/openai.ts
|
|
2
|
+
function createMemVaultTools(config) {
|
|
3
|
+
const tenant = config.vault.tenant(config.tenantId);
|
|
4
|
+
const tools = [
|
|
5
|
+
{
|
|
6
|
+
type: "function",
|
|
7
|
+
function: {
|
|
8
|
+
name: "memvault_remember",
|
|
9
|
+
description: "Save important information to persistent memory for this user. Use this when the user shares preferences, facts about themselves, project context, feedback, or anything worth remembering across sessions.",
|
|
10
|
+
parameters: {
|
|
11
|
+
type: "object",
|
|
12
|
+
properties: {
|
|
13
|
+
content: {
|
|
14
|
+
type: "string",
|
|
15
|
+
description: "The information to remember. Be specific and concise."
|
|
16
|
+
},
|
|
17
|
+
type: {
|
|
18
|
+
type: "string",
|
|
19
|
+
description: 'Category: "preference", "fact", "feedback", "project", "reference", or any custom type. Defaults to "general".'
|
|
20
|
+
},
|
|
21
|
+
tags: {
|
|
22
|
+
type: "array",
|
|
23
|
+
items: { type: "string" },
|
|
24
|
+
description: "Tags for categorization and filtering."
|
|
25
|
+
},
|
|
26
|
+
ttl: {
|
|
27
|
+
type: "number",
|
|
28
|
+
description: "Time-to-live in seconds. Omit for permanent memory."
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
required: ["content"]
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
type: "function",
|
|
37
|
+
function: {
|
|
38
|
+
name: "memvault_recall",
|
|
39
|
+
description: "Retrieve memories for this user. Use this BEFORE responding when you need context about the user's preferences, past conversations, or project details.",
|
|
40
|
+
parameters: {
|
|
41
|
+
type: "object",
|
|
42
|
+
properties: {
|
|
43
|
+
type: {
|
|
44
|
+
type: "string",
|
|
45
|
+
description: "Filter by memory type."
|
|
46
|
+
},
|
|
47
|
+
tags: {
|
|
48
|
+
type: "array",
|
|
49
|
+
items: { type: "string" },
|
|
50
|
+
description: "Filter by tags."
|
|
51
|
+
},
|
|
52
|
+
search: {
|
|
53
|
+
type: "string",
|
|
54
|
+
description: "Search memory content (case-insensitive)."
|
|
55
|
+
},
|
|
56
|
+
limit: {
|
|
57
|
+
type: "number",
|
|
58
|
+
description: "Max number of memories to return."
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
required: []
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
type: "function",
|
|
67
|
+
function: {
|
|
68
|
+
name: "memvault_forget",
|
|
69
|
+
description: "Delete a specific memory by ID. Use when the user asks to forget something.",
|
|
70
|
+
parameters: {
|
|
71
|
+
type: "object",
|
|
72
|
+
properties: {
|
|
73
|
+
id: { type: "string", description: "The memory ID to delete." }
|
|
74
|
+
},
|
|
75
|
+
required: ["id"]
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
type: "function",
|
|
81
|
+
function: {
|
|
82
|
+
name: "memvault_update",
|
|
83
|
+
description: "Update an existing memory. Use when information has changed.",
|
|
84
|
+
parameters: {
|
|
85
|
+
type: "object",
|
|
86
|
+
properties: {
|
|
87
|
+
id: { type: "string", description: "The memory ID to update." },
|
|
88
|
+
content: { type: "string", description: "New content." },
|
|
89
|
+
type: { type: "string", description: "New type." },
|
|
90
|
+
tags: {
|
|
91
|
+
type: "array",
|
|
92
|
+
items: { type: "string" },
|
|
93
|
+
description: "New tags."
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
required: ["id"]
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
];
|
|
101
|
+
async function handleToolCall(name, args) {
|
|
102
|
+
switch (name) {
|
|
103
|
+
case "memvault_remember": {
|
|
104
|
+
const memory = await tenant.remember({
|
|
105
|
+
content: args.content,
|
|
106
|
+
type: args.type,
|
|
107
|
+
tags: args.tags,
|
|
108
|
+
ttl: args.ttl
|
|
109
|
+
});
|
|
110
|
+
return JSON.stringify({
|
|
111
|
+
success: true,
|
|
112
|
+
id: memory.id,
|
|
113
|
+
message: `Remembered: "${memory.content}"`
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
case "memvault_recall": {
|
|
117
|
+
const memories = await tenant.recall({
|
|
118
|
+
type: args.type,
|
|
119
|
+
tags: args.tags,
|
|
120
|
+
search: args.search,
|
|
121
|
+
limit: args.limit
|
|
122
|
+
});
|
|
123
|
+
return JSON.stringify({
|
|
124
|
+
count: memories.length,
|
|
125
|
+
memories: memories.map((m) => ({
|
|
126
|
+
id: m.id,
|
|
127
|
+
type: m.type,
|
|
128
|
+
content: m.content,
|
|
129
|
+
tags: m.tags,
|
|
130
|
+
createdAt: m.createdAt.toISOString()
|
|
131
|
+
}))
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
case "memvault_forget": {
|
|
135
|
+
await tenant.forget(args.id);
|
|
136
|
+
return JSON.stringify({
|
|
137
|
+
success: true,
|
|
138
|
+
message: `Memory ${args.id} deleted.`
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
case "memvault_update": {
|
|
142
|
+
const { id, ...updates } = args;
|
|
143
|
+
const memory = await tenant.update(id, updates);
|
|
144
|
+
return JSON.stringify({
|
|
145
|
+
success: true,
|
|
146
|
+
id: memory.id,
|
|
147
|
+
message: `Updated memory: "${memory.content}"`
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
default:
|
|
151
|
+
return JSON.stringify({ error: `Unknown tool: ${name}` });
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return { tools, handleToolCall };
|
|
155
|
+
}
|
|
156
|
+
export {
|
|
157
|
+
createMemVaultTools
|
|
158
|
+
};
|
|
159
|
+
//# sourceMappingURL=openai.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/integrations/openai.ts"],"sourcesContent":["import type { ToolsConfig, TenantVaultInstance } from \"../types.js\";\n\n/**\n * Tool definitions for the OpenAI SDK (Responses API & Chat Completions).\n *\n * Usage:\n * ```ts\n * import { createMemVaultTools, handleToolCall } from \"memvault/openai\"\n *\n * const { tools, handleToolCall } = createMemVaultTools({ vault, tenantId: user.id })\n *\n * const response = await openai.responses.create({\n * model: \"gpt-4o\",\n * tools,\n * input: \"Help the user...\"\n * })\n * ```\n */\n\ninterface OpenAIFunctionTool {\n type: \"function\";\n function: {\n name: string;\n description: string;\n parameters: Record<string, unknown>;\n };\n}\n\nexport function createMemVaultTools(config: ToolsConfig) {\n const tenant = config.vault.tenant(config.tenantId);\n\n const tools: OpenAIFunctionTool[] = [\n {\n type: \"function\",\n function: {\n name: \"memvault_remember\",\n description:\n \"Save important information to persistent memory for this user. \" +\n \"Use this when the user shares preferences, facts about themselves, \" +\n \"project context, feedback, or anything worth remembering across sessions.\",\n parameters: {\n type: \"object\",\n properties: {\n content: {\n type: \"string\",\n description:\n \"The information to remember. Be specific and concise.\",\n },\n type: {\n type: \"string\",\n description:\n 'Category: \"preference\", \"fact\", \"feedback\", \"project\", \"reference\", or any custom type. Defaults to \"general\".',\n },\n tags: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Tags for categorization and filtering.\",\n },\n ttl: {\n type: \"number\",\n description:\n \"Time-to-live in seconds. Omit for permanent memory.\",\n },\n },\n required: [\"content\"],\n },\n },\n },\n {\n type: \"function\",\n function: {\n name: \"memvault_recall\",\n description:\n \"Retrieve memories for this user. Use this BEFORE responding when you need \" +\n \"context about the user's preferences, past conversations, or project details.\",\n parameters: {\n type: \"object\",\n properties: {\n type: {\n type: \"string\",\n description: \"Filter by memory type.\",\n },\n tags: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Filter by tags.\",\n },\n search: {\n type: \"string\",\n description: \"Search memory content (case-insensitive).\",\n },\n limit: {\n type: \"number\",\n description: \"Max number of memories to return.\",\n },\n },\n required: [],\n },\n },\n },\n {\n type: \"function\",\n function: {\n name: \"memvault_forget\",\n description:\n \"Delete a specific memory by ID. Use when the user asks to forget something.\",\n parameters: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"The memory ID to delete.\" },\n },\n required: [\"id\"],\n },\n },\n },\n {\n type: \"function\",\n function: {\n name: \"memvault_update\",\n description:\n \"Update an existing memory. Use when information has changed.\",\n parameters: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"The memory ID to update.\" },\n content: { type: \"string\", description: \"New content.\" },\n type: { type: \"string\", description: \"New type.\" },\n tags: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"New tags.\",\n },\n },\n required: [\"id\"],\n },\n },\n },\n ];\n\n /**\n * Execute a tool call returned by the OpenAI API.\n * Pass the function name and parsed arguments.\n */\n async function handleToolCall(\n name: string,\n args: Record<string, unknown>,\n ): Promise<string> {\n switch (name) {\n case \"memvault_remember\": {\n const memory = await tenant.remember({\n content: args.content as string,\n type: args.type as string | undefined,\n tags: args.tags as string[] | undefined,\n ttl: args.ttl as number | undefined,\n });\n return JSON.stringify({\n success: true,\n id: memory.id,\n message: `Remembered: \"${memory.content}\"`,\n });\n }\n case \"memvault_recall\": {\n const memories = await tenant.recall({\n type: args.type as string | undefined,\n tags: args.tags as string[] | undefined,\n search: args.search as string | undefined,\n limit: args.limit as number | undefined,\n });\n return JSON.stringify({\n count: memories.length,\n memories: memories.map((m) => ({\n id: m.id,\n type: m.type,\n content: m.content,\n tags: m.tags,\n createdAt: m.createdAt.toISOString(),\n })),\n });\n }\n case \"memvault_forget\": {\n await tenant.forget(args.id as string);\n return JSON.stringify({\n success: true,\n message: `Memory ${args.id} deleted.`,\n });\n }\n case \"memvault_update\": {\n const { id, ...updates } = args;\n const memory = await tenant.update(id as string, updates);\n return JSON.stringify({\n success: true,\n id: memory.id,\n message: `Updated memory: \"${memory.content}\"`,\n });\n }\n default:\n return JSON.stringify({ error: `Unknown tool: ${name}` });\n }\n }\n\n return { tools, handleToolCall };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A stored memory record.
|
|
3
|
+
*/
|
|
4
|
+
interface Memory {
|
|
5
|
+
id: string;
|
|
6
|
+
tenantId: string;
|
|
7
|
+
type: string;
|
|
8
|
+
content: string;
|
|
9
|
+
metadata: Record<string, unknown> | null;
|
|
10
|
+
tags: string[];
|
|
11
|
+
createdAt: Date;
|
|
12
|
+
updatedAt: Date;
|
|
13
|
+
expiresAt: Date | null;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Input for creating a new memory.
|
|
17
|
+
*/
|
|
18
|
+
interface MemoryInput {
|
|
19
|
+
content: string;
|
|
20
|
+
type?: string;
|
|
21
|
+
metadata?: Record<string, unknown>;
|
|
22
|
+
tags?: string[];
|
|
23
|
+
/** Time-to-live in seconds. Sets expiresAt relative to now. */
|
|
24
|
+
ttl?: number;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Input for updating an existing memory.
|
|
28
|
+
*/
|
|
29
|
+
interface MemoryUpdate {
|
|
30
|
+
content?: string;
|
|
31
|
+
type?: string;
|
|
32
|
+
metadata?: Record<string, unknown>;
|
|
33
|
+
tags?: string[];
|
|
34
|
+
/** Time-to-live in seconds. Resets expiresAt relative to now. null clears expiry. */
|
|
35
|
+
ttl?: number | null;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Filters for querying memories.
|
|
39
|
+
*/
|
|
40
|
+
interface MemoryFilter {
|
|
41
|
+
type?: string;
|
|
42
|
+
tags?: string[];
|
|
43
|
+
search?: string;
|
|
44
|
+
limit?: number;
|
|
45
|
+
/** Include expired memories. Defaults to false. */
|
|
46
|
+
includeExpired?: boolean;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* The Prisma delegate interface that MemVault requires.
|
|
50
|
+
* This matches the shape of `prisma.memvaultMemory` after adding the schema.
|
|
51
|
+
*/
|
|
52
|
+
interface MemvaultPrismaDelegate {
|
|
53
|
+
create(args: {
|
|
54
|
+
data: Record<string, unknown>;
|
|
55
|
+
}): Promise<Memory>;
|
|
56
|
+
findMany(args?: {
|
|
57
|
+
where?: Record<string, unknown>;
|
|
58
|
+
orderBy?: Record<string, unknown> | Record<string, unknown>[];
|
|
59
|
+
take?: number;
|
|
60
|
+
}): Promise<Memory[]>;
|
|
61
|
+
findUnique(args: {
|
|
62
|
+
where: Record<string, unknown>;
|
|
63
|
+
}): Promise<Memory | null>;
|
|
64
|
+
update(args: {
|
|
65
|
+
where: Record<string, unknown>;
|
|
66
|
+
data: Record<string, unknown>;
|
|
67
|
+
}): Promise<Memory>;
|
|
68
|
+
delete(args: {
|
|
69
|
+
where: Record<string, unknown>;
|
|
70
|
+
}): Promise<Memory>;
|
|
71
|
+
deleteMany(args?: {
|
|
72
|
+
where?: Record<string, unknown>;
|
|
73
|
+
}): Promise<{
|
|
74
|
+
count: number;
|
|
75
|
+
}>;
|
|
76
|
+
count(args?: {
|
|
77
|
+
where?: Record<string, unknown>;
|
|
78
|
+
}): Promise<number>;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Configuration for MemVault.
|
|
82
|
+
*/
|
|
83
|
+
interface MemVaultConfig {
|
|
84
|
+
/** The Prisma delegate for the MemvaultMemory model (e.g. prisma.memvaultMemory) */
|
|
85
|
+
db: MemvaultPrismaDelegate;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Configuration for creating SDK tools.
|
|
89
|
+
*/
|
|
90
|
+
interface ToolsConfig {
|
|
91
|
+
/** The MemVault instance */
|
|
92
|
+
vault: MemVaultInstance;
|
|
93
|
+
/** Tenant ID to scope all memory operations */
|
|
94
|
+
tenantId: string;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* The public MemVault instance interface.
|
|
98
|
+
*/
|
|
99
|
+
interface MemVaultInstance {
|
|
100
|
+
tenant(tenantId: string): TenantVaultInstance;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* The public TenantVault interface — all operations scoped to one tenant.
|
|
104
|
+
*/
|
|
105
|
+
interface TenantVaultInstance {
|
|
106
|
+
readonly tenantId: string;
|
|
107
|
+
remember(input: MemoryInput): Promise<Memory>;
|
|
108
|
+
recall(filter?: MemoryFilter): Promise<Memory[]>;
|
|
109
|
+
get(id: string): Promise<Memory | null>;
|
|
110
|
+
update(id: string, input: MemoryUpdate): Promise<Memory>;
|
|
111
|
+
forget(id: string): Promise<void>;
|
|
112
|
+
forgetAll(): Promise<number>;
|
|
113
|
+
count(filter?: MemoryFilter): Promise<number>;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export type { MemvaultPrismaDelegate as M, TenantVaultInstance as T, MemoryInput as a, Memory as b, MemoryFilter as c, MemoryUpdate as d, MemVaultInstance as e, MemVaultConfig as f, ToolsConfig as g };
|
package/package.json
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "memvault",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Persistent, tenant-isolated memory tools for AI agents. Drop-in tools for Vercel AI SDK, OpenAI, and Anthropic. Prisma-powered.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
},
|
|
13
|
+
"./ai-sdk": {
|
|
14
|
+
"import": "./dist/integrations/ai-sdk.js",
|
|
15
|
+
"types": "./dist/integrations/ai-sdk.d.ts"
|
|
16
|
+
},
|
|
17
|
+
"./openai": {
|
|
18
|
+
"import": "./dist/integrations/openai.js",
|
|
19
|
+
"types": "./dist/integrations/openai.d.ts"
|
|
20
|
+
},
|
|
21
|
+
"./anthropic": {
|
|
22
|
+
"import": "./dist/integrations/anthropic.js",
|
|
23
|
+
"types": "./dist/integrations/anthropic.d.ts"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"dist",
|
|
28
|
+
"prisma",
|
|
29
|
+
"README.md"
|
|
30
|
+
],
|
|
31
|
+
"scripts": {
|
|
32
|
+
"build": "tsup",
|
|
33
|
+
"test": "vitest run",
|
|
34
|
+
"test:watch": "vitest",
|
|
35
|
+
"lint": "tsc --noEmit",
|
|
36
|
+
"prepublishOnly": "npm run build"
|
|
37
|
+
},
|
|
38
|
+
"keywords": [
|
|
39
|
+
"ai",
|
|
40
|
+
"memory",
|
|
41
|
+
"llm",
|
|
42
|
+
"agent",
|
|
43
|
+
"persistent",
|
|
44
|
+
"tenant",
|
|
45
|
+
"prisma",
|
|
46
|
+
"openai",
|
|
47
|
+
"anthropic",
|
|
48
|
+
"vercel-ai-sdk",
|
|
49
|
+
"multi-tenant",
|
|
50
|
+
"tools",
|
|
51
|
+
"function-calling"
|
|
52
|
+
],
|
|
53
|
+
"author": "iamsaad640",
|
|
54
|
+
"license": "MIT",
|
|
55
|
+
"repository": {
|
|
56
|
+
"type": "git",
|
|
57
|
+
"url": "https://github.com/iamsaad640/memvault.git"
|
|
58
|
+
},
|
|
59
|
+
"peerDependencies": {
|
|
60
|
+
"@prisma/client": "^7.0.0"
|
|
61
|
+
},
|
|
62
|
+
"peerDependenciesMeta": {
|
|
63
|
+
"@prisma/client": {
|
|
64
|
+
"optional": false
|
|
65
|
+
},
|
|
66
|
+
"ai": {
|
|
67
|
+
"optional": true
|
|
68
|
+
},
|
|
69
|
+
"zod": {
|
|
70
|
+
"optional": true
|
|
71
|
+
},
|
|
72
|
+
"openai": {
|
|
73
|
+
"optional": true
|
|
74
|
+
},
|
|
75
|
+
"@anthropic-ai/sdk": {
|
|
76
|
+
"optional": true
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
"devDependencies": {
|
|
80
|
+
"@prisma/client": "7.6.0",
|
|
81
|
+
"prisma": "7.6.0",
|
|
82
|
+
"ai": "6.0.142",
|
|
83
|
+
"zod": "4.3.6",
|
|
84
|
+
"openai": "6.33.0",
|
|
85
|
+
"@anthropic-ai/sdk": "0.82.0",
|
|
86
|
+
"tsup": "8.5.1",
|
|
87
|
+
"typescript": "6.0.2",
|
|
88
|
+
"vitest": "4.1.2"
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// MemVault — Add this model to your existing Prisma schema.
|
|
2
|
+
// After adding, run: npx prisma migrate dev --name add-memvault
|
|
3
|
+
//
|
|
4
|
+
// This model stores persistent memories with tenant-level isolation.
|
|
5
|
+
// Every query is scoped by tenantId — no tenant can access another's data.
|
|
6
|
+
|
|
7
|
+
generator client {
|
|
8
|
+
provider = "prisma-client"
|
|
9
|
+
output = "../generated/prisma"
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
datasource db {
|
|
13
|
+
provider = "postgresql"
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
model MemvaultMemory {
|
|
17
|
+
id String @id @default(cuid())
|
|
18
|
+
tenantId String
|
|
19
|
+
type String @default("general")
|
|
20
|
+
content String
|
|
21
|
+
metadata Json?
|
|
22
|
+
tags String[]
|
|
23
|
+
createdAt DateTime @default(now())
|
|
24
|
+
updatedAt DateTime @updatedAt
|
|
25
|
+
expiresAt DateTime?
|
|
26
|
+
|
|
27
|
+
@@index([tenantId])
|
|
28
|
+
@@index([tenantId, type])
|
|
29
|
+
@@map("memvault_memories")
|
|
30
|
+
}
|