@prmichaelsen/remember-mcp 3.15.7 → 3.16.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/.github/workflows/publish.yml +55 -0
- package/CHANGELOG.md +20 -0
- package/agent/design/local.unified-internal-memory-tools.md +325 -0
- package/agent/milestones/milestone-20-unified-internal-memory-tools.md +58 -0
- package/agent/progress.yaml +115 -1
- package/agent/tasks/milestone-20-unified-internal-memory-tools/task-212-add-internal-context-type.md +54 -0
- package/agent/tasks/milestone-20-unified-internal-memory-tools/task-213-update-server-factory-internal-context.md +117 -0
- package/agent/tasks/milestone-20-unified-internal-memory-tools/task-214-create-tag-builder-utility.md +50 -0
- package/agent/tasks/milestone-20-unified-internal-memory-tools/task-215-create-unified-internal-memory-tools.md +65 -0
- package/agent/tasks/milestone-20-unified-internal-memory-tools/task-216-update-default-search-filters.md +46 -0
- package/agent/tasks/milestone-20-unified-internal-memory-tools/task-217-delete-standalone-ghost-tools.md +46 -0
- package/agent/tasks/milestone-20-unified-internal-memory-tools/task-218-add-tests-unified-internal-tools.md +66 -0
- package/dist/e2e-helpers.d.ts +1 -1
- package/dist/server-factory.d.ts +17 -41
- package/dist/server-factory.js +420 -149
- package/dist/server.js +202 -20
- package/dist/tools/{create-ghost-memory.d.ts → create-internal-memory.d.ts} +7 -9
- package/dist/tools/internal-tools.spec.d.ts +2 -0
- package/dist/tools/{query-ghost-memory.d.ts → query-internal-memory.d.ts} +6 -6
- package/dist/tools/{search-ghost-memory-by.d.ts → search-internal-memory-by.d.ts} +6 -6
- package/dist/tools/{search-ghost-memory.d.ts → search-internal-memory.d.ts} +6 -6
- package/dist/tools/{update-ghost-memory.d.ts → update-internal-memory.d.ts} +6 -6
- package/dist/types/auth.d.ts +22 -8
- package/dist/utils/internal-tags.d.ts +14 -0
- package/dist/utils/internal-tags.spec.d.ts +2 -0
- package/package.json +2 -3
- package/src/e2e-helpers.ts +4 -2
- package/src/ghost-persona.e2e.ts +18 -17
- package/src/server-factory.ts +117 -55
- package/src/tools/create-internal-memory.ts +105 -0
- package/src/tools/find-similar.ts +2 -2
- package/src/tools/internal-tools.spec.ts +312 -0
- package/src/tools/query-internal-memory.ts +73 -0
- package/src/tools/query-memory.ts +15 -12
- package/src/tools/search-by.spec.ts +6 -2
- package/src/tools/search-by.ts +6 -6
- package/src/tools/{search-ghost-memory-by.ts → search-internal-memory-by.ts} +34 -27
- package/src/tools/search-internal-memory.ts +87 -0
- package/src/tools/search-memory.ts +15 -12
- package/src/tools/search-space.ts +1 -0
- package/src/tools/{update-ghost-memory.ts → update-internal-memory.ts} +23 -17
- package/src/types/auth.ts +22 -8
- package/src/utils/internal-tags.spec.ts +104 -0
- package/src/utils/internal-tags.ts +46 -0
- package/dist/tools/ghost-tools.spec.d.ts +0 -2
- package/src/tools/create-ghost-memory.ts +0 -103
- package/src/tools/ghost-tools.spec.ts +0 -361
- package/src/tools/query-ghost-memory.ts +0 -63
- package/src/tools/search-ghost-memory.ts +0 -73
package/dist/server.js
CHANGED
|
@@ -1935,7 +1935,13 @@ var COMMON_MEMORY_PROPERTIES = [
|
|
|
1935
1935
|
{ name: "total_significance", dataType: configure.dataType.NUMBER },
|
|
1936
1936
|
// REM metadata
|
|
1937
1937
|
{ name: "rem_touched_at", dataType: configure.dataType.TEXT },
|
|
1938
|
-
{ name: "rem_visits", dataType: configure.dataType.INT }
|
|
1938
|
+
{ name: "rem_visits", dataType: configure.dataType.INT },
|
|
1939
|
+
// Curation scoring (M36)
|
|
1940
|
+
{ name: "curated_score", dataType: configure.dataType.NUMBER },
|
|
1941
|
+
{ name: "editorial_score", dataType: configure.dataType.NUMBER },
|
|
1942
|
+
{ name: "click_count", dataType: configure.dataType.INT },
|
|
1943
|
+
{ name: "share_count", dataType: configure.dataType.INT },
|
|
1944
|
+
{ name: "comment_count", dataType: configure.dataType.INT }
|
|
1939
1945
|
];
|
|
1940
1946
|
var PUBLISHED_MEMORY_PROPERTIES = [
|
|
1941
1947
|
// Publication metadata
|
|
@@ -2586,7 +2592,13 @@ var ALL_MEMORY_PROPERTIES = [
|
|
|
2586
2592
|
"functional_significance",
|
|
2587
2593
|
"total_significance",
|
|
2588
2594
|
"rem_touched_at",
|
|
2589
|
-
"rem_visits"
|
|
2595
|
+
"rem_visits",
|
|
2596
|
+
// Curation scoring (M36)
|
|
2597
|
+
"curated_score",
|
|
2598
|
+
"editorial_score",
|
|
2599
|
+
"click_count",
|
|
2600
|
+
"share_count",
|
|
2601
|
+
"comment_count"
|
|
2590
2602
|
];
|
|
2591
2603
|
async function fetchMemoryWithAllProperties(collection, memoryId) {
|
|
2592
2604
|
try {
|
|
@@ -3362,6 +3374,99 @@ var MemoryService = class {
|
|
|
3362
3374
|
total_pool_size: totalPoolSize
|
|
3363
3375
|
};
|
|
3364
3376
|
}
|
|
3377
|
+
// ── By Curated (composite quality score) ──────────────────────────
|
|
3378
|
+
async byCurated(input) {
|
|
3379
|
+
const limit = input.limit ?? 50;
|
|
3380
|
+
const offset = input.offset ?? 0;
|
|
3381
|
+
const direction = input.direction ?? "desc";
|
|
3382
|
+
const memoryFilters = buildMemoryOnlyFilters(this.collection, input.filters);
|
|
3383
|
+
const ghostFilters = [];
|
|
3384
|
+
if (input.ghost_context) {
|
|
3385
|
+
ghostFilters.push(buildTrustFilter(this.collection, input.ghost_context.accessor_trust_level));
|
|
3386
|
+
}
|
|
3387
|
+
if (!input.ghost_context?.include_ghost_content && !input.filters?.types?.includes("ghost")) {
|
|
3388
|
+
ghostFilters.push(this.collection.filter.byProperty("content_type").notEqual("ghost"));
|
|
3389
|
+
}
|
|
3390
|
+
if (!input.filters?.types?.includes("rem")) {
|
|
3391
|
+
ghostFilters.push(this.collection.filter.byProperty("content_type").notEqual("rem"));
|
|
3392
|
+
}
|
|
3393
|
+
const hasQuery = input.query?.trim();
|
|
3394
|
+
const fetchLimit = (limit + offset) * 2;
|
|
3395
|
+
const executeScoredQuery = async (useDeletedFilter) => {
|
|
3396
|
+
const deletedFilter = useDeletedFilter ? buildDeletedFilter(this.collection, input.deleted_filter || "exclude") : null;
|
|
3397
|
+
const scoredFilter = this.collection.filter.byProperty("curated_score").greaterThan(0);
|
|
3398
|
+
const combined = combineFiltersWithAnd([deletedFilter, memoryFilters, scoredFilter, ...ghostFilters].filter((f) => f !== null));
|
|
3399
|
+
if (hasQuery) {
|
|
3400
|
+
const queryOptions2 = {
|
|
3401
|
+
limit: fetchLimit,
|
|
3402
|
+
alpha: 0.7,
|
|
3403
|
+
query: hasQuery
|
|
3404
|
+
};
|
|
3405
|
+
if (combined)
|
|
3406
|
+
queryOptions2.filters = combined;
|
|
3407
|
+
return this.collection.query.hybrid(hasQuery, queryOptions2);
|
|
3408
|
+
}
|
|
3409
|
+
const queryOptions = {
|
|
3410
|
+
limit: fetchLimit,
|
|
3411
|
+
sort: this.collection.sort.byProperty("curated_score", direction === "asc")
|
|
3412
|
+
};
|
|
3413
|
+
if (combined)
|
|
3414
|
+
queryOptions.filters = combined;
|
|
3415
|
+
return this.collection.query.fetchObjects(queryOptions);
|
|
3416
|
+
};
|
|
3417
|
+
const executeUnscoredQuery = async (useDeletedFilter) => {
|
|
3418
|
+
const deletedFilter = useDeletedFilter ? buildDeletedFilter(this.collection, input.deleted_filter || "exclude") : null;
|
|
3419
|
+
const unscoredFilters = [];
|
|
3420
|
+
const combined = combineFiltersWithAnd([deletedFilter, memoryFilters, ...ghostFilters].filter((f) => f !== null));
|
|
3421
|
+
const queryOptions = {
|
|
3422
|
+
limit: Math.ceil(fetchLimit / 4),
|
|
3423
|
+
sort: this.collection.sort.byProperty("created_at", false)
|
|
3424
|
+
// newest first
|
|
3425
|
+
};
|
|
3426
|
+
if (combined)
|
|
3427
|
+
queryOptions.filters = combined;
|
|
3428
|
+
return this.collection.query.fetchObjects(queryOptions);
|
|
3429
|
+
};
|
|
3430
|
+
const scoredResults = await this.retryWithoutDeletedFilter(executeScoredQuery);
|
|
3431
|
+
const unscoredResults = await this.retryWithoutDeletedFilter(executeUnscoredQuery);
|
|
3432
|
+
const scored = [];
|
|
3433
|
+
for (const obj of scoredResults.objects) {
|
|
3434
|
+
const doc = normalizeDoc({ id: obj.uuid, ...obj.properties });
|
|
3435
|
+
if (doc.doc_type === "memory" && doc.curated_score > 0) {
|
|
3436
|
+
scored.push(doc);
|
|
3437
|
+
}
|
|
3438
|
+
}
|
|
3439
|
+
if (hasQuery) {
|
|
3440
|
+
scored.sort((a, b) => {
|
|
3441
|
+
const aScore = a.curated_score ?? 0;
|
|
3442
|
+
const bScore = b.curated_score ?? 0;
|
|
3443
|
+
return direction === "asc" ? aScore - bScore : bScore - aScore;
|
|
3444
|
+
});
|
|
3445
|
+
}
|
|
3446
|
+
const unscored = [];
|
|
3447
|
+
for (const obj of unscoredResults.objects) {
|
|
3448
|
+
const doc = normalizeDoc({ id: obj.uuid, ...obj.properties });
|
|
3449
|
+
if (doc.doc_type === "memory" && !doc.curated_score) {
|
|
3450
|
+
unscored.push(doc);
|
|
3451
|
+
}
|
|
3452
|
+
}
|
|
3453
|
+
const interleaved = interleaveDiscovery({
|
|
3454
|
+
rated: scored,
|
|
3455
|
+
discovery: unscored,
|
|
3456
|
+
offset,
|
|
3457
|
+
limit
|
|
3458
|
+
});
|
|
3459
|
+
const memories = interleaved.map((item) => ({
|
|
3460
|
+
...item.item,
|
|
3461
|
+
...item.is_discovery ? { is_discovery: true } : {}
|
|
3462
|
+
}));
|
|
3463
|
+
return {
|
|
3464
|
+
memories,
|
|
3465
|
+
total: memories.length,
|
|
3466
|
+
offset,
|
|
3467
|
+
limit
|
|
3468
|
+
};
|
|
3469
|
+
}
|
|
3365
3470
|
// ── Find Similar (vector) ──────────────────────────────────────────
|
|
3366
3471
|
async findSimilar(input) {
|
|
3367
3472
|
if (!input.memory_id && !input.text)
|
|
@@ -3378,6 +3483,7 @@ var MemoryService = class {
|
|
|
3378
3483
|
ghostFilters.push(this.collection.filter.byProperty("content_type").notEqual("ghost"));
|
|
3379
3484
|
}
|
|
3380
3485
|
ghostFilters.push(this.collection.filter.byProperty("content_type").notEqual("rem"));
|
|
3486
|
+
ghostFilters.push(this.collection.filter.byProperty("content_type").notEqual("comment"));
|
|
3381
3487
|
let memoryObj = null;
|
|
3382
3488
|
if (input.memory_id) {
|
|
3383
3489
|
memoryObj = await this.collection.query.fetchObjectById(input.memory_id, {
|
|
@@ -3569,6 +3675,28 @@ var MemoryService = class {
|
|
|
3569
3675
|
orphaned_relationship_ids: orphanedIds
|
|
3570
3676
|
};
|
|
3571
3677
|
}
|
|
3678
|
+
// ── Engagement Counters ───────────────────────────────────────────
|
|
3679
|
+
async incrementClick(memoryId) {
|
|
3680
|
+
await this.incrementCounter(memoryId, "click_count");
|
|
3681
|
+
}
|
|
3682
|
+
async incrementShare(memoryId) {
|
|
3683
|
+
await this.incrementCounter(memoryId, "share_count");
|
|
3684
|
+
}
|
|
3685
|
+
async incrementComment(memoryId) {
|
|
3686
|
+
await this.incrementCounter(memoryId, "comment_count");
|
|
3687
|
+
}
|
|
3688
|
+
async incrementCounter(memoryId, field) {
|
|
3689
|
+
const existing = await this.collection.query.fetchObjectById(memoryId, {
|
|
3690
|
+
returnProperties: [field]
|
|
3691
|
+
});
|
|
3692
|
+
if (!existing)
|
|
3693
|
+
throw new Error(`Memory not found: ${memoryId}`);
|
|
3694
|
+
const current = existing.properties?.[field] ?? 0;
|
|
3695
|
+
await this.collection.data.update({
|
|
3696
|
+
id: memoryId,
|
|
3697
|
+
properties: { [field]: current + 1 }
|
|
3698
|
+
});
|
|
3699
|
+
}
|
|
3572
3700
|
};
|
|
3573
3701
|
|
|
3574
3702
|
// node_modules/@prmichaelsen/remember-core/dist/services/relationship.service.js
|
|
@@ -5010,6 +5138,42 @@ var SpaceService = class {
|
|
|
5010
5138
|
});
|
|
5011
5139
|
return { spaces_searched: spacesSearched, groups_searched: groupsSearched, results, total_pool_size: totalPoolSize };
|
|
5012
5140
|
}
|
|
5141
|
+
// ── By Curated (composite quality score) ──────────────────────────
|
|
5142
|
+
async byCurated(input, authContext) {
|
|
5143
|
+
const spaces = input.spaces || [];
|
|
5144
|
+
const groups = input.groups || [];
|
|
5145
|
+
const limit = input.limit ?? 50;
|
|
5146
|
+
const offset = input.offset ?? 0;
|
|
5147
|
+
const direction = input.direction ?? "desc";
|
|
5148
|
+
this.validateSpaceGroupInput(spaces, groups, input.moderation_filter || "approved", authContext);
|
|
5149
|
+
const fetchLimit = (limit + offset) * 2;
|
|
5150
|
+
const hasQuery = input.query?.trim();
|
|
5151
|
+
const { allResults, spacesSearched, groupsSearched } = await this.fetchAcrossCollections(input, spaces, groups, async (collection, baseFilters) => {
|
|
5152
|
+
const combined = baseFilters.length > 0 ? Filters4.and(...baseFilters) : void 0;
|
|
5153
|
+
if (hasQuery) {
|
|
5154
|
+
const opts2 = { limit: fetchLimit, alpha: 0.7, query: hasQuery };
|
|
5155
|
+
if (combined)
|
|
5156
|
+
opts2.filters = combined;
|
|
5157
|
+
return (await collection.query.hybrid(hasQuery, opts2)).objects;
|
|
5158
|
+
}
|
|
5159
|
+
const opts = {
|
|
5160
|
+
limit: fetchLimit,
|
|
5161
|
+
sort: collection.sort.byProperty("curated_score", direction === "asc")
|
|
5162
|
+
};
|
|
5163
|
+
if (combined)
|
|
5164
|
+
opts.filters = combined;
|
|
5165
|
+
return (await collection.query.fetchObjects(opts)).objects;
|
|
5166
|
+
});
|
|
5167
|
+
const deduped = dedupeBySourceId(allResults, input.dedupe);
|
|
5168
|
+
deduped.sort((a, b) => {
|
|
5169
|
+
const aVal = a.properties?.curated_score ?? 0;
|
|
5170
|
+
const bVal = b.properties?.curated_score ?? 0;
|
|
5171
|
+
return direction === "desc" ? bVal - aVal : aVal - bVal;
|
|
5172
|
+
});
|
|
5173
|
+
const paginated = deduped.slice(offset, offset + limit);
|
|
5174
|
+
const memories = paginated.filter((obj) => obj.properties?.doc_type === "memory").map((obj) => ({ id: obj.uuid, ...obj.properties }));
|
|
5175
|
+
return { spaces_searched: spacesSearched, groups_searched: groupsSearched, memories, total: memories.length, offset, limit };
|
|
5176
|
+
}
|
|
5013
5177
|
// ── Private: Validate Space/Group Input ───────────────────────────
|
|
5014
5178
|
validateSpaceGroupInput(spaces, groups, moderationFilter, authContext) {
|
|
5015
5179
|
if (spaces.length > 0) {
|
|
@@ -5154,6 +5318,18 @@ var REM_STATE_COLLECTION = `${BASE}.rem_state`;
|
|
|
5154
5318
|
// node_modules/@prmichaelsen/remember-core/dist/services/rem.clustering.js
|
|
5155
5319
|
import { Filters as Filters5 } from "weaviate-client";
|
|
5156
5320
|
|
|
5321
|
+
// node_modules/@prmichaelsen/remember-core/dist/services/rem.service.js
|
|
5322
|
+
import { Filters as Filters9 } from "weaviate-client";
|
|
5323
|
+
|
|
5324
|
+
// node_modules/@prmichaelsen/remember-core/dist/services/scoring-context.service.js
|
|
5325
|
+
import { Filters as Filters6 } from "weaviate-client";
|
|
5326
|
+
|
|
5327
|
+
// node_modules/@prmichaelsen/remember-core/dist/services/rem.pruning.js
|
|
5328
|
+
import { Filters as Filters7 } from "weaviate-client";
|
|
5329
|
+
|
|
5330
|
+
// node_modules/@prmichaelsen/remember-core/dist/services/rem.reconciliation.js
|
|
5331
|
+
import { Filters as Filters8 } from "weaviate-client";
|
|
5332
|
+
|
|
5157
5333
|
// node_modules/@prmichaelsen/remember-core/dist/services/classification.service.js
|
|
5158
5334
|
var GENRES = [
|
|
5159
5335
|
"short_story",
|
|
@@ -5789,12 +5965,12 @@ var searchMemoryTool = {
|
|
|
5789
5965
|
}
|
|
5790
5966
|
};
|
|
5791
5967
|
async function handleSearchMemory(args, userId, authContext) {
|
|
5792
|
-
const
|
|
5793
|
-
const searchUserId =
|
|
5794
|
-
const debug = createDebugLogger({ tool: "remember_search_memory", userId: searchUserId, operation:
|
|
5968
|
+
const internalContext = authContext?.internalContext;
|
|
5969
|
+
const searchUserId = internalContext?.owner_user_id ?? userId;
|
|
5970
|
+
const debug = createDebugLogger({ tool: "remember_search_memory", userId: searchUserId, operation: internalContext ? "internal search" : "search memory" });
|
|
5795
5971
|
try {
|
|
5796
5972
|
debug.info("Tool invoked");
|
|
5797
|
-
debug.trace("Arguments", { args,
|
|
5973
|
+
debug.trace("Arguments", { args, internalContext: !!internalContext });
|
|
5798
5974
|
if (!args.query || args.query.trim() === "") {
|
|
5799
5975
|
throw new Error("Query cannot be empty");
|
|
5800
5976
|
}
|
|
@@ -5803,18 +5979,21 @@ async function handleSearchMemory(args, userId, authContext) {
|
|
|
5803
5979
|
userId: searchUserId,
|
|
5804
5980
|
query: args.query,
|
|
5805
5981
|
includeRelationships,
|
|
5806
|
-
|
|
5982
|
+
internalContext: !!internalContext
|
|
5807
5983
|
});
|
|
5808
5984
|
const collection = getMemoryCollection2(searchUserId);
|
|
5809
5985
|
const alpha = args.alpha ?? 0.7;
|
|
5810
5986
|
const limit = args.limit ?? 10;
|
|
5811
5987
|
const offset = args.offset ?? 0;
|
|
5812
5988
|
const deletedFilter = buildDeletedFilter(collection, args.deleted_filter || "exclude");
|
|
5813
|
-
const trustFilter =
|
|
5989
|
+
const trustFilter = internalContext?.accessor_trust_level != null ? buildTrustFilter(collection, internalContext.accessor_trust_level) : null;
|
|
5814
5990
|
const searchFilters = includeRelationships ? buildCombinedSearchFilters(collection, args.filters) : buildMemoryOnlyFilters(collection, args.filters);
|
|
5815
5991
|
const hasExplicitTypeFilter = args.filters?.types && args.filters.types.length > 0;
|
|
5816
|
-
const
|
|
5817
|
-
|
|
5992
|
+
const internalExclusionFilter = !hasExplicitTypeFilter ? combineFiltersWithAnd([
|
|
5993
|
+
collection.filter.byProperty("content_type").notEqual("ghost"),
|
|
5994
|
+
collection.filter.byProperty("content_type").notEqual("agent")
|
|
5995
|
+
]) : null;
|
|
5996
|
+
const combinedFilters = combineFiltersWithAnd([deletedFilter, trustFilter, internalExclusionFilter, searchFilters].filter((f) => f !== null));
|
|
5818
5997
|
const searchOptions = {
|
|
5819
5998
|
alpha,
|
|
5820
5999
|
limit,
|
|
@@ -6160,7 +6339,7 @@ async function handleFindSimilar(args, userId, authContext) {
|
|
|
6160
6339
|
deleted_filter: args.deleted_filter
|
|
6161
6340
|
});
|
|
6162
6341
|
const filteredMemories = coreResult.similar_memories.filter(
|
|
6163
|
-
(m) => m.content_type !== "ghost"
|
|
6342
|
+
(m) => m.content_type !== "ghost" && m.content_type !== "agent"
|
|
6164
6343
|
);
|
|
6165
6344
|
const result = {
|
|
6166
6345
|
query: {
|
|
@@ -6303,27 +6482,30 @@ var queryMemoryTool = {
|
|
|
6303
6482
|
}
|
|
6304
6483
|
};
|
|
6305
6484
|
async function handleQueryMemory(args, userId, authContext) {
|
|
6306
|
-
const
|
|
6307
|
-
const searchUserId =
|
|
6308
|
-
const debug = createDebugLogger({ tool: "remember_query_memory", userId: searchUserId, operation:
|
|
6485
|
+
const internalContext = authContext?.internalContext;
|
|
6486
|
+
const searchUserId = internalContext?.owner_user_id ?? userId;
|
|
6487
|
+
const debug = createDebugLogger({ tool: "remember_query_memory", userId: searchUserId, operation: internalContext ? "internal query" : "query memory" });
|
|
6309
6488
|
try {
|
|
6310
6489
|
debug.info("Tool invoked");
|
|
6311
|
-
debug.trace("Arguments", { args,
|
|
6490
|
+
debug.trace("Arguments", { args, internalContext: !!internalContext });
|
|
6312
6491
|
if (!args.query || args.query.trim() === "") {
|
|
6313
6492
|
throw new Error("Query cannot be empty");
|
|
6314
6493
|
}
|
|
6315
|
-
logger.info("Querying memories", { userId: searchUserId, query: args.query,
|
|
6494
|
+
logger.info("Querying memories", { userId: searchUserId, query: args.query, internalContext: !!internalContext });
|
|
6316
6495
|
const collection = getMemoryCollection2(searchUserId);
|
|
6317
6496
|
const limit = args.limit ?? 5;
|
|
6318
6497
|
const minRelevance = args.min_relevance ?? 0.6;
|
|
6319
6498
|
const includeContext = args.include_context ?? true;
|
|
6320
6499
|
const format = args.format ?? "detailed";
|
|
6321
6500
|
const deletedFilter = buildDeletedFilter(collection, args.deleted_filter || "exclude");
|
|
6322
|
-
const trustFilter =
|
|
6501
|
+
const trustFilter = internalContext?.accessor_trust_level != null ? buildTrustFilter(collection, internalContext.accessor_trust_level) : null;
|
|
6323
6502
|
const searchFilters = buildCombinedSearchFilters(collection, args.filters);
|
|
6324
6503
|
const hasExplicitTypeFilter = args.filters?.types && args.filters.types.length > 0;
|
|
6325
|
-
const
|
|
6326
|
-
|
|
6504
|
+
const internalExclusionFilter = !hasExplicitTypeFilter ? combineFiltersWithAnd([
|
|
6505
|
+
collection.filter.byProperty("content_type").notEqual("ghost"),
|
|
6506
|
+
collection.filter.byProperty("content_type").notEqual("agent")
|
|
6507
|
+
]) : null;
|
|
6508
|
+
const combinedFilters = combineFiltersWithAnd([deletedFilter, trustFilter, internalExclusionFilter, searchFilters].filter((f) => f !== null));
|
|
6327
6509
|
const searchOptions = {
|
|
6328
6510
|
limit,
|
|
6329
6511
|
distance: 1 - minRelevance,
|
|
@@ -7435,7 +7617,7 @@ async function handleDeny(args, userId, authContext) {
|
|
|
7435
7617
|
}
|
|
7436
7618
|
|
|
7437
7619
|
// src/tools/search-space.ts
|
|
7438
|
-
import { Filters as
|
|
7620
|
+
import { Filters as Filters10 } from "weaviate-client";
|
|
7439
7621
|
var searchSpaceTool = {
|
|
7440
7622
|
name: "remember_search_space",
|
|
7441
7623
|
description: `Search shared spaces and/or groups to discover memories from other users.
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* Creates a ghost memory
|
|
2
|
+
* remember_create_internal_memory tool
|
|
3
|
+
* Creates a ghost or agent memory based on the current session's InternalContext.
|
|
4
|
+
* Content type and tags are derived from platform HTTP headers, not tool args.
|
|
4
5
|
*/
|
|
5
6
|
import type { AuthContext } from '../types/auth.js';
|
|
6
|
-
export declare const
|
|
7
|
+
export declare const createInternalMemoryTool: {
|
|
7
8
|
name: string;
|
|
8
9
|
description: string;
|
|
9
10
|
inputSchema: {
|
|
@@ -40,25 +41,22 @@ export declare const createGhostMemoryTool: {
|
|
|
40
41
|
type: string;
|
|
41
42
|
minimum: number;
|
|
42
43
|
maximum: number;
|
|
43
|
-
description: string;
|
|
44
44
|
};
|
|
45
45
|
feel_social_weight: {
|
|
46
46
|
type: string;
|
|
47
47
|
minimum: number;
|
|
48
48
|
maximum: number;
|
|
49
|
-
description: string;
|
|
50
49
|
};
|
|
51
50
|
feel_narrative_importance: {
|
|
52
51
|
type: string;
|
|
53
52
|
minimum: number;
|
|
54
53
|
maximum: number;
|
|
55
|
-
description: string;
|
|
56
54
|
};
|
|
57
55
|
};
|
|
58
56
|
required: string[];
|
|
59
57
|
};
|
|
60
58
|
};
|
|
61
|
-
export interface
|
|
59
|
+
export interface CreateInternalMemoryArgs {
|
|
62
60
|
content: string;
|
|
63
61
|
title?: string;
|
|
64
62
|
tags?: string[];
|
|
@@ -66,5 +64,5 @@ export interface CreateGhostMemoryArgs {
|
|
|
66
64
|
trust?: number;
|
|
67
65
|
[key: string]: any;
|
|
68
66
|
}
|
|
69
|
-
export declare function
|
|
70
|
-
//# sourceMappingURL=create-
|
|
67
|
+
export declare function handleCreateInternalMemory(args: CreateInternalMemoryArgs, userId: string, authContext?: AuthContext): Promise<string>;
|
|
68
|
+
//# sourceMappingURL=create-internal-memory.d.ts.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* Wraps query_memory with
|
|
2
|
+
* remember_query_internal_memory tool
|
|
3
|
+
* Wraps query_memory with auto-scoped content type and ghost source filters.
|
|
4
4
|
*/
|
|
5
5
|
import type { AuthContext } from '../types/auth.js';
|
|
6
|
-
export declare const
|
|
6
|
+
export declare const queryInternalMemoryTool: {
|
|
7
7
|
name: string;
|
|
8
8
|
description: string;
|
|
9
9
|
inputSchema: {
|
|
@@ -25,10 +25,10 @@ export declare const queryGhostMemoryTool: {
|
|
|
25
25
|
required: string[];
|
|
26
26
|
};
|
|
27
27
|
};
|
|
28
|
-
export interface
|
|
28
|
+
export interface QueryInternalMemoryArgs {
|
|
29
29
|
query: string;
|
|
30
30
|
limit?: number;
|
|
31
31
|
min_relevance?: number;
|
|
32
32
|
}
|
|
33
|
-
export declare function
|
|
34
|
-
//# sourceMappingURL=query-
|
|
33
|
+
export declare function handleQueryInternalMemory(args: QueryInternalMemoryArgs, userId: string, authContext?: AuthContext): Promise<string>;
|
|
34
|
+
//# sourceMappingURL=query-internal-memory.d.ts.map
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* Wraps search_by with
|
|
2
|
+
* remember_search_internal_memory_by tool
|
|
3
|
+
* Wraps search_by with auto-scoped content type and ghost source filters.
|
|
4
4
|
*/
|
|
5
5
|
import type { AuthContext } from '../types/auth.js';
|
|
6
6
|
import type { SearchByMode } from './search-by.js';
|
|
7
|
-
export declare const
|
|
7
|
+
export declare const searchInternalMemoryByTool: {
|
|
8
8
|
name: string;
|
|
9
9
|
description: string;
|
|
10
10
|
inputSchema: {
|
|
@@ -41,7 +41,7 @@ export declare const searchGhostMemoryByTool: {
|
|
|
41
41
|
required: string[];
|
|
42
42
|
};
|
|
43
43
|
};
|
|
44
|
-
export interface
|
|
44
|
+
export interface SearchInternalMemoryByArgs {
|
|
45
45
|
mode: SearchByMode;
|
|
46
46
|
query?: string;
|
|
47
47
|
sort_order?: 'asc' | 'desc';
|
|
@@ -50,5 +50,5 @@ export interface SearchGhostMemoryByArgs {
|
|
|
50
50
|
offset?: number;
|
|
51
51
|
deleted_filter?: 'exclude' | 'include' | 'only';
|
|
52
52
|
}
|
|
53
|
-
export declare function
|
|
54
|
-
//# sourceMappingURL=search-
|
|
53
|
+
export declare function handleSearchInternalMemoryBy(args: SearchInternalMemoryByArgs, userId: string, authContext?: AuthContext): Promise<string>;
|
|
54
|
+
//# sourceMappingURL=search-internal-memory-by.d.ts.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* Wraps search_memory with
|
|
2
|
+
* remember_search_internal_memory tool
|
|
3
|
+
* Wraps search_memory with auto-scoped content type and ghost source filters.
|
|
4
4
|
*/
|
|
5
5
|
import type { AuthContext } from '../types/auth.js';
|
|
6
|
-
export declare const
|
|
6
|
+
export declare const searchInternalMemoryTool: {
|
|
7
7
|
name: string;
|
|
8
8
|
description: string;
|
|
9
9
|
inputSchema: {
|
|
@@ -41,7 +41,7 @@ export declare const searchGhostMemoryTool: {
|
|
|
41
41
|
required: string[];
|
|
42
42
|
};
|
|
43
43
|
};
|
|
44
|
-
export interface
|
|
44
|
+
export interface SearchInternalMemoryArgs {
|
|
45
45
|
query: string;
|
|
46
46
|
alpha?: number;
|
|
47
47
|
tags?: string[];
|
|
@@ -49,5 +49,5 @@ export interface SearchGhostMemoryArgs {
|
|
|
49
49
|
offset?: number;
|
|
50
50
|
deleted_filter?: 'exclude' | 'include' | 'only';
|
|
51
51
|
}
|
|
52
|
-
export declare function
|
|
53
|
-
//# sourceMappingURL=search-
|
|
52
|
+
export declare function handleSearchInternalMemory(args: SearchInternalMemoryArgs, userId: string, authContext?: AuthContext): Promise<string>;
|
|
53
|
+
//# sourceMappingURL=search-internal-memory.d.ts.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* Updates a ghost memory after validating content_type
|
|
2
|
+
* remember_update_internal_memory tool
|
|
3
|
+
* Updates a ghost or agent memory after validating content_type matches session context.
|
|
4
4
|
*/
|
|
5
5
|
import type { AuthContext } from '../types/auth.js';
|
|
6
|
-
export declare const
|
|
6
|
+
export declare const updateInternalMemoryTool: {
|
|
7
7
|
name: string;
|
|
8
8
|
description: string;
|
|
9
9
|
inputSchema: {
|
|
@@ -39,7 +39,7 @@ export declare const updateGhostMemoryTool: {
|
|
|
39
39
|
required: string[];
|
|
40
40
|
};
|
|
41
41
|
};
|
|
42
|
-
export interface
|
|
42
|
+
export interface UpdateInternalMemoryArgs {
|
|
43
43
|
memory_id: string;
|
|
44
44
|
content?: string;
|
|
45
45
|
title?: string;
|
|
@@ -47,5 +47,5 @@ export interface UpdateGhostMemoryArgs {
|
|
|
47
47
|
weight?: number;
|
|
48
48
|
trust?: number;
|
|
49
49
|
}
|
|
50
|
-
export declare function
|
|
51
|
-
//# sourceMappingURL=update-
|
|
50
|
+
export declare function handleUpdateInternalMemory(args: UpdateInternalMemoryArgs, userId: string, authContext?: AuthContext): Promise<string>;
|
|
51
|
+
//# sourceMappingURL=update-internal-memory.d.ts.map
|
package/dist/types/auth.d.ts
CHANGED
|
@@ -24,20 +24,34 @@ export interface UserCredentials {
|
|
|
24
24
|
user_id: string;
|
|
25
25
|
group_memberships: GroupMembership[];
|
|
26
26
|
}
|
|
27
|
-
/**
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
27
|
+
/**
|
|
28
|
+
* Internal context for ghost/agent sessions — resolved server-side from
|
|
29
|
+
* platform HTTP headers, never from tool args.
|
|
30
|
+
*
|
|
31
|
+
* Replaces the former GhostModeContext. All ghost identity, trust, and
|
|
32
|
+
* agent context is unified here.
|
|
33
|
+
*/
|
|
34
|
+
export interface InternalContext {
|
|
35
|
+
/** Whether this is a ghost or agent session */
|
|
36
|
+
type: 'ghost' | 'agent';
|
|
37
|
+
/** Ghost sub-type (required when type is 'ghost') */
|
|
38
|
+
ghost_type?: 'user' | 'space' | 'group';
|
|
39
|
+
/** Space ID (space ghosts only) */
|
|
40
|
+
ghost_space?: string;
|
|
41
|
+
/** Group ID (group ghosts only) */
|
|
42
|
+
ghost_group?: string;
|
|
43
|
+
/** The ghost owner's user ID (user ghosts — whose memories are searched) */
|
|
44
|
+
owner_user_id?: string;
|
|
45
|
+
/** The accessor's user ID (who is conversing) */
|
|
32
46
|
accessor_user_id: string;
|
|
33
47
|
/** Resolved trust level (looked up from GhostConfig, not user-supplied) */
|
|
34
|
-
accessor_trust_level
|
|
48
|
+
accessor_trust_level?: number;
|
|
35
49
|
}
|
|
36
50
|
export interface AuthContext {
|
|
37
51
|
accessToken: string | null;
|
|
38
52
|
credentials: UserCredentials | null;
|
|
39
|
-
/** Present when the server is running in ghost
|
|
40
|
-
|
|
53
|
+
/** Present when the server is running in ghost or agent mode */
|
|
54
|
+
internalContext?: InternalContext;
|
|
41
55
|
}
|
|
42
56
|
export type WriteMode = 'owner_only' | 'group_editors' | 'anyone';
|
|
43
57
|
export interface CredentialsProvider {
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { AuthContext } from '../types/auth.js';
|
|
2
|
+
/**
|
|
3
|
+
* Build tags for internal (ghost/agent) memories based on the current
|
|
4
|
+
* session's InternalContext. These tags implement ghost source isolation
|
|
5
|
+
* so memories from different ghost conversations are distinguishable.
|
|
6
|
+
*
|
|
7
|
+
* Tag scheme:
|
|
8
|
+
* User ghost (alice): ['ghost', 'ghost_type:user', 'ghost_owner:user:alice']
|
|
9
|
+
* Space ghost (music-lovers): ['ghost', 'ghost_type:space', 'ghost_owner:space:music-lovers']
|
|
10
|
+
* Group ghost (band-mates): ['ghost', 'ghost_type:group', 'ghost_owner:group:band-mates']
|
|
11
|
+
* Agent: ['agent']
|
|
12
|
+
*/
|
|
13
|
+
export declare function buildInternalTags(authContext: AuthContext): string[];
|
|
14
|
+
//# sourceMappingURL=internal-tags.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prmichaelsen/remember-mcp",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.16.2",
|
|
4
4
|
"description": "Multi-tenant memory system MCP server with vector search and relationships",
|
|
5
5
|
"main": "dist/server.js",
|
|
6
6
|
"type": "module",
|
|
@@ -51,8 +51,7 @@
|
|
|
51
51
|
"@google-cloud/vision": "^5.3.4",
|
|
52
52
|
"@modelcontextprotocol/sdk": "^1.0.4",
|
|
53
53
|
"@prmichaelsen/firebase-admin-sdk-v8": "^2.2.0",
|
|
54
|
-
"@prmichaelsen/
|
|
55
|
-
"@prmichaelsen/remember-core": "^0.45.0",
|
|
54
|
+
"@prmichaelsen/remember-core": "^0.49.16",
|
|
56
55
|
"dotenv": "^16.4.5",
|
|
57
56
|
"uuid": "^13.0.0",
|
|
58
57
|
"weaviate-client": "^3.2.0"
|
package/src/e2e-helpers.ts
CHANGED
|
@@ -24,12 +24,14 @@ export function e2eAuthContext(): AuthContext {
|
|
|
24
24
|
return { accessToken: null, credentials: null };
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
/** AuthContext with ghost
|
|
27
|
+
/** AuthContext with ghost internal context for cross-user tests */
|
|
28
28
|
export function e2eGhostAuthContext(ownerUserId: string, accessorUserId: string, trustLevel = 0.5): AuthContext {
|
|
29
29
|
return {
|
|
30
30
|
accessToken: null,
|
|
31
31
|
credentials: null,
|
|
32
|
-
|
|
32
|
+
internalContext: {
|
|
33
|
+
type: 'ghost',
|
|
34
|
+
ghost_type: 'user',
|
|
33
35
|
owner_user_id: ownerUserId,
|
|
34
36
|
accessor_user_id: accessorUserId,
|
|
35
37
|
accessor_trust_level: trustLevel,
|