@prmichaelsen/remember-mcp 0.1.0 → 0.2.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/agent/progress.yaml +96 -36
- package/dist/server-factory.d.ts +2 -0
- package/dist/server-factory.js +1157 -51
- package/dist/server.js +1075 -1
- package/dist/tools/create-relationship.d.ts +79 -0
- package/dist/tools/delete-relationship.d.ts +41 -0
- package/dist/tools/find-similar.d.ts +77 -0
- package/dist/tools/query-memory.d.ts +115 -0
- package/dist/tools/search-relationship.d.ts +86 -0
- package/dist/tools/update-memory.d.ts +92 -0
- package/dist/tools/update-relationship.d.ts +74 -0
- package/package.json +1 -1
- package/src/server-factory.ts +98 -5
- package/src/server.ts +46 -0
- package/src/tools/create-relationship.ts +242 -0
- package/src/tools/delete-relationship.ts +160 -0
- package/src/tools/find-similar.ts +199 -0
- package/src/tools/query-memory.ts +284 -0
- package/src/tools/search-relationship.ts +228 -0
- package/src/tools/update-memory.ts +230 -0
- package/src/tools/update-relationship.ts +189 -0
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* remember_update_memory tool
|
|
3
|
+
* Update an existing memory with partial updates
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { Memory, MemoryUpdate } from '../types/memory.js';
|
|
7
|
+
import { getMemoryCollection } from '../weaviate/schema.js';
|
|
8
|
+
import { logger } from '../utils/logger.js';
|
|
9
|
+
import { isValidContentType } from '../constants/content-types.js';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Tool definition for remember_update_memory
|
|
13
|
+
*/
|
|
14
|
+
export const updateMemoryTool = {
|
|
15
|
+
name: 'remember_update_memory',
|
|
16
|
+
description: `Update an existing memory with partial updates.
|
|
17
|
+
|
|
18
|
+
Supports updating any field except id, user_id, doc_type, created_at.
|
|
19
|
+
Version number is automatically incremented and updated_at is set.
|
|
20
|
+
Only provided fields are updated (partial updates supported).
|
|
21
|
+
|
|
22
|
+
Examples:
|
|
23
|
+
- "Update that camping note to add more details"
|
|
24
|
+
- "Change the weight of my recipe memory"
|
|
25
|
+
- "Add tags to the meeting note from yesterday"
|
|
26
|
+
`,
|
|
27
|
+
inputSchema: {
|
|
28
|
+
type: 'object',
|
|
29
|
+
properties: {
|
|
30
|
+
memory_id: {
|
|
31
|
+
type: 'string',
|
|
32
|
+
description: 'ID of the memory to update',
|
|
33
|
+
},
|
|
34
|
+
content: {
|
|
35
|
+
type: 'string',
|
|
36
|
+
description: 'Updated memory content',
|
|
37
|
+
},
|
|
38
|
+
title: {
|
|
39
|
+
type: 'string',
|
|
40
|
+
description: 'Updated title',
|
|
41
|
+
},
|
|
42
|
+
type: {
|
|
43
|
+
type: 'string',
|
|
44
|
+
description: 'Updated content type',
|
|
45
|
+
},
|
|
46
|
+
weight: {
|
|
47
|
+
type: 'number',
|
|
48
|
+
description: 'Updated significance/priority (0-1)',
|
|
49
|
+
minimum: 0,
|
|
50
|
+
maximum: 1,
|
|
51
|
+
},
|
|
52
|
+
trust: {
|
|
53
|
+
type: 'number',
|
|
54
|
+
description: 'Updated access control level (0-1)',
|
|
55
|
+
minimum: 0,
|
|
56
|
+
maximum: 1,
|
|
57
|
+
},
|
|
58
|
+
tags: {
|
|
59
|
+
type: 'array',
|
|
60
|
+
items: { type: 'string' },
|
|
61
|
+
description: 'Updated tags (replaces existing tags)',
|
|
62
|
+
},
|
|
63
|
+
references: {
|
|
64
|
+
type: 'array',
|
|
65
|
+
items: { type: 'string' },
|
|
66
|
+
description: 'Updated source URLs (replaces existing references)',
|
|
67
|
+
},
|
|
68
|
+
structured_content: {
|
|
69
|
+
type: 'object',
|
|
70
|
+
description: 'Updated structured content',
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
required: ['memory_id'],
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Update memory arguments
|
|
79
|
+
*/
|
|
80
|
+
export interface UpdateMemoryArgs {
|
|
81
|
+
memory_id: string;
|
|
82
|
+
content?: string;
|
|
83
|
+
title?: string;
|
|
84
|
+
type?: string;
|
|
85
|
+
weight?: number;
|
|
86
|
+
trust?: number;
|
|
87
|
+
tags?: string[];
|
|
88
|
+
references?: string[];
|
|
89
|
+
structured_content?: Record<string, any>;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Update memory result
|
|
94
|
+
*/
|
|
95
|
+
export interface UpdateMemoryResult {
|
|
96
|
+
memory_id: string;
|
|
97
|
+
updated_at: string;
|
|
98
|
+
version: number;
|
|
99
|
+
updated_fields: string[];
|
|
100
|
+
message: string;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Handle remember_update_memory tool
|
|
105
|
+
*/
|
|
106
|
+
export async function handleUpdateMemory(
|
|
107
|
+
args: UpdateMemoryArgs,
|
|
108
|
+
userId: string
|
|
109
|
+
): Promise<string> {
|
|
110
|
+
try {
|
|
111
|
+
logger.info('Updating memory', { userId, memoryId: args.memory_id });
|
|
112
|
+
|
|
113
|
+
const collection = getMemoryCollection(userId);
|
|
114
|
+
|
|
115
|
+
// Get existing memory to verify ownership and get current version
|
|
116
|
+
const existingMemory = await collection.query.fetchObjectById(args.memory_id, {
|
|
117
|
+
returnProperties: ['user_id', 'doc_type', 'version', 'type', 'weight', 'base_weight'],
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
if (!existingMemory) {
|
|
121
|
+
throw new Error(`Memory not found: ${args.memory_id}`);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Verify ownership
|
|
125
|
+
if (existingMemory.properties.user_id !== userId) {
|
|
126
|
+
throw new Error('Unauthorized: Cannot update another user\'s memory');
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Verify it's a memory (not a relationship)
|
|
130
|
+
if (existingMemory.properties.doc_type !== 'memory') {
|
|
131
|
+
throw new Error('Cannot update relationships using this tool. Use remember_update_relationship instead.');
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Build update object with only provided fields
|
|
135
|
+
const updates: Record<string, any> = {};
|
|
136
|
+
const updatedFields: string[] = [];
|
|
137
|
+
|
|
138
|
+
// Update content fields
|
|
139
|
+
if (args.content !== undefined) {
|
|
140
|
+
updates.content = args.content;
|
|
141
|
+
updatedFields.push('content');
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (args.title !== undefined) {
|
|
145
|
+
updates.title = args.title;
|
|
146
|
+
updates.summary = args.title; // Keep summary in sync with title
|
|
147
|
+
updatedFields.push('title');
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (args.type !== undefined) {
|
|
151
|
+
if (!isValidContentType(args.type)) {
|
|
152
|
+
throw new Error(`Invalid content type: ${args.type}`);
|
|
153
|
+
}
|
|
154
|
+
updates.type = args.type;
|
|
155
|
+
updatedFields.push('type');
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Update scoring fields
|
|
159
|
+
if (args.weight !== undefined) {
|
|
160
|
+
if (args.weight < 0 || args.weight > 1) {
|
|
161
|
+
throw new Error('Weight must be between 0 and 1');
|
|
162
|
+
}
|
|
163
|
+
updates.weight = args.weight;
|
|
164
|
+
updates.base_weight = args.weight;
|
|
165
|
+
updates.computed_weight = args.weight; // Recalculate if needed
|
|
166
|
+
updatedFields.push('weight');
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (args.trust !== undefined) {
|
|
170
|
+
if (args.trust < 0 || args.trust > 1) {
|
|
171
|
+
throw new Error('Trust must be between 0 and 1');
|
|
172
|
+
}
|
|
173
|
+
updates.trust = args.trust;
|
|
174
|
+
updatedFields.push('trust');
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Update organization fields
|
|
178
|
+
if (args.tags !== undefined) {
|
|
179
|
+
updates.tags = args.tags;
|
|
180
|
+
updatedFields.push('tags');
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if (args.references !== undefined) {
|
|
184
|
+
updates.references = args.references;
|
|
185
|
+
updatedFields.push('references');
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Update structured content
|
|
189
|
+
if (args.structured_content !== undefined) {
|
|
190
|
+
updates.structured_content = args.structured_content;
|
|
191
|
+
updatedFields.push('structured_content');
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Check if any fields were provided
|
|
195
|
+
if (updatedFields.length === 0) {
|
|
196
|
+
throw new Error('No fields provided for update. At least one field must be specified.');
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Update metadata
|
|
200
|
+
const now = new Date().toISOString();
|
|
201
|
+
updates.updated_at = now;
|
|
202
|
+
updates.version = (existingMemory.properties.version as number) + 1;
|
|
203
|
+
|
|
204
|
+
// Perform update in Weaviate
|
|
205
|
+
await collection.data.update({
|
|
206
|
+
id: args.memory_id,
|
|
207
|
+
properties: updates,
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
logger.info('Memory updated successfully', {
|
|
211
|
+
userId,
|
|
212
|
+
memoryId: args.memory_id,
|
|
213
|
+
version: updates.version,
|
|
214
|
+
updatedFields,
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
const result: UpdateMemoryResult = {
|
|
218
|
+
memory_id: args.memory_id,
|
|
219
|
+
updated_at: now,
|
|
220
|
+
version: updates.version,
|
|
221
|
+
updated_fields: updatedFields,
|
|
222
|
+
message: `Memory updated successfully. Updated fields: ${updatedFields.join(', ')}`,
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
return JSON.stringify(result, null, 2);
|
|
226
|
+
} catch (error) {
|
|
227
|
+
logger.error('Failed to update memory:', error);
|
|
228
|
+
throw new Error(`Failed to update memory: ${error instanceof Error ? error.message : String(error)}`);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* remember_update_relationship tool
|
|
3
|
+
* Update an existing relationship with partial updates
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { RelationshipUpdate } from '../types/memory.js';
|
|
7
|
+
import { getMemoryCollection } from '../weaviate/schema.js';
|
|
8
|
+
import { logger } from '../utils/logger.js';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Tool definition for remember_update_relationship
|
|
12
|
+
*/
|
|
13
|
+
export const updateRelationshipTool = {
|
|
14
|
+
name: 'remember_update_relationship',
|
|
15
|
+
description: `Update an existing relationship with partial updates.
|
|
16
|
+
|
|
17
|
+
Supports updating relationship_type, observation, strength, confidence, and tags.
|
|
18
|
+
Version number is automatically incremented and updated_at is set.
|
|
19
|
+
Only provided fields are updated (partial updates supported).
|
|
20
|
+
|
|
21
|
+
Examples:
|
|
22
|
+
- "Update that relationship to increase the strength"
|
|
23
|
+
- "Change the observation text for the camping relationship"
|
|
24
|
+
- "Add tags to the inspiration relationship"
|
|
25
|
+
`,
|
|
26
|
+
inputSchema: {
|
|
27
|
+
type: 'object',
|
|
28
|
+
properties: {
|
|
29
|
+
relationship_id: {
|
|
30
|
+
type: 'string',
|
|
31
|
+
description: 'ID of the relationship to update',
|
|
32
|
+
},
|
|
33
|
+
relationship_type: {
|
|
34
|
+
type: 'string',
|
|
35
|
+
description: 'Updated relationship type',
|
|
36
|
+
},
|
|
37
|
+
observation: {
|
|
38
|
+
type: 'string',
|
|
39
|
+
description: 'Updated observation/description',
|
|
40
|
+
},
|
|
41
|
+
strength: {
|
|
42
|
+
type: 'number',
|
|
43
|
+
description: 'Updated strength (0-1)',
|
|
44
|
+
minimum: 0,
|
|
45
|
+
maximum: 1,
|
|
46
|
+
},
|
|
47
|
+
confidence: {
|
|
48
|
+
type: 'number',
|
|
49
|
+
description: 'Updated confidence (0-1)',
|
|
50
|
+
minimum: 0,
|
|
51
|
+
maximum: 1,
|
|
52
|
+
},
|
|
53
|
+
tags: {
|
|
54
|
+
type: 'array',
|
|
55
|
+
items: { type: 'string' },
|
|
56
|
+
description: 'Updated tags (replaces existing tags)',
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
required: ['relationship_id'],
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Update relationship arguments
|
|
65
|
+
*/
|
|
66
|
+
export interface UpdateRelationshipArgs {
|
|
67
|
+
relationship_id: string;
|
|
68
|
+
relationship_type?: string;
|
|
69
|
+
observation?: string;
|
|
70
|
+
strength?: number;
|
|
71
|
+
confidence?: number;
|
|
72
|
+
tags?: string[];
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Update relationship result
|
|
77
|
+
*/
|
|
78
|
+
export interface UpdateRelationshipResult {
|
|
79
|
+
relationship_id: string;
|
|
80
|
+
updated_at: string;
|
|
81
|
+
version: number;
|
|
82
|
+
updated_fields: string[];
|
|
83
|
+
message: string;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Handle remember_update_relationship tool
|
|
88
|
+
*/
|
|
89
|
+
export async function handleUpdateRelationship(
|
|
90
|
+
args: UpdateRelationshipArgs,
|
|
91
|
+
userId: string
|
|
92
|
+
): Promise<string> {
|
|
93
|
+
try {
|
|
94
|
+
logger.info('Updating relationship', { userId, relationshipId: args.relationship_id });
|
|
95
|
+
|
|
96
|
+
const collection = getMemoryCollection(userId);
|
|
97
|
+
|
|
98
|
+
// Get existing relationship to verify ownership and get current version
|
|
99
|
+
const existingRelationship = await collection.query.fetchObjectById(args.relationship_id, {
|
|
100
|
+
returnProperties: ['user_id', 'doc_type', 'version', 'relationship_type', 'strength', 'confidence'],
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
if (!existingRelationship) {
|
|
104
|
+
throw new Error(`Relationship not found: ${args.relationship_id}`);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Verify ownership
|
|
108
|
+
if (existingRelationship.properties.user_id !== userId) {
|
|
109
|
+
throw new Error('Unauthorized: Cannot update another user\'s relationship');
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Verify it's a relationship (not a memory)
|
|
113
|
+
if (existingRelationship.properties.doc_type !== 'relationship') {
|
|
114
|
+
throw new Error('Cannot update memories using this tool. Use remember_update_memory instead.');
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Build update object with only provided fields
|
|
118
|
+
const updates: Record<string, any> = {};
|
|
119
|
+
const updatedFields: string[] = [];
|
|
120
|
+
|
|
121
|
+
// Update relationship fields
|
|
122
|
+
if (args.relationship_type !== undefined) {
|
|
123
|
+
updates.relationship_type = args.relationship_type;
|
|
124
|
+
updatedFields.push('relationship_type');
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (args.observation !== undefined) {
|
|
128
|
+
updates.observation = args.observation;
|
|
129
|
+
updatedFields.push('observation');
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (args.strength !== undefined) {
|
|
133
|
+
if (args.strength < 0 || args.strength > 1) {
|
|
134
|
+
throw new Error('Strength must be between 0 and 1');
|
|
135
|
+
}
|
|
136
|
+
updates.strength = args.strength;
|
|
137
|
+
updatedFields.push('strength');
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (args.confidence !== undefined) {
|
|
141
|
+
if (args.confidence < 0 || args.confidence > 1) {
|
|
142
|
+
throw new Error('Confidence must be between 0 and 1');
|
|
143
|
+
}
|
|
144
|
+
updates.confidence = args.confidence;
|
|
145
|
+
updatedFields.push('confidence');
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (args.tags !== undefined) {
|
|
149
|
+
updates.tags = args.tags;
|
|
150
|
+
updatedFields.push('tags');
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Check if any fields were provided
|
|
154
|
+
if (updatedFields.length === 0) {
|
|
155
|
+
throw new Error('No fields provided for update. At least one field must be specified.');
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Update metadata
|
|
159
|
+
const now = new Date().toISOString();
|
|
160
|
+
updates.updated_at = now;
|
|
161
|
+
updates.version = (existingRelationship.properties.version as number) + 1;
|
|
162
|
+
|
|
163
|
+
// Perform update in Weaviate
|
|
164
|
+
await collection.data.update({
|
|
165
|
+
id: args.relationship_id,
|
|
166
|
+
properties: updates,
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
logger.info('Relationship updated successfully', {
|
|
170
|
+
userId,
|
|
171
|
+
relationshipId: args.relationship_id,
|
|
172
|
+
version: updates.version,
|
|
173
|
+
updatedFields,
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
const result: UpdateRelationshipResult = {
|
|
177
|
+
relationship_id: args.relationship_id,
|
|
178
|
+
updated_at: now,
|
|
179
|
+
version: updates.version,
|
|
180
|
+
updated_fields: updatedFields,
|
|
181
|
+
message: `Relationship updated successfully. Updated fields: ${updatedFields.join(', ')}`,
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
return JSON.stringify(result, null, 2);
|
|
185
|
+
} catch (error) {
|
|
186
|
+
logger.error('Failed to update relationship:', error);
|
|
187
|
+
throw new Error(`Failed to update relationship: ${error instanceof Error ? error.message : String(error)}`);
|
|
188
|
+
}
|
|
189
|
+
}
|