@prmichaelsen/remember-mcp 3.14.1 → 3.14.2
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/dist/server-factory.js +59 -30
- package/dist/server.js +59 -30
- package/package.json +1 -1
package/dist/server-factory.js
CHANGED
|
@@ -2256,6 +2256,20 @@ var MemoryService = class {
|
|
|
2256
2256
|
this.userId = userId;
|
|
2257
2257
|
this.logger = logger2;
|
|
2258
2258
|
}
|
|
2259
|
+
/**
|
|
2260
|
+
* Execute a search function, retrying without the deleted_at filter if
|
|
2261
|
+
* the collection lacks indexNullState (created before soft-delete support).
|
|
2262
|
+
*/
|
|
2263
|
+
async retryWithoutDeletedFilter(fn) {
|
|
2264
|
+
try {
|
|
2265
|
+
return await fn(true);
|
|
2266
|
+
} catch (err2) {
|
|
2267
|
+
if (err2?.message?.includes("Nullstate must be indexed")) {
|
|
2268
|
+
return fn(false);
|
|
2269
|
+
}
|
|
2270
|
+
throw err2;
|
|
2271
|
+
}
|
|
2272
|
+
}
|
|
2259
2273
|
// ── Create ──────────────────────────────────────────────────────────
|
|
2260
2274
|
async create(input) {
|
|
2261
2275
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -2301,7 +2315,6 @@ var MemoryService = class {
|
|
|
2301
2315
|
const alpha = input.alpha ?? 0.7;
|
|
2302
2316
|
const limit = input.limit ?? 10;
|
|
2303
2317
|
const offset = input.offset ?? 0;
|
|
2304
|
-
const deletedFilter = buildDeletedFilter(this.collection, input.deleted_filter || "exclude");
|
|
2305
2318
|
const searchFilters = includeRelationships ? buildCombinedSearchFilters(this.collection, input.filters) : buildMemoryOnlyFilters(this.collection, input.filters);
|
|
2306
2319
|
const ghostFilters = [];
|
|
2307
2320
|
if (input.ghost_context) {
|
|
@@ -2310,11 +2323,21 @@ var MemoryService = class {
|
|
|
2310
2323
|
if (!input.ghost_context?.include_ghost_content) {
|
|
2311
2324
|
ghostFilters.push(this.collection.filter.byProperty("content_type").notEqual("ghost"));
|
|
2312
2325
|
}
|
|
2313
|
-
const
|
|
2314
|
-
const
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2326
|
+
const isWildcard = input.query === "*";
|
|
2327
|
+
const executeSearch = async (useDeletedFilter) => {
|
|
2328
|
+
const deletedFilter = useDeletedFilter ? buildDeletedFilter(this.collection, input.deleted_filter || "exclude") : null;
|
|
2329
|
+
const combinedFilters = combineFiltersWithAnd([deletedFilter, searchFilters, ...ghostFilters].filter((f) => f !== null));
|
|
2330
|
+
const searchOptions = { limit: limit + offset };
|
|
2331
|
+
if (combinedFilters)
|
|
2332
|
+
searchOptions.filters = combinedFilters;
|
|
2333
|
+
if (isWildcard) {
|
|
2334
|
+
return this.collection.query.fetchObjects(searchOptions);
|
|
2335
|
+
} else {
|
|
2336
|
+
searchOptions.alpha = alpha;
|
|
2337
|
+
return this.collection.query.hybrid(input.query, searchOptions);
|
|
2338
|
+
}
|
|
2339
|
+
};
|
|
2340
|
+
const results = await this.retryWithoutDeletedFilter(executeSearch);
|
|
2318
2341
|
const paginated = results.objects.slice(offset);
|
|
2319
2342
|
const memories = [];
|
|
2320
2343
|
const relationships = [];
|
|
@@ -2341,7 +2364,6 @@ var MemoryService = class {
|
|
|
2341
2364
|
throw new Error("Provide either memory_id or text, not both");
|
|
2342
2365
|
const limit = input.limit ?? 10;
|
|
2343
2366
|
const minSimilarity = input.min_similarity ?? 0.7;
|
|
2344
|
-
const deletedFilter = buildDeletedFilter(this.collection, input.deleted_filter || "exclude");
|
|
2345
2367
|
const ghostFilters = [];
|
|
2346
2368
|
if (input.ghost_context) {
|
|
2347
2369
|
ghostFilters.push(buildTrustFilter(this.collection, input.ghost_context.accessor_trust_level));
|
|
@@ -2349,29 +2371,35 @@ var MemoryService = class {
|
|
|
2349
2371
|
if (!input.ghost_context?.include_ghost_content) {
|
|
2350
2372
|
ghostFilters.push(this.collection.filter.byProperty("content_type").notEqual("ghost"));
|
|
2351
2373
|
}
|
|
2352
|
-
|
|
2353
|
-
let results;
|
|
2374
|
+
let memoryObj = null;
|
|
2354
2375
|
if (input.memory_id) {
|
|
2355
|
-
|
|
2376
|
+
memoryObj = await this.collection.query.fetchObjectById(input.memory_id, {
|
|
2356
2377
|
returnProperties: ["user_id", "doc_type", "content"]
|
|
2357
2378
|
});
|
|
2358
|
-
if (!
|
|
2379
|
+
if (!memoryObj)
|
|
2359
2380
|
throw new Error(`Memory not found: ${input.memory_id}`);
|
|
2360
|
-
if (
|
|
2381
|
+
if (memoryObj.properties.user_id !== this.userId)
|
|
2361
2382
|
throw new Error("Unauthorized");
|
|
2362
|
-
if (
|
|
2383
|
+
if (memoryObj.properties.doc_type !== "memory")
|
|
2363
2384
|
throw new Error("Can only find similar for memory documents");
|
|
2364
|
-
const opts = { limit: limit + 1, distance: 1 - minSimilarity, returnMetadata: ["distance"] };
|
|
2365
|
-
if (combinedFilter)
|
|
2366
|
-
opts.filters = combinedFilter;
|
|
2367
|
-
results = await this.collection.query.nearObject(input.memory_id, opts);
|
|
2368
|
-
results.objects = results.objects.filter((o) => o.uuid !== input.memory_id);
|
|
2369
|
-
} else {
|
|
2370
|
-
const opts = { limit, distance: 1 - minSimilarity, returnMetadata: ["distance"] };
|
|
2371
|
-
if (combinedFilter)
|
|
2372
|
-
opts.filters = combinedFilter;
|
|
2373
|
-
results = await this.collection.query.nearText(input.text, opts);
|
|
2374
2385
|
}
|
|
2386
|
+
const results = await this.retryWithoutDeletedFilter(async (useDeletedFilter) => {
|
|
2387
|
+
const deletedFilter = useDeletedFilter ? buildDeletedFilter(this.collection, input.deleted_filter || "exclude") : null;
|
|
2388
|
+
const combinedFilter = combineFiltersWithAnd([deletedFilter, ...ghostFilters].filter((f) => f !== null));
|
|
2389
|
+
if (input.memory_id) {
|
|
2390
|
+
const opts = { limit: limit + 1, distance: 1 - minSimilarity, returnMetadata: ["distance"] };
|
|
2391
|
+
if (combinedFilter)
|
|
2392
|
+
opts.filters = combinedFilter;
|
|
2393
|
+
const res = await this.collection.query.nearObject(input.memory_id, opts);
|
|
2394
|
+
res.objects = res.objects.filter((o) => o.uuid !== input.memory_id);
|
|
2395
|
+
return res;
|
|
2396
|
+
} else {
|
|
2397
|
+
const opts = { limit, distance: 1 - minSimilarity, returnMetadata: ["distance"] };
|
|
2398
|
+
if (combinedFilter)
|
|
2399
|
+
opts.filters = combinedFilter;
|
|
2400
|
+
return this.collection.query.nearText(input.text, opts);
|
|
2401
|
+
}
|
|
2402
|
+
});
|
|
2375
2403
|
if (!input.include_relationships) {
|
|
2376
2404
|
results.objects = results.objects.filter((o) => o.properties.doc_type === "memory");
|
|
2377
2405
|
}
|
|
@@ -2388,7 +2416,6 @@ var MemoryService = class {
|
|
|
2388
2416
|
throw new Error("Query cannot be empty");
|
|
2389
2417
|
const limit = input.limit ?? 5;
|
|
2390
2418
|
const minRelevance = input.min_relevance ?? 0.6;
|
|
2391
|
-
const deletedFilter = buildDeletedFilter(this.collection, input.deleted_filter || "exclude");
|
|
2392
2419
|
const searchFilters = buildCombinedSearchFilters(this.collection, input.filters);
|
|
2393
2420
|
const ghostFilters = [];
|
|
2394
2421
|
if (input.ghost_context) {
|
|
@@ -2397,11 +2424,14 @@ var MemoryService = class {
|
|
|
2397
2424
|
if (!input.ghost_context?.include_ghost_content) {
|
|
2398
2425
|
ghostFilters.push(this.collection.filter.byProperty("content_type").notEqual("ghost"));
|
|
2399
2426
|
}
|
|
2400
|
-
const
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
opts
|
|
2404
|
-
|
|
2427
|
+
const results = await this.retryWithoutDeletedFilter(async (useDeletedFilter) => {
|
|
2428
|
+
const deletedFilter = useDeletedFilter ? buildDeletedFilter(this.collection, input.deleted_filter || "exclude") : null;
|
|
2429
|
+
const combinedFilters = combineFiltersWithAnd([deletedFilter, searchFilters, ...ghostFilters].filter((f) => f !== null));
|
|
2430
|
+
const opts = { limit, distance: 1 - minRelevance, returnMetadata: ["distance"] };
|
|
2431
|
+
if (combinedFilters)
|
|
2432
|
+
opts.filters = combinedFilters;
|
|
2433
|
+
return this.collection.query.nearText(input.query, opts);
|
|
2434
|
+
});
|
|
2405
2435
|
const items = results.objects.map((obj) => ({
|
|
2406
2436
|
id: obj.uuid,
|
|
2407
2437
|
...obj.properties,
|
|
@@ -3510,7 +3540,6 @@ var SpaceService = class {
|
|
|
3510
3540
|
// ── Private: Build Base Filters ─────────────────────────────────────
|
|
3511
3541
|
buildBaseFilters(collection, input) {
|
|
3512
3542
|
const filterList = [];
|
|
3513
|
-
filterList.push(collection.filter.byProperty("deleted_at").isNull(true));
|
|
3514
3543
|
filterList.push(collection.filter.byProperty("doc_type").equal("memory"));
|
|
3515
3544
|
const moderationFilter = buildModerationFilter(collection, input.moderation_filter);
|
|
3516
3545
|
if (moderationFilter)
|
package/dist/server.js
CHANGED
|
@@ -1940,6 +1940,20 @@ var MemoryService = class {
|
|
|
1940
1940
|
this.userId = userId;
|
|
1941
1941
|
this.logger = logger2;
|
|
1942
1942
|
}
|
|
1943
|
+
/**
|
|
1944
|
+
* Execute a search function, retrying without the deleted_at filter if
|
|
1945
|
+
* the collection lacks indexNullState (created before soft-delete support).
|
|
1946
|
+
*/
|
|
1947
|
+
async retryWithoutDeletedFilter(fn) {
|
|
1948
|
+
try {
|
|
1949
|
+
return await fn(true);
|
|
1950
|
+
} catch (err2) {
|
|
1951
|
+
if (err2?.message?.includes("Nullstate must be indexed")) {
|
|
1952
|
+
return fn(false);
|
|
1953
|
+
}
|
|
1954
|
+
throw err2;
|
|
1955
|
+
}
|
|
1956
|
+
}
|
|
1943
1957
|
// ── Create ──────────────────────────────────────────────────────────
|
|
1944
1958
|
async create(input) {
|
|
1945
1959
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -1985,7 +1999,6 @@ var MemoryService = class {
|
|
|
1985
1999
|
const alpha = input.alpha ?? 0.7;
|
|
1986
2000
|
const limit = input.limit ?? 10;
|
|
1987
2001
|
const offset = input.offset ?? 0;
|
|
1988
|
-
const deletedFilter = buildDeletedFilter(this.collection, input.deleted_filter || "exclude");
|
|
1989
2002
|
const searchFilters = includeRelationships ? buildCombinedSearchFilters(this.collection, input.filters) : buildMemoryOnlyFilters(this.collection, input.filters);
|
|
1990
2003
|
const ghostFilters = [];
|
|
1991
2004
|
if (input.ghost_context) {
|
|
@@ -1994,11 +2007,21 @@ var MemoryService = class {
|
|
|
1994
2007
|
if (!input.ghost_context?.include_ghost_content) {
|
|
1995
2008
|
ghostFilters.push(this.collection.filter.byProperty("content_type").notEqual("ghost"));
|
|
1996
2009
|
}
|
|
1997
|
-
const
|
|
1998
|
-
const
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2010
|
+
const isWildcard = input.query === "*";
|
|
2011
|
+
const executeSearch = async (useDeletedFilter) => {
|
|
2012
|
+
const deletedFilter = useDeletedFilter ? buildDeletedFilter(this.collection, input.deleted_filter || "exclude") : null;
|
|
2013
|
+
const combinedFilters = combineFiltersWithAnd([deletedFilter, searchFilters, ...ghostFilters].filter((f) => f !== null));
|
|
2014
|
+
const searchOptions = { limit: limit + offset };
|
|
2015
|
+
if (combinedFilters)
|
|
2016
|
+
searchOptions.filters = combinedFilters;
|
|
2017
|
+
if (isWildcard) {
|
|
2018
|
+
return this.collection.query.fetchObjects(searchOptions);
|
|
2019
|
+
} else {
|
|
2020
|
+
searchOptions.alpha = alpha;
|
|
2021
|
+
return this.collection.query.hybrid(input.query, searchOptions);
|
|
2022
|
+
}
|
|
2023
|
+
};
|
|
2024
|
+
const results = await this.retryWithoutDeletedFilter(executeSearch);
|
|
2002
2025
|
const paginated = results.objects.slice(offset);
|
|
2003
2026
|
const memories = [];
|
|
2004
2027
|
const relationships = [];
|
|
@@ -2025,7 +2048,6 @@ var MemoryService = class {
|
|
|
2025
2048
|
throw new Error("Provide either memory_id or text, not both");
|
|
2026
2049
|
const limit = input.limit ?? 10;
|
|
2027
2050
|
const minSimilarity = input.min_similarity ?? 0.7;
|
|
2028
|
-
const deletedFilter = buildDeletedFilter(this.collection, input.deleted_filter || "exclude");
|
|
2029
2051
|
const ghostFilters = [];
|
|
2030
2052
|
if (input.ghost_context) {
|
|
2031
2053
|
ghostFilters.push(buildTrustFilter(this.collection, input.ghost_context.accessor_trust_level));
|
|
@@ -2033,29 +2055,35 @@ var MemoryService = class {
|
|
|
2033
2055
|
if (!input.ghost_context?.include_ghost_content) {
|
|
2034
2056
|
ghostFilters.push(this.collection.filter.byProperty("content_type").notEqual("ghost"));
|
|
2035
2057
|
}
|
|
2036
|
-
|
|
2037
|
-
let results;
|
|
2058
|
+
let memoryObj = null;
|
|
2038
2059
|
if (input.memory_id) {
|
|
2039
|
-
|
|
2060
|
+
memoryObj = await this.collection.query.fetchObjectById(input.memory_id, {
|
|
2040
2061
|
returnProperties: ["user_id", "doc_type", "content"]
|
|
2041
2062
|
});
|
|
2042
|
-
if (!
|
|
2063
|
+
if (!memoryObj)
|
|
2043
2064
|
throw new Error(`Memory not found: ${input.memory_id}`);
|
|
2044
|
-
if (
|
|
2065
|
+
if (memoryObj.properties.user_id !== this.userId)
|
|
2045
2066
|
throw new Error("Unauthorized");
|
|
2046
|
-
if (
|
|
2067
|
+
if (memoryObj.properties.doc_type !== "memory")
|
|
2047
2068
|
throw new Error("Can only find similar for memory documents");
|
|
2048
|
-
const opts = { limit: limit + 1, distance: 1 - minSimilarity, returnMetadata: ["distance"] };
|
|
2049
|
-
if (combinedFilter)
|
|
2050
|
-
opts.filters = combinedFilter;
|
|
2051
|
-
results = await this.collection.query.nearObject(input.memory_id, opts);
|
|
2052
|
-
results.objects = results.objects.filter((o) => o.uuid !== input.memory_id);
|
|
2053
|
-
} else {
|
|
2054
|
-
const opts = { limit, distance: 1 - minSimilarity, returnMetadata: ["distance"] };
|
|
2055
|
-
if (combinedFilter)
|
|
2056
|
-
opts.filters = combinedFilter;
|
|
2057
|
-
results = await this.collection.query.nearText(input.text, opts);
|
|
2058
2069
|
}
|
|
2070
|
+
const results = await this.retryWithoutDeletedFilter(async (useDeletedFilter) => {
|
|
2071
|
+
const deletedFilter = useDeletedFilter ? buildDeletedFilter(this.collection, input.deleted_filter || "exclude") : null;
|
|
2072
|
+
const combinedFilter = combineFiltersWithAnd([deletedFilter, ...ghostFilters].filter((f) => f !== null));
|
|
2073
|
+
if (input.memory_id) {
|
|
2074
|
+
const opts = { limit: limit + 1, distance: 1 - minSimilarity, returnMetadata: ["distance"] };
|
|
2075
|
+
if (combinedFilter)
|
|
2076
|
+
opts.filters = combinedFilter;
|
|
2077
|
+
const res = await this.collection.query.nearObject(input.memory_id, opts);
|
|
2078
|
+
res.objects = res.objects.filter((o) => o.uuid !== input.memory_id);
|
|
2079
|
+
return res;
|
|
2080
|
+
} else {
|
|
2081
|
+
const opts = { limit, distance: 1 - minSimilarity, returnMetadata: ["distance"] };
|
|
2082
|
+
if (combinedFilter)
|
|
2083
|
+
opts.filters = combinedFilter;
|
|
2084
|
+
return this.collection.query.nearText(input.text, opts);
|
|
2085
|
+
}
|
|
2086
|
+
});
|
|
2059
2087
|
if (!input.include_relationships) {
|
|
2060
2088
|
results.objects = results.objects.filter((o) => o.properties.doc_type === "memory");
|
|
2061
2089
|
}
|
|
@@ -2072,7 +2100,6 @@ var MemoryService = class {
|
|
|
2072
2100
|
throw new Error("Query cannot be empty");
|
|
2073
2101
|
const limit = input.limit ?? 5;
|
|
2074
2102
|
const minRelevance = input.min_relevance ?? 0.6;
|
|
2075
|
-
const deletedFilter = buildDeletedFilter(this.collection, input.deleted_filter || "exclude");
|
|
2076
2103
|
const searchFilters = buildCombinedSearchFilters(this.collection, input.filters);
|
|
2077
2104
|
const ghostFilters = [];
|
|
2078
2105
|
if (input.ghost_context) {
|
|
@@ -2081,11 +2108,14 @@ var MemoryService = class {
|
|
|
2081
2108
|
if (!input.ghost_context?.include_ghost_content) {
|
|
2082
2109
|
ghostFilters.push(this.collection.filter.byProperty("content_type").notEqual("ghost"));
|
|
2083
2110
|
}
|
|
2084
|
-
const
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
opts
|
|
2088
|
-
|
|
2111
|
+
const results = await this.retryWithoutDeletedFilter(async (useDeletedFilter) => {
|
|
2112
|
+
const deletedFilter = useDeletedFilter ? buildDeletedFilter(this.collection, input.deleted_filter || "exclude") : null;
|
|
2113
|
+
const combinedFilters = combineFiltersWithAnd([deletedFilter, searchFilters, ...ghostFilters].filter((f) => f !== null));
|
|
2114
|
+
const opts = { limit, distance: 1 - minRelevance, returnMetadata: ["distance"] };
|
|
2115
|
+
if (combinedFilters)
|
|
2116
|
+
opts.filters = combinedFilters;
|
|
2117
|
+
return this.collection.query.nearText(input.query, opts);
|
|
2118
|
+
});
|
|
2089
2119
|
const items = results.objects.map((obj) => ({
|
|
2090
2120
|
id: obj.uuid,
|
|
2091
2121
|
...obj.properties,
|
|
@@ -3194,7 +3224,6 @@ var SpaceService = class {
|
|
|
3194
3224
|
// ── Private: Build Base Filters ─────────────────────────────────────
|
|
3195
3225
|
buildBaseFilters(collection, input) {
|
|
3196
3226
|
const filterList = [];
|
|
3197
|
-
filterList.push(collection.filter.byProperty("deleted_at").isNull(true));
|
|
3198
3227
|
filterList.push(collection.filter.byProperty("doc_type").equal("memory"));
|
|
3199
3228
|
const moderationFilter = buildModerationFilter(collection, input.moderation_filter);
|
|
3200
3229
|
if (moderationFilter)
|