@prmichaelsen/remember-mcp 2.6.13 → 2.7.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/CHANGELOG.md +27 -0
- package/dist/server-factory.js +13 -10
- package/dist/server.js +13 -10
- package/package.json +1 -1
- package/src/tools/update-memory.ts +19 -13
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,33 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [2.7.0] - 2026-02-17
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- **CRITICAL: `remember_update_memory` Now Uses `replace()` Instead of `update()`**
|
|
13
|
+
- Switched from `collection.data.update()` to `collection.data.replace()`
|
|
14
|
+
- Fixes Weaviate bug where `update()` only persists if vectorized fields change
|
|
15
|
+
- Now fetches full object and merges updates before replacing
|
|
16
|
+
- Updates to non-vectorized fields (title, type, weight, tags, etc.) now persist correctly
|
|
17
|
+
- Resolves issue where updates returned success but changes weren't saved
|
|
18
|
+
- **Breaking Change**: This is a minor version bump due to behavior change (more reliable updates)
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
|
|
22
|
+
- Fetch strategy: Now fetches all properties (not just 3) since we need full object for replace
|
|
23
|
+
- Update strategy: Merge updates with existing properties, then replace entire object
|
|
24
|
+
- Logging: Changed "Calling Weaviate update" to "Calling Weaviate replace"
|
|
25
|
+
|
|
26
|
+
### Root Cause
|
|
27
|
+
|
|
28
|
+
- Weaviate has a known bug where `update()` only persists changes if at least one vectorized field is modified
|
|
29
|
+
- Our schema only vectorizes `content` and `observation`
|
|
30
|
+
- Updates to `title`, `type`, `weight`, `tags`, etc. were silently ignored
|
|
31
|
+
- `replace()` doesn't have this limitation and always persists changes
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
8
35
|
## [2.6.13] - 2026-02-17
|
|
9
36
|
|
|
10
37
|
### Changed
|
package/dist/server-factory.js
CHANGED
|
@@ -1948,9 +1948,7 @@ async function handleUpdateMemory(args, userId) {
|
|
|
1948
1948
|
const collection = getMemoryCollection(userId);
|
|
1949
1949
|
let existingMemory;
|
|
1950
1950
|
try {
|
|
1951
|
-
existingMemory = await collection.query.fetchObjectById(args.memory_id
|
|
1952
|
-
returnProperties: ["user_id", "doc_type", "version"]
|
|
1953
|
-
});
|
|
1951
|
+
existingMemory = await collection.query.fetchObjectById(args.memory_id);
|
|
1954
1952
|
} catch (fetchError) {
|
|
1955
1953
|
const fetchErrorMsg = fetchError instanceof Error ? fetchError.message : String(fetchError);
|
|
1956
1954
|
logger.error("Failed to fetch memory for update:", {
|
|
@@ -1961,7 +1959,7 @@ async function handleUpdateMemory(args, userId) {
|
|
|
1961
1959
|
});
|
|
1962
1960
|
throw new Error(`Failed to fetch memory ${args.memory_id}: ${fetchErrorMsg}`);
|
|
1963
1961
|
}
|
|
1964
|
-
if (!existingMemory) {
|
|
1962
|
+
if (!existingMemory || !existingMemory.properties) {
|
|
1965
1963
|
throw new Error(`Memory not found: ${args.memory_id}. It may have been deleted or never existed.`);
|
|
1966
1964
|
}
|
|
1967
1965
|
if (existingMemory.properties.user_id !== userId) {
|
|
@@ -2034,26 +2032,31 @@ async function handleUpdateMemory(args, userId) {
|
|
|
2034
2032
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
2035
2033
|
updates.updated_at = now;
|
|
2036
2034
|
updates.version = existingMemory.properties.version + 1;
|
|
2037
|
-
|
|
2035
|
+
const mergedProperties = {
|
|
2036
|
+
...existingMemory.properties,
|
|
2037
|
+
...updates
|
|
2038
|
+
};
|
|
2039
|
+
logger.info("Calling Weaviate replace", {
|
|
2038
2040
|
userId,
|
|
2039
2041
|
memoryId: args.memory_id,
|
|
2040
2042
|
updateFields: Object.keys(updates),
|
|
2041
2043
|
updateValues: updates,
|
|
2042
|
-
collectionName: `Memory_${userId}
|
|
2044
|
+
collectionName: `Memory_${userId}`,
|
|
2045
|
+
totalProperties: Object.keys(mergedProperties).length
|
|
2043
2046
|
});
|
|
2044
2047
|
try {
|
|
2045
|
-
await collection.data.
|
|
2048
|
+
await collection.data.replace({
|
|
2046
2049
|
id: args.memory_id,
|
|
2047
|
-
properties:
|
|
2050
|
+
properties: mergedProperties
|
|
2048
2051
|
});
|
|
2049
|
-
logger.info("Weaviate
|
|
2052
|
+
logger.info("Weaviate replace completed (no error thrown)", {
|
|
2050
2053
|
userId,
|
|
2051
2054
|
memoryId: args.memory_id,
|
|
2052
2055
|
updatedFields: Object.keys(updates)
|
|
2053
2056
|
});
|
|
2054
2057
|
} catch (updateError) {
|
|
2055
2058
|
const updateErrorMsg = updateError instanceof Error ? updateError.message : String(updateError);
|
|
2056
|
-
logger.error("Failed to perform Weaviate
|
|
2059
|
+
logger.error("Failed to perform Weaviate replace:", {
|
|
2057
2060
|
error: updateErrorMsg,
|
|
2058
2061
|
userId,
|
|
2059
2062
|
memoryId: args.memory_id,
|
package/dist/server.js
CHANGED
|
@@ -2016,9 +2016,7 @@ async function handleUpdateMemory(args, userId) {
|
|
|
2016
2016
|
const collection = getMemoryCollection(userId);
|
|
2017
2017
|
let existingMemory;
|
|
2018
2018
|
try {
|
|
2019
|
-
existingMemory = await collection.query.fetchObjectById(args.memory_id
|
|
2020
|
-
returnProperties: ["user_id", "doc_type", "version"]
|
|
2021
|
-
});
|
|
2019
|
+
existingMemory = await collection.query.fetchObjectById(args.memory_id);
|
|
2022
2020
|
} catch (fetchError) {
|
|
2023
2021
|
const fetchErrorMsg = fetchError instanceof Error ? fetchError.message : String(fetchError);
|
|
2024
2022
|
logger.error("Failed to fetch memory for update:", {
|
|
@@ -2029,7 +2027,7 @@ async function handleUpdateMemory(args, userId) {
|
|
|
2029
2027
|
});
|
|
2030
2028
|
throw new Error(`Failed to fetch memory ${args.memory_id}: ${fetchErrorMsg}`);
|
|
2031
2029
|
}
|
|
2032
|
-
if (!existingMemory) {
|
|
2030
|
+
if (!existingMemory || !existingMemory.properties) {
|
|
2033
2031
|
throw new Error(`Memory not found: ${args.memory_id}. It may have been deleted or never existed.`);
|
|
2034
2032
|
}
|
|
2035
2033
|
if (existingMemory.properties.user_id !== userId) {
|
|
@@ -2102,26 +2100,31 @@ async function handleUpdateMemory(args, userId) {
|
|
|
2102
2100
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
2103
2101
|
updates.updated_at = now;
|
|
2104
2102
|
updates.version = existingMemory.properties.version + 1;
|
|
2105
|
-
|
|
2103
|
+
const mergedProperties = {
|
|
2104
|
+
...existingMemory.properties,
|
|
2105
|
+
...updates
|
|
2106
|
+
};
|
|
2107
|
+
logger.info("Calling Weaviate replace", {
|
|
2106
2108
|
userId,
|
|
2107
2109
|
memoryId: args.memory_id,
|
|
2108
2110
|
updateFields: Object.keys(updates),
|
|
2109
2111
|
updateValues: updates,
|
|
2110
|
-
collectionName: `Memory_${userId}
|
|
2112
|
+
collectionName: `Memory_${userId}`,
|
|
2113
|
+
totalProperties: Object.keys(mergedProperties).length
|
|
2111
2114
|
});
|
|
2112
2115
|
try {
|
|
2113
|
-
await collection.data.
|
|
2116
|
+
await collection.data.replace({
|
|
2114
2117
|
id: args.memory_id,
|
|
2115
|
-
properties:
|
|
2118
|
+
properties: mergedProperties
|
|
2116
2119
|
});
|
|
2117
|
-
logger.info("Weaviate
|
|
2120
|
+
logger.info("Weaviate replace completed (no error thrown)", {
|
|
2118
2121
|
userId,
|
|
2119
2122
|
memoryId: args.memory_id,
|
|
2120
2123
|
updatedFields: Object.keys(updates)
|
|
2121
2124
|
});
|
|
2122
2125
|
} catch (updateError) {
|
|
2123
2126
|
const updateErrorMsg = updateError instanceof Error ? updateError.message : String(updateError);
|
|
2124
|
-
logger.error("Failed to perform Weaviate
|
|
2127
|
+
logger.error("Failed to perform Weaviate replace:", {
|
|
2125
2128
|
error: updateErrorMsg,
|
|
2126
2129
|
userId,
|
|
2127
2130
|
memoryId: args.memory_id,
|
package/package.json
CHANGED
|
@@ -130,14 +130,12 @@ export async function handleUpdateMemory(
|
|
|
130
130
|
|
|
131
131
|
const collection = getMemoryCollection(userId);
|
|
132
132
|
|
|
133
|
-
// Get existing memory
|
|
134
|
-
//
|
|
135
|
-
//
|
|
133
|
+
// Get existing memory - fetch ALL properties for replace operation
|
|
134
|
+
// We need the full object to use replace() instead of update()
|
|
135
|
+
// (Weaviate bug: update() only persists if vectorized fields change)
|
|
136
136
|
let existingMemory;
|
|
137
137
|
try {
|
|
138
|
-
existingMemory = await collection.query.fetchObjectById(args.memory_id
|
|
139
|
-
returnProperties: ['user_id', 'doc_type', 'version'],
|
|
140
|
-
});
|
|
138
|
+
existingMemory = await collection.query.fetchObjectById(args.memory_id);
|
|
141
139
|
} catch (fetchError) {
|
|
142
140
|
const fetchErrorMsg = fetchError instanceof Error ? fetchError.message : String(fetchError);
|
|
143
141
|
logger.error('Failed to fetch memory for update:', {
|
|
@@ -149,7 +147,7 @@ export async function handleUpdateMemory(
|
|
|
149
147
|
throw new Error(`Failed to fetch memory ${args.memory_id}: ${fetchErrorMsg}`);
|
|
150
148
|
}
|
|
151
149
|
|
|
152
|
-
if (!existingMemory) {
|
|
150
|
+
if (!existingMemory || !existingMemory.properties) {
|
|
153
151
|
throw new Error(`Memory not found: ${args.memory_id}. It may have been deleted or never existed.`);
|
|
154
152
|
}
|
|
155
153
|
|
|
@@ -249,29 +247,37 @@ export async function handleUpdateMemory(
|
|
|
249
247
|
updates.updated_at = now;
|
|
250
248
|
updates.version = (existingMemory.properties.version as number) + 1;
|
|
251
249
|
|
|
252
|
-
//
|
|
253
|
-
|
|
250
|
+
// Merge updates with existing properties
|
|
251
|
+
// Use replace() instead of update() due to Weaviate bug where update() only
|
|
252
|
+
// persists if vectorized fields (content/observation) are changed
|
|
253
|
+
const mergedProperties = {
|
|
254
|
+
...existingMemory.properties,
|
|
255
|
+
...updates,
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
logger.info('Calling Weaviate replace', {
|
|
254
259
|
userId,
|
|
255
260
|
memoryId: args.memory_id,
|
|
256
261
|
updateFields: Object.keys(updates),
|
|
257
262
|
updateValues: updates,
|
|
258
263
|
collectionName: `Memory_${userId}`,
|
|
264
|
+
totalProperties: Object.keys(mergedProperties).length,
|
|
259
265
|
});
|
|
260
266
|
|
|
261
267
|
try {
|
|
262
|
-
await collection.data.
|
|
268
|
+
await collection.data.replace({
|
|
263
269
|
id: args.memory_id,
|
|
264
|
-
properties:
|
|
270
|
+
properties: mergedProperties,
|
|
265
271
|
});
|
|
266
272
|
|
|
267
|
-
logger.info('Weaviate
|
|
273
|
+
logger.info('Weaviate replace completed (no error thrown)', {
|
|
268
274
|
userId,
|
|
269
275
|
memoryId: args.memory_id,
|
|
270
276
|
updatedFields: Object.keys(updates),
|
|
271
277
|
});
|
|
272
278
|
} catch (updateError) {
|
|
273
279
|
const updateErrorMsg = updateError instanceof Error ? updateError.message : String(updateError);
|
|
274
|
-
logger.error('Failed to perform Weaviate
|
|
280
|
+
logger.error('Failed to perform Weaviate replace:', {
|
|
275
281
|
error: updateErrorMsg,
|
|
276
282
|
userId,
|
|
277
283
|
memoryId: args.memory_id,
|