@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/src/mcp/handlers.ts
CHANGED
|
@@ -1,34 +1,96 @@
|
|
|
1
1
|
import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
|
|
2
2
|
import type { MemoryService } from "../services/memory.service.js";
|
|
3
3
|
|
|
4
|
-
export async function
|
|
4
|
+
export async function handleStoreMemories(
|
|
5
5
|
args: Record<string, unknown> | undefined,
|
|
6
6
|
service: MemoryService
|
|
7
7
|
): Promise<CallToolResult> {
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
const memories = args?.memories as Array<{
|
|
9
|
+
content: string;
|
|
10
|
+
embedding_text?: string;
|
|
11
|
+
metadata?: Record<string, unknown>;
|
|
12
|
+
}>;
|
|
13
|
+
|
|
14
|
+
const ids: string[] = [];
|
|
15
|
+
for (const item of memories) {
|
|
16
|
+
const memory = await service.store(
|
|
17
|
+
item.content,
|
|
18
|
+
item.metadata ?? {},
|
|
19
|
+
item.embedding_text
|
|
20
|
+
);
|
|
21
|
+
ids.push(memory.id);
|
|
22
|
+
}
|
|
12
23
|
|
|
13
24
|
return {
|
|
14
|
-
content: [
|
|
25
|
+
content: [
|
|
26
|
+
{
|
|
27
|
+
type: "text",
|
|
28
|
+
text:
|
|
29
|
+
ids.length === 1
|
|
30
|
+
? `Memory stored with ID: ${ids[0]}`
|
|
31
|
+
: `Stored ${ids.length} memories:\n${ids.map((id) => `- ${id}`).join("\n")}`,
|
|
32
|
+
},
|
|
33
|
+
],
|
|
15
34
|
};
|
|
16
35
|
}
|
|
17
36
|
|
|
18
|
-
export async function
|
|
37
|
+
export async function handleDeleteMemories(
|
|
19
38
|
args: Record<string, unknown> | undefined,
|
|
20
39
|
service: MemoryService
|
|
21
40
|
): Promise<CallToolResult> {
|
|
22
|
-
const
|
|
23
|
-
const
|
|
41
|
+
const ids = args?.ids as string[];
|
|
42
|
+
const results: string[] = [];
|
|
43
|
+
|
|
44
|
+
for (const id of ids) {
|
|
45
|
+
const success = await service.delete(id);
|
|
46
|
+
results.push(
|
|
47
|
+
success ? `Memory ${id} deleted successfully` : `Memory ${id} not found`
|
|
48
|
+
);
|
|
49
|
+
}
|
|
24
50
|
|
|
25
51
|
return {
|
|
26
52
|
content: [
|
|
27
53
|
{
|
|
28
54
|
type: "text",
|
|
29
|
-
text:
|
|
30
|
-
|
|
31
|
-
|
|
55
|
+
text: results.join("\n"),
|
|
56
|
+
},
|
|
57
|
+
],
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
export async function handleUpdateMemories(
|
|
63
|
+
args: Record<string, unknown> | undefined,
|
|
64
|
+
service: MemoryService
|
|
65
|
+
): Promise<CallToolResult> {
|
|
66
|
+
const updates = args?.updates as Array<{
|
|
67
|
+
id: string;
|
|
68
|
+
content?: string;
|
|
69
|
+
embedding_text?: string;
|
|
70
|
+
metadata?: Record<string, unknown>;
|
|
71
|
+
}>;
|
|
72
|
+
|
|
73
|
+
const results: string[] = [];
|
|
74
|
+
|
|
75
|
+
for (const update of updates) {
|
|
76
|
+
const memory = await service.update(update.id, {
|
|
77
|
+
content: update.content,
|
|
78
|
+
embeddingText: update.embedding_text,
|
|
79
|
+
metadata: update.metadata,
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
if (memory) {
|
|
83
|
+
results.push(`Memory ${update.id} updated successfully`);
|
|
84
|
+
} else {
|
|
85
|
+
results.push(`Memory ${update.id} not found`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return {
|
|
90
|
+
content: [
|
|
91
|
+
{
|
|
92
|
+
type: "text",
|
|
93
|
+
text: results.join("\n"),
|
|
32
94
|
},
|
|
33
95
|
],
|
|
34
96
|
};
|
|
@@ -40,7 +102,8 @@ export async function handleSearchMemories(
|
|
|
40
102
|
): Promise<CallToolResult> {
|
|
41
103
|
const query = args?.query as string;
|
|
42
104
|
const limit = (args?.limit as number) ?? 10;
|
|
43
|
-
const
|
|
105
|
+
const includeDeleted = (args?.include_deleted as boolean) ?? false;
|
|
106
|
+
const memories = await service.search(query, limit, includeDeleted);
|
|
44
107
|
|
|
45
108
|
if (memories.length === 0) {
|
|
46
109
|
return {
|
|
@@ -53,6 +116,9 @@ export async function handleSearchMemories(
|
|
|
53
116
|
if (Object.keys(mem.metadata).length > 0) {
|
|
54
117
|
result += `\nMetadata: ${JSON.stringify(mem.metadata)}`;
|
|
55
118
|
}
|
|
119
|
+
if (includeDeleted && mem.supersededBy) {
|
|
120
|
+
result += `\n[DELETED]`;
|
|
121
|
+
}
|
|
56
122
|
return result;
|
|
57
123
|
});
|
|
58
124
|
|
|
@@ -61,31 +127,95 @@ export async function handleSearchMemories(
|
|
|
61
127
|
};
|
|
62
128
|
}
|
|
63
129
|
|
|
64
|
-
export async function
|
|
130
|
+
export async function handleGetMemories(
|
|
65
131
|
args: Record<string, unknown> | undefined,
|
|
66
132
|
service: MemoryService
|
|
67
133
|
): Promise<CallToolResult> {
|
|
68
|
-
const
|
|
69
|
-
const memory = await service.get(id);
|
|
134
|
+
const ids = args?.ids as string[];
|
|
70
135
|
|
|
71
|
-
|
|
136
|
+
const format = (
|
|
137
|
+
memoryId: string,
|
|
138
|
+
memory: Awaited<ReturnType<MemoryService["get"]>>
|
|
139
|
+
) => {
|
|
140
|
+
if (!memory) {
|
|
141
|
+
return `Memory ${memoryId} not found`;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
let result = `ID: ${memory.id}\nContent: ${memory.content}`;
|
|
145
|
+
if (Object.keys(memory.metadata).length > 0) {
|
|
146
|
+
result += `\nMetadata: ${JSON.stringify(memory.metadata)}`;
|
|
147
|
+
}
|
|
148
|
+
result += `\nCreated: ${memory.createdAt.toISOString()}`;
|
|
149
|
+
result += `\nUpdated: ${memory.updatedAt.toISOString()}`;
|
|
150
|
+
if (memory.supersededBy) {
|
|
151
|
+
result += `\nSuperseded by: ${memory.supersededBy}`;
|
|
152
|
+
}
|
|
153
|
+
return result;
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
const blocks: string[] = [];
|
|
157
|
+
for (const id of ids) {
|
|
158
|
+
const memory = await service.get(id);
|
|
159
|
+
blocks.push(format(id, memory));
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return {
|
|
163
|
+
content: [{ type: "text", text: blocks.join("\n\n---\n\n") }],
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export async function handleStoreHandoff(
|
|
168
|
+
args: Record<string, unknown> | undefined,
|
|
169
|
+
service: MemoryService
|
|
170
|
+
): Promise<CallToolResult> {
|
|
171
|
+
const memory = await service.storeHandoff({
|
|
172
|
+
project: args?.project as string,
|
|
173
|
+
branch: args?.branch as string | undefined,
|
|
174
|
+
summary: args?.summary as string,
|
|
175
|
+
completed: (args?.completed as string[] | undefined) ?? [],
|
|
176
|
+
in_progress_blocked: (args?.in_progress_blocked as string[] | undefined) ?? [],
|
|
177
|
+
key_decisions: (args?.key_decisions as string[] | undefined) ?? [],
|
|
178
|
+
next_steps: (args?.next_steps as string[] | undefined) ?? [],
|
|
179
|
+
memory_ids: (args?.memory_ids as string[] | undefined) ?? [],
|
|
180
|
+
metadata: (args?.metadata as Record<string, unknown>) ?? {},
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
return {
|
|
184
|
+
content: [{ type: "text", text: `Handoff stored with memory ID: ${memory.id}` }],
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export async function handleGetHandoff(
|
|
189
|
+
_args: Record<string, unknown> | undefined,
|
|
190
|
+
service: MemoryService
|
|
191
|
+
): Promise<CallToolResult> {
|
|
192
|
+
const handoff = await service.getLatestHandoff();
|
|
193
|
+
|
|
194
|
+
if (!handoff) {
|
|
72
195
|
return {
|
|
73
|
-
content: [{ type: "text", text:
|
|
196
|
+
content: [{ type: "text", text: "No stored handoff found." }],
|
|
74
197
|
};
|
|
75
198
|
}
|
|
76
199
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
200
|
+
// Fetch referenced memories if any
|
|
201
|
+
const memoryIds = (handoff.metadata.memory_ids as string[] | undefined) ?? [];
|
|
202
|
+
let memoriesSection = "";
|
|
203
|
+
|
|
204
|
+
if (memoryIds.length > 0) {
|
|
205
|
+
const memories: string[] = [];
|
|
206
|
+
for (const id of memoryIds) {
|
|
207
|
+
const memory = await service.get(id);
|
|
208
|
+
if (memory) {
|
|
209
|
+
memories.push(`### Memory: ${id}\n${memory.content}`);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
if (memories.length > 0) {
|
|
213
|
+
memoriesSection = `\n\n## Referenced Memories\n\n${memories.join("\n\n")}`;
|
|
214
|
+
}
|
|
85
215
|
}
|
|
86
216
|
|
|
87
217
|
return {
|
|
88
|
-
content: [{ type: "text", text:
|
|
218
|
+
content: [{ type: "text", text: handoff.content + memoriesSection }],
|
|
89
219
|
};
|
|
90
220
|
}
|
|
91
221
|
|
|
@@ -95,14 +225,20 @@ export async function handleToolCall(
|
|
|
95
225
|
service: MemoryService
|
|
96
226
|
): Promise<CallToolResult> {
|
|
97
227
|
switch (name) {
|
|
98
|
-
case "
|
|
99
|
-
return
|
|
100
|
-
case "
|
|
101
|
-
return
|
|
228
|
+
case "store_memories":
|
|
229
|
+
return handleStoreMemories(args, service);
|
|
230
|
+
case "update_memories":
|
|
231
|
+
return handleUpdateMemories(args, service);
|
|
232
|
+
case "delete_memories":
|
|
233
|
+
return handleDeleteMemories(args, service);
|
|
102
234
|
case "search_memories":
|
|
103
235
|
return handleSearchMemories(args, service);
|
|
104
|
-
case "
|
|
105
|
-
return
|
|
236
|
+
case "get_memories":
|
|
237
|
+
return handleGetMemories(args, service);
|
|
238
|
+
case "store_handoff":
|
|
239
|
+
return handleStoreHandoff(args, service);
|
|
240
|
+
case "get_handoff":
|
|
241
|
+
return handleGetHandoff(args, service);
|
|
106
242
|
default:
|
|
107
243
|
return {
|
|
108
244
|
content: [{ type: "text", text: `Unknown tool: ${name}` }],
|
package/src/mcp/server.ts
CHANGED
|
@@ -11,7 +11,7 @@ import type { MemoryService } from "../services/memory.service.js";
|
|
|
11
11
|
|
|
12
12
|
export function createServer(memoryService: MemoryService): Server {
|
|
13
13
|
const server = new Server(
|
|
14
|
-
{ name: "vector-memory-mcp", version: "0.
|
|
14
|
+
{ name: "vector-memory-mcp", version: "0.6.0" },
|
|
15
15
|
{ capabilities: { tools: {} } }
|
|
16
16
|
);
|
|
17
17
|
|
package/src/mcp/tools.ts
CHANGED
|
@@ -1,109 +1,214 @@
|
|
|
1
1
|
import type { Tool } from "@modelcontextprotocol/sdk/types.js";
|
|
2
2
|
|
|
3
|
-
export const
|
|
4
|
-
name: "
|
|
3
|
+
export const storeMemoriesTool: Tool = {
|
|
4
|
+
name: "store_memories",
|
|
5
5
|
description:
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
"(2) Problems are solved (bugs fixed, errors resolved - include the solution); " +
|
|
10
|
-
"(3) User preferences or conventions are established; " +
|
|
11
|
-
"(4) Project-specific patterns or configurations are discussed; " +
|
|
12
|
-
"(5) Key information would be valuable in future sessions. " +
|
|
13
|
-
"IMPORTANT: If the content exceeds 1000 characters, you MUST provide an embedding_text " +
|
|
14
|
-
"parameter with a concise summary (under 1000 characters) that captures the key semantic " +
|
|
15
|
-
"meaning for search purposes. The full content will still be stored and returned in search results.",
|
|
6
|
+
"Build persistent memory across conversations. Store decisions, solutions, user preferences, " +
|
|
7
|
+
"patterns, or anything worth remembering. Batch related items in one call. " +
|
|
8
|
+
"For long content (>1000 chars), provide embedding_text with a searchable summary.",
|
|
16
9
|
inputSchema: {
|
|
17
10
|
type: "object",
|
|
18
11
|
properties: {
|
|
19
|
-
|
|
20
|
-
type: "
|
|
21
|
-
description:
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
12
|
+
memories: {
|
|
13
|
+
type: "array",
|
|
14
|
+
description: "Memories to store.",
|
|
15
|
+
items: {
|
|
16
|
+
type: "object",
|
|
17
|
+
properties: {
|
|
18
|
+
content: {
|
|
19
|
+
type: "string",
|
|
20
|
+
description: "The content to store.",
|
|
21
|
+
},
|
|
22
|
+
embedding_text: {
|
|
23
|
+
type: "string",
|
|
24
|
+
description:
|
|
25
|
+
"Summary for search embedding (required if content >1000 chars).",
|
|
26
|
+
},
|
|
27
|
+
metadata: {
|
|
28
|
+
type: "object",
|
|
29
|
+
description: "Optional key-value metadata.",
|
|
30
|
+
additionalProperties: true,
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
required: ["content"],
|
|
34
|
+
},
|
|
31
35
|
},
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
36
|
+
},
|
|
37
|
+
required: ["memories"],
|
|
38
|
+
},
|
|
39
|
+
};;
|
|
40
|
+
|
|
41
|
+
export const deleteMemoriesTool: Tool = {
|
|
42
|
+
name: "delete_memories",
|
|
43
|
+
description:
|
|
44
|
+
"Remove memories that are no longer needed—outdated info, superseded decisions, or incorrect content. " +
|
|
45
|
+
"Deleted memories can be recovered via search_memories with include_deleted: true.",
|
|
46
|
+
inputSchema: {
|
|
47
|
+
type: "object",
|
|
48
|
+
properties: {
|
|
49
|
+
ids: {
|
|
50
|
+
type: "array",
|
|
51
|
+
description: "IDs of memories to delete.",
|
|
52
|
+
items: {
|
|
53
|
+
type: "string",
|
|
54
|
+
},
|
|
37
55
|
},
|
|
38
56
|
},
|
|
39
|
-
required: ["
|
|
57
|
+
required: ["ids"],
|
|
40
58
|
},
|
|
41
|
-
}
|
|
59
|
+
};;
|
|
42
60
|
|
|
43
|
-
|
|
44
|
-
|
|
61
|
+
|
|
62
|
+
const updateMemoriesTool: Tool = {
|
|
63
|
+
name: "update_memories",
|
|
45
64
|
description:
|
|
46
|
-
"
|
|
65
|
+
"Update existing memories in place. Use to correct content, refine embedding text, or replace metadata " +
|
|
66
|
+
"without changing the memory ID. Prefer over delete+create when updating the same conceptual item.",
|
|
47
67
|
inputSchema: {
|
|
48
68
|
type: "object",
|
|
49
69
|
properties: {
|
|
50
|
-
|
|
51
|
-
type: "
|
|
52
|
-
description: "
|
|
70
|
+
updates: {
|
|
71
|
+
type: "array",
|
|
72
|
+
description: "Updates to apply. Each must include id and at least one field to change.",
|
|
73
|
+
items: {
|
|
74
|
+
type: "object",
|
|
75
|
+
properties: {
|
|
76
|
+
id: {
|
|
77
|
+
type: "string",
|
|
78
|
+
description: "ID of memory to update.",
|
|
79
|
+
},
|
|
80
|
+
content: {
|
|
81
|
+
type: "string",
|
|
82
|
+
description: "New content (triggers embedding regeneration).",
|
|
83
|
+
},
|
|
84
|
+
embedding_text: {
|
|
85
|
+
type: "string",
|
|
86
|
+
description: "New embedding summary (triggers embedding regeneration).",
|
|
87
|
+
},
|
|
88
|
+
metadata: {
|
|
89
|
+
type: "object",
|
|
90
|
+
description: "New metadata (replaces existing entirely).",
|
|
91
|
+
additionalProperties: true,
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
required: ["id"],
|
|
95
|
+
},
|
|
53
96
|
},
|
|
54
97
|
},
|
|
55
|
-
required: ["
|
|
98
|
+
required: ["updates"],
|
|
56
99
|
},
|
|
57
100
|
};
|
|
58
101
|
|
|
59
102
|
export const searchMemoriesTool: Tool = {
|
|
60
103
|
name: "search_memories",
|
|
61
104
|
description:
|
|
62
|
-
"Search
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"
|
|
67
|
-
"(4) Debugging issues that may have been solved before; " +
|
|
68
|
-
"(5) Questions about established patterns, conventions, or preferences. " +
|
|
69
|
-
"When in doubt, search - it's better to check for relevant context than to miss important prior decisions.",
|
|
105
|
+
"Search stored memories semantically. Use PROACTIVELY—don't wait to be asked. " +
|
|
106
|
+
"Triggers: references to past decisions ('what did we decide', 'as discussed'), " +
|
|
107
|
+
"questions about prior work, returning to a project, debugging something potentially solved before, " +
|
|
108
|
+
"or questions about established patterns/preferences. " +
|
|
109
|
+
"When uncertain, search—missing relevant memories is costlier than an extra query.",
|
|
70
110
|
inputSchema: {
|
|
71
111
|
type: "object",
|
|
72
112
|
properties: {
|
|
73
113
|
query: {
|
|
74
114
|
type: "string",
|
|
75
115
|
description:
|
|
76
|
-
"
|
|
77
|
-
"Include relevant keywords, project names, or technical terms for better results.",
|
|
116
|
+
"Natural language search query. Include relevant keywords, project names, or technical terms.",
|
|
78
117
|
},
|
|
79
118
|
limit: {
|
|
80
119
|
type: "integer",
|
|
81
|
-
description: "Maximum
|
|
120
|
+
description: "Maximum results to return (default: 10).",
|
|
82
121
|
default: 10,
|
|
83
122
|
},
|
|
123
|
+
include_deleted: {
|
|
124
|
+
type: "boolean",
|
|
125
|
+
description: "Include soft-deleted memories in results (default: false). Useful for recovering prior information.",
|
|
126
|
+
default: false,
|
|
127
|
+
},
|
|
84
128
|
},
|
|
85
129
|
required: ["query"],
|
|
86
130
|
},
|
|
87
131
|
};
|
|
88
132
|
|
|
89
|
-
export const
|
|
90
|
-
name: "
|
|
91
|
-
description:
|
|
133
|
+
export const getMemoriesTool: Tool = {
|
|
134
|
+
name: "get_memories",
|
|
135
|
+
description:
|
|
136
|
+
"Retrieve full memory details by ID. Use when you have specific IDs from search results or prior references—otherwise use search_memories.",
|
|
92
137
|
inputSchema: {
|
|
93
138
|
type: "object",
|
|
94
139
|
properties: {
|
|
95
|
-
|
|
96
|
-
type: "
|
|
97
|
-
description: "
|
|
140
|
+
ids: {
|
|
141
|
+
type: "array",
|
|
142
|
+
description: "Memory IDs to retrieve.",
|
|
143
|
+
items: { type: "string" },
|
|
98
144
|
},
|
|
99
145
|
},
|
|
100
|
-
required: ["
|
|
146
|
+
required: ["ids"],
|
|
147
|
+
},
|
|
148
|
+
};;
|
|
149
|
+
|
|
150
|
+
export const storeHandoffTool: Tool = {
|
|
151
|
+
name: "store_handoff",
|
|
152
|
+
description:
|
|
153
|
+
"Capture structured project state for handoff: summary, completed work, blockers, key decisions, next steps. " +
|
|
154
|
+
"Retrievable via get_handoff.",
|
|
155
|
+
inputSchema: {
|
|
156
|
+
type: "object",
|
|
157
|
+
properties: {
|
|
158
|
+
project: { type: "string", description: "Project name." },
|
|
159
|
+
branch: { type: "string", description: "Branch name (optional)." },
|
|
160
|
+
summary: { type: "string", description: "2-3 sentences: primary goal, current status." },
|
|
161
|
+
completed: {
|
|
162
|
+
type: "array",
|
|
163
|
+
items: { type: "string" },
|
|
164
|
+
description: "Completed items (include file paths where relevant).",
|
|
165
|
+
},
|
|
166
|
+
in_progress_blocked: {
|
|
167
|
+
type: "array",
|
|
168
|
+
items: { type: "string" },
|
|
169
|
+
description: "In progress or blocked items.",
|
|
170
|
+
},
|
|
171
|
+
key_decisions: {
|
|
172
|
+
type: "array",
|
|
173
|
+
items: { type: "string" },
|
|
174
|
+
description: "Decisions made and why.",
|
|
175
|
+
},
|
|
176
|
+
next_steps: {
|
|
177
|
+
type: "array",
|
|
178
|
+
items: { type: "string" },
|
|
179
|
+
description: "Concrete next steps.",
|
|
180
|
+
},
|
|
181
|
+
memory_ids: {
|
|
182
|
+
type: "array",
|
|
183
|
+
items: { type: "string" },
|
|
184
|
+
description: "Memory IDs referenced by this handoff.",
|
|
185
|
+
},
|
|
186
|
+
metadata: {
|
|
187
|
+
type: "object",
|
|
188
|
+
description: "Additional metadata.",
|
|
189
|
+
additionalProperties: true,
|
|
190
|
+
},
|
|
191
|
+
},
|
|
192
|
+
required: ["project", "summary"],
|
|
193
|
+
},
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
export const getHandoffTool: Tool = {
|
|
197
|
+
name: "get_handoff",
|
|
198
|
+
description:
|
|
199
|
+
"Load the current project handoff snapshot. Call at conversation start or when resuming a project.",
|
|
200
|
+
inputSchema: {
|
|
201
|
+
type: "object",
|
|
202
|
+
properties: {},
|
|
101
203
|
},
|
|
102
204
|
};
|
|
103
205
|
|
|
104
206
|
export const tools: Tool[] = [
|
|
105
|
-
|
|
106
|
-
|
|
207
|
+
storeMemoriesTool,
|
|
208
|
+
updateMemoriesTool,
|
|
209
|
+
deleteMemoriesTool,
|
|
107
210
|
searchMemoriesTool,
|
|
108
|
-
|
|
211
|
+
getMemoriesTool,
|
|
212
|
+
storeHandoffTool,
|
|
213
|
+
getHandoffTool,
|
|
109
214
|
];
|
|
@@ -21,9 +21,11 @@ export class EmbeddingsService {
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
if (!this.initPromise) {
|
|
24
|
-
this.initPromise = pipeline(
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
this.initPromise = pipeline(
|
|
25
|
+
"feature-extraction",
|
|
26
|
+
this.modelName,
|
|
27
|
+
{ dtype: "fp32" } as any
|
|
28
|
+
) as Promise<FeatureExtractionPipeline>;
|
|
27
29
|
}
|
|
28
30
|
|
|
29
31
|
this.extractor = await this.initPromise;
|