@prmichaelsen/remember-mcp 2.3.4 → 2.5.1

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 (34) hide show
  1. package/AGENT.md +2 -2
  2. package/CHANGELOG.md +63 -0
  3. package/README.md +50 -5
  4. package/agent/commands/git.commit.md +511 -0
  5. package/agent/commands/git.init.md +513 -0
  6. package/agent/milestones/milestone-11-unified-public-collection.md +205 -0
  7. package/agent/scripts/install.sh +31 -16
  8. package/agent/scripts/update.sh +32 -17
  9. package/agent/tasks/task-45-fix-publish-false-success-bug.md +114 -181
  10. package/agent/tasks/task-46-update-spacememory-types.md +94 -0
  11. package/agent/tasks/task-47-update-space-schema.md +102 -0
  12. package/agent/tasks/task-48-create-memory-public-collection.md +96 -0
  13. package/agent/tasks/task-49-update-remember-publish.md +153 -0
  14. package/agent/tasks/task-50-update-remember-confirm.md +111 -0
  15. package/agent/tasks/task-51-update-remember-search-space.md +154 -0
  16. package/agent/tasks/task-52-update-remember-query-space.md +142 -0
  17. package/agent/tasks/task-53-add-multispace-tests.md +193 -0
  18. package/agent/tasks/task-54-update-documentation-multispace.md +191 -0
  19. package/dist/server-factory.js +203 -107
  20. package/dist/server.js +203 -107
  21. package/dist/tools/publish.d.ts +1 -1
  22. package/dist/tools/query-space.d.ts +1 -1
  23. package/dist/tools/search-space.d.ts +1 -1
  24. package/dist/types/space-memory.d.ts +5 -3
  25. package/dist/weaviate/space-schema.d.ts +16 -0
  26. package/package.json +1 -1
  27. package/src/services/confirmation-token.service.ts +74 -30
  28. package/src/tools/confirm.ts +15 -16
  29. package/src/tools/publish.ts +42 -20
  30. package/src/tools/query-space.ts +38 -24
  31. package/src/tools/search-space.ts +51 -28
  32. package/src/types/space-memory.ts +5 -3
  33. package/src/weaviate/space-schema.spec.ts +55 -0
  34. package/src/weaviate/space-schema.ts +45 -6
@@ -3241,33 +3241,72 @@ var ConfirmationTokenService = class {
3241
3241
  * @returns Request ID and token
3242
3242
  */
3243
3243
  async createRequest(userId, action, payload, targetCollection) {
3244
- const token = randomUUID();
3245
- const now = /* @__PURE__ */ new Date();
3246
- const expiresAt = new Date(now.getTime() + this.EXPIRY_MINUTES * 60 * 1e3);
3247
- const request = {
3248
- user_id: userId,
3249
- token,
3250
- action,
3251
- target_collection: targetCollection,
3252
- payload,
3253
- created_at: now.toISOString(),
3254
- expires_at: expiresAt.toISOString(),
3255
- status: "pending"
3256
- };
3257
- const collectionPath = `users/${userId}/requests`;
3258
- console.log("[ConfirmationTokenService] Creating request:", {
3259
- userId,
3260
- action,
3261
- targetCollection,
3262
- collectionPath
3263
- });
3264
- const docRef = await addDocument(collectionPath, request);
3265
- console.log("[ConfirmationTokenService] Request created:", {
3266
- requestId: docRef.id,
3267
- token,
3268
- expiresAt: request.expires_at
3269
- });
3270
- return { requestId: docRef.id, token };
3244
+ try {
3245
+ const token = randomUUID();
3246
+ const now = /* @__PURE__ */ new Date();
3247
+ const expiresAt = new Date(now.getTime() + this.EXPIRY_MINUTES * 60 * 1e3);
3248
+ const request = {
3249
+ user_id: userId,
3250
+ token,
3251
+ action,
3252
+ target_collection: targetCollection,
3253
+ payload,
3254
+ created_at: now.toISOString(),
3255
+ expires_at: expiresAt.toISOString(),
3256
+ status: "pending"
3257
+ };
3258
+ const collectionPath = `users/${userId}/requests`;
3259
+ console.log("[ConfirmationTokenService] Creating request:", {
3260
+ userId,
3261
+ action,
3262
+ targetCollection,
3263
+ collectionPath,
3264
+ requestData: {
3265
+ token,
3266
+ action,
3267
+ payloadKeys: Object.keys(payload)
3268
+ }
3269
+ });
3270
+ console.log("[ConfirmationTokenService] Calling addDocument...");
3271
+ const docRef = await addDocument(collectionPath, request);
3272
+ console.log("[ConfirmationTokenService] addDocument returned:", {
3273
+ hasDocRef: !!docRef,
3274
+ hasId: !!docRef?.id,
3275
+ docRefId: docRef?.id
3276
+ });
3277
+ if (!docRef) {
3278
+ const error = new Error("Firestore addDocument returned null/undefined");
3279
+ console.error("[ConfirmationTokenService] CRITICAL: addDocument returned null", {
3280
+ userId,
3281
+ collectionPath
3282
+ });
3283
+ throw error;
3284
+ }
3285
+ if (!docRef.id) {
3286
+ const error = new Error("Firestore addDocument returned docRef without ID");
3287
+ console.error("[ConfirmationTokenService] CRITICAL: docRef has no ID", {
3288
+ userId,
3289
+ collectionPath,
3290
+ docRef
3291
+ });
3292
+ throw error;
3293
+ }
3294
+ console.log("[ConfirmationTokenService] Request created successfully:", {
3295
+ requestId: docRef.id,
3296
+ token,
3297
+ expiresAt: request.expires_at
3298
+ });
3299
+ return { requestId: docRef.id, token };
3300
+ } catch (error) {
3301
+ console.error("[ConfirmationTokenService] FAILED to create request:", {
3302
+ error: error instanceof Error ? error.message : String(error),
3303
+ stack: error instanceof Error ? error.stack : void 0,
3304
+ userId,
3305
+ action,
3306
+ collectionPath: `users/${userId}/requests`
3307
+ });
3308
+ throw error;
3309
+ }
3271
3310
  }
3272
3311
  /**
3273
3312
  * Validate and retrieve a confirmation request
@@ -3404,6 +3443,7 @@ var confirmationTokenService = new ConfirmationTokenService();
3404
3443
  // src/weaviate/space-schema.ts
3405
3444
  init_space_memory();
3406
3445
  import weaviate3 from "weaviate-client";
3446
+ var PUBLIC_COLLECTION_NAME = "Memory_public";
3407
3447
  function getSpaceCollectionName(spaceId) {
3408
3448
  return `Memory_${spaceId}`;
3409
3449
  }
@@ -3411,7 +3451,7 @@ function isValidSpaceId(spaceId) {
3411
3451
  return SUPPORTED_SPACES.includes(spaceId);
3412
3452
  }
3413
3453
  async function createSpaceCollection(client2, spaceId) {
3414
- const collectionName = getSpaceCollectionName(spaceId);
3454
+ const collectionName = spaceId === "public" ? PUBLIC_COLLECTION_NAME : getSpaceCollectionName(spaceId);
3415
3455
  console.log(`[Weaviate] Creating space collection ${collectionName}...`);
3416
3456
  await client2.collections.create({
3417
3457
  name: collectionName,
@@ -3429,10 +3469,15 @@ async function createSpaceCollection(client2, spaceId) {
3429
3469
  description: 'Document type: "space_memory"'
3430
3470
  },
3431
3471
  // Space identity
3472
+ {
3473
+ name: "spaces",
3474
+ dataType: "text[]",
3475
+ description: 'Spaces this memory is published to (e.g., ["the_void", "dogs"])'
3476
+ },
3432
3477
  {
3433
3478
  name: "space_id",
3434
3479
  dataType: "text",
3435
- description: 'Space identifier (e.g., "the_void")'
3480
+ description: "DEPRECATED: Use spaces array instead. Will be removed in v3.0.0."
3436
3481
  },
3437
3482
  {
3438
3483
  name: "author_id",
@@ -3566,14 +3611,11 @@ async function createSpaceCollection(client2, spaceId) {
3566
3611
  });
3567
3612
  console.log(`[Weaviate] Space collection ${collectionName} created successfully`);
3568
3613
  }
3569
- async function ensureSpaceCollection(client2, spaceId) {
3570
- if (!isValidSpaceId(spaceId)) {
3571
- throw new Error(`Invalid space ID: ${spaceId}. Supported spaces: ${SUPPORTED_SPACES.join(", ")}`);
3572
- }
3573
- const collectionName = getSpaceCollectionName(spaceId);
3614
+ async function ensurePublicCollection(client2) {
3615
+ const collectionName = PUBLIC_COLLECTION_NAME;
3574
3616
  const exists = await client2.collections.exists(collectionName);
3575
3617
  if (!exists) {
3576
- await createSpaceCollection(client2, spaceId);
3618
+ await createSpaceCollection(client2, "public");
3577
3619
  }
3578
3620
  return client2.collections.get(collectionName);
3579
3621
  }
@@ -3582,7 +3624,7 @@ async function ensureSpaceCollection(client2, spaceId) {
3582
3624
  init_space_memory();
3583
3625
  var publishTool = {
3584
3626
  name: "remember_publish",
3585
- description: 'Publish a memory to a shared space (like "The Void"). The memory will be COPIED (not moved) from your personal collection. Generates a confirmation token. Use remember_confirm to execute.',
3627
+ description: 'Publish a memory to one or more shared spaces (like "The Void"). The memory will be COPIED (not moved) from your personal collection. Generates a confirmation token. Use remember_confirm to execute.',
3586
3628
  inputSchema: {
3587
3629
  type: "object",
3588
3630
  properties: {
@@ -3590,11 +3632,15 @@ var publishTool = {
3590
3632
  type: "string",
3591
3633
  description: "ID of the memory from your personal collection to publish"
3592
3634
  },
3593
- target: {
3594
- type: "string",
3595
- description: "Target space to publish to (snake_case ID)",
3596
- enum: SUPPORTED_SPACES,
3597
- default: "the_void"
3635
+ spaces: {
3636
+ type: "array",
3637
+ items: {
3638
+ type: "string",
3639
+ enum: SUPPORTED_SPACES
3640
+ },
3641
+ description: 'Spaces to publish to (e.g., ["the_void", "dogs"]). Can publish to multiple spaces at once.',
3642
+ minItems: 1,
3643
+ default: ["the_void"]
3598
3644
  },
3599
3645
  additional_tags: {
3600
3646
  type: "array",
@@ -3603,7 +3649,7 @@ var publishTool = {
3603
3649
  default: []
3604
3650
  }
3605
3651
  },
3606
- required: ["memory_id", "target"]
3652
+ required: ["memory_id", "spaces"]
3607
3653
  }
3608
3654
  };
3609
3655
  async function handlePublish(args, userId) {
@@ -3611,18 +3657,21 @@ async function handlePublish(args, userId) {
3611
3657
  console.log("[remember_publish] Starting publish request:", {
3612
3658
  userId,
3613
3659
  memoryId: args.memory_id,
3614
- target: args.target,
3660
+ spaces: args.spaces,
3661
+ spaceCount: args.spaces.length,
3615
3662
  additionalTags: args.additional_tags?.length || 0
3616
3663
  });
3617
- if (!isValidSpaceId(args.target)) {
3618
- console.log("[remember_publish] Invalid space ID:", args.target);
3664
+ const invalidSpaces = args.spaces.filter((s) => !isValidSpaceId(s));
3665
+ if (invalidSpaces.length > 0) {
3666
+ console.log("[remember_publish] Invalid space IDs:", invalidSpaces);
3619
3667
  return JSON.stringify(
3620
3668
  {
3621
3669
  success: false,
3622
- error: "Invalid space ID",
3623
- message: `Space "${args.target}" is not supported. Supported spaces: ${SUPPORTED_SPACES.join(", ")}`,
3670
+ error: "Invalid space IDs",
3671
+ message: `Invalid spaces: ${invalidSpaces.join(", ")}. Supported spaces: ${SUPPORTED_SPACES.join(", ")}`,
3624
3672
  context: {
3625
- provided_space: args.target,
3673
+ invalid_spaces: invalidSpaces,
3674
+ provided_spaces: args.spaces,
3626
3675
  supported_spaces: SUPPORTED_SPACES
3627
3676
  }
3628
3677
  },
@@ -3630,6 +3679,18 @@ async function handlePublish(args, userId) {
3630
3679
  2
3631
3680
  );
3632
3681
  }
3682
+ if (args.spaces.length === 0) {
3683
+ console.log("[remember_publish] Empty spaces array");
3684
+ return JSON.stringify(
3685
+ {
3686
+ success: false,
3687
+ error: "Empty spaces array",
3688
+ message: "Must specify at least one space to publish to"
3689
+ },
3690
+ null,
3691
+ 2
3692
+ );
3693
+ }
3633
3694
  const weaviateClient = getWeaviateClient();
3634
3695
  const collectionName = getMemoryCollectionName(userId);
3635
3696
  console.log("[remember_publish] Fetching memory from collection:", collectionName);
@@ -3688,6 +3749,7 @@ async function handlePublish(args, userId) {
3688
3749
  }
3689
3750
  const payload = {
3690
3751
  memory_id: args.memory_id,
3752
+ spaces: args.spaces,
3691
3753
  additional_tags: args.additional_tags || []
3692
3754
  };
3693
3755
  console.log("[remember_publish] Generating confirmation token");
@@ -3695,7 +3757,8 @@ async function handlePublish(args, userId) {
3695
3757
  userId,
3696
3758
  "publish_memory",
3697
3759
  payload,
3698
- args.target
3760
+ void 0
3761
+ // No single target_collection anymore
3699
3762
  );
3700
3763
  console.log("[remember_publish] Token generated:", {
3701
3764
  requestId,
@@ -3711,12 +3774,12 @@ async function handlePublish(args, userId) {
3711
3774
  2
3712
3775
  );
3713
3776
  } catch (error) {
3714
- handleToolError(error, {
3777
+ return handleToolError(error, {
3715
3778
  toolName: "remember_publish",
3716
3779
  userId,
3717
3780
  operation: "publish memory",
3718
3781
  memory_id: args.memory_id,
3719
- target: args.target
3782
+ spaces: args.spaces
3720
3783
  });
3721
3784
  }
3722
3785
  }
@@ -3778,7 +3841,8 @@ async function executePublishMemory(request, userId) {
3778
3841
  console.log("[executePublishMemory] Starting execution:", {
3779
3842
  userId,
3780
3843
  memoryId: request.payload.memory_id,
3781
- targetSpace: request.target_collection
3844
+ spaces: request.payload.spaces,
3845
+ spaceCount: request.payload.spaces?.length || 0
3782
3846
  });
3783
3847
  const weaviateClient = getWeaviateClient();
3784
3848
  const userCollection = weaviateClient.collections.get(
@@ -3816,18 +3880,16 @@ async function executePublishMemory(request, userId) {
3816
3880
  2
3817
3881
  );
3818
3882
  }
3819
- console.log("[executePublishMemory] Ensuring space collection:", request.target_collection || "the_void");
3820
- const targetCollection = await ensureSpaceCollection(
3821
- weaviateClient,
3822
- request.target_collection || "the_void"
3823
- );
3824
- console.log("[executePublishMemory] Space collection ready");
3883
+ console.log("[executePublishMemory] Ensuring public collection");
3884
+ const publicCollection = await ensurePublicCollection(weaviateClient);
3885
+ console.log("[executePublishMemory] Public collection ready");
3825
3886
  const originalTags = Array.isArray(originalMemory.properties.tags) ? originalMemory.properties.tags : [];
3826
3887
  const additionalTags = Array.isArray(request.payload.additional_tags) ? request.payload.additional_tags : [];
3827
3888
  const publishedMemory = {
3828
3889
  ...originalMemory.properties,
3829
3890
  // Add space-specific fields
3830
- space_id: request.target_collection || "the_void",
3891
+ spaces: request.payload.spaces || ["the_void"],
3892
+ // ✅ Array of spaces!
3831
3893
  author_id: userId,
3832
3894
  // Track original author
3833
3895
  published_at: (/* @__PURE__ */ new Date()).toISOString(),
@@ -3841,14 +3903,14 @@ async function executePublishMemory(request, userId) {
3841
3903
  updated_at: (/* @__PURE__ */ new Date()).toISOString(),
3842
3904
  version: 1
3843
3905
  };
3844
- console.log("[executePublishMemory] Inserting into space collection:", {
3845
- spaceId: request.target_collection || "the_void",
3906
+ console.log("[executePublishMemory] Inserting into Memory_public:", {
3907
+ spaces: request.payload.spaces,
3908
+ spaceCount: request.payload.spaces?.length || 0,
3846
3909
  memoryId: request.payload.memory_id,
3847
3910
  hasUserId: !!publishedMemory.user_id,
3848
- hasAuthorId: !!publishedMemory.author_id,
3849
- hasSpaceId: !!publishedMemory.space_id
3911
+ hasAuthorId: !!publishedMemory.author_id
3850
3912
  });
3851
- const result = await targetCollection.data.insert(publishedMemory);
3913
+ const result = await publicCollection.data.insert(publishedMemory);
3852
3914
  console.log("[executePublishMemory] Insert result:", {
3853
3915
  success: !!result,
3854
3916
  spaceMemoryId: result
@@ -3856,7 +3918,8 @@ async function executePublishMemory(request, userId) {
3856
3918
  return JSON.stringify(
3857
3919
  {
3858
3920
  success: true,
3859
- space_memory_id: result
3921
+ space_memory_id: result,
3922
+ spaces: request.payload.spaces || ["the_void"]
3860
3923
  },
3861
3924
  null,
3862
3925
  2
@@ -3922,7 +3985,7 @@ import { Filters as Filters3 } from "weaviate-client";
3922
3985
  init_space_memory();
3923
3986
  var searchSpaceTool = {
3924
3987
  name: "remember_search_space",
3925
- description: "Search shared spaces to discover thoughts, ideas, and memories. Works like remember_search_memory but searches shared spaces instead of personal memories.",
3988
+ description: "Search one or more shared spaces to discover thoughts, ideas, and memories. Works like remember_search_memory but searches shared spaces instead of personal memories. Can search multiple spaces in a single query.",
3926
3989
  inputSchema: {
3927
3990
  type: "object",
3928
3991
  properties: {
@@ -3930,11 +3993,15 @@ var searchSpaceTool = {
3930
3993
  type: "string",
3931
3994
  description: "Search query (semantic + keyword hybrid)"
3932
3995
  },
3933
- space: {
3934
- type: "string",
3935
- description: "Which space to search",
3936
- enum: SUPPORTED_SPACES,
3937
- default: "the_void"
3996
+ spaces: {
3997
+ type: "array",
3998
+ items: {
3999
+ type: "string",
4000
+ enum: SUPPORTED_SPACES
4001
+ },
4002
+ description: 'Spaces to search (e.g., ["the_void", "dogs"]). Can search multiple spaces at once.',
4003
+ minItems: 1,
4004
+ default: ["the_void"]
3938
4005
  },
3939
4006
  content_type: {
3940
4007
  type: "string",
@@ -3976,49 +4043,66 @@ var searchSpaceTool = {
3976
4043
  description: "Offset for pagination"
3977
4044
  }
3978
4045
  },
3979
- required: ["query", "space"]
4046
+ required: ["query", "spaces"]
3980
4047
  }
3981
4048
  };
3982
4049
  async function handleSearchSpace(args, userId) {
3983
4050
  try {
3984
- if (!isValidSpaceId(args.space)) {
4051
+ const invalidSpaces = args.spaces.filter((s) => !isValidSpaceId(s));
4052
+ if (invalidSpaces.length > 0) {
3985
4053
  return JSON.stringify(
3986
4054
  {
3987
4055
  success: false,
3988
- error: "Invalid space ID",
3989
- message: `Space "${args.space}" is not supported. Supported spaces: ${SUPPORTED_SPACES.join(", ")}`
4056
+ error: "Invalid space IDs",
4057
+ message: `Invalid spaces: ${invalidSpaces.join(", ")}. Supported spaces: ${SUPPORTED_SPACES.join(", ")}`,
4058
+ context: {
4059
+ invalid_spaces: invalidSpaces,
4060
+ provided_spaces: args.spaces,
4061
+ supported_spaces: SUPPORTED_SPACES
4062
+ }
4063
+ },
4064
+ null,
4065
+ 2
4066
+ );
4067
+ }
4068
+ if (args.spaces.length === 0) {
4069
+ return JSON.stringify(
4070
+ {
4071
+ success: false,
4072
+ error: "Empty spaces array",
4073
+ message: "Must specify at least one space to search"
3990
4074
  },
3991
4075
  null,
3992
4076
  2
3993
4077
  );
3994
4078
  }
3995
4079
  const weaviateClient = getWeaviateClient();
3996
- const spaceCollection = await ensureSpaceCollection(weaviateClient, args.space);
4080
+ const publicCollection = await ensurePublicCollection(weaviateClient);
3997
4081
  const filterList = [];
3998
- filterList.push(spaceCollection.filter.byProperty("space_id").equal(args.space));
3999
- filterList.push(spaceCollection.filter.byProperty("doc_type").equal("space_memory"));
4082
+ filterList.push(publicCollection.filter.byProperty("spaces").containsAny(args.spaces));
4083
+ filterList.push(publicCollection.filter.byProperty("doc_type").equal("space_memory"));
4000
4084
  if (args.content_type) {
4001
- filterList.push(spaceCollection.filter.byProperty("type").equal(args.content_type));
4085
+ filterList.push(publicCollection.filter.byProperty("type").equal(args.content_type));
4002
4086
  }
4003
4087
  if (args.tags && args.tags.length > 0) {
4004
4088
  args.tags.forEach((tag) => {
4005
- filterList.push(spaceCollection.filter.byProperty("tags").containsAny([tag]));
4089
+ filterList.push(publicCollection.filter.byProperty("tags").containsAny([tag]));
4006
4090
  });
4007
4091
  }
4008
4092
  if (args.min_weight !== void 0) {
4009
- filterList.push(spaceCollection.filter.byProperty("weight").greaterOrEqual(args.min_weight));
4093
+ filterList.push(publicCollection.filter.byProperty("weight").greaterOrEqual(args.min_weight));
4010
4094
  }
4011
4095
  if (args.max_weight !== void 0) {
4012
- filterList.push(spaceCollection.filter.byProperty("weight").lessOrEqual(args.max_weight));
4096
+ filterList.push(publicCollection.filter.byProperty("weight").lessOrEqual(args.max_weight));
4013
4097
  }
4014
4098
  if (args.date_from) {
4015
- filterList.push(spaceCollection.filter.byProperty("created_at").greaterOrEqual(new Date(args.date_from)));
4099
+ filterList.push(publicCollection.filter.byProperty("created_at").greaterOrEqual(new Date(args.date_from)));
4016
4100
  }
4017
4101
  if (args.date_to) {
4018
- filterList.push(spaceCollection.filter.byProperty("created_at").lessOrEqual(new Date(args.date_to)));
4102
+ filterList.push(publicCollection.filter.byProperty("created_at").lessOrEqual(new Date(args.date_to)));
4019
4103
  }
4020
4104
  const whereFilter = filterList.length > 0 ? Filters3.and(...filterList) : void 0;
4021
- const searchResults = await spaceCollection.query.hybrid(args.query, {
4105
+ const searchResults = await publicCollection.query.hybrid(args.query, {
4022
4106
  limit: args.limit || 10,
4023
4107
  offset: args.offset || 0,
4024
4108
  ...whereFilter && { where: whereFilter }
@@ -4029,7 +4113,7 @@ async function handleSearchSpace(args, userId) {
4029
4113
  _score: obj.metadata?.score
4030
4114
  }));
4031
4115
  const result = {
4032
- space: args.space,
4116
+ spaces_searched: args.spaces,
4033
4117
  query: args.query,
4034
4118
  memories,
4035
4119
  total: memories.length,
@@ -4038,10 +4122,10 @@ async function handleSearchSpace(args, userId) {
4038
4122
  };
4039
4123
  return JSON.stringify(result, null, 2);
4040
4124
  } catch (error) {
4041
- handleToolError(error, {
4125
+ return handleToolError(error, {
4042
4126
  toolName: "remember_search_space",
4043
- operation: "search space",
4044
- space: args.space,
4127
+ operation: "search spaces",
4128
+ spaces: args.spaces,
4045
4129
  query: args.query
4046
4130
  });
4047
4131
  }
@@ -4101,46 +4185,58 @@ var querySpaceTool = {
4101
4185
  description: "Output format: detailed (full objects) or compact (text summary)"
4102
4186
  }
4103
4187
  },
4104
- required: ["question", "space"]
4188
+ required: ["question", "spaces"]
4105
4189
  }
4106
4190
  };
4107
4191
  async function handleQuerySpace(args, userId) {
4108
4192
  try {
4109
- if (!isValidSpaceId(args.space)) {
4193
+ const invalidSpaces = args.spaces.filter((s) => !isValidSpaceId(s));
4194
+ if (invalidSpaces.length > 0) {
4110
4195
  return JSON.stringify(
4111
4196
  {
4112
4197
  success: false,
4113
- error: "Invalid space ID",
4114
- message: `Space "${args.space}" is not supported. Supported spaces: ${SUPPORTED_SPACES.join(", ")}`
4198
+ error: "Invalid space IDs",
4199
+ message: `Invalid spaces: ${invalidSpaces.join(", ")}. Supported spaces: ${SUPPORTED_SPACES.join(", ")}`
4200
+ },
4201
+ null,
4202
+ 2
4203
+ );
4204
+ }
4205
+ if (args.spaces.length === 0) {
4206
+ return JSON.stringify(
4207
+ {
4208
+ success: false,
4209
+ error: "Empty spaces array",
4210
+ message: "Must specify at least one space to query"
4115
4211
  },
4116
4212
  null,
4117
4213
  2
4118
4214
  );
4119
4215
  }
4120
4216
  const weaviateClient = getWeaviateClient();
4121
- const spaceCollection = await ensureSpaceCollection(weaviateClient, args.space);
4217
+ const publicCollection = await ensurePublicCollection(weaviateClient);
4122
4218
  const filterList = [];
4123
- filterList.push(spaceCollection.filter.byProperty("space_id").equal(args.space));
4124
- filterList.push(spaceCollection.filter.byProperty("doc_type").equal("space_memory"));
4219
+ filterList.push(publicCollection.filter.byProperty("spaces").containsAny(args.spaces));
4220
+ filterList.push(publicCollection.filter.byProperty("doc_type").equal("space_memory"));
4125
4221
  if (args.content_type) {
4126
- filterList.push(spaceCollection.filter.byProperty("type").equal(args.content_type));
4222
+ filterList.push(publicCollection.filter.byProperty("type").equal(args.content_type));
4127
4223
  }
4128
4224
  if (args.tags && args.tags.length > 0) {
4129
4225
  args.tags.forEach((tag) => {
4130
- filterList.push(spaceCollection.filter.byProperty("tags").containsAny([tag]));
4226
+ filterList.push(publicCollection.filter.byProperty("tags").containsAny([tag]));
4131
4227
  });
4132
4228
  }
4133
4229
  if (args.min_weight !== void 0) {
4134
- filterList.push(spaceCollection.filter.byProperty("weight").greaterOrEqual(args.min_weight));
4230
+ filterList.push(publicCollection.filter.byProperty("weight").greaterOrEqual(args.min_weight));
4135
4231
  }
4136
4232
  if (args.date_from) {
4137
- filterList.push(spaceCollection.filter.byProperty("created_at").greaterOrEqual(new Date(args.date_from)));
4233
+ filterList.push(publicCollection.filter.byProperty("created_at").greaterOrEqual(new Date(args.date_from)));
4138
4234
  }
4139
4235
  if (args.date_to) {
4140
- filterList.push(spaceCollection.filter.byProperty("created_at").lessOrEqual(new Date(args.date_to)));
4236
+ filterList.push(publicCollection.filter.byProperty("created_at").lessOrEqual(new Date(args.date_to)));
4141
4237
  }
4142
4238
  const whereFilter = filterList.length > 0 ? Filters4.and(...filterList) : void 0;
4143
- const searchResults = await spaceCollection.query.nearText(args.question, {
4239
+ const searchResults = await publicCollection.query.nearText(args.question, {
4144
4240
  limit: args.limit || 10,
4145
4241
  ...whereFilter && { where: whereFilter }
4146
4242
  });
@@ -4152,7 +4248,7 @@ async function handleQuerySpace(args, userId) {
4152
4248
  });
4153
4249
  const result = {
4154
4250
  question: args.question,
4155
- space: args.space,
4251
+ spaces_queried: args.spaces,
4156
4252
  format: "compact",
4157
4253
  summary: summaries.join("\n"),
4158
4254
  count: searchResults.objects.length
@@ -4166,7 +4262,7 @@ async function handleQuerySpace(args, userId) {
4166
4262
  }));
4167
4263
  const result = {
4168
4264
  question: args.question,
4169
- space: args.space,
4265
+ spaces_queried: args.spaces,
4170
4266
  format: "detailed",
4171
4267
  memories,
4172
4268
  total: memories.length
@@ -4174,10 +4270,10 @@ async function handleQuerySpace(args, userId) {
4174
4270
  return JSON.stringify(result, null, 2);
4175
4271
  }
4176
4272
  } catch (error) {
4177
- handleToolError(error, {
4273
+ return handleToolError(error, {
4178
4274
  toolName: "remember_query_space",
4179
- operation: "query space",
4180
- space: args.space,
4275
+ operation: "query spaces",
4276
+ spaces: args.spaces,
4181
4277
  question: args.question
4182
4278
  });
4183
4279
  }