@prmichaelsen/remember-mcp 3.14.19 → 3.14.20
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 +116 -3
- package/dist/server.js +116 -3
- package/package.json +2 -2
package/dist/server-factory.js
CHANGED
|
@@ -886,7 +886,7 @@ var DEFAULT_PREFERENCES = {
|
|
|
886
886
|
share_with_memories: true
|
|
887
887
|
},
|
|
888
888
|
privacy: {
|
|
889
|
-
default_trust_level:
|
|
889
|
+
default_trust_level: 2,
|
|
890
890
|
allow_cross_user_access: false,
|
|
891
891
|
auto_approve_requests: false,
|
|
892
892
|
audit_logging: true
|
|
@@ -905,6 +905,14 @@ var DEFAULT_PREFERENCES = {
|
|
|
905
905
|
}
|
|
906
906
|
};
|
|
907
907
|
|
|
908
|
+
// node_modules/@prmichaelsen/remember-core/dist/types/rating.types.js
|
|
909
|
+
var RATING_MIN_THRESHOLD = 5;
|
|
910
|
+
function computeRatingAvg(ratingSum, ratingCount) {
|
|
911
|
+
if (ratingCount < RATING_MIN_THRESHOLD)
|
|
912
|
+
return null;
|
|
913
|
+
return ratingSum / ratingCount;
|
|
914
|
+
}
|
|
915
|
+
|
|
908
916
|
// node_modules/@prmichaelsen/remember-core/dist/types/space.types.js
|
|
909
917
|
var SUPPORTED_SPACES = [
|
|
910
918
|
"the_void",
|
|
@@ -1361,6 +1369,35 @@ var DebugLevel2;
|
|
|
1361
1369
|
DebugLevel3[DebugLevel3["TRACE"] = 5] = "TRACE";
|
|
1362
1370
|
})(DebugLevel2 || (DebugLevel2 = {}));
|
|
1363
1371
|
|
|
1372
|
+
// node_modules/@prmichaelsen/remember-core/dist/errors/base.error.js
|
|
1373
|
+
var AppError = class extends Error {
|
|
1374
|
+
context;
|
|
1375
|
+
constructor(message, context = {}) {
|
|
1376
|
+
super(message);
|
|
1377
|
+
this.context = context;
|
|
1378
|
+
this.name = this.constructor.name;
|
|
1379
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
1380
|
+
}
|
|
1381
|
+
toJSON() {
|
|
1382
|
+
return {
|
|
1383
|
+
kind: this.kind,
|
|
1384
|
+
name: this.name,
|
|
1385
|
+
message: this.message,
|
|
1386
|
+
context: this.context
|
|
1387
|
+
};
|
|
1388
|
+
}
|
|
1389
|
+
};
|
|
1390
|
+
|
|
1391
|
+
// node_modules/@prmichaelsen/remember-core/dist/errors/app-errors.js
|
|
1392
|
+
var ValidationError = class extends AppError {
|
|
1393
|
+
fields;
|
|
1394
|
+
kind = "validation";
|
|
1395
|
+
constructor(message, fields = {}) {
|
|
1396
|
+
super(message, { fields });
|
|
1397
|
+
this.fields = fields;
|
|
1398
|
+
}
|
|
1399
|
+
};
|
|
1400
|
+
|
|
1364
1401
|
// node_modules/@prmichaelsen/remember-core/node_modules/uuid/dist/esm/regex.js
|
|
1365
1402
|
var regex_default = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/i;
|
|
1366
1403
|
|
|
@@ -1637,6 +1674,9 @@ function buildDocTypeFilters(collection, docType, filters) {
|
|
|
1637
1674
|
if (filters?.relationship_count_max !== void 0) {
|
|
1638
1675
|
filterList.push(collection.filter.byProperty("relationship_count").lessOrEqual(filters.relationship_count_max));
|
|
1639
1676
|
}
|
|
1677
|
+
if (filters?.rating_min !== void 0) {
|
|
1678
|
+
filterList.push(collection.filter.byProperty("rating_bayesian").greaterOrEqual(filters.rating_min));
|
|
1679
|
+
}
|
|
1640
1680
|
if (filters?.tags && filters.tags.length > 0) {
|
|
1641
1681
|
filterList.push(collection.filter.byProperty("tags").containsAny(filters.tags));
|
|
1642
1682
|
}
|
|
@@ -2004,6 +2044,9 @@ var ALL_MEMORY_PROPERTIES = [
|
|
|
2004
2044
|
"observation",
|
|
2005
2045
|
"strength",
|
|
2006
2046
|
"source",
|
|
2047
|
+
"rating_sum",
|
|
2048
|
+
"rating_count",
|
|
2049
|
+
"rating_bayesian",
|
|
2007
2050
|
"access_count",
|
|
2008
2051
|
"last_accessed_at",
|
|
2009
2052
|
"tags",
|
|
@@ -2053,6 +2096,11 @@ function normalizeDoc(doc) {
|
|
|
2053
2096
|
if ("trust_score" in doc) {
|
|
2054
2097
|
doc.trust_score = normalizeTrustScore(doc.trust_score);
|
|
2055
2098
|
}
|
|
2099
|
+
const ratingSum = doc.rating_sum;
|
|
2100
|
+
const ratingCount = doc.rating_count;
|
|
2101
|
+
if (ratingSum !== void 0 && ratingCount !== void 0) {
|
|
2102
|
+
doc.rating_avg = computeRatingAvg(ratingSum, ratingCount);
|
|
2103
|
+
}
|
|
2056
2104
|
return doc;
|
|
2057
2105
|
}
|
|
2058
2106
|
var MemoryService = class {
|
|
@@ -2125,12 +2173,16 @@ var MemoryService = class {
|
|
|
2125
2173
|
summary: input.title,
|
|
2126
2174
|
content_type: contentType,
|
|
2127
2175
|
weight: input.weight ?? 0.5,
|
|
2128
|
-
trust_score: input.trust ?? TrustLevel.INTERNAL,
|
|
2176
|
+
trust_score: normalizeTrustScore(input.trust ?? TrustLevel.INTERNAL),
|
|
2129
2177
|
confidence: 1,
|
|
2130
2178
|
context_summary: input.context_summary || "Memory created",
|
|
2131
2179
|
context_conversation_id: input.context_conversation_id,
|
|
2132
2180
|
relationship_ids: [],
|
|
2133
2181
|
relationship_count: 0,
|
|
2182
|
+
rating_sum: 0,
|
|
2183
|
+
rating_count: 0,
|
|
2184
|
+
rating_bayesian: 3,
|
|
2185
|
+
// (0 + 15) / (0 + 5) = 3.0 (prior mean)
|
|
2134
2186
|
access_count: 0,
|
|
2135
2187
|
last_accessed_at: now,
|
|
2136
2188
|
created_at: now,
|
|
@@ -2294,6 +2346,47 @@ var MemoryService = class {
|
|
|
2294
2346
|
limit
|
|
2295
2347
|
};
|
|
2296
2348
|
}
|
|
2349
|
+
// ── By Rating (Bayesian average) ─────────────────────────────────
|
|
2350
|
+
async byRating(input) {
|
|
2351
|
+
const limit = input.limit ?? 50;
|
|
2352
|
+
const offset = input.offset ?? 0;
|
|
2353
|
+
const direction = input.direction ?? "desc";
|
|
2354
|
+
const memoryFilters = buildMemoryOnlyFilters(this.collection, input.filters);
|
|
2355
|
+
const ghostFilters = [];
|
|
2356
|
+
if (input.ghost_context) {
|
|
2357
|
+
ghostFilters.push(buildTrustFilter(this.collection, input.ghost_context.accessor_trust_level));
|
|
2358
|
+
}
|
|
2359
|
+
if (!input.ghost_context?.include_ghost_content) {
|
|
2360
|
+
ghostFilters.push(this.collection.filter.byProperty("content_type").notEqual("ghost"));
|
|
2361
|
+
}
|
|
2362
|
+
const executeQuery = async (useDeletedFilter) => {
|
|
2363
|
+
const deletedFilter = useDeletedFilter ? buildDeletedFilter(this.collection, input.deleted_filter || "exclude") : null;
|
|
2364
|
+
const combinedFilters = combineFiltersWithAnd([deletedFilter, memoryFilters, ...ghostFilters].filter((f) => f !== null));
|
|
2365
|
+
const queryOptions = {
|
|
2366
|
+
limit: limit + offset,
|
|
2367
|
+
sort: this.collection.sort.byProperty("rating_bayesian", direction === "asc")
|
|
2368
|
+
};
|
|
2369
|
+
if (combinedFilters) {
|
|
2370
|
+
queryOptions.filters = combinedFilters;
|
|
2371
|
+
}
|
|
2372
|
+
return this.collection.query.fetchObjects(queryOptions);
|
|
2373
|
+
};
|
|
2374
|
+
const results = await this.retryWithoutDeletedFilter(executeQuery);
|
|
2375
|
+
const paginated = results.objects.slice(offset);
|
|
2376
|
+
const memories = [];
|
|
2377
|
+
for (const obj of paginated) {
|
|
2378
|
+
const doc = normalizeDoc({ id: obj.uuid, ...obj.properties });
|
|
2379
|
+
if (doc.doc_type === "memory") {
|
|
2380
|
+
memories.push(doc);
|
|
2381
|
+
}
|
|
2382
|
+
}
|
|
2383
|
+
return {
|
|
2384
|
+
memories,
|
|
2385
|
+
total: memories.length,
|
|
2386
|
+
offset,
|
|
2387
|
+
limit
|
|
2388
|
+
};
|
|
2389
|
+
}
|
|
2297
2390
|
// ── Find Similar (vector) ──────────────────────────────────────────
|
|
2298
2391
|
async findSimilar(input) {
|
|
2299
2392
|
if (!input.memory_id && !input.text)
|
|
@@ -2869,6 +2962,10 @@ var COMMON_MEMORY_PROPERTIES = [
|
|
|
2869
2962
|
{ name: "relationships", dataType: configure.dataType.TEXT_ARRAY },
|
|
2870
2963
|
{ name: "memory_ids", dataType: configure.dataType.TEXT_ARRAY },
|
|
2871
2964
|
{ name: "relationship_count", dataType: configure.dataType.INT },
|
|
2965
|
+
// Rating aggregates (denormalized from Firestore individual ratings)
|
|
2966
|
+
{ name: "rating_sum", dataType: configure.dataType.INT },
|
|
2967
|
+
{ name: "rating_count", dataType: configure.dataType.INT },
|
|
2968
|
+
{ name: "rating_bayesian", dataType: configure.dataType.NUMBER },
|
|
2872
2969
|
// Access tracking
|
|
2873
2970
|
{ name: "access_count", dataType: configure.dataType.NUMBER },
|
|
2874
2971
|
{ name: "last_accessed_at", dataType: configure.dataType.DATE },
|
|
@@ -3045,12 +3142,26 @@ var SpaceService = class {
|
|
|
3045
3142
|
userId;
|
|
3046
3143
|
confirmationTokenService;
|
|
3047
3144
|
logger;
|
|
3048
|
-
|
|
3145
|
+
moderationClient;
|
|
3146
|
+
constructor(weaviateClient, userCollection, userId, confirmationTokenService, logger2, options) {
|
|
3049
3147
|
this.weaviateClient = weaviateClient;
|
|
3050
3148
|
this.userCollection = userCollection;
|
|
3051
3149
|
this.userId = userId;
|
|
3052
3150
|
this.confirmationTokenService = confirmationTokenService;
|
|
3053
3151
|
this.logger = logger2;
|
|
3152
|
+
this.moderationClient = options?.moderationClient;
|
|
3153
|
+
}
|
|
3154
|
+
// ── Content moderation helper ────────────────────────────────────────
|
|
3155
|
+
async checkModeration(content) {
|
|
3156
|
+
if (!this.moderationClient)
|
|
3157
|
+
return;
|
|
3158
|
+
const result = await this.moderationClient.moderate(content);
|
|
3159
|
+
if (!result.pass) {
|
|
3160
|
+
throw new ValidationError(result.reason, {
|
|
3161
|
+
moderation: ["blocked"],
|
|
3162
|
+
...result.category ? { category: [result.category] } : {}
|
|
3163
|
+
});
|
|
3164
|
+
}
|
|
3054
3165
|
}
|
|
3055
3166
|
// ── Publish (phase 1: generate confirmation token) ──────────────────
|
|
3056
3167
|
async publish(input) {
|
|
@@ -3085,6 +3196,7 @@ var SpaceService = class {
|
|
|
3085
3196
|
throw new Error(`Space '${spaceId}' only accepts content_type '${requiredType}', got '${memoryContentType ?? "undefined"}'`);
|
|
3086
3197
|
}
|
|
3087
3198
|
}
|
|
3199
|
+
await this.checkModeration(memory.properties.content);
|
|
3088
3200
|
const { token } = await this.confirmationTokenService.createRequest(this.userId, "publish_memory", {
|
|
3089
3201
|
memory_id: input.memory_id,
|
|
3090
3202
|
spaces,
|
|
@@ -3151,6 +3263,7 @@ var SpaceService = class {
|
|
|
3151
3263
|
if (spaceIds.length === 0 && groupIds.length === 0) {
|
|
3152
3264
|
throw new Error("Memory has no published copies to revise. Publish first with publish().");
|
|
3153
3265
|
}
|
|
3266
|
+
await this.checkModeration(memory.properties.content);
|
|
3154
3267
|
const { token } = await this.confirmationTokenService.createRequest(this.userId, "revise_memory", {
|
|
3155
3268
|
memory_id: input.memory_id,
|
|
3156
3269
|
space_ids: spaceIds,
|
package/dist/server.js
CHANGED
|
@@ -890,7 +890,7 @@ var DEFAULT_PREFERENCES = {
|
|
|
890
890
|
share_with_memories: true
|
|
891
891
|
},
|
|
892
892
|
privacy: {
|
|
893
|
-
default_trust_level:
|
|
893
|
+
default_trust_level: 2,
|
|
894
894
|
allow_cross_user_access: false,
|
|
895
895
|
auto_approve_requests: false,
|
|
896
896
|
audit_logging: true
|
|
@@ -909,6 +909,14 @@ var DEFAULT_PREFERENCES = {
|
|
|
909
909
|
}
|
|
910
910
|
};
|
|
911
911
|
|
|
912
|
+
// node_modules/@prmichaelsen/remember-core/dist/types/rating.types.js
|
|
913
|
+
var RATING_MIN_THRESHOLD = 5;
|
|
914
|
+
function computeRatingAvg(ratingSum, ratingCount) {
|
|
915
|
+
if (ratingCount < RATING_MIN_THRESHOLD)
|
|
916
|
+
return null;
|
|
917
|
+
return ratingSum / ratingCount;
|
|
918
|
+
}
|
|
919
|
+
|
|
912
920
|
// node_modules/@prmichaelsen/remember-core/dist/types/space.types.js
|
|
913
921
|
var SUPPORTED_SPACES = [
|
|
914
922
|
"the_void",
|
|
@@ -1365,6 +1373,35 @@ var DebugLevel2;
|
|
|
1365
1373
|
DebugLevel3[DebugLevel3["TRACE"] = 5] = "TRACE";
|
|
1366
1374
|
})(DebugLevel2 || (DebugLevel2 = {}));
|
|
1367
1375
|
|
|
1376
|
+
// node_modules/@prmichaelsen/remember-core/dist/errors/base.error.js
|
|
1377
|
+
var AppError = class extends Error {
|
|
1378
|
+
context;
|
|
1379
|
+
constructor(message, context = {}) {
|
|
1380
|
+
super(message);
|
|
1381
|
+
this.context = context;
|
|
1382
|
+
this.name = this.constructor.name;
|
|
1383
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
1384
|
+
}
|
|
1385
|
+
toJSON() {
|
|
1386
|
+
return {
|
|
1387
|
+
kind: this.kind,
|
|
1388
|
+
name: this.name,
|
|
1389
|
+
message: this.message,
|
|
1390
|
+
context: this.context
|
|
1391
|
+
};
|
|
1392
|
+
}
|
|
1393
|
+
};
|
|
1394
|
+
|
|
1395
|
+
// node_modules/@prmichaelsen/remember-core/dist/errors/app-errors.js
|
|
1396
|
+
var ValidationError = class extends AppError {
|
|
1397
|
+
fields;
|
|
1398
|
+
kind = "validation";
|
|
1399
|
+
constructor(message, fields = {}) {
|
|
1400
|
+
super(message, { fields });
|
|
1401
|
+
this.fields = fields;
|
|
1402
|
+
}
|
|
1403
|
+
};
|
|
1404
|
+
|
|
1368
1405
|
// node_modules/@prmichaelsen/remember-core/node_modules/uuid/dist/esm/regex.js
|
|
1369
1406
|
var regex_default = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/i;
|
|
1370
1407
|
|
|
@@ -1641,6 +1678,9 @@ function buildDocTypeFilters(collection, docType, filters) {
|
|
|
1641
1678
|
if (filters?.relationship_count_max !== void 0) {
|
|
1642
1679
|
filterList.push(collection.filter.byProperty("relationship_count").lessOrEqual(filters.relationship_count_max));
|
|
1643
1680
|
}
|
|
1681
|
+
if (filters?.rating_min !== void 0) {
|
|
1682
|
+
filterList.push(collection.filter.byProperty("rating_bayesian").greaterOrEqual(filters.rating_min));
|
|
1683
|
+
}
|
|
1644
1684
|
if (filters?.tags && filters.tags.length > 0) {
|
|
1645
1685
|
filterList.push(collection.filter.byProperty("tags").containsAny(filters.tags));
|
|
1646
1686
|
}
|
|
@@ -2008,6 +2048,9 @@ var ALL_MEMORY_PROPERTIES = [
|
|
|
2008
2048
|
"observation",
|
|
2009
2049
|
"strength",
|
|
2010
2050
|
"source",
|
|
2051
|
+
"rating_sum",
|
|
2052
|
+
"rating_count",
|
|
2053
|
+
"rating_bayesian",
|
|
2011
2054
|
"access_count",
|
|
2012
2055
|
"last_accessed_at",
|
|
2013
2056
|
"tags",
|
|
@@ -2057,6 +2100,11 @@ function normalizeDoc(doc) {
|
|
|
2057
2100
|
if ("trust_score" in doc) {
|
|
2058
2101
|
doc.trust_score = normalizeTrustScore(doc.trust_score);
|
|
2059
2102
|
}
|
|
2103
|
+
const ratingSum = doc.rating_sum;
|
|
2104
|
+
const ratingCount = doc.rating_count;
|
|
2105
|
+
if (ratingSum !== void 0 && ratingCount !== void 0) {
|
|
2106
|
+
doc.rating_avg = computeRatingAvg(ratingSum, ratingCount);
|
|
2107
|
+
}
|
|
2060
2108
|
return doc;
|
|
2061
2109
|
}
|
|
2062
2110
|
var MemoryService = class {
|
|
@@ -2129,12 +2177,16 @@ var MemoryService = class {
|
|
|
2129
2177
|
summary: input.title,
|
|
2130
2178
|
content_type: contentType,
|
|
2131
2179
|
weight: input.weight ?? 0.5,
|
|
2132
|
-
trust_score: input.trust ?? TrustLevel.INTERNAL,
|
|
2180
|
+
trust_score: normalizeTrustScore(input.trust ?? TrustLevel.INTERNAL),
|
|
2133
2181
|
confidence: 1,
|
|
2134
2182
|
context_summary: input.context_summary || "Memory created",
|
|
2135
2183
|
context_conversation_id: input.context_conversation_id,
|
|
2136
2184
|
relationship_ids: [],
|
|
2137
2185
|
relationship_count: 0,
|
|
2186
|
+
rating_sum: 0,
|
|
2187
|
+
rating_count: 0,
|
|
2188
|
+
rating_bayesian: 3,
|
|
2189
|
+
// (0 + 15) / (0 + 5) = 3.0 (prior mean)
|
|
2138
2190
|
access_count: 0,
|
|
2139
2191
|
last_accessed_at: now,
|
|
2140
2192
|
created_at: now,
|
|
@@ -2298,6 +2350,47 @@ var MemoryService = class {
|
|
|
2298
2350
|
limit
|
|
2299
2351
|
};
|
|
2300
2352
|
}
|
|
2353
|
+
// ── By Rating (Bayesian average) ─────────────────────────────────
|
|
2354
|
+
async byRating(input) {
|
|
2355
|
+
const limit = input.limit ?? 50;
|
|
2356
|
+
const offset = input.offset ?? 0;
|
|
2357
|
+
const direction = input.direction ?? "desc";
|
|
2358
|
+
const memoryFilters = buildMemoryOnlyFilters(this.collection, input.filters);
|
|
2359
|
+
const ghostFilters = [];
|
|
2360
|
+
if (input.ghost_context) {
|
|
2361
|
+
ghostFilters.push(buildTrustFilter(this.collection, input.ghost_context.accessor_trust_level));
|
|
2362
|
+
}
|
|
2363
|
+
if (!input.ghost_context?.include_ghost_content) {
|
|
2364
|
+
ghostFilters.push(this.collection.filter.byProperty("content_type").notEqual("ghost"));
|
|
2365
|
+
}
|
|
2366
|
+
const executeQuery = async (useDeletedFilter) => {
|
|
2367
|
+
const deletedFilter = useDeletedFilter ? buildDeletedFilter(this.collection, input.deleted_filter || "exclude") : null;
|
|
2368
|
+
const combinedFilters = combineFiltersWithAnd([deletedFilter, memoryFilters, ...ghostFilters].filter((f) => f !== null));
|
|
2369
|
+
const queryOptions = {
|
|
2370
|
+
limit: limit + offset,
|
|
2371
|
+
sort: this.collection.sort.byProperty("rating_bayesian", direction === "asc")
|
|
2372
|
+
};
|
|
2373
|
+
if (combinedFilters) {
|
|
2374
|
+
queryOptions.filters = combinedFilters;
|
|
2375
|
+
}
|
|
2376
|
+
return this.collection.query.fetchObjects(queryOptions);
|
|
2377
|
+
};
|
|
2378
|
+
const results = await this.retryWithoutDeletedFilter(executeQuery);
|
|
2379
|
+
const paginated = results.objects.slice(offset);
|
|
2380
|
+
const memories = [];
|
|
2381
|
+
for (const obj of paginated) {
|
|
2382
|
+
const doc = normalizeDoc({ id: obj.uuid, ...obj.properties });
|
|
2383
|
+
if (doc.doc_type === "memory") {
|
|
2384
|
+
memories.push(doc);
|
|
2385
|
+
}
|
|
2386
|
+
}
|
|
2387
|
+
return {
|
|
2388
|
+
memories,
|
|
2389
|
+
total: memories.length,
|
|
2390
|
+
offset,
|
|
2391
|
+
limit
|
|
2392
|
+
};
|
|
2393
|
+
}
|
|
2301
2394
|
// ── Find Similar (vector) ──────────────────────────────────────────
|
|
2302
2395
|
async findSimilar(input) {
|
|
2303
2396
|
if (!input.memory_id && !input.text)
|
|
@@ -2873,6 +2966,10 @@ var COMMON_MEMORY_PROPERTIES = [
|
|
|
2873
2966
|
{ name: "relationships", dataType: configure.dataType.TEXT_ARRAY },
|
|
2874
2967
|
{ name: "memory_ids", dataType: configure.dataType.TEXT_ARRAY },
|
|
2875
2968
|
{ name: "relationship_count", dataType: configure.dataType.INT },
|
|
2969
|
+
// Rating aggregates (denormalized from Firestore individual ratings)
|
|
2970
|
+
{ name: "rating_sum", dataType: configure.dataType.INT },
|
|
2971
|
+
{ name: "rating_count", dataType: configure.dataType.INT },
|
|
2972
|
+
{ name: "rating_bayesian", dataType: configure.dataType.NUMBER },
|
|
2876
2973
|
// Access tracking
|
|
2877
2974
|
{ name: "access_count", dataType: configure.dataType.NUMBER },
|
|
2878
2975
|
{ name: "last_accessed_at", dataType: configure.dataType.DATE },
|
|
@@ -3049,12 +3146,26 @@ var SpaceService = class {
|
|
|
3049
3146
|
userId;
|
|
3050
3147
|
confirmationTokenService;
|
|
3051
3148
|
logger;
|
|
3052
|
-
|
|
3149
|
+
moderationClient;
|
|
3150
|
+
constructor(weaviateClient, userCollection, userId, confirmationTokenService, logger2, options) {
|
|
3053
3151
|
this.weaviateClient = weaviateClient;
|
|
3054
3152
|
this.userCollection = userCollection;
|
|
3055
3153
|
this.userId = userId;
|
|
3056
3154
|
this.confirmationTokenService = confirmationTokenService;
|
|
3057
3155
|
this.logger = logger2;
|
|
3156
|
+
this.moderationClient = options?.moderationClient;
|
|
3157
|
+
}
|
|
3158
|
+
// ── Content moderation helper ────────────────────────────────────────
|
|
3159
|
+
async checkModeration(content) {
|
|
3160
|
+
if (!this.moderationClient)
|
|
3161
|
+
return;
|
|
3162
|
+
const result = await this.moderationClient.moderate(content);
|
|
3163
|
+
if (!result.pass) {
|
|
3164
|
+
throw new ValidationError(result.reason, {
|
|
3165
|
+
moderation: ["blocked"],
|
|
3166
|
+
...result.category ? { category: [result.category] } : {}
|
|
3167
|
+
});
|
|
3168
|
+
}
|
|
3058
3169
|
}
|
|
3059
3170
|
// ── Publish (phase 1: generate confirmation token) ──────────────────
|
|
3060
3171
|
async publish(input) {
|
|
@@ -3089,6 +3200,7 @@ var SpaceService = class {
|
|
|
3089
3200
|
throw new Error(`Space '${spaceId}' only accepts content_type '${requiredType}', got '${memoryContentType ?? "undefined"}'`);
|
|
3090
3201
|
}
|
|
3091
3202
|
}
|
|
3203
|
+
await this.checkModeration(memory.properties.content);
|
|
3092
3204
|
const { token } = await this.confirmationTokenService.createRequest(this.userId, "publish_memory", {
|
|
3093
3205
|
memory_id: input.memory_id,
|
|
3094
3206
|
spaces,
|
|
@@ -3155,6 +3267,7 @@ var SpaceService = class {
|
|
|
3155
3267
|
if (spaceIds.length === 0 && groupIds.length === 0) {
|
|
3156
3268
|
throw new Error("Memory has no published copies to revise. Publish first with publish().");
|
|
3157
3269
|
}
|
|
3270
|
+
await this.checkModeration(memory.properties.content);
|
|
3158
3271
|
const { token } = await this.confirmationTokenService.createRequest(this.userId, "revise_memory", {
|
|
3159
3272
|
memory_id: input.memory_id,
|
|
3160
3273
|
space_ids: spaceIds,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prmichaelsen/remember-mcp",
|
|
3
|
-
"version": "3.14.
|
|
3
|
+
"version": "3.14.20",
|
|
4
4
|
"description": "Multi-tenant memory system MCP server with vector search and relationships",
|
|
5
5
|
"main": "dist/server.js",
|
|
6
6
|
"type": "module",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"@modelcontextprotocol/sdk": "^1.0.4",
|
|
51
51
|
"@prmichaelsen/firebase-admin-sdk-v8": "^2.2.0",
|
|
52
52
|
"@prmichaelsen/mcp-auth": "^7.0.4",
|
|
53
|
-
"@prmichaelsen/remember-core": "^0.
|
|
53
|
+
"@prmichaelsen/remember-core": "^0.32.1",
|
|
54
54
|
"dotenv": "^16.4.5",
|
|
55
55
|
"uuid": "^13.0.0",
|
|
56
56
|
"weaviate-client": "^3.2.0"
|