@prmichaelsen/remember-mcp 2.2.1 → 2.3.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 (69) hide show
  1. package/AGENT.md +98 -5
  2. package/CHANGELOG.md +45 -0
  3. package/README.md +43 -3
  4. package/agent/commands/acp.init.md +376 -0
  5. package/agent/commands/acp.package-install.md +347 -0
  6. package/agent/commands/acp.proceed.md +311 -0
  7. package/agent/commands/acp.report.md +392 -0
  8. package/agent/commands/acp.status.md +280 -0
  9. package/agent/commands/acp.sync.md +323 -0
  10. package/agent/commands/acp.update.md +301 -0
  11. package/agent/commands/acp.validate.md +385 -0
  12. package/agent/commands/acp.version-check-for-updates.md +275 -0
  13. package/agent/commands/acp.version-check.md +190 -0
  14. package/agent/commands/acp.version-update.md +288 -0
  15. package/agent/commands/command.template.md +273 -0
  16. package/agent/design/core-memory-user-profile.md +1253 -0
  17. package/agent/design/ghost-profiles-pseudonymous-identity.md +194 -0
  18. package/agent/design/publish-tools-confirmation-flow.md +922 -0
  19. package/agent/milestones/milestone-10-shared-spaces.md +169 -0
  20. package/agent/progress.yaml +90 -4
  21. package/agent/scripts/install.sh +118 -0
  22. package/agent/scripts/update.sh +22 -10
  23. package/agent/scripts/version.sh +35 -0
  24. package/agent/tasks/task-27-implement-llm-provider-interface.md +51 -0
  25. package/agent/tasks/task-28-implement-llm-provider-factory.md +64 -0
  26. package/agent/tasks/task-29-update-config-for-llm.md +71 -0
  27. package/agent/tasks/task-30-implement-bedrock-provider.md +147 -0
  28. package/agent/tasks/task-31-implement-background-job-service.md +120 -0
  29. package/agent/tasks/task-32-test-llm-provider-integration.md +152 -0
  30. package/agent/tasks/task-34-create-confirmation-token-service.md +191 -0
  31. package/agent/tasks/task-35-create-space-memory-types-schema.md +183 -0
  32. package/agent/tasks/task-36-implement-remember-publish.md +227 -0
  33. package/agent/tasks/task-37-implement-remember-confirm.md +225 -0
  34. package/agent/tasks/task-38-implement-remember-deny.md +161 -0
  35. package/agent/tasks/task-39-implement-remember-search-space.md +188 -0
  36. package/agent/tasks/task-40-implement-remember-query-space.md +193 -0
  37. package/agent/tasks/task-41-configure-firestore-ttl.md +188 -0
  38. package/agent/tasks/task-42-create-tests-shared-spaces.md +216 -0
  39. package/agent/tasks/task-43-update-documentation.md +255 -0
  40. package/agent/tasks/task-44-implement-remember-retract.md +263 -0
  41. package/agent/tasks/task-45-fix-publish-false-success-bug.md +230 -0
  42. package/dist/llm/types.d.ts +1 -0
  43. package/dist/server-factory.js +1000 -1
  44. package/dist/server.js +1002 -3
  45. package/dist/services/confirmation-token.service.d.ts +99 -0
  46. package/dist/services/confirmation-token.service.spec.d.ts +5 -0
  47. package/dist/tools/confirm.d.ts +20 -0
  48. package/dist/tools/deny.d.ts +19 -0
  49. package/dist/tools/publish.d.ts +22 -0
  50. package/dist/tools/query-space.d.ts +28 -0
  51. package/dist/tools/search-space.d.ts +29 -0
  52. package/dist/types/space-memory.d.ts +80 -0
  53. package/dist/weaviate/space-schema.d.ts +59 -0
  54. package/dist/weaviate/space-schema.spec.d.ts +5 -0
  55. package/package.json +1 -1
  56. package/src/llm/types.ts +0 -0
  57. package/src/server-factory.ts +33 -0
  58. package/src/server.ts +33 -0
  59. package/src/services/confirmation-token.service.spec.ts +254 -0
  60. package/src/services/confirmation-token.service.ts +265 -0
  61. package/src/tools/confirm.ts +219 -0
  62. package/src/tools/create-memory.ts +7 -0
  63. package/src/tools/deny.ts +70 -0
  64. package/src/tools/publish.ts +190 -0
  65. package/src/tools/query-space.ts +197 -0
  66. package/src/tools/search-space.ts +189 -0
  67. package/src/types/space-memory.ts +94 -0
  68. package/src/weaviate/space-schema.spec.ts +131 -0
  69. package/src/weaviate/space-schema.ts +275 -0
@@ -0,0 +1,219 @@
1
+ /**
2
+ * remember_confirm tool
3
+ *
4
+ * Generic confirmation tool that executes any pending action.
5
+ * This is the second phase of the confirmation workflow.
6
+ */
7
+
8
+ import type { Tool } from '@modelcontextprotocol/sdk/types.js';
9
+ import { confirmationTokenService, type ConfirmationRequest } from '../services/confirmation-token.service.js';
10
+ import { getWeaviateClient, getMemoryCollectionName } from '../weaviate/client.js';
11
+ import { ensureSpaceCollection } from '../weaviate/space-schema.js';
12
+ import { handleToolError } from '../utils/error-handler.js';
13
+
14
+ /**
15
+ * Tool definition for remember_confirm
16
+ */
17
+ export const confirmTool: Tool = {
18
+ name: 'remember_confirm',
19
+ description: 'Confirm and execute a pending action using the token. Works for any action that requires confirmation (publish, delete, etc.).',
20
+ inputSchema: {
21
+ type: 'object',
22
+ properties: {
23
+ token: {
24
+ type: 'string',
25
+ description: 'The confirmation token from the action tool',
26
+ },
27
+ },
28
+ required: ['token'],
29
+ },
30
+ };
31
+
32
+ interface ConfirmArgs {
33
+ token: string;
34
+ }
35
+
36
+ /**
37
+ * Handle remember_confirm tool execution
38
+ */
39
+ export async function handleConfirm(
40
+ args: ConfirmArgs,
41
+ userId: string
42
+ ): Promise<string> {
43
+ try {
44
+ console.log('[remember_confirm] Starting confirmation:', {
45
+ userId,
46
+ token: args.token,
47
+ });
48
+
49
+ // Validate and confirm token
50
+ const request = await confirmationTokenService.confirmRequest(userId, args.token);
51
+
52
+ console.log('[remember_confirm] Token validation result:', {
53
+ requestFound: !!request,
54
+ action: request?.action,
55
+ });
56
+
57
+ if (!request) {
58
+ console.log('[remember_confirm] Token invalid or expired');
59
+ return JSON.stringify(
60
+ {
61
+ success: false,
62
+ error: 'Invalid or expired token',
63
+ message: 'The confirmation token is invalid, expired, or has already been used.',
64
+ },
65
+ null,
66
+ 2
67
+ );
68
+ }
69
+
70
+ console.log('[remember_confirm] Executing action:', request.action);
71
+
72
+ // GENERIC: Execute action based on type
73
+ // This is where the generic pattern delegates to action-specific executors
74
+ if (request.action === 'publish_memory') {
75
+ return await executePublishMemory(request, userId);
76
+ }
77
+
78
+ // Add other action types here as needed
79
+ // if (request.action === 'retract_memory') {
80
+ // return await executeRetractMemory(request, userId);
81
+ // }
82
+
83
+ throw new Error(`Unknown action type: ${request.action}`);
84
+ } catch (error) {
85
+ handleToolError(error, {
86
+ toolName: 'remember_confirm',
87
+ userId,
88
+ operation: 'confirm action',
89
+ token: args.token,
90
+ });
91
+ }
92
+ }
93
+
94
+ /**
95
+ * Execute publish memory action
96
+ */
97
+ async function executePublishMemory(
98
+ request: ConfirmationRequest & { request_id: string },
99
+ userId: string
100
+ ): Promise<string> {
101
+ try {
102
+ console.log('[executePublishMemory] Starting execution:', {
103
+ userId,
104
+ memoryId: request.payload.memory_id,
105
+ targetSpace: request.target_collection,
106
+ });
107
+
108
+ // Fetch the memory NOW (during confirmation, not from stored payload)
109
+ const weaviateClient = getWeaviateClient();
110
+ const userCollection = weaviateClient.collections.get(
111
+ getMemoryCollectionName(userId)
112
+ );
113
+
114
+ console.log('[executePublishMemory] Fetching original memory from:', getMemoryCollectionName(userId));
115
+
116
+ const originalMemory = await userCollection.query.fetchObjectById(
117
+ request.payload.memory_id
118
+ );
119
+
120
+ console.log('[executePublishMemory] Original memory fetch result:', {
121
+ found: !!originalMemory,
122
+ memoryId: request.payload.memory_id,
123
+ });
124
+
125
+ if (!originalMemory) {
126
+ console.log('[executePublishMemory] Memory not found');
127
+ return JSON.stringify(
128
+ {
129
+ success: false,
130
+ error: 'Memory not found',
131
+ message: `Original memory ${request.payload.memory_id} no longer exists`,
132
+ },
133
+ null,
134
+ 2
135
+ );
136
+ }
137
+
138
+ // Verify ownership again
139
+ if (originalMemory.properties.user_id !== userId) {
140
+ console.log('[executePublishMemory] Permission denied - wrong owner');
141
+ return JSON.stringify(
142
+ {
143
+ success: false,
144
+ error: 'Permission denied',
145
+ message: 'You can only publish your own memories',
146
+ },
147
+ null,
148
+ 2
149
+ );
150
+ }
151
+
152
+ console.log('[executePublishMemory] Ensuring space collection:', request.target_collection || 'the_void');
153
+
154
+ // Get target collection
155
+ const targetCollection = await ensureSpaceCollection(
156
+ weaviateClient,
157
+ request.target_collection || 'the_void'
158
+ );
159
+
160
+ console.log('[executePublishMemory] Space collection ready');
161
+
162
+ // Create published memory (copy with modifications)
163
+ const originalTags = Array.isArray(originalMemory.properties.tags)
164
+ ? originalMemory.properties.tags
165
+ : [];
166
+ const additionalTags = Array.isArray(request.payload.additional_tags)
167
+ ? request.payload.additional_tags
168
+ : [];
169
+
170
+ const publishedMemory = {
171
+ ...originalMemory.properties,
172
+ // Override specific fields
173
+ space_id: request.target_collection || 'the_void',
174
+ author_id: userId, // Always attributed
175
+ published_at: new Date().toISOString(),
176
+ discovery_count: 0,
177
+ doc_type: 'space_memory',
178
+ attribution: 'user' as const,
179
+ // Merge additional tags
180
+ tags: [...originalTags, ...additionalTags],
181
+ // Update timestamps
182
+ created_at: new Date().toISOString(),
183
+ updated_at: new Date().toISOString(),
184
+ version: 1,
185
+ };
186
+
187
+ console.log('[executePublishMemory] Inserting into space collection:', {
188
+ spaceId: request.target_collection || 'the_void',
189
+ memoryId: request.payload.memory_id,
190
+ hasProperties: !!publishedMemory,
191
+ });
192
+
193
+ const result = await targetCollection.data.insert({
194
+ properties: publishedMemory as any,
195
+ });
196
+
197
+ console.log('[executePublishMemory] Insert result:', {
198
+ success: !!result,
199
+ spaceMemoryId: result,
200
+ });
201
+
202
+ // Return minimal response - agent already knows original memory
203
+ return JSON.stringify(
204
+ {
205
+ success: true,
206
+ space_memory_id: result,
207
+ },
208
+ null,
209
+ 2
210
+ );
211
+ } catch (error) {
212
+ handleToolError(error, {
213
+ toolName: 'remember_confirm',
214
+ userId,
215
+ operation: 'execute publish_memory',
216
+ action: 'publish_memory',
217
+ });
218
+ }
219
+ }
@@ -20,6 +20,13 @@ export const createMemoryTool = {
20
20
  Each memory has a weight (significance 0-1) and trust level (access control 0-1).
21
21
  Location and context are automatically captured from the request.
22
22
 
23
+ **IMPORTANT - Content vs Summary**:
24
+ - **content**: MUST be EXACT user-provided text. DO NOT paraphrase or modify.
25
+ - **summary**: Use for AI-generated summaries or interpretations.
26
+ - Example: User says "Remember: Meeting at 3pm tomorrow"
27
+ → content: "Meeting at 3pm tomorrow" (EXACT)
28
+ → summary: "User has meeting on 2026-02-17 at 15:00" (AI interpretation)
29
+
23
30
  Examples:
24
31
  - "Remember that I met Sarah at the conference"
25
32
  - "Save this recipe for chocolate chip cookies"
@@ -0,0 +1,70 @@
1
+ /**
2
+ * remember_deny tool
3
+ *
4
+ * Generic denial tool for any pending action.
5
+ */
6
+
7
+ import type { Tool } from '@modelcontextprotocol/sdk/types.js';
8
+ import { confirmationTokenService } from '../services/confirmation-token.service.js';
9
+ import { handleToolError } from '../utils/error-handler.js';
10
+
11
+ /**
12
+ * Tool definition for remember_deny
13
+ */
14
+ export const denyTool: Tool = {
15
+ name: 'remember_deny',
16
+ description: 'Deny a pending action. The request will be marked as denied and the token invalidated. Works for any action that requires confirmation.',
17
+ inputSchema: {
18
+ type: 'object',
19
+ properties: {
20
+ token: {
21
+ type: 'string',
22
+ description: 'The confirmation token from the action tool',
23
+ },
24
+ },
25
+ required: ['token'],
26
+ },
27
+ };
28
+
29
+ interface DenyArgs {
30
+ token: string;
31
+ }
32
+
33
+ /**
34
+ * Handle remember_deny tool execution
35
+ */
36
+ export async function handleDeny(
37
+ args: DenyArgs,
38
+ userId: string
39
+ ): Promise<string> {
40
+ try {
41
+ const success = await confirmationTokenService.denyRequest(userId, args.token);
42
+
43
+ if (!success) {
44
+ return JSON.stringify(
45
+ {
46
+ success: false,
47
+ error: 'Invalid token',
48
+ message: 'Token not found or already used',
49
+ },
50
+ null,
51
+ 2
52
+ );
53
+ }
54
+
55
+ return JSON.stringify(
56
+ {
57
+ success: true,
58
+ },
59
+ null,
60
+ 2
61
+ );
62
+ } catch (error) {
63
+ handleToolError(error, {
64
+ toolName: 'remember_deny',
65
+ userId,
66
+ operation: 'deny action',
67
+ token: args.token,
68
+ });
69
+ }
70
+ }
@@ -0,0 +1,190 @@
1
+ /**
2
+ * remember_publish tool
3
+ *
4
+ * Generates a confirmation token for publishing a memory to a shared space.
5
+ * This is the first phase of the two-phase publish workflow.
6
+ */
7
+
8
+ import type { Tool } from '@modelcontextprotocol/sdk/types.js';
9
+ import { confirmationTokenService } from '../services/confirmation-token.service.js';
10
+ import { getWeaviateClient, getMemoryCollectionName } from '../weaviate/client.js';
11
+ import { isValidSpaceId } from '../weaviate/space-schema.js';
12
+ import { handleToolError } from '../utils/error-handler.js';
13
+ import { SUPPORTED_SPACES } from '../types/space-memory.js';
14
+
15
+ /**
16
+ * Tool definition for remember_publish
17
+ */
18
+ export const publishTool: Tool = {
19
+ name: 'remember_publish',
20
+ 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.',
21
+ inputSchema: {
22
+ type: 'object',
23
+ properties: {
24
+ memory_id: {
25
+ type: 'string',
26
+ description: 'ID of the memory from your personal collection to publish',
27
+ },
28
+ target: {
29
+ type: 'string',
30
+ description: 'Target space to publish to (snake_case ID)',
31
+ enum: SUPPORTED_SPACES,
32
+ default: 'the_void',
33
+ },
34
+ additional_tags: {
35
+ type: 'array',
36
+ items: { type: 'string' },
37
+ description: 'Additional tags for discovery (merged with original tags)',
38
+ default: [],
39
+ },
40
+ },
41
+ required: ['memory_id', 'target'],
42
+ },
43
+ };
44
+
45
+ interface PublishArgs {
46
+ memory_id: string;
47
+ target: string;
48
+ additional_tags?: string[];
49
+ }
50
+
51
+ /**
52
+ * Handle remember_publish tool execution
53
+ */
54
+ export async function handlePublish(
55
+ args: PublishArgs,
56
+ userId: string
57
+ ): Promise<string> {
58
+ try {
59
+ console.log('[remember_publish] Starting publish request:', {
60
+ userId,
61
+ memoryId: args.memory_id,
62
+ target: args.target,
63
+ additionalTags: args.additional_tags?.length || 0,
64
+ });
65
+
66
+ // Validate space ID
67
+ if (!isValidSpaceId(args.target)) {
68
+ console.log('[remember_publish] Invalid space ID:', args.target);
69
+ return JSON.stringify(
70
+ {
71
+ success: false,
72
+ error: 'Invalid space ID',
73
+ message: `Space "${args.target}" is not supported. Supported spaces: ${SUPPORTED_SPACES.join(', ')}`,
74
+ context: {
75
+ provided_space: args.target,
76
+ supported_spaces: SUPPORTED_SPACES,
77
+ },
78
+ },
79
+ null,
80
+ 2
81
+ );
82
+ }
83
+
84
+ // Verify memory exists and user owns it
85
+ const weaviateClient = getWeaviateClient();
86
+ const collectionName = getMemoryCollectionName(userId);
87
+ console.log('[remember_publish] Fetching memory from collection:', collectionName);
88
+
89
+ const userCollection = weaviateClient.collections.get(collectionName);
90
+
91
+ const memory = await userCollection.query.fetchObjectById(args.memory_id);
92
+
93
+ console.log('[remember_publish] Memory fetch result:', {
94
+ found: !!memory,
95
+ memoryId: args.memory_id,
96
+ });
97
+
98
+ if (!memory) {
99
+ console.log('[remember_publish] Memory not found');
100
+ return JSON.stringify(
101
+ {
102
+ success: false,
103
+ error: 'Memory not found',
104
+ message: `No memory found with ID: ${args.memory_id}`,
105
+ context: {
106
+ collection_name: getMemoryCollectionName(userId),
107
+ memory_id: args.memory_id,
108
+ },
109
+ },
110
+ null,
111
+ 2
112
+ );
113
+ }
114
+
115
+ // Verify ownership
116
+ if (memory.properties.user_id !== userId) {
117
+ return JSON.stringify(
118
+ {
119
+ success: false,
120
+ error: 'Permission denied',
121
+ message: 'You can only publish your own memories',
122
+ context: {
123
+ memory_id: args.memory_id,
124
+ memory_owner: memory.properties.user_id,
125
+ requesting_user: userId,
126
+ },
127
+ },
128
+ null,
129
+ 2
130
+ );
131
+ }
132
+
133
+ // Verify it's a memory (not a relationship)
134
+ if (memory.properties.doc_type !== 'memory') {
135
+ return JSON.stringify(
136
+ {
137
+ success: false,
138
+ error: 'Invalid document type',
139
+ message: 'Only memories can be published (not relationships)',
140
+ context: {
141
+ memory_id: args.memory_id,
142
+ doc_type: memory.properties.doc_type,
143
+ },
144
+ },
145
+ null,
146
+ 2
147
+ );
148
+ }
149
+
150
+ // Create payload with only memory_id (content fetched during confirmation)
151
+ const payload = {
152
+ memory_id: args.memory_id,
153
+ additional_tags: args.additional_tags || [],
154
+ };
155
+
156
+ console.log('[remember_publish] Generating confirmation token');
157
+
158
+ // Generate confirmation token
159
+ const { requestId, token } = await confirmationTokenService.createRequest(
160
+ userId,
161
+ 'publish_memory',
162
+ payload,
163
+ args.target
164
+ );
165
+
166
+ console.log('[remember_publish] Token generated:', {
167
+ requestId,
168
+ token,
169
+ action: 'publish_memory',
170
+ });
171
+
172
+ // Return minimal response - agent already knows memory details
173
+ return JSON.stringify(
174
+ {
175
+ success: true,
176
+ token,
177
+ },
178
+ null,
179
+ 2
180
+ );
181
+ } catch (error) {
182
+ handleToolError(error, {
183
+ toolName: 'remember_publish',
184
+ userId,
185
+ operation: 'publish memory',
186
+ memory_id: args.memory_id,
187
+ target: args.target,
188
+ });
189
+ }
190
+ }
@@ -0,0 +1,197 @@
1
+ /**
2
+ * remember_query_space tool
3
+ *
4
+ * RAG-optimized natural language queries for shared spaces.
5
+ * Similar to remember_query_memory but queries space collections.
6
+ */
7
+
8
+ import type { Tool } from '@modelcontextprotocol/sdk/types.js';
9
+ import { Filters } from 'weaviate-client';
10
+ import { getWeaviateClient } from '../weaviate/client.js';
11
+ import { ensureSpaceCollection, isValidSpaceId } from '../weaviate/space-schema.js';
12
+ import { SUPPORTED_SPACES } from '../types/space-memory.js';
13
+ import { handleToolError } from '../utils/error-handler.js';
14
+
15
+ /**
16
+ * Tool definition for remember_query_space
17
+ */
18
+ export const querySpaceTool: Tool = {
19
+ name: 'remember_query_space',
20
+ description: 'Ask natural language questions about memories in shared spaces. Works like remember_query_memory but queries shared spaces.',
21
+ inputSchema: {
22
+ type: 'object',
23
+ properties: {
24
+ question: {
25
+ type: 'string',
26
+ description: 'Natural language question',
27
+ },
28
+ space: {
29
+ type: 'string',
30
+ description: 'Which space to query',
31
+ enum: SUPPORTED_SPACES,
32
+ default: 'the_void',
33
+ },
34
+ content_type: {
35
+ type: 'string',
36
+ description: 'Filter by content type',
37
+ },
38
+ tags: {
39
+ type: 'array',
40
+ items: { type: 'string' },
41
+ description: 'Filter by tags',
42
+ },
43
+ min_weight: {
44
+ type: 'number',
45
+ minimum: 0,
46
+ maximum: 1,
47
+ description: 'Minimum weight/significance (0-1)',
48
+ },
49
+ date_from: {
50
+ type: 'string',
51
+ description: 'Filter memories created after this date (ISO 8601)',
52
+ },
53
+ date_to: {
54
+ type: 'string',
55
+ description: 'Filter memories created before this date (ISO 8601)',
56
+ },
57
+ limit: {
58
+ type: 'number',
59
+ default: 10,
60
+ description: 'Maximum number of results',
61
+ },
62
+ format: {
63
+ type: 'string',
64
+ enum: ['detailed', 'compact'],
65
+ default: 'detailed',
66
+ description: 'Output format: detailed (full objects) or compact (text summary)',
67
+ },
68
+ },
69
+ required: ['question', 'space'],
70
+ },
71
+ };
72
+
73
+ interface QuerySpaceArgs {
74
+ question: string;
75
+ space: string;
76
+ content_type?: string;
77
+ tags?: string[];
78
+ min_weight?: number;
79
+ date_from?: string;
80
+ date_to?: string;
81
+ limit?: number;
82
+ format?: 'detailed' | 'compact';
83
+ }
84
+
85
+ /**
86
+ * Handle remember_query_space tool execution
87
+ */
88
+ export async function handleQuerySpace(
89
+ args: QuerySpaceArgs,
90
+ userId: string // May be used for private spaces in future
91
+ ): Promise<string> {
92
+ try {
93
+ // Validate space ID
94
+ if (!isValidSpaceId(args.space)) {
95
+ return JSON.stringify(
96
+ {
97
+ success: false,
98
+ error: 'Invalid space ID',
99
+ message: `Space "${args.space}" is not supported. Supported spaces: ${SUPPORTED_SPACES.join(', ')}`,
100
+ },
101
+ null,
102
+ 2
103
+ );
104
+ }
105
+
106
+ const weaviateClient = getWeaviateClient();
107
+ const spaceCollection = await ensureSpaceCollection(weaviateClient, args.space);
108
+
109
+ // Build filters
110
+ const filterList: any[] = [];
111
+
112
+ // Filter by space_id
113
+ filterList.push(spaceCollection.filter.byProperty('space_id').equal(args.space));
114
+
115
+ // Filter by doc_type (space_memory)
116
+ filterList.push(spaceCollection.filter.byProperty('doc_type').equal('space_memory'));
117
+
118
+ // Apply content type filter
119
+ if (args.content_type) {
120
+ filterList.push(spaceCollection.filter.byProperty('type').equal(args.content_type));
121
+ }
122
+
123
+ // Apply tags filter
124
+ if (args.tags && args.tags.length > 0) {
125
+ args.tags.forEach(tag => {
126
+ filterList.push(spaceCollection.filter.byProperty('tags').containsAny([tag]));
127
+ });
128
+ }
129
+
130
+ // Apply weight filter
131
+ if (args.min_weight !== undefined) {
132
+ filterList.push(spaceCollection.filter.byProperty('weight').greaterOrEqual(args.min_weight));
133
+ }
134
+
135
+ // Apply date filters
136
+ if (args.date_from) {
137
+ filterList.push(spaceCollection.filter.byProperty('created_at').greaterOrEqual(new Date(args.date_from)));
138
+ }
139
+
140
+ if (args.date_to) {
141
+ filterList.push(spaceCollection.filter.byProperty('created_at').lessOrEqual(new Date(args.date_to)));
142
+ }
143
+
144
+ const whereFilter = filterList.length > 0 ? Filters.and(...filterList) : undefined;
145
+
146
+ // Execute semantic search using nearText
147
+ const searchResults = await spaceCollection.query.nearText(args.question, {
148
+ limit: args.limit || 10,
149
+ ...(whereFilter && { where: whereFilter }),
150
+ });
151
+
152
+ // Format results based on requested format
153
+ const format = args.format || 'detailed';
154
+
155
+ if (format === 'compact') {
156
+ // Compact format: text summary for LLM context
157
+ const summaries = searchResults.objects.map((obj, idx) => {
158
+ const props = obj.properties;
159
+ return `${idx + 1}. ${props.title || props.content?.substring(0, 100) || 'Untitled'}`;
160
+ });
161
+
162
+ const result = {
163
+ question: args.question,
164
+ space: args.space,
165
+ format: 'compact',
166
+ summary: summaries.join('\n'),
167
+ count: searchResults.objects.length,
168
+ };
169
+
170
+ return JSON.stringify(result, null, 2);
171
+ } else {
172
+ // Detailed format: full objects
173
+ const memories = searchResults.objects.map((obj) => ({
174
+ id: obj.uuid,
175
+ ...obj.properties,
176
+ _distance: obj.metadata?.distance,
177
+ }));
178
+
179
+ const result = {
180
+ question: args.question,
181
+ space: args.space,
182
+ format: 'detailed',
183
+ memories,
184
+ total: memories.length,
185
+ };
186
+
187
+ return JSON.stringify(result, null, 2);
188
+ }
189
+ } catch (error) {
190
+ handleToolError(error, {
191
+ toolName: 'remember_query_space',
192
+ operation: 'query space',
193
+ space: args.space,
194
+ question: args.question,
195
+ });
196
+ }
197
+ }