@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.
Files changed (49) hide show
  1. package/.github/workflows/publish.yml +55 -0
  2. package/CHANGELOG.md +20 -0
  3. package/agent/design/local.unified-internal-memory-tools.md +325 -0
  4. package/agent/milestones/milestone-20-unified-internal-memory-tools.md +58 -0
  5. package/agent/progress.yaml +115 -1
  6. package/agent/tasks/milestone-20-unified-internal-memory-tools/task-212-add-internal-context-type.md +54 -0
  7. package/agent/tasks/milestone-20-unified-internal-memory-tools/task-213-update-server-factory-internal-context.md +117 -0
  8. package/agent/tasks/milestone-20-unified-internal-memory-tools/task-214-create-tag-builder-utility.md +50 -0
  9. package/agent/tasks/milestone-20-unified-internal-memory-tools/task-215-create-unified-internal-memory-tools.md +65 -0
  10. package/agent/tasks/milestone-20-unified-internal-memory-tools/task-216-update-default-search-filters.md +46 -0
  11. package/agent/tasks/milestone-20-unified-internal-memory-tools/task-217-delete-standalone-ghost-tools.md +46 -0
  12. package/agent/tasks/milestone-20-unified-internal-memory-tools/task-218-add-tests-unified-internal-tools.md +66 -0
  13. package/dist/e2e-helpers.d.ts +1 -1
  14. package/dist/server-factory.d.ts +17 -41
  15. package/dist/server-factory.js +420 -149
  16. package/dist/server.js +202 -20
  17. package/dist/tools/{create-ghost-memory.d.ts → create-internal-memory.d.ts} +7 -9
  18. package/dist/tools/internal-tools.spec.d.ts +2 -0
  19. package/dist/tools/{query-ghost-memory.d.ts → query-internal-memory.d.ts} +6 -6
  20. package/dist/tools/{search-ghost-memory-by.d.ts → search-internal-memory-by.d.ts} +6 -6
  21. package/dist/tools/{search-ghost-memory.d.ts → search-internal-memory.d.ts} +6 -6
  22. package/dist/tools/{update-ghost-memory.d.ts → update-internal-memory.d.ts} +6 -6
  23. package/dist/types/auth.d.ts +22 -8
  24. package/dist/utils/internal-tags.d.ts +14 -0
  25. package/dist/utils/internal-tags.spec.d.ts +2 -0
  26. package/package.json +2 -3
  27. package/src/e2e-helpers.ts +4 -2
  28. package/src/ghost-persona.e2e.ts +18 -17
  29. package/src/server-factory.ts +117 -55
  30. package/src/tools/create-internal-memory.ts +105 -0
  31. package/src/tools/find-similar.ts +2 -2
  32. package/src/tools/internal-tools.spec.ts +312 -0
  33. package/src/tools/query-internal-memory.ts +73 -0
  34. package/src/tools/query-memory.ts +15 -12
  35. package/src/tools/search-by.spec.ts +6 -2
  36. package/src/tools/search-by.ts +6 -6
  37. package/src/tools/{search-ghost-memory-by.ts → search-internal-memory-by.ts} +34 -27
  38. package/src/tools/search-internal-memory.ts +87 -0
  39. package/src/tools/search-memory.ts +15 -12
  40. package/src/tools/search-space.ts +1 -0
  41. package/src/tools/{update-ghost-memory.ts → update-internal-memory.ts} +23 -17
  42. package/src/types/auth.ts +22 -8
  43. package/src/utils/internal-tags.spec.ts +104 -0
  44. package/src/utils/internal-tags.ts +46 -0
  45. package/dist/tools/ghost-tools.spec.d.ts +0 -2
  46. package/src/tools/create-ghost-memory.ts +0 -103
  47. package/src/tools/ghost-tools.spec.ts +0 -361
  48. package/src/tools/query-ghost-memory.ts +0 -63
  49. package/src/tools/search-ghost-memory.ts +0 -73
@@ -1931,7 +1931,13 @@ var COMMON_MEMORY_PROPERTIES = [
1931
1931
  { name: "total_significance", dataType: configure.dataType.NUMBER },
1932
1932
  // REM metadata
1933
1933
  { name: "rem_touched_at", dataType: configure.dataType.TEXT },
1934
- { name: "rem_visits", dataType: configure.dataType.INT }
1934
+ { name: "rem_visits", dataType: configure.dataType.INT },
1935
+ // Curation scoring (M36)
1936
+ { name: "curated_score", dataType: configure.dataType.NUMBER },
1937
+ { name: "editorial_score", dataType: configure.dataType.NUMBER },
1938
+ { name: "click_count", dataType: configure.dataType.INT },
1939
+ { name: "share_count", dataType: configure.dataType.INT },
1940
+ { name: "comment_count", dataType: configure.dataType.INT }
1935
1941
  ];
1936
1942
  var PUBLISHED_MEMORY_PROPERTIES = [
1937
1943
  // Publication metadata
@@ -2582,7 +2588,13 @@ var ALL_MEMORY_PROPERTIES = [
2582
2588
  "functional_significance",
2583
2589
  "total_significance",
2584
2590
  "rem_touched_at",
2585
- "rem_visits"
2591
+ "rem_visits",
2592
+ // Curation scoring (M36)
2593
+ "curated_score",
2594
+ "editorial_score",
2595
+ "click_count",
2596
+ "share_count",
2597
+ "comment_count"
2586
2598
  ];
2587
2599
  async function fetchMemoryWithAllProperties(collection, memoryId) {
2588
2600
  try {
@@ -3358,6 +3370,99 @@ var MemoryService = class {
3358
3370
  total_pool_size: totalPoolSize
3359
3371
  };
3360
3372
  }
3373
+ // ── By Curated (composite quality score) ──────────────────────────
3374
+ async byCurated(input) {
3375
+ const limit = input.limit ?? 50;
3376
+ const offset = input.offset ?? 0;
3377
+ const direction = input.direction ?? "desc";
3378
+ const memoryFilters = buildMemoryOnlyFilters(this.collection, input.filters);
3379
+ const ghostFilters = [];
3380
+ if (input.ghost_context) {
3381
+ ghostFilters.push(buildTrustFilter(this.collection, input.ghost_context.accessor_trust_level));
3382
+ }
3383
+ if (!input.ghost_context?.include_ghost_content && !input.filters?.types?.includes("ghost")) {
3384
+ ghostFilters.push(this.collection.filter.byProperty("content_type").notEqual("ghost"));
3385
+ }
3386
+ if (!input.filters?.types?.includes("rem")) {
3387
+ ghostFilters.push(this.collection.filter.byProperty("content_type").notEqual("rem"));
3388
+ }
3389
+ const hasQuery = input.query?.trim();
3390
+ const fetchLimit = (limit + offset) * 2;
3391
+ const executeScoredQuery = async (useDeletedFilter) => {
3392
+ const deletedFilter = useDeletedFilter ? buildDeletedFilter(this.collection, input.deleted_filter || "exclude") : null;
3393
+ const scoredFilter = this.collection.filter.byProperty("curated_score").greaterThan(0);
3394
+ const combined = combineFiltersWithAnd([deletedFilter, memoryFilters, scoredFilter, ...ghostFilters].filter((f) => f !== null));
3395
+ if (hasQuery) {
3396
+ const queryOptions2 = {
3397
+ limit: fetchLimit,
3398
+ alpha: 0.7,
3399
+ query: hasQuery
3400
+ };
3401
+ if (combined)
3402
+ queryOptions2.filters = combined;
3403
+ return this.collection.query.hybrid(hasQuery, queryOptions2);
3404
+ }
3405
+ const queryOptions = {
3406
+ limit: fetchLimit,
3407
+ sort: this.collection.sort.byProperty("curated_score", direction === "asc")
3408
+ };
3409
+ if (combined)
3410
+ queryOptions.filters = combined;
3411
+ return this.collection.query.fetchObjects(queryOptions);
3412
+ };
3413
+ const executeUnscoredQuery = async (useDeletedFilter) => {
3414
+ const deletedFilter = useDeletedFilter ? buildDeletedFilter(this.collection, input.deleted_filter || "exclude") : null;
3415
+ const unscoredFilters = [];
3416
+ const combined = combineFiltersWithAnd([deletedFilter, memoryFilters, ...ghostFilters].filter((f) => f !== null));
3417
+ const queryOptions = {
3418
+ limit: Math.ceil(fetchLimit / 4),
3419
+ sort: this.collection.sort.byProperty("created_at", false)
3420
+ // newest first
3421
+ };
3422
+ if (combined)
3423
+ queryOptions.filters = combined;
3424
+ return this.collection.query.fetchObjects(queryOptions);
3425
+ };
3426
+ const scoredResults = await this.retryWithoutDeletedFilter(executeScoredQuery);
3427
+ const unscoredResults = await this.retryWithoutDeletedFilter(executeUnscoredQuery);
3428
+ const scored = [];
3429
+ for (const obj of scoredResults.objects) {
3430
+ const doc = normalizeDoc({ id: obj.uuid, ...obj.properties });
3431
+ if (doc.doc_type === "memory" && doc.curated_score > 0) {
3432
+ scored.push(doc);
3433
+ }
3434
+ }
3435
+ if (hasQuery) {
3436
+ scored.sort((a, b) => {
3437
+ const aScore = a.curated_score ?? 0;
3438
+ const bScore = b.curated_score ?? 0;
3439
+ return direction === "asc" ? aScore - bScore : bScore - aScore;
3440
+ });
3441
+ }
3442
+ const unscored = [];
3443
+ for (const obj of unscoredResults.objects) {
3444
+ const doc = normalizeDoc({ id: obj.uuid, ...obj.properties });
3445
+ if (doc.doc_type === "memory" && !doc.curated_score) {
3446
+ unscored.push(doc);
3447
+ }
3448
+ }
3449
+ const interleaved = interleaveDiscovery({
3450
+ rated: scored,
3451
+ discovery: unscored,
3452
+ offset,
3453
+ limit
3454
+ });
3455
+ const memories = interleaved.map((item) => ({
3456
+ ...item.item,
3457
+ ...item.is_discovery ? { is_discovery: true } : {}
3458
+ }));
3459
+ return {
3460
+ memories,
3461
+ total: memories.length,
3462
+ offset,
3463
+ limit
3464
+ };
3465
+ }
3361
3466
  // ── Find Similar (vector) ──────────────────────────────────────────
3362
3467
  async findSimilar(input) {
3363
3468
  if (!input.memory_id && !input.text)
@@ -3374,6 +3479,7 @@ var MemoryService = class {
3374
3479
  ghostFilters.push(this.collection.filter.byProperty("content_type").notEqual("ghost"));
3375
3480
  }
3376
3481
  ghostFilters.push(this.collection.filter.byProperty("content_type").notEqual("rem"));
3482
+ ghostFilters.push(this.collection.filter.byProperty("content_type").notEqual("comment"));
3377
3483
  let memoryObj = null;
3378
3484
  if (input.memory_id) {
3379
3485
  memoryObj = await this.collection.query.fetchObjectById(input.memory_id, {
@@ -3565,6 +3671,28 @@ var MemoryService = class {
3565
3671
  orphaned_relationship_ids: orphanedIds
3566
3672
  };
3567
3673
  }
3674
+ // ── Engagement Counters ───────────────────────────────────────────
3675
+ async incrementClick(memoryId) {
3676
+ await this.incrementCounter(memoryId, "click_count");
3677
+ }
3678
+ async incrementShare(memoryId) {
3679
+ await this.incrementCounter(memoryId, "share_count");
3680
+ }
3681
+ async incrementComment(memoryId) {
3682
+ await this.incrementCounter(memoryId, "comment_count");
3683
+ }
3684
+ async incrementCounter(memoryId, field) {
3685
+ const existing = await this.collection.query.fetchObjectById(memoryId, {
3686
+ returnProperties: [field]
3687
+ });
3688
+ if (!existing)
3689
+ throw new Error(`Memory not found: ${memoryId}`);
3690
+ const current = existing.properties?.[field] ?? 0;
3691
+ await this.collection.data.update({
3692
+ id: memoryId,
3693
+ properties: { [field]: current + 1 }
3694
+ });
3695
+ }
3568
3696
  };
3569
3697
 
3570
3698
  // node_modules/@prmichaelsen/remember-core/dist/services/relationship.service.js
@@ -5006,6 +5134,42 @@ var SpaceService = class {
5006
5134
  });
5007
5135
  return { spaces_searched: spacesSearched, groups_searched: groupsSearched, results, total_pool_size: totalPoolSize };
5008
5136
  }
5137
+ // ── By Curated (composite quality score) ──────────────────────────
5138
+ async byCurated(input, authContext) {
5139
+ const spaces = input.spaces || [];
5140
+ const groups = input.groups || [];
5141
+ const limit = input.limit ?? 50;
5142
+ const offset = input.offset ?? 0;
5143
+ const direction = input.direction ?? "desc";
5144
+ this.validateSpaceGroupInput(spaces, groups, input.moderation_filter || "approved", authContext);
5145
+ const fetchLimit = (limit + offset) * 2;
5146
+ const hasQuery = input.query?.trim();
5147
+ const { allResults, spacesSearched, groupsSearched } = await this.fetchAcrossCollections(input, spaces, groups, async (collection, baseFilters) => {
5148
+ const combined = baseFilters.length > 0 ? Filters4.and(...baseFilters) : void 0;
5149
+ if (hasQuery) {
5150
+ const opts2 = { limit: fetchLimit, alpha: 0.7, query: hasQuery };
5151
+ if (combined)
5152
+ opts2.filters = combined;
5153
+ return (await collection.query.hybrid(hasQuery, opts2)).objects;
5154
+ }
5155
+ const opts = {
5156
+ limit: fetchLimit,
5157
+ sort: collection.sort.byProperty("curated_score", direction === "asc")
5158
+ };
5159
+ if (combined)
5160
+ opts.filters = combined;
5161
+ return (await collection.query.fetchObjects(opts)).objects;
5162
+ });
5163
+ const deduped = dedupeBySourceId(allResults, input.dedupe);
5164
+ deduped.sort((a, b) => {
5165
+ const aVal = a.properties?.curated_score ?? 0;
5166
+ const bVal = b.properties?.curated_score ?? 0;
5167
+ return direction === "desc" ? bVal - aVal : aVal - bVal;
5168
+ });
5169
+ const paginated = deduped.slice(offset, offset + limit);
5170
+ const memories = paginated.filter((obj) => obj.properties?.doc_type === "memory").map((obj) => ({ id: obj.uuid, ...obj.properties }));
5171
+ return { spaces_searched: spacesSearched, groups_searched: groupsSearched, memories, total: memories.length, offset, limit };
5172
+ }
5009
5173
  // ── Private: Validate Space/Group Input ───────────────────────────
5010
5174
  validateSpaceGroupInput(spaces, groups, moderationFilter, authContext) {
5011
5175
  if (spaces.length > 0) {
@@ -5150,6 +5314,18 @@ var REM_STATE_COLLECTION = `${BASE}.rem_state`;
5150
5314
  // node_modules/@prmichaelsen/remember-core/dist/services/rem.clustering.js
5151
5315
  import { Filters as Filters5 } from "weaviate-client";
5152
5316
 
5317
+ // node_modules/@prmichaelsen/remember-core/dist/services/rem.service.js
5318
+ import { Filters as Filters9 } from "weaviate-client";
5319
+
5320
+ // node_modules/@prmichaelsen/remember-core/dist/services/scoring-context.service.js
5321
+ import { Filters as Filters6 } from "weaviate-client";
5322
+
5323
+ // node_modules/@prmichaelsen/remember-core/dist/services/rem.pruning.js
5324
+ import { Filters as Filters7 } from "weaviate-client";
5325
+
5326
+ // node_modules/@prmichaelsen/remember-core/dist/services/rem.reconciliation.js
5327
+ import { Filters as Filters8 } from "weaviate-client";
5328
+
5153
5329
  // node_modules/@prmichaelsen/remember-core/dist/services/classification.service.js
5154
5330
  var GENRES = [
5155
5331
  "short_story",
@@ -5785,12 +5961,12 @@ var searchMemoryTool = {
5785
5961
  }
5786
5962
  };
5787
5963
  async function handleSearchMemory(args, userId, authContext) {
5788
- const ghostMode = authContext?.ghostMode;
5789
- const searchUserId = ghostMode?.owner_user_id ?? userId;
5790
- const debug = createDebugLogger({ tool: "remember_search_memory", userId: searchUserId, operation: ghostMode ? "ghost search" : "search memory" });
5964
+ const internalContext = authContext?.internalContext;
5965
+ const searchUserId = internalContext?.owner_user_id ?? userId;
5966
+ const debug = createDebugLogger({ tool: "remember_search_memory", userId: searchUserId, operation: internalContext ? "internal search" : "search memory" });
5791
5967
  try {
5792
5968
  debug.info("Tool invoked");
5793
- debug.trace("Arguments", { args, ghostMode: !!ghostMode });
5969
+ debug.trace("Arguments", { args, internalContext: !!internalContext });
5794
5970
  if (!args.query || args.query.trim() === "") {
5795
5971
  throw new Error("Query cannot be empty");
5796
5972
  }
@@ -5799,18 +5975,21 @@ async function handleSearchMemory(args, userId, authContext) {
5799
5975
  userId: searchUserId,
5800
5976
  query: args.query,
5801
5977
  includeRelationships,
5802
- ghostMode: !!ghostMode
5978
+ internalContext: !!internalContext
5803
5979
  });
5804
5980
  const collection = getMemoryCollection2(searchUserId);
5805
5981
  const alpha = args.alpha ?? 0.7;
5806
5982
  const limit = args.limit ?? 10;
5807
5983
  const offset = args.offset ?? 0;
5808
5984
  const deletedFilter = buildDeletedFilter(collection, args.deleted_filter || "exclude");
5809
- const trustFilter = ghostMode ? buildTrustFilter(collection, ghostMode.accessor_trust_level) : null;
5985
+ const trustFilter = internalContext?.accessor_trust_level != null ? buildTrustFilter(collection, internalContext.accessor_trust_level) : null;
5810
5986
  const searchFilters = includeRelationships ? buildCombinedSearchFilters(collection, args.filters) : buildMemoryOnlyFilters(collection, args.filters);
5811
5987
  const hasExplicitTypeFilter = args.filters?.types && args.filters.types.length > 0;
5812
- const ghostExclusionFilter = !hasExplicitTypeFilter ? collection.filter.byProperty("content_type").notEqual("ghost") : null;
5813
- const combinedFilters = combineFiltersWithAnd([deletedFilter, trustFilter, ghostExclusionFilter, searchFilters].filter((f) => f !== null));
5988
+ const internalExclusionFilter = !hasExplicitTypeFilter ? combineFiltersWithAnd([
5989
+ collection.filter.byProperty("content_type").notEqual("ghost"),
5990
+ collection.filter.byProperty("content_type").notEqual("agent")
5991
+ ]) : null;
5992
+ const combinedFilters = combineFiltersWithAnd([deletedFilter, trustFilter, internalExclusionFilter, searchFilters].filter((f) => f !== null));
5814
5993
  const searchOptions = {
5815
5994
  alpha,
5816
5995
  limit,
@@ -6156,7 +6335,7 @@ async function handleFindSimilar(args, userId, authContext) {
6156
6335
  deleted_filter: args.deleted_filter
6157
6336
  });
6158
6337
  const filteredMemories = coreResult.similar_memories.filter(
6159
- (m) => m.content_type !== "ghost"
6338
+ (m) => m.content_type !== "ghost" && m.content_type !== "agent"
6160
6339
  );
6161
6340
  const result = {
6162
6341
  query: {
@@ -6299,27 +6478,30 @@ var queryMemoryTool = {
6299
6478
  }
6300
6479
  };
6301
6480
  async function handleQueryMemory(args, userId, authContext) {
6302
- const ghostMode = authContext?.ghostMode;
6303
- const searchUserId = ghostMode?.owner_user_id ?? userId;
6304
- const debug = createDebugLogger({ tool: "remember_query_memory", userId: searchUserId, operation: ghostMode ? "ghost query" : "query memory" });
6481
+ const internalContext = authContext?.internalContext;
6482
+ const searchUserId = internalContext?.owner_user_id ?? userId;
6483
+ const debug = createDebugLogger({ tool: "remember_query_memory", userId: searchUserId, operation: internalContext ? "internal query" : "query memory" });
6305
6484
  try {
6306
6485
  debug.info("Tool invoked");
6307
- debug.trace("Arguments", { args, ghostMode: !!ghostMode });
6486
+ debug.trace("Arguments", { args, internalContext: !!internalContext });
6308
6487
  if (!args.query || args.query.trim() === "") {
6309
6488
  throw new Error("Query cannot be empty");
6310
6489
  }
6311
- logger.info("Querying memories", { userId: searchUserId, query: args.query, ghostMode: !!ghostMode });
6490
+ logger.info("Querying memories", { userId: searchUserId, query: args.query, internalContext: !!internalContext });
6312
6491
  const collection = getMemoryCollection2(searchUserId);
6313
6492
  const limit = args.limit ?? 5;
6314
6493
  const minRelevance = args.min_relevance ?? 0.6;
6315
6494
  const includeContext = args.include_context ?? true;
6316
6495
  const format = args.format ?? "detailed";
6317
6496
  const deletedFilter = buildDeletedFilter(collection, args.deleted_filter || "exclude");
6318
- const trustFilter = ghostMode ? buildTrustFilter(collection, ghostMode.accessor_trust_level) : null;
6497
+ const trustFilter = internalContext?.accessor_trust_level != null ? buildTrustFilter(collection, internalContext.accessor_trust_level) : null;
6319
6498
  const searchFilters = buildCombinedSearchFilters(collection, args.filters);
6320
6499
  const hasExplicitTypeFilter = args.filters?.types && args.filters.types.length > 0;
6321
- const ghostExclusionFilter = !hasExplicitTypeFilter ? collection.filter.byProperty("content_type").notEqual("ghost") : null;
6322
- const combinedFilters = combineFiltersWithAnd([deletedFilter, trustFilter, ghostExclusionFilter, searchFilters].filter((f) => f !== null));
6500
+ const internalExclusionFilter = !hasExplicitTypeFilter ? combineFiltersWithAnd([
6501
+ collection.filter.byProperty("content_type").notEqual("ghost"),
6502
+ collection.filter.byProperty("content_type").notEqual("agent")
6503
+ ]) : null;
6504
+ const combinedFilters = combineFiltersWithAnd([deletedFilter, trustFilter, internalExclusionFilter, searchFilters].filter((f) => f !== null));
6323
6505
  const searchOptions = {
6324
6506
  limit,
6325
6507
  distance: 1 - minRelevance,
@@ -7431,7 +7613,7 @@ async function handleDeny(args, userId, authContext) {
7431
7613
  }
7432
7614
 
7433
7615
  // src/tools/search-space.ts
7434
- import { Filters as Filters6 } from "weaviate-client";
7616
+ import { Filters as Filters10 } from "weaviate-client";
7435
7617
  var searchSpaceTool = {
7436
7618
  name: "remember_search_space",
7437
7619
  description: `Search shared spaces and/or groups to discover memories from other users.
@@ -8277,16 +8459,16 @@ var searchByTool = {
8277
8459
  }
8278
8460
  };
8279
8461
  async function handleSearchBy(args, userId, authContext) {
8280
- const ghostMode = authContext?.ghostMode;
8281
- const searchUserId = ghostMode?.owner_user_id ?? userId;
8462
+ const internalContext = authContext?.internalContext;
8463
+ const searchUserId = internalContext?.owner_user_id ?? userId;
8282
8464
  const debug = createDebugLogger({ tool: "remember_search_by", userId: searchUserId, operation: `search by ${args.mode}` });
8283
8465
  try {
8284
8466
  debug.info("Tool invoked");
8285
- debug.trace("Arguments", { args, ghostMode: !!ghostMode });
8467
+ debug.trace("Arguments", { args, internalContext: !!internalContext });
8286
8468
  const { memory } = createCoreServices(searchUserId);
8287
- const ghostContext = ghostMode ? {
8288
- accessor_trust_level: ghostMode.accessor_trust_level,
8289
- owner_user_id: ghostMode.owner_user_id
8469
+ const ghostContext = internalContext?.accessor_trust_level != null ? {
8470
+ accessor_trust_level: internalContext.accessor_trust_level,
8471
+ owner_user_id: internalContext.owner_user_id
8290
8472
  } : void 0;
8291
8473
  const limit = args.limit ?? 10;
8292
8474
  const offset = args.offset ?? 0;
@@ -8398,45 +8580,78 @@ async function handleSearchBy(args, userId, authContext) {
8398
8580
  }
8399
8581
  }
8400
8582
 
8401
- // src/tools/create-ghost-memory.ts
8402
- var createGhostMemoryTool = {
8403
- name: "remember_create_ghost_memory",
8404
- description: `Create a ghost memory (cross-user interaction record).
8583
+ // src/utils/internal-tags.ts
8584
+ function buildInternalTags(authContext) {
8585
+ const ctx = authContext.internalContext;
8586
+ if (!ctx)
8587
+ return [];
8588
+ if (ctx.type === "agent") {
8589
+ return ["agent"];
8590
+ }
8591
+ const tags = ["ghost"];
8592
+ switch (ctx.ghost_type) {
8593
+ case "user":
8594
+ tags.push("ghost_type:user");
8595
+ if (ctx.owner_user_id) {
8596
+ tags.push(`ghost_owner:user:${ctx.owner_user_id}`);
8597
+ }
8598
+ break;
8599
+ case "space":
8600
+ tags.push("ghost_type:space");
8601
+ if (ctx.ghost_space) {
8602
+ tags.push(`ghost_owner:space:${ctx.ghost_space}`);
8603
+ }
8604
+ break;
8605
+ case "group":
8606
+ tags.push("ghost_type:group");
8607
+ if (ctx.ghost_group) {
8608
+ tags.push(`ghost_owner:group:${ctx.ghost_group}`);
8609
+ }
8610
+ break;
8611
+ }
8612
+ return tags;
8613
+ }
8614
+
8615
+ // src/tools/create-internal-memory.ts
8616
+ var createInternalMemoryTool = {
8617
+ name: "remember_create_internal_memory",
8618
+ description: `Create an internal memory (ghost observation or agent note) based on the current session context.
8619
+
8620
+ In ghost mode: creates a ghost memory tracking conversation observations, impressions,
8621
+ and insights. Automatically tagged with ghost source isolation tags.
8405
8622
 
8406
- Ghost memories track what happened during ghost conversations \u2014 observations,
8407
- impressions, and insights about the accessor. Automatically sets content_type
8408
- to 'ghost' and adds ghost-specific tags.
8623
+ In agent mode: creates an agent memory for AI observations and notes.
8624
+ Automatically tagged with agent tags.
8409
8625
 
8410
- Ghost memories are excluded from default searches. They are only visible when
8411
- explicitly searching with content_type: 'ghost' or using ghost memory tools.`,
8626
+ Content type and tags are determined by the platform session context.
8627
+ This tool errors if no internal session context is present.`,
8412
8628
  inputSchema: {
8413
8629
  type: "object",
8414
8630
  properties: {
8415
- content: { type: "string", description: "Ghost memory content" },
8631
+ content: { type: "string", description: "Memory content" },
8416
8632
  title: { type: "string", description: "Optional title" },
8417
- tags: { type: "array", items: { type: "string" }, description: "Additional tags (ghost-specific tags added automatically)" },
8633
+ tags: { type: "array", items: { type: "string" }, description: "Additional tags (internal tags added automatically)" },
8418
8634
  weight: { type: "number", minimum: 0, maximum: 1, description: "Significance (0-1)" },
8419
8635
  trust: { type: "number", minimum: 0, maximum: 1, description: "Trust level (0-1)" },
8420
- feel_salience: { type: "number", minimum: 0, maximum: 1, description: "How unexpected/novel (0-1)" },
8421
- feel_social_weight: { type: "number", minimum: 0, maximum: 1, description: "Relationship/reputation impact (0-1)" },
8422
- feel_narrative_importance: { type: "number", minimum: 0, maximum: 1, description: "Story arc importance (0-1)" }
8636
+ feel_salience: { type: "number", minimum: 0, maximum: 1 },
8637
+ feel_social_weight: { type: "number", minimum: 0, maximum: 1 },
8638
+ feel_narrative_importance: { type: "number", minimum: 0, maximum: 1 }
8423
8639
  },
8424
8640
  required: ["content"]
8425
8641
  }
8426
8642
  };
8427
- async function handleCreateGhostMemory(args, userId, authContext) {
8428
- const debug = createDebugLogger({ tool: "remember_create_ghost_memory", userId, operation: "create ghost memory" });
8643
+ async function handleCreateInternalMemory(args, userId, authContext) {
8644
+ const debug = createDebugLogger({ tool: "remember_create_internal_memory", userId, operation: "create internal memory" });
8429
8645
  try {
8430
8646
  debug.info("Tool invoked");
8431
- debug.trace("Arguments", { args });
8432
- const { memory } = createCoreServices(userId);
8433
- const accessorUserId = authContext?.ghostMode?.accessor_user_id;
8434
- const ghostTags = ["ghost"];
8435
- if (accessorUserId) {
8436
- ghostTags.push(`ghost:${accessorUserId}`);
8647
+ const ctx = authContext?.internalContext;
8648
+ if (!ctx) {
8649
+ return JSON.stringify({ error: "Internal context required. X-Internal-Type header must be set." });
8437
8650
  }
8651
+ const { memory } = createCoreServices(userId);
8652
+ const internalTags = buildInternalTags(authContext);
8438
8653
  const userTags = args.tags ?? [];
8439
- const mergedTags = [.../* @__PURE__ */ new Set([...ghostTags, ...userTags])];
8654
+ const mergedTags = [.../* @__PURE__ */ new Set([...internalTags, ...userTags])];
8440
8655
  const feelFields = {};
8441
8656
  for (const [key, value] of Object.entries(args)) {
8442
8657
  if (key.startsWith("feel_") && typeof value === "number") {
@@ -8446,38 +8661,39 @@ async function handleCreateGhostMemory(args, userId, authContext) {
8446
8661
  const result = await memory.create({
8447
8662
  content: args.content,
8448
8663
  title: args.title,
8449
- type: "ghost",
8664
+ type: ctx.type,
8450
8665
  weight: args.weight,
8451
8666
  trust: args.trust,
8452
8667
  tags: mergedTags,
8453
- context_summary: "Ghost memory created via MCP",
8668
+ context_summary: `Internal memory created via MCP (${ctx.type})`,
8454
8669
  ...feelFields
8455
8670
  });
8456
8671
  return JSON.stringify({
8457
8672
  memory_id: result.memory_id,
8458
8673
  created_at: result.created_at,
8459
- content_type: "ghost",
8674
+ content_type: ctx.type,
8460
8675
  tags: mergedTags,
8461
- message: `Ghost memory created successfully with ID: ${result.memory_id}`
8676
+ message: `${ctx.type} memory created successfully with ID: ${result.memory_id}`
8462
8677
  }, null, 2);
8463
8678
  } catch (error) {
8464
8679
  debug.error("Tool failed", { error: error instanceof Error ? error.message : String(error) });
8465
8680
  handleToolError(error, {
8466
- toolName: "remember_create_ghost_memory",
8467
- operation: "create ghost memory",
8681
+ toolName: "remember_create_internal_memory",
8682
+ operation: "create internal memory",
8468
8683
  userId
8469
8684
  });
8470
8685
  }
8471
8686
  }
8472
8687
 
8473
- // src/tools/update-ghost-memory.ts
8474
- var updateGhostMemoryTool = {
8475
- name: "remember_update_ghost_memory",
8476
- description: "Update a ghost memory. Only works on memories with content_type: ghost.",
8688
+ // src/tools/update-internal-memory.ts
8689
+ var updateInternalMemoryTool = {
8690
+ name: "remember_update_internal_memory",
8691
+ description: `Update an internal memory (ghost or agent). Only works on memories matching
8692
+ the current session's content type. Use remember_update_memory for regular memories.`,
8477
8693
  inputSchema: {
8478
8694
  type: "object",
8479
8695
  properties: {
8480
- memory_id: { type: "string", description: "Ghost memory ID to update" },
8696
+ memory_id: { type: "string", description: "Memory ID to update" },
8481
8697
  content: { type: "string" },
8482
8698
  title: { type: "string" },
8483
8699
  tags: { type: "array", items: { type: "string" } },
@@ -8487,19 +8703,23 @@ var updateGhostMemoryTool = {
8487
8703
  required: ["memory_id"]
8488
8704
  }
8489
8705
  };
8490
- async function handleUpdateGhostMemory(args, userId, authContext) {
8491
- const debug = createDebugLogger({ tool: "remember_update_ghost_memory", userId, operation: "update ghost memory" });
8706
+ async function handleUpdateInternalMemory(args, userId, authContext) {
8707
+ const debug = createDebugLogger({ tool: "remember_update_internal_memory", userId, operation: "update internal memory" });
8492
8708
  try {
8493
8709
  debug.info("Tool invoked");
8494
- debug.trace("Arguments", { args });
8710
+ const ctx = authContext?.internalContext;
8711
+ if (!ctx) {
8712
+ return JSON.stringify({ error: "Internal context required. X-Internal-Type header must be set." });
8713
+ }
8495
8714
  const collection = getMemoryCollection2(userId);
8496
8715
  const existing = await collection.query.fetchObjectById(args.memory_id);
8497
8716
  if (!existing) {
8498
8717
  return JSON.stringify({ error: `Memory ${args.memory_id} not found` });
8499
8718
  }
8500
- if (existing.properties.content_type !== "ghost") {
8719
+ const existingType = existing.properties.content_type;
8720
+ if (existingType !== ctx.type) {
8501
8721
  return JSON.stringify({
8502
- error: `Memory ${args.memory_id} is not a ghost memory (content_type: ${existing.properties.content_type}). Use remember_update_memory for non-ghost memories.`
8722
+ error: `Memory ${args.memory_id} is content_type: ${existingType}, but current session is ${ctx.type}. Use remember_update_memory for non-internal memories.`
8503
8723
  });
8504
8724
  }
8505
8725
  const { memory } = createCoreServices(userId);
@@ -8516,31 +8736,33 @@ async function handleUpdateGhostMemory(args, userId, authContext) {
8516
8736
  updated_at: result.updated_at,
8517
8737
  version: result.version,
8518
8738
  updated_fields: result.updated_fields,
8519
- message: `Ghost memory updated successfully. Updated fields: ${result.updated_fields.join(", ")}`
8739
+ message: `${ctx.type} memory updated successfully. Updated fields: ${result.updated_fields.join(", ")}`
8520
8740
  }, null, 2);
8521
8741
  } catch (error) {
8522
8742
  debug.error("Tool failed", { error: error instanceof Error ? error.message : String(error) });
8523
8743
  handleToolError(error, {
8524
- toolName: "remember_update_ghost_memory",
8525
- operation: "update ghost memory",
8744
+ toolName: "remember_update_internal_memory",
8745
+ operation: "update internal memory",
8526
8746
  userId,
8527
8747
  memoryId: args.memory_id
8528
8748
  });
8529
8749
  }
8530
8750
  }
8531
8751
 
8532
- // src/tools/search-ghost-memory.ts
8533
- var searchGhostMemoryTool = {
8534
- name: "remember_search_ghost_memory",
8535
- description: `Search ghost memories using hybrid semantic + keyword search.
8536
- Automatically filters to content_type: ghost. Use this to find specific
8537
- ghost interaction records.`,
8752
+ // src/tools/search-internal-memory.ts
8753
+ var searchInternalMemoryTool = {
8754
+ name: "remember_search_internal_memory",
8755
+ description: `Search internal memories (ghost or agent) using hybrid semantic + keyword search.
8756
+
8757
+ Automatically scoped to the current session's content type and ghost source.
8758
+ In ghost mode, only shows memories from the current ghost conversation
8759
+ (e.g., only alice's ghost memories, not carol's).`,
8538
8760
  inputSchema: {
8539
8761
  type: "object",
8540
8762
  properties: {
8541
8763
  query: { type: "string", description: "Search query" },
8542
8764
  alpha: { type: "number", minimum: 0, maximum: 1, description: "Semantic vs keyword balance. Default: 0.7" },
8543
- tags: { type: "array", items: { type: "string" }, description: "Filter by tags" },
8765
+ tags: { type: "array", items: { type: "string" }, description: "Additional tag filters" },
8544
8766
  limit: { type: "number", description: "Max results. Default: 10" },
8545
8767
  offset: { type: "number" },
8546
8768
  deleted_filter: { type: "string", enum: ["exclude", "include", "only"] }
@@ -8548,11 +8770,18 @@ var searchGhostMemoryTool = {
8548
8770
  required: ["query"]
8549
8771
  }
8550
8772
  };
8551
- async function handleSearchGhostMemory(args, userId, authContext) {
8552
- const debug = createDebugLogger({ tool: "remember_search_ghost_memory", userId, operation: "search ghost memories" });
8773
+ async function handleSearchInternalMemory(args, userId, authContext) {
8774
+ const debug = createDebugLogger({ tool: "remember_search_internal_memory", userId, operation: "search internal memories" });
8553
8775
  try {
8554
8776
  debug.info("Tool invoked");
8555
- debug.trace("Arguments", { args });
8777
+ const ctx = authContext?.internalContext;
8778
+ if (!ctx) {
8779
+ return JSON.stringify({ error: "Internal context required. X-Internal-Type header must be set." });
8780
+ }
8781
+ const allTags = buildInternalTags(authContext);
8782
+ const scopeTags = allTags.filter((t) => t !== "ghost" && t !== "agent");
8783
+ const userTags = args.tags ?? [];
8784
+ const mergedTags = [.../* @__PURE__ */ new Set([...scopeTags, ...userTags])];
8556
8785
  return await handleSearchMemory(
8557
8786
  {
8558
8787
  query: args.query,
@@ -8560,8 +8789,8 @@ async function handleSearchGhostMemory(args, userId, authContext) {
8560
8789
  limit: args.limit,
8561
8790
  offset: args.offset,
8562
8791
  filters: {
8563
- types: ["ghost"],
8564
- tags: args.tags
8792
+ types: [ctx.type],
8793
+ tags: mergedTags.length > 0 ? mergedTags : void 0
8565
8794
  },
8566
8795
  deleted_filter: args.deleted_filter
8567
8796
  },
@@ -8571,18 +8800,19 @@ async function handleSearchGhostMemory(args, userId, authContext) {
8571
8800
  } catch (error) {
8572
8801
  debug.error("Tool failed", { error: error instanceof Error ? error.message : String(error) });
8573
8802
  handleToolError(error, {
8574
- toolName: "remember_search_ghost_memory",
8575
- operation: "search ghost memories",
8803
+ toolName: "remember_search_internal_memory",
8804
+ operation: "search internal memories",
8576
8805
  userId
8577
8806
  });
8578
8807
  }
8579
8808
  }
8580
8809
 
8581
- // src/tools/query-ghost-memory.ts
8582
- var queryGhostMemoryTool = {
8583
- name: "remember_query_ghost_memory",
8584
- description: `Query ghost memories using natural language (pure semantic search).
8585
- Automatically filters to content_type: ghost.`,
8810
+ // src/tools/query-internal-memory.ts
8811
+ var queryInternalMemoryTool = {
8812
+ name: "remember_query_internal_memory",
8813
+ description: `Query internal memories (ghost or agent) using natural language (pure semantic search).
8814
+
8815
+ Automatically scoped to the current session's content type and ghost source.`,
8586
8816
  inputSchema: {
8587
8817
  type: "object",
8588
8818
  properties: {
@@ -8593,18 +8823,24 @@ var queryGhostMemoryTool = {
8593
8823
  required: ["query"]
8594
8824
  }
8595
8825
  };
8596
- async function handleQueryGhostMemory(args, userId, authContext) {
8597
- const debug = createDebugLogger({ tool: "remember_query_ghost_memory", userId, operation: "query ghost memories" });
8826
+ async function handleQueryInternalMemory(args, userId, authContext) {
8827
+ const debug = createDebugLogger({ tool: "remember_query_internal_memory", userId, operation: "query internal memories" });
8598
8828
  try {
8599
8829
  debug.info("Tool invoked");
8600
- debug.trace("Arguments", { args });
8830
+ const ctx = authContext?.internalContext;
8831
+ if (!ctx) {
8832
+ return JSON.stringify({ error: "Internal context required. X-Internal-Type header must be set." });
8833
+ }
8834
+ const allTags = buildInternalTags(authContext);
8835
+ const scopeTags = allTags.filter((t) => t !== "ghost" && t !== "agent");
8601
8836
  return await handleQueryMemory(
8602
8837
  {
8603
8838
  query: args.query,
8604
8839
  limit: args.limit,
8605
8840
  min_relevance: args.min_relevance,
8606
8841
  filters: {
8607
- types: ["ghost"]
8842
+ types: [ctx.type],
8843
+ tags: scopeTags.length > 0 ? scopeTags : void 0
8608
8844
  }
8609
8845
  },
8610
8846
  userId,
@@ -8613,45 +8849,43 @@ async function handleQueryGhostMemory(args, userId, authContext) {
8613
8849
  } catch (error) {
8614
8850
  debug.error("Tool failed", { error: error instanceof Error ? error.message : String(error) });
8615
8851
  handleToolError(error, {
8616
- toolName: "remember_query_ghost_memory",
8617
- operation: "query ghost memories",
8852
+ toolName: "remember_query_internal_memory",
8853
+ operation: "query internal memories",
8618
8854
  userId
8619
8855
  });
8620
8856
  }
8621
8857
  }
8622
8858
 
8623
- // src/tools/search-ghost-memory-by.ts
8624
- var searchGhostMemoryByTool = {
8625
- name: "remember_search_ghost_memory_by",
8626
- description: `Search ghost memories using specialized sort/discovery modes. Automatically filters to content_type: ghost.
8859
+ // src/tools/search-internal-memory-by.ts
8860
+ var searchInternalMemoryByTool = {
8861
+ name: "remember_search_internal_memory_by",
8862
+ description: `Search internal memories (ghost or agent) using specialized sort/discovery modes.
8863
+ Automatically scoped to the current session's content type and ghost source.
8627
8864
 
8628
8865
  Modes:
8629
8866
  - byTime: Chronological sort (newest/oldest first)
8630
- - byDensity: Sort by relationship count (most connected ghost memories)
8631
- - byRating: Sort by Bayesian rating average (social ratings from spaces)
8867
+ - byDensity: Sort by relationship count (most connected memories)
8868
+ - byRating: Sort by Bayesian rating average
8632
8869
  - byDiscovery: Interleaved rated + unrated content for exploration (4:1 ratio)
8633
- - byProperty: Sort by any memory property (e.g., feel_trauma, weight, feel_salience). Requires sort_field.
8634
- - bySignificance: Sort by total_significance (combined emotional + functional score from REM)
8635
- - byBroad: Massive results with truncated content (content_head/mid/tail ~100 chars each) for scan-and-drill-in workflow
8870
+ - byProperty: Sort by any memory property (e.g., feel_trauma, weight). Requires sort_field.
8871
+ - bySignificance: Sort by total_significance (combined emotional + functional score)
8872
+ - byBroad: Massive results with truncated content for scan-and-drill-in
8636
8873
  - byRandom: Random sampling for serendipitous rediscovery
8637
8874
 
8638
- Use remember_search_ghost_memory for hybrid semantic+keyword search.
8639
- Use this tool for structured browsing, sorting, and discovery of ghost interaction records.
8640
-
8641
8875
  Available sort_field values for byProperty:
8642
8876
  Emotions (0-1): feel_emotional_significance, feel_vulnerability, feel_trauma, feel_humor, feel_happiness, feel_sadness, feel_fear, feel_anger, feel_surprise, feel_disgust, feel_contempt, feel_embarrassment, feel_shame, feel_guilt, feel_excitement, feel_pride, feel_intensity, feel_coherence_tension
8643
- Affect dimensions: feel_valence (-1 to 1), feel_arousal (0-1), feel_dominance (0-1)
8644
- Functional signals (0-1): functional_salience, functional_urgency, functional_social_weight, functional_agency, functional_novelty, functional_retrieval_utility, functional_narrative_importance, functional_aesthetic_quality, functional_valence, functional_coherence_tension
8645
- Composite scores: feel_significance, functional_significance, total_significance
8877
+ Affect: feel_valence (-1 to 1), feel_arousal (0-1), feel_dominance (0-1)
8878
+ Functional (0-1): functional_salience, functional_urgency, functional_social_weight, functional_agency, functional_novelty, functional_retrieval_utility, functional_narrative_importance, functional_aesthetic_quality, functional_valence, functional_coherence_tension
8879
+ Composite: feel_significance, functional_significance, total_significance
8646
8880
  Core: weight, trust_score, relationship_count, version
8647
- REM metadata: rem_visits`,
8881
+ REM: rem_visits`,
8648
8882
  inputSchema: {
8649
8883
  type: "object",
8650
8884
  properties: {
8651
8885
  mode: {
8652
8886
  type: "string",
8653
8887
  enum: ["byTime", "byDensity", "byRating", "byDiscovery", "byProperty", "bySignificance", "byRandom", "byBroad"],
8654
- description: "Search mode: byTime (chronological), byDensity (most connected), byRating (highest rated), byDiscovery (explore mix), byProperty (sort by field), bySignificance (emotional+functional score), byRandom (random sample), byBroad (scan many truncated)"
8888
+ description: "Search mode"
8655
8889
  },
8656
8890
  query: { type: "string", description: "Optional search query" },
8657
8891
  sort_order: { type: "string", enum: ["asc", "desc"] },
@@ -8663,11 +8897,16 @@ var searchGhostMemoryByTool = {
8663
8897
  required: ["mode"]
8664
8898
  }
8665
8899
  };
8666
- async function handleSearchGhostMemoryBy(args, userId, authContext) {
8667
- const debug = createDebugLogger({ tool: "remember_search_ghost_memory_by", userId, operation: "search ghost memories by mode" });
8900
+ async function handleSearchInternalMemoryBy(args, userId, authContext) {
8901
+ const debug = createDebugLogger({ tool: "remember_search_internal_memory_by", userId, operation: "search internal memories by mode" });
8668
8902
  try {
8669
8903
  debug.info("Tool invoked");
8670
- debug.trace("Arguments", { args });
8904
+ const ctx = authContext?.internalContext;
8905
+ if (!ctx) {
8906
+ return JSON.stringify({ error: "Internal context required. X-Internal-Type header must be set." });
8907
+ }
8908
+ const allTags = buildInternalTags(authContext);
8909
+ const scopeTags = allTags.filter((t) => t !== "ghost" && t !== "agent");
8671
8910
  return await handleSearchBy(
8672
8911
  {
8673
8912
  mode: args.mode,
@@ -8677,7 +8916,8 @@ async function handleSearchGhostMemoryBy(args, userId, authContext) {
8677
8916
  limit: args.limit,
8678
8917
  offset: args.offset,
8679
8918
  filters: {
8680
- types: ["ghost"]
8919
+ types: [ctx.type],
8920
+ tags: scopeTags.length > 0 ? scopeTags : void 0
8681
8921
  },
8682
8922
  deleted_filter: args.deleted_filter
8683
8923
  },
@@ -8687,8 +8927,8 @@ async function handleSearchGhostMemoryBy(args, userId, authContext) {
8687
8927
  } catch (error) {
8688
8928
  debug.error("Tool failed", { error: error instanceof Error ? error.message : String(error) });
8689
8929
  handleToolError(error, {
8690
- toolName: "remember_search_ghost_memory_by",
8691
- operation: "search ghost memories by mode",
8930
+ toolName: "remember_search_internal_memory_by",
8931
+ operation: "search internal memories by mode",
8692
8932
  userId
8693
8933
  });
8694
8934
  }
@@ -8999,16 +9239,37 @@ async function ensureDatabasesInitialized() {
8999
9239
  })();
9000
9240
  return initializationPromise;
9001
9241
  }
9242
+ function normalizeOptions(raw, userId) {
9243
+ if ("internalContext" in raw || !("internal_type" in raw)) {
9244
+ return raw;
9245
+ }
9246
+ const extras = raw;
9247
+ const internalType = extras.internal_type;
9248
+ if (!internalType) {
9249
+ return {};
9250
+ }
9251
+ return {
9252
+ internalContext: {
9253
+ type: internalType,
9254
+ ghost_type: extras.ghost_type,
9255
+ ghost_space: extras.ghost_space,
9256
+ ghost_group: extras.ghost_group,
9257
+ owner_user_id: extras.ghost_owner,
9258
+ accessor_user_id: userId
9259
+ }
9260
+ };
9261
+ }
9002
9262
  async function createServer(accessToken, userId, options = {}) {
9003
9263
  if (!userId) {
9004
9264
  throw new Error("userId is required");
9005
9265
  }
9266
+ const opts = normalizeOptions(options, userId);
9006
9267
  logger.debug("Creating server instance", { userId });
9007
9268
  await ensureDatabasesInitialized();
9008
9269
  const server = new Server(
9009
9270
  {
9010
- name: options.name || "remember-mcp",
9011
- version: options.version || "0.2.0"
9271
+ name: opts.name || "remember-mcp",
9272
+ version: opts.version || "0.2.0"
9012
9273
  },
9013
9274
  {
9014
9275
  capabilities: {
@@ -9016,25 +9277,35 @@ async function createServer(accessToken, userId, options = {}) {
9016
9277
  }
9017
9278
  }
9018
9279
  );
9019
- let resolvedGhostMode;
9020
- if (options.ghostMode) {
9021
- const ghostConfig = await getGhostConfig2(options.ghostMode.owner_user_id);
9022
- const trustLevel = await resolveAccessorTrustLevel2(ghostConfig, options.ghostMode.owner_user_id, options.ghostMode.accessor_user_id);
9023
- resolvedGhostMode = {
9024
- owner_user_id: options.ghostMode.owner_user_id,
9025
- accessor_user_id: options.ghostMode.accessor_user_id,
9026
- accessor_trust_level: trustLevel
9280
+ let resolvedInternalContext;
9281
+ if (opts.internalContext) {
9282
+ const ic = opts.internalContext;
9283
+ let accessorTrustLevel;
9284
+ if (ic.type === "ghost" && ic.owner_user_id) {
9285
+ const ghostConfig = await getGhostConfig2(ic.owner_user_id);
9286
+ accessorTrustLevel = await resolveAccessorTrustLevel2(ghostConfig, ic.owner_user_id, ic.accessor_user_id);
9287
+ }
9288
+ resolvedInternalContext = {
9289
+ type: ic.type,
9290
+ ghost_type: ic.ghost_type,
9291
+ ghost_space: ic.ghost_space,
9292
+ ghost_group: ic.ghost_group,
9293
+ owner_user_id: ic.owner_user_id,
9294
+ accessor_user_id: ic.accessor_user_id,
9295
+ accessor_trust_level: accessorTrustLevel
9027
9296
  };
9028
- logger.info("Ghost mode resolved", {
9029
- ownerUserId: resolvedGhostMode.owner_user_id,
9030
- accessorUserId: resolvedGhostMode.accessor_user_id,
9031
- trustLevel: resolvedGhostMode.accessor_trust_level
9297
+ logger.info("Internal context resolved", {
9298
+ type: resolvedInternalContext.type,
9299
+ ghostType: resolvedInternalContext.ghost_type,
9300
+ ownerUserId: resolvedInternalContext.owner_user_id,
9301
+ accessorUserId: resolvedInternalContext.accessor_user_id,
9302
+ trustLevel: resolvedInternalContext.accessor_trust_level
9032
9303
  });
9033
9304
  }
9034
- registerHandlers(server, userId, accessToken, resolvedGhostMode);
9305
+ registerHandlers(server, userId, accessToken, resolvedInternalContext);
9035
9306
  return server;
9036
9307
  }
9037
- function registerHandlers(server, userId, accessToken, ghostMode) {
9308
+ function registerHandlers(server, userId, accessToken, internalContext) {
9038
9309
  server.setRequestHandler(ListToolsRequestSchema, async () => {
9039
9310
  return {
9040
9311
  tools: [
@@ -9065,12 +9336,12 @@ function registerHandlers(server, userId, accessToken, ghostMode) {
9065
9336
  ghostConfigTool,
9066
9337
  // Search modes
9067
9338
  searchByTool,
9068
- // Ghost memory tools
9069
- createGhostMemoryTool,
9070
- updateGhostMemoryTool,
9071
- searchGhostMemoryTool,
9072
- queryGhostMemoryTool,
9073
- searchGhostMemoryByTool,
9339
+ // Unified internal memory tools
9340
+ createInternalMemoryTool,
9341
+ updateInternalMemoryTool,
9342
+ searchInternalMemoryTool,
9343
+ queryInternalMemoryTool,
9344
+ searchInternalMemoryByTool,
9074
9345
  // Core introspection
9075
9346
  getCoreTool,
9076
9347
  // Space search modes
@@ -9082,7 +9353,7 @@ function registerHandlers(server, userId, accessToken, ghostMode) {
9082
9353
  const { name, arguments: args } = request.params;
9083
9354
  try {
9084
9355
  const credentials = await credentialsProvider.getCredentials(accessToken, userId);
9085
- const authContext = { accessToken, credentials, ghostMode };
9356
+ const authContext = { accessToken, credentials, internalContext };
9086
9357
  let result;
9087
9358
  switch (name) {
9088
9359
  case "remember_create_memory":
@@ -9151,20 +9422,20 @@ function registerHandlers(server, userId, accessToken, ghostMode) {
9151
9422
  case "remember_search_by":
9152
9423
  result = await handleSearchBy(args, userId, authContext);
9153
9424
  break;
9154
- case "remember_create_ghost_memory":
9155
- result = await handleCreateGhostMemory(args, userId, authContext);
9425
+ case "remember_create_internal_memory":
9426
+ result = await handleCreateInternalMemory(args, userId, authContext);
9156
9427
  break;
9157
- case "remember_update_ghost_memory":
9158
- result = await handleUpdateGhostMemory(args, userId, authContext);
9428
+ case "remember_update_internal_memory":
9429
+ result = await handleUpdateInternalMemory(args, userId, authContext);
9159
9430
  break;
9160
- case "remember_search_ghost_memory":
9161
- result = await handleSearchGhostMemory(args, userId, authContext);
9431
+ case "remember_search_internal_memory":
9432
+ result = await handleSearchInternalMemory(args, userId, authContext);
9162
9433
  break;
9163
- case "remember_query_ghost_memory":
9164
- result = await handleQueryGhostMemory(args, userId, authContext);
9434
+ case "remember_query_internal_memory":
9435
+ result = await handleQueryInternalMemory(args, userId, authContext);
9165
9436
  break;
9166
- case "remember_search_ghost_memory_by":
9167
- result = await handleSearchGhostMemoryBy(args, userId, authContext);
9437
+ case "remember_search_internal_memory_by":
9438
+ result = await handleSearchInternalMemoryBy(args, userId, authContext);
9168
9439
  break;
9169
9440
  case "remember_get_core":
9170
9441
  result = await handleGetCore(args, userId, authContext);