@prmichaelsen/remember-mcp 2.6.2 → 2.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +34 -0
- package/agent/progress.yaml +163 -13
- package/agent/tasks/task-62-fix-confirmation-response-storage.md +323 -0
- package/agent/tasks/task-63-fix-fetchobjectbyid-missing-properties.md +397 -0
- package/dist/server-factory.js +41 -4
- package/dist/server.js +41 -4
- package/dist/weaviate/client.d.ts +16 -0
- package/package.json +1 -1
- package/src/tools/confirm.ts +7 -2
- package/src/tools/publish.ts +6 -2
- package/src/weaviate/client.ts +47 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,40 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [2.6.3] - 2026-02-16
|
|
9
|
+
|
|
10
|
+
### 🐛 Fixed
|
|
11
|
+
|
|
12
|
+
- **CRITICAL: Fixed Empty Published Memories Bug**
|
|
13
|
+
- Published memories were empty shells with no content, title, or properties
|
|
14
|
+
- Root cause: `fetchObjectById()` calls missing `returnProperties` parameter
|
|
15
|
+
- Fixed in `remember_publish` and `remember_confirm` (executePublishMemory)
|
|
16
|
+
- All published memories now include complete property data
|
|
17
|
+
|
|
18
|
+
### ✨ Added
|
|
19
|
+
|
|
20
|
+
- **New Utility Function**: `fetchMemoryWithAllProperties()`
|
|
21
|
+
- Centralized helper in `src/weaviate/client.ts`
|
|
22
|
+
- Ensures all memory properties are fetched consistently
|
|
23
|
+
- Prevents future bugs from missing properties
|
|
24
|
+
- Includes `ALL_MEMORY_PROPERTIES` constant (20+ properties)
|
|
25
|
+
|
|
26
|
+
### 🔧 Improved
|
|
27
|
+
|
|
28
|
+
- Enhanced debug logging in publish flow
|
|
29
|
+
- Added property count verification
|
|
30
|
+
- Added hasTitle and hasContent checks
|
|
31
|
+
- Better diagnostics for troubleshooting
|
|
32
|
+
|
|
33
|
+
### 🎯 Impact
|
|
34
|
+
|
|
35
|
+
- **Fixes**: All published memories since v2.4.0 were empty
|
|
36
|
+
- **Search**: Published memories now searchable (have content)
|
|
37
|
+
- **Discovery**: Space functionality now works as designed
|
|
38
|
+
- **Note**: Existing empty memories need to be re-published
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
8
42
|
## [2.6.2] - 2026-02-16
|
|
9
43
|
|
|
10
44
|
### 🔒 Security
|
package/agent/progress.yaml
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
project:
|
|
4
4
|
name: remember-mcp
|
|
5
|
-
version: 2.
|
|
5
|
+
version: 2.6.3
|
|
6
6
|
started: 2026-02-11
|
|
7
7
|
status: in_progress
|
|
8
|
-
current_milestone:
|
|
8
|
+
current_milestone: M12
|
|
9
9
|
last_updated: 2026-02-16
|
|
10
10
|
|
|
11
11
|
milestones:
|
|
@@ -162,7 +162,26 @@ milestones:
|
|
|
162
162
|
✅ No memory duplication across spaces
|
|
163
163
|
✅ All tests passing with multi-space support
|
|
164
164
|
✅ Documentation updated with multi-space examples
|
|
165
|
-
|
|
165
|
+
|
|
166
|
+
- id: M12
|
|
167
|
+
name: Comment System (Phase 1)
|
|
168
|
+
status: in_progress
|
|
169
|
+
progress: 60%
|
|
170
|
+
started: 2026-02-16
|
|
171
|
+
completed: null
|
|
172
|
+
estimated_weeks: 1
|
|
173
|
+
tasks_completed: 3
|
|
174
|
+
tasks_total: 5
|
|
175
|
+
notes: |
|
|
176
|
+
✅ Task 55: Added 3 comment fields to schema (parent_id, thread_root_id, moderation_flags)
|
|
177
|
+
✅ Task 56: Updated remember_search_space with include_comments parameter
|
|
178
|
+
✅ Task 57: Updated remember_query_space with include_comments parameter
|
|
179
|
+
📋 Task 58: Add Comment Unit Tests (pending)
|
|
180
|
+
📋 Task 59: Update Documentation for Comments (pending)
|
|
181
|
+
✅ Zero new tools required - reuses existing infrastructure
|
|
182
|
+
✅ Backward compatible - comments excluded by default
|
|
183
|
+
✅ Released v2.6.0 with comment system foundation
|
|
184
|
+
|
|
166
185
|
- id: M7
|
|
167
186
|
name: Trust & Permissions
|
|
168
187
|
status: not_started
|
|
@@ -406,11 +425,97 @@ tasks:
|
|
|
406
425
|
✅ Context inclusion toggle
|
|
407
426
|
✅ Integrated into server.ts and server-factory.ts
|
|
408
427
|
|
|
428
|
+
milestone_12:
|
|
429
|
+
- id: task-55
|
|
430
|
+
name: Add Comment Fields to Weaviate Schema
|
|
431
|
+
status: completed
|
|
432
|
+
file: agent/tasks/task-55-add-comment-fields-to-schema.md
|
|
433
|
+
estimated_hours: 2
|
|
434
|
+
completed_date: 2026-02-16
|
|
435
|
+
notes: |
|
|
436
|
+
✅ Added 3 fields to Memory schema: parent_id, thread_root_id, moderation_flags
|
|
437
|
+
✅ Added same fields to Memory_public collection
|
|
438
|
+
✅ Enables infinite comment nesting
|
|
439
|
+
✅ Per-space moderation support
|
|
440
|
+
✅ Released in v2.6.0
|
|
441
|
+
|
|
442
|
+
- id: task-56
|
|
443
|
+
name: Update remember_search_space for Comments
|
|
444
|
+
status: completed
|
|
445
|
+
file: agent/tasks/task-56-update-search-space-for-comments.md
|
|
446
|
+
estimated_hours: 2
|
|
447
|
+
completed_date: 2026-02-16
|
|
448
|
+
notes: |
|
|
449
|
+
✅ Added include_comments parameter (default: false)
|
|
450
|
+
✅ Comments excluded from search by default
|
|
451
|
+
✅ Opt-in via include_comments: true
|
|
452
|
+
✅ Backward compatible
|
|
453
|
+
✅ Released in v2.6.0
|
|
454
|
+
|
|
455
|
+
- id: task-57
|
|
456
|
+
name: Update remember_query_space for Comments
|
|
457
|
+
status: completed
|
|
458
|
+
file: agent/tasks/task-57-update-query-space-for-comments.md
|
|
459
|
+
estimated_hours: 1
|
|
460
|
+
completed_date: 2026-02-16
|
|
461
|
+
notes: |
|
|
462
|
+
✅ Added include_comments parameter (default: false)
|
|
463
|
+
✅ Same filtering logic as search_space
|
|
464
|
+
✅ Backward compatible
|
|
465
|
+
✅ Released in v2.6.0
|
|
466
|
+
|
|
467
|
+
- id: task-58
|
|
468
|
+
name: Add Comment Unit Tests
|
|
469
|
+
status: not_started
|
|
470
|
+
file: agent/tasks/task-58-add-comment-unit-tests.md
|
|
471
|
+
estimated_hours: 3
|
|
472
|
+
notes: |
|
|
473
|
+
📋 Pending: Schema tests, filtering tests, edge cases
|
|
474
|
+
📋 Test infinite nesting support
|
|
475
|
+
📋 Test moderation flags
|
|
476
|
+
|
|
477
|
+
- id: task-59
|
|
478
|
+
name: Update Documentation for Comments
|
|
479
|
+
status: not_started
|
|
480
|
+
file: agent/tasks/task-59-update-documentation-for-comments.md
|
|
481
|
+
estimated_hours: 2
|
|
482
|
+
notes: |
|
|
483
|
+
📋 Pending: README updates, CHANGELOG entry, examples
|
|
484
|
+
📋 Document comment creation workflow
|
|
485
|
+
📋 Add threading examples
|
|
486
|
+
|
|
487
|
+
- id: task-60
|
|
488
|
+
name: Standardize Structured Logging
|
|
489
|
+
status: completed
|
|
490
|
+
file: agent/tasks/task-60-standardize-structured-logging.md
|
|
491
|
+
estimated_hours: 3
|
|
492
|
+
completed_date: 2026-02-16
|
|
493
|
+
notes: |
|
|
494
|
+
✅ Replaced 54 console.log/error/warn calls with structured logger
|
|
495
|
+
✅ Updated 8 files: confirmation-token.service, publish, confirm, deny, weaviate client/schema/space-schema, firestore init, config
|
|
496
|
+
✅ All logs include context objects (service, module, tool names)
|
|
497
|
+
✅ Fixed circular dependency in config.ts with dynamic import
|
|
498
|
+
✅ Released in v2.6.1
|
|
499
|
+
|
|
500
|
+
- id: task-61
|
|
501
|
+
name: Enhance Confirmation Tool Safety Guidelines
|
|
502
|
+
status: completed
|
|
503
|
+
file: agent/tasks/task-61-enhance-confirmation-tool-descriptions.md
|
|
504
|
+
estimated_hours: 1
|
|
505
|
+
completed_date: 2026-02-16
|
|
506
|
+
notes: |
|
|
507
|
+
✅ Enhanced remember_confirm tool description with 5 critical safety requirements
|
|
508
|
+
✅ Enhanced remember_deny tool description with same safety guidelines
|
|
509
|
+
✅ Added JSDoc comments explaining proper workflow
|
|
510
|
+
✅ Prevents agents from bypassing user consent
|
|
511
|
+
✅ Visual indicators (⚠️) for critical requirements
|
|
512
|
+
✅ Released in v2.6.2
|
|
513
|
+
|
|
409
514
|
documentation:
|
|
410
515
|
design_documents: 23
|
|
411
|
-
milestone_documents:
|
|
516
|
+
milestone_documents: 11
|
|
412
517
|
pattern_documents: 5
|
|
413
|
-
task_documents:
|
|
518
|
+
task_documents: 61
|
|
414
519
|
|
|
415
520
|
progress:
|
|
416
521
|
planning: 100%
|
|
@@ -418,6 +523,33 @@ progress:
|
|
|
418
523
|
overall: 50%
|
|
419
524
|
|
|
420
525
|
recent_work:
|
|
526
|
+
- date: 2026-02-16
|
|
527
|
+
description: Comment System, Structured Logging, and Safety Guidelines (v2.6.0-v2.6.2)
|
|
528
|
+
items:
|
|
529
|
+
- 🎉 M12 STARTED: Comment System (Phase 1) - 60% complete (3/5 tasks)
|
|
530
|
+
- ✅ Task 55: Added 3 comment fields to Weaviate schema
|
|
531
|
+
- ✅ parent_id, thread_root_id, moderation_flags fields added
|
|
532
|
+
- ✅ Enables infinite comment nesting with no depth limit
|
|
533
|
+
- ✅ Per-space moderation flags support
|
|
534
|
+
- ✅ Task 56: Updated remember_search_space with include_comments parameter
|
|
535
|
+
- ✅ Comments excluded by default for clean discovery
|
|
536
|
+
- ✅ Opt-in via include_comments: true
|
|
537
|
+
- ✅ Task 57: Updated remember_query_space with include_comments parameter
|
|
538
|
+
- ✅ Same filtering logic as search_space
|
|
539
|
+
- ✅ Released v2.6.0 with comment system foundation
|
|
540
|
+
- ✅ Task 60: Standardized structured logging across 8 files
|
|
541
|
+
- ✅ Replaced 54 console.log/error/warn calls with logger.info/error/warn/debug
|
|
542
|
+
- ✅ All logs include context objects (service, module, tool names)
|
|
543
|
+
- ✅ Fixed circular dependency in config.ts with dynamic import
|
|
544
|
+
- ✅ Released v2.6.1 with structured logging
|
|
545
|
+
- ✅ Task 61: Enhanced confirmation tool safety guidelines
|
|
546
|
+
- ✅ Added 5 critical safety requirements to remember_confirm and remember_deny
|
|
547
|
+
- ✅ Prevents agents from chaining confirmations without user consent
|
|
548
|
+
- ✅ Visual indicators (⚠️) and JSDoc comments added
|
|
549
|
+
- ✅ Released v2.6.2 with safety enhancements
|
|
550
|
+
- 📋 Next: Complete M12 with Tasks 58-59 (tests + documentation)
|
|
551
|
+
- 📋 6 commits ready to push to origin
|
|
552
|
+
|
|
421
553
|
- date: 2026-02-16
|
|
422
554
|
description: ACP Initialization Complete - Multi-Space Architecture Verified (v2.5.1)
|
|
423
555
|
items:
|
|
@@ -743,18 +875,21 @@ recent_work:
|
|
|
743
875
|
- ✅ Build successful
|
|
744
876
|
|
|
745
877
|
next_steps:
|
|
746
|
-
-
|
|
747
|
-
-
|
|
748
|
-
-
|
|
749
|
-
-
|
|
750
|
-
-
|
|
751
|
-
-
|
|
878
|
+
- Complete Task 58: Add Comment Unit Tests (3 hours)
|
|
879
|
+
- Complete Task 59: Update Documentation for Comments (2 hours)
|
|
880
|
+
- Push 6 commits to origin (v2.6.0, v2.6.1, v2.6.2)
|
|
881
|
+
- Deploy v2.6.2 to Cloud Run
|
|
882
|
+
- Test comment system end-to-end (create, search, thread fetching)
|
|
883
|
+
- Test structured logging in Cloud Run logs
|
|
884
|
+
- Verify confirmation tool safety guidelines in production
|
|
885
|
+
- Complete M12: Comment System (Phase 1)
|
|
752
886
|
- Start M5: Template System (15 default templates + auto-suggestion)
|
|
753
887
|
- Optional: Create integration tests (Task 6)
|
|
754
888
|
- Optional: Add development documentation (Task 7)
|
|
755
889
|
- Consider M6: Auth & Multi-Tenancy
|
|
756
890
|
|
|
757
891
|
notes:
|
|
892
|
+
- 🚀 Milestone 12 (Comment System Phase 1) IN PROGRESS - 60% complete!
|
|
758
893
|
- 🎉 Milestone 11 (Unified Public Collection) COMPLETED!
|
|
759
894
|
- 🎉 Milestone 10 (Shared Spaces & Confirmation Flow) COMPLETED!
|
|
760
895
|
- 🎉 Milestone 4 (User Preferences) COMPLETED!
|
|
@@ -769,6 +904,10 @@ notes:
|
|
|
769
904
|
- ✅ M4: 2/2 preference tools complete (100% progress)
|
|
770
905
|
- ✅ M10: 10/10 shared space tools complete (100% progress)
|
|
771
906
|
- ✅ M11: 9/9 multi-space architecture tasks complete (100% progress)
|
|
907
|
+
- 🚀 M12: 3/5 comment system tasks complete (60% progress)
|
|
908
|
+
- ✅ Comment system foundation implemented (v2.6.0)
|
|
909
|
+
- ✅ Structured logging standardized (v2.6.1)
|
|
910
|
+
- ✅ Confirmation tool safety enhanced (v2.6.2)
|
|
772
911
|
- ✅ Complete memory CRUD operations (create, read, update, delete)
|
|
773
912
|
- ✅ Complete relationship CRUD operations (create, read, update, delete)
|
|
774
913
|
- ✅ Advanced search capabilities (hybrid, similarity, RAG queries)
|
|
@@ -833,8 +972,10 @@ build_status:
|
|
|
833
972
|
- ✅ Source maps generated
|
|
834
973
|
- ✅ Type definitions generated (.d.ts files)
|
|
835
974
|
- ✅ Package exports configured for both entry points
|
|
836
|
-
- ✅ Version 2.
|
|
837
|
-
- ✅
|
|
975
|
+
- ✅ Version 2.6.2 published (patch release - safety guidelines)
|
|
976
|
+
- ✅ Version 2.6.1 published (patch release - structured logging)
|
|
977
|
+
- ✅ Version 2.6.0 published (minor release - comment system)
|
|
978
|
+
- ✅ 30 TypeScript source files
|
|
838
979
|
- ✅ All 12 tools implemented
|
|
839
980
|
- ✅ Weaviate v3 filter API implemented
|
|
840
981
|
- ✅ Or/And operator validation implemented
|
|
@@ -857,6 +998,12 @@ tools_status:
|
|
|
857
998
|
preference_tools:
|
|
858
999
|
- ✅ remember_set_preference (src/tools/set-preference.ts)
|
|
859
1000
|
- ✅ remember_get_preferences (src/tools/get-preferences.ts)
|
|
1001
|
+
space_tools:
|
|
1002
|
+
- ✅ remember_publish (src/tools/publish.ts) - Multi-space support
|
|
1003
|
+
- ✅ remember_confirm (src/tools/confirm.ts) - Enhanced safety guidelines
|
|
1004
|
+
- ✅ remember_deny (src/tools/deny.ts) - Enhanced safety guidelines
|
|
1005
|
+
- ✅ remember_search_space (src/tools/search-space.ts) - Comment filtering
|
|
1006
|
+
- ✅ remember_query_space (src/tools/query-space.ts) - Comment filtering
|
|
860
1007
|
|
|
861
1008
|
implementation_notes:
|
|
862
1009
|
- All 12 core tools implemented and integrated
|
|
@@ -899,3 +1046,6 @@ task_20_completion:
|
|
|
899
1046
|
releases:
|
|
900
1047
|
- v1.0.0: Major release with breaking change (async createServer)
|
|
901
1048
|
- v1.0.1: Patch release with Or operator bug fix
|
|
1049
|
+
- v2.6.0: Minor release with comment system foundation
|
|
1050
|
+
- v2.6.1: Patch release with structured logging
|
|
1051
|
+
- v2.6.2: Patch release with confirmation tool safety guidelines
|
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
# Task 62: Fix Confirmation Response Storage
|
|
2
|
+
|
|
3
|
+
**Milestone**: M12 (Comment System / Bug Fixes)
|
|
4
|
+
**Estimated Time**: 2 hours
|
|
5
|
+
**Dependencies**: None
|
|
6
|
+
**Status**: Not Started
|
|
7
|
+
**Priority**: High
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Objective
|
|
12
|
+
|
|
13
|
+
Fix bug where `remember_confirm` executes actions successfully but doesn't store the response data in the Firestore confirmation record. This prevents agents and users from verifying action results and breaks the audit trail.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Context
|
|
18
|
+
|
|
19
|
+
**Current Behavior:**
|
|
20
|
+
1. `remember_confirm` validates token and marks request as "confirmed"
|
|
21
|
+
2. Action executes successfully (e.g., `executePublishMemory`)
|
|
22
|
+
3. Response data (space_memory_id, etc.) is returned to agent
|
|
23
|
+
4. **BUG**: Response data is NOT saved to Firestore
|
|
24
|
+
5. Database record shows `status: confirmed` but no response/result data
|
|
25
|
+
|
|
26
|
+
**Impact:**
|
|
27
|
+
- ⚠️ Agents cannot verify publication success
|
|
28
|
+
- ⚠️ No space_memory_id available for reference
|
|
29
|
+
- ⚠️ Audit trail incomplete
|
|
30
|
+
- ⚠️ Cannot track what happened after confirmation
|
|
31
|
+
|
|
32
|
+
**Root Cause:**
|
|
33
|
+
- `ConfirmationRequest` interface lacks `response` field
|
|
34
|
+
- `confirmRequest()` method only updates status, not response
|
|
35
|
+
- `executePublishMemory()` returns data but doesn't persist it
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Steps
|
|
40
|
+
|
|
41
|
+
### 1. Update ConfirmationRequest Interface
|
|
42
|
+
|
|
43
|
+
Add response field to store action results:
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
// src/services/confirmation-token.service.ts
|
|
47
|
+
|
|
48
|
+
export interface ConfirmationRequest {
|
|
49
|
+
user_id: string;
|
|
50
|
+
token: string;
|
|
51
|
+
action: string;
|
|
52
|
+
target_collection?: string;
|
|
53
|
+
payload: any;
|
|
54
|
+
created_at: string;
|
|
55
|
+
expires_at: string;
|
|
56
|
+
status: 'pending' | 'confirmed' | 'denied' | 'expired' | 'retracted';
|
|
57
|
+
confirmed_at?: string;
|
|
58
|
+
response?: any; // ✅ ADD THIS - Stores action execution result
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### 2. Add storeResponse Method
|
|
63
|
+
|
|
64
|
+
Create method to store response data after action execution:
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
// src/services/confirmation-token.service.ts
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Store response data for a confirmed request
|
|
71
|
+
*
|
|
72
|
+
* @param userId - User ID
|
|
73
|
+
* @param requestId - Request ID
|
|
74
|
+
* @param response - Response data from action execution
|
|
75
|
+
*/
|
|
76
|
+
async storeResponse(
|
|
77
|
+
userId: string,
|
|
78
|
+
requestId: string,
|
|
79
|
+
response: any
|
|
80
|
+
): Promise<void> {
|
|
81
|
+
logger.info('Storing confirmation response', {
|
|
82
|
+
service: 'ConfirmationTokenService',
|
|
83
|
+
userId,
|
|
84
|
+
requestId,
|
|
85
|
+
hasResponse: !!response,
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
const docPath = `users/${userId}/requests/${requestId}`;
|
|
89
|
+
|
|
90
|
+
await updateDocument(docPath, {
|
|
91
|
+
response,
|
|
92
|
+
updated_at: new Date().toISOString(),
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
logger.info('Response stored successfully', {
|
|
96
|
+
service: 'ConfirmationTokenService',
|
|
97
|
+
requestId,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### 3. Update handleConfirm to Store Response
|
|
103
|
+
|
|
104
|
+
Modify `remember_confirm` to persist response data:
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
// src/tools/confirm.ts
|
|
108
|
+
|
|
109
|
+
export async function handleConfirm(
|
|
110
|
+
args: ConfirmArgs,
|
|
111
|
+
userId: string
|
|
112
|
+
): Promise<string> {
|
|
113
|
+
try {
|
|
114
|
+
logger.info('Starting confirmation', {
|
|
115
|
+
tool: 'remember_confirm',
|
|
116
|
+
userId,
|
|
117
|
+
token: args.token,
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
// Validate and confirm token
|
|
121
|
+
const request = await confirmationTokenService.confirmRequest(userId, args.token);
|
|
122
|
+
|
|
123
|
+
if (!request) {
|
|
124
|
+
logger.info('Token invalid or expired', {
|
|
125
|
+
tool: 'remember_confirm',
|
|
126
|
+
userId,
|
|
127
|
+
});
|
|
128
|
+
return JSON.stringify({
|
|
129
|
+
success: false,
|
|
130
|
+
error: 'Invalid or expired token',
|
|
131
|
+
message: 'The confirmation token is invalid, expired, or has already been used.',
|
|
132
|
+
}, null, 2);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
logger.info('Executing confirmed action', {
|
|
136
|
+
tool: 'remember_confirm',
|
|
137
|
+
action: request.action,
|
|
138
|
+
userId,
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
// Execute action based on type
|
|
142
|
+
let responseJson: string;
|
|
143
|
+
if (request.action === 'publish_memory') {
|
|
144
|
+
responseJson = await executePublishMemory(request, userId);
|
|
145
|
+
} else {
|
|
146
|
+
throw new Error(`Unknown action type: ${request.action}`);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// ✅ NEW: Parse and store response data
|
|
150
|
+
try {
|
|
151
|
+
const responseData = JSON.parse(responseJson);
|
|
152
|
+
|
|
153
|
+
logger.info('Storing action response', {
|
|
154
|
+
tool: 'remember_confirm',
|
|
155
|
+
requestId: request.request_id,
|
|
156
|
+
success: responseData.success,
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
await confirmationTokenService.storeResponse(
|
|
160
|
+
userId,
|
|
161
|
+
request.request_id,
|
|
162
|
+
responseData
|
|
163
|
+
);
|
|
164
|
+
|
|
165
|
+
logger.info('Response stored successfully', {
|
|
166
|
+
tool: 'remember_confirm',
|
|
167
|
+
requestId: request.request_id,
|
|
168
|
+
});
|
|
169
|
+
} catch (parseError) {
|
|
170
|
+
logger.warn('Failed to parse/store response', {
|
|
171
|
+
tool: 'remember_confirm',
|
|
172
|
+
error: parseError instanceof Error ? parseError.message : String(parseError),
|
|
173
|
+
});
|
|
174
|
+
// Don't fail the whole operation if storage fails
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Return response to agent
|
|
178
|
+
return responseJson;
|
|
179
|
+
} catch (error) {
|
|
180
|
+
handleToolError(error, {
|
|
181
|
+
toolName: 'remember_confirm',
|
|
182
|
+
userId,
|
|
183
|
+
operation: 'confirm action',
|
|
184
|
+
token: args.token,
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### 4. Update Tests
|
|
191
|
+
|
|
192
|
+
Add tests for response storage:
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
// tests/unit/confirmation-token.service.test.ts
|
|
196
|
+
|
|
197
|
+
describe('ConfirmationTokenService', () => {
|
|
198
|
+
describe('storeResponse', () => {
|
|
199
|
+
it('should store response data for confirmed request', async () => {
|
|
200
|
+
const service = new ConfirmationTokenService();
|
|
201
|
+
const userId = 'test-user';
|
|
202
|
+
const requestId = 'test-request';
|
|
203
|
+
const response = {
|
|
204
|
+
success: true,
|
|
205
|
+
space_memory_id: 'space-123',
|
|
206
|
+
spaces: ['the_void'],
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
await service.storeResponse(userId, requestId, response);
|
|
210
|
+
|
|
211
|
+
// Verify response was stored
|
|
212
|
+
const request = await getDocument(`users/${userId}/requests/${requestId}`);
|
|
213
|
+
expect(request.response).toEqual(response);
|
|
214
|
+
expect(request.updated_at).toBeDefined();
|
|
215
|
+
});
|
|
216
|
+
});
|
|
217
|
+
});
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### 5. Update Documentation
|
|
221
|
+
|
|
222
|
+
Document the response field in design docs:
|
|
223
|
+
|
|
224
|
+
```markdown
|
|
225
|
+
# agent/design/publish-tools-confirmation-flow.md
|
|
226
|
+
|
|
227
|
+
## Confirmation Record Structure
|
|
228
|
+
|
|
229
|
+
After confirmation, the record includes:
|
|
230
|
+
- `status`: 'confirmed'
|
|
231
|
+
- `confirmed_at`: ISO timestamp
|
|
232
|
+
- `response`: Action execution result (NEW)
|
|
233
|
+
- For publish_memory: { success, space_memory_id, spaces }
|
|
234
|
+
- For other actions: Action-specific response data
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
## Verification
|
|
240
|
+
|
|
241
|
+
- [ ] ConfirmationRequest interface has `response?: any` field
|
|
242
|
+
- [ ] `storeResponse()` method exists in ConfirmationTokenService
|
|
243
|
+
- [ ] `handleConfirm` calls `storeResponse()` after action execution
|
|
244
|
+
- [ ] Response data is persisted to Firestore
|
|
245
|
+
- [ ] Agent receives response data in tool output
|
|
246
|
+
- [ ] Database record contains response field after confirmation
|
|
247
|
+
- [ ] Tests pass for response storage
|
|
248
|
+
- [ ] TypeScript compiles without errors
|
|
249
|
+
- [ ] Build successful
|
|
250
|
+
- [ ] Manual test: Publish memory and verify response in Firestore
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
## Expected Output
|
|
255
|
+
|
|
256
|
+
**Before Fix:**
|
|
257
|
+
```json
|
|
258
|
+
{
|
|
259
|
+
"status": "confirmed",
|
|
260
|
+
"confirmed_at": "2026-02-16T21:44:39.154Z",
|
|
261
|
+
"action": "publish_memory",
|
|
262
|
+
"payload": { "memory_id": "...", "spaces": ["the_void"] }
|
|
263
|
+
// ❌ No response field
|
|
264
|
+
}
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
**After Fix:**
|
|
268
|
+
```json
|
|
269
|
+
{
|
|
270
|
+
"status": "confirmed",
|
|
271
|
+
"confirmed_at": "2026-02-16T21:44:39.154Z",
|
|
272
|
+
"action": "publish_memory",
|
|
273
|
+
"payload": { "memory_id": "...", "spaces": ["the_void"] },
|
|
274
|
+
"response": {
|
|
275
|
+
"success": true,
|
|
276
|
+
"space_memory_id": "9b536938-1188-4e69-b3cd-4362d84fff1c",
|
|
277
|
+
"spaces": ["the_void"]
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
---
|
|
283
|
+
|
|
284
|
+
## Common Issues and Solutions
|
|
285
|
+
|
|
286
|
+
### Issue 1: Response not storing
|
|
287
|
+
|
|
288
|
+
**Cause**: Parse error or Firestore write failure
|
|
289
|
+
**Solution**: Check logs for errors, verify Firestore permissions
|
|
290
|
+
|
|
291
|
+
### Issue 2: Response field undefined
|
|
292
|
+
|
|
293
|
+
**Cause**: Old records don't have response field
|
|
294
|
+
**Solution**: This is expected - only new confirmations will have response
|
|
295
|
+
|
|
296
|
+
### Issue 3: Response too large for Firestore
|
|
297
|
+
|
|
298
|
+
**Cause**: Response data exceeds Firestore document size limit (1MB)
|
|
299
|
+
**Solution**: Store only essential fields (space_memory_id, success, spaces)
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
## Resources
|
|
304
|
+
|
|
305
|
+
- [Firestore Document Limits](https://firebase.google.com/docs/firestore/quotas)
|
|
306
|
+
- [ConfirmationTokenService](../src/services/confirmation-token.service.ts)
|
|
307
|
+
- [remember_confirm Tool](../src/tools/confirm.ts)
|
|
308
|
+
- [Confirmation Flow Design](../design/publish-tools-confirmation-flow.md)
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
312
|
+
## Notes
|
|
313
|
+
|
|
314
|
+
- This is a backward-compatible change - old records without response field will continue to work
|
|
315
|
+
- Response storage is best-effort - if it fails, the action still succeeds
|
|
316
|
+
- Response data is primarily for audit trail and debugging
|
|
317
|
+
- Agents receive response data regardless of storage success
|
|
318
|
+
- Consider adding response field to remember_deny as well (for consistency)
|
|
319
|
+
|
|
320
|
+
---
|
|
321
|
+
|
|
322
|
+
**Status**: Not Started
|
|
323
|
+
**Recommendation**: Implement this fix before completing M12 to ensure proper audit trail
|
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
# Task 63: Fix fetchObjectById Missing Properties in Publish Flow
|
|
2
|
+
|
|
3
|
+
**Milestone**: M12 (Bug Fixes)
|
|
4
|
+
**Estimated Time**: 1 hour
|
|
5
|
+
**Dependencies**: None
|
|
6
|
+
**Status**: Not Started
|
|
7
|
+
**Priority**: CRITICAL 🚨
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Objective
|
|
12
|
+
|
|
13
|
+
Fix critical bug where `remember_publish` and `remember_confirm` (executePublishMemory) fail to fetch all memory properties because they don't specify `returnProperties` parameter in `fetchObjectById()` calls. This causes published memories to be empty shells with only metadata and vectors.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Context
|
|
18
|
+
|
|
19
|
+
**Critical Bug Discovered**: Published memories in `Memory_public` have no content!
|
|
20
|
+
|
|
21
|
+
**Symptom**:
|
|
22
|
+
- Space memory created with ID ✅
|
|
23
|
+
- Vector embedding generated ✅
|
|
24
|
+
- Metadata exists ✅
|
|
25
|
+
- **All properties missing** ❌ (no title, content, tags, etc.)
|
|
26
|
+
|
|
27
|
+
**Root Cause**:
|
|
28
|
+
Weaviate v3 API `fetchObjectById()` requires explicit `returnProperties` parameter. Without it, only metadata is returned, not the actual property values.
|
|
29
|
+
|
|
30
|
+
**Affected Code**:
|
|
31
|
+
1. [`src/tools/publish.ts:125`](src/tools/publish.ts) - `remember_publish` tool
|
|
32
|
+
2. [`src/tools/confirm.ts:154`](src/tools/confirm.ts) - `executePublishMemory` function
|
|
33
|
+
|
|
34
|
+
**Evidence**:
|
|
35
|
+
All other tools correctly specify `returnProperties`:
|
|
36
|
+
- `update-relationship.ts:100` ✅ Specifies properties
|
|
37
|
+
- `create-relationship.ts:119` ✅ Specifies properties
|
|
38
|
+
- `find-similar.ts:120` ✅ Specifies properties
|
|
39
|
+
- `update-memory.ts:119` ✅ Specifies properties
|
|
40
|
+
- `delete-relationship.ts:66` ✅ Specifies properties
|
|
41
|
+
- `delete-memory.ts:72` ✅ Specifies properties
|
|
42
|
+
- **`publish.ts:125`** ❌ Missing returnProperties
|
|
43
|
+
- **`confirm.ts:154`** ❌ Missing returnProperties
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Steps
|
|
48
|
+
|
|
49
|
+
### 1. Create Utility Function for Consistent Property Fetching
|
|
50
|
+
|
|
51
|
+
Create a helper function to ensure all memory properties are always fetched:
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
// src/weaviate/client.ts (add after existing functions)
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* List of all memory properties to fetch
|
|
58
|
+
* Centralized to ensure consistency across all tools
|
|
59
|
+
*/
|
|
60
|
+
export const ALL_MEMORY_PROPERTIES = [
|
|
61
|
+
'user_id',
|
|
62
|
+
'doc_type',
|
|
63
|
+
'type',
|
|
64
|
+
'title',
|
|
65
|
+
'content',
|
|
66
|
+
'tags',
|
|
67
|
+
'weight',
|
|
68
|
+
'base_weight',
|
|
69
|
+
'trust_level',
|
|
70
|
+
'context',
|
|
71
|
+
'location',
|
|
72
|
+
'relationships',
|
|
73
|
+
'created_at',
|
|
74
|
+
'updated_at',
|
|
75
|
+
'version',
|
|
76
|
+
'attribution',
|
|
77
|
+
'source_url',
|
|
78
|
+
'author',
|
|
79
|
+
'parent_id',
|
|
80
|
+
'thread_root_id',
|
|
81
|
+
'moderation_flags',
|
|
82
|
+
] as const;
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Fetch a memory object by ID with all properties
|
|
86
|
+
*
|
|
87
|
+
* @param collection - Weaviate collection
|
|
88
|
+
* @param memoryId - Memory ID to fetch
|
|
89
|
+
* @returns Memory object with all properties
|
|
90
|
+
*/
|
|
91
|
+
export async function fetchMemoryWithAllProperties(
|
|
92
|
+
collection: any,
|
|
93
|
+
memoryId: string
|
|
94
|
+
) {
|
|
95
|
+
return await collection.query.fetchObjectById(memoryId, {
|
|
96
|
+
returnProperties: ALL_MEMORY_PROPERTIES,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### 2. Fix remember_publish Tool
|
|
102
|
+
|
|
103
|
+
Update `fetchObjectById` call to return all properties:
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
// src/tools/publish.ts (around line 125)
|
|
107
|
+
|
|
108
|
+
// BEFORE (BROKEN):
|
|
109
|
+
const memory = await userCollection.query.fetchObjectById(args.memory_id);
|
|
110
|
+
|
|
111
|
+
// AFTER (FIXED):
|
|
112
|
+
const memory = await userCollection.query.fetchObjectById(args.memory_id, {
|
|
113
|
+
returnProperties: [
|
|
114
|
+
'user_id',
|
|
115
|
+
'doc_type',
|
|
116
|
+
'type',
|
|
117
|
+
'title',
|
|
118
|
+
'content',
|
|
119
|
+
'tags',
|
|
120
|
+
'weight',
|
|
121
|
+
'base_weight',
|
|
122
|
+
'trust_level',
|
|
123
|
+
'context',
|
|
124
|
+
'location',
|
|
125
|
+
'relationships',
|
|
126
|
+
'created_at',
|
|
127
|
+
'updated_at',
|
|
128
|
+
'version',
|
|
129
|
+
'attribution',
|
|
130
|
+
'source_url',
|
|
131
|
+
'author',
|
|
132
|
+
'parent_id',
|
|
133
|
+
'thread_root_id',
|
|
134
|
+
'moderation_flags',
|
|
135
|
+
],
|
|
136
|
+
});
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### 2. Fix executePublishMemory in remember_confirm
|
|
140
|
+
|
|
141
|
+
Update `fetchObjectById` call in confirm tool:
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
// src/tools/confirm.ts (around line 154)
|
|
145
|
+
|
|
146
|
+
// BEFORE (BROKEN):
|
|
147
|
+
const originalMemory = await userCollection.query.fetchObjectById(
|
|
148
|
+
request.payload.memory_id
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
// AFTER (FIXED):
|
|
152
|
+
const originalMemory = await userCollection.query.fetchObjectById(
|
|
153
|
+
request.payload.memory_id,
|
|
154
|
+
{
|
|
155
|
+
returnProperties: [
|
|
156
|
+
'user_id',
|
|
157
|
+
'doc_type',
|
|
158
|
+
'type',
|
|
159
|
+
'title',
|
|
160
|
+
'content',
|
|
161
|
+
'tags',
|
|
162
|
+
'weight',
|
|
163
|
+
'base_weight',
|
|
164
|
+
'trust_level',
|
|
165
|
+
'context',
|
|
166
|
+
'location',
|
|
167
|
+
'relationships',
|
|
168
|
+
'created_at',
|
|
169
|
+
'updated_at',
|
|
170
|
+
'version',
|
|
171
|
+
'attribution',
|
|
172
|
+
'source_url',
|
|
173
|
+
'author',
|
|
174
|
+
'parent_id',
|
|
175
|
+
'thread_root_id',
|
|
176
|
+
'moderation_flags',
|
|
177
|
+
],
|
|
178
|
+
}
|
|
179
|
+
);
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### 3. Add Logging to Verify Properties
|
|
183
|
+
|
|
184
|
+
Add debug logging to confirm properties are fetched:
|
|
185
|
+
|
|
186
|
+
```typescript
|
|
187
|
+
// src/tools/confirm.ts (after fetch)
|
|
188
|
+
|
|
189
|
+
logger.debug('Original memory fetch result', {
|
|
190
|
+
function: 'executePublishMemory',
|
|
191
|
+
found: !!originalMemory,
|
|
192
|
+
memoryId: request.payload.memory_id,
|
|
193
|
+
hasProperties: !!originalMemory?.properties,
|
|
194
|
+
propertyCount: originalMemory?.properties ? Object.keys(originalMemory.properties).length : 0,
|
|
195
|
+
hasTitle: !!originalMemory?.properties?.title,
|
|
196
|
+
hasContent: !!originalMemory?.properties?.content,
|
|
197
|
+
});
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### 4. Test the Fix
|
|
201
|
+
|
|
202
|
+
Manual test to verify properties are copied:
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
# 1. Create a test memory
|
|
206
|
+
remember_create_memory({
|
|
207
|
+
type: "note",
|
|
208
|
+
title: "Test Memory",
|
|
209
|
+
content: "This is test content",
|
|
210
|
+
tags: ["test"]
|
|
211
|
+
})
|
|
212
|
+
|
|
213
|
+
# 2. Publish it
|
|
214
|
+
remember_publish({
|
|
215
|
+
memory_id: "<memory_id>",
|
|
216
|
+
spaces: ["the_void"]
|
|
217
|
+
})
|
|
218
|
+
|
|
219
|
+
# 3. Confirm publication
|
|
220
|
+
remember_confirm({
|
|
221
|
+
token: "<token>"
|
|
222
|
+
})
|
|
223
|
+
|
|
224
|
+
# 4. Search for it
|
|
225
|
+
remember_search_space({
|
|
226
|
+
spaces: ["the_void"],
|
|
227
|
+
query: "test content",
|
|
228
|
+
include_comments: false
|
|
229
|
+
})
|
|
230
|
+
|
|
231
|
+
# 5. Verify result has title, content, tags
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### 5. Update Tests
|
|
235
|
+
|
|
236
|
+
Add test case for property copying:
|
|
237
|
+
|
|
238
|
+
```typescript
|
|
239
|
+
// tests/unit/publish.test.ts
|
|
240
|
+
|
|
241
|
+
describe('remember_publish', () => {
|
|
242
|
+
it('should fetch all memory properties', async () => {
|
|
243
|
+
const mockMemory = {
|
|
244
|
+
properties: {
|
|
245
|
+
user_id: 'test-user',
|
|
246
|
+
title: 'Test Title',
|
|
247
|
+
content: 'Test Content',
|
|
248
|
+
tags: ['tag1', 'tag2'],
|
|
249
|
+
// ... all properties
|
|
250
|
+
},
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
mockCollection.query.fetchObjectById.mockResolvedValue(mockMemory);
|
|
254
|
+
|
|
255
|
+
await handlePublish({ memory_id: 'test-id', spaces: ['the_void'] }, 'test-user');
|
|
256
|
+
|
|
257
|
+
expect(mockCollection.query.fetchObjectById).toHaveBeenCalledWith(
|
|
258
|
+
'test-id',
|
|
259
|
+
expect.objectContaining({
|
|
260
|
+
returnProperties: expect.arrayContaining([
|
|
261
|
+
'title',
|
|
262
|
+
'content',
|
|
263
|
+
'tags',
|
|
264
|
+
'user_id',
|
|
265
|
+
'doc_type',
|
|
266
|
+
]),
|
|
267
|
+
})
|
|
268
|
+
);
|
|
269
|
+
});
|
|
270
|
+
});
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
275
|
+
## Verification
|
|
276
|
+
|
|
277
|
+
- [ ] Created `fetchMemoryWithAllProperties` utility function in `src/weaviate/client.ts`
|
|
278
|
+
- [ ] Created `ALL_MEMORY_PROPERTIES` constant with all 20+ properties
|
|
279
|
+
- [ ] `remember_publish` uses `fetchMemoryWithAllProperties`
|
|
280
|
+
- [ ] `executePublishMemory` uses `fetchMemoryWithAllProperties`
|
|
281
|
+
- [ ] Utility function exported from client module
|
|
282
|
+
- [ ] Debug logging shows property count > 0
|
|
283
|
+
- [ ] Debug logging shows `hasTitle: true` and `hasContent: true`
|
|
284
|
+
- [ ] Manual test: Published memory has title, content, tags
|
|
285
|
+
- [ ] Search returns published memory with full content
|
|
286
|
+
- [ ] TypeScript compiles without errors
|
|
287
|
+
- [ ] Build successful
|
|
288
|
+
- [ ] All tests passing
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
## Expected Output
|
|
293
|
+
|
|
294
|
+
**Before Fix** (Current - BROKEN):
|
|
295
|
+
```json
|
|
296
|
+
{
|
|
297
|
+
"id": "9b536938-1188-4e69-b3cd-4362d84fff1c",
|
|
298
|
+
"vector": [...],
|
|
299
|
+
// ❌ NO PROPERTIES - Empty shell
|
|
300
|
+
}
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
**After Fix**:
|
|
304
|
+
```json
|
|
305
|
+
{
|
|
306
|
+
"id": "9b536938-1188-4e69-b3cd-4362d84fff1c",
|
|
307
|
+
"vector": [...],
|
|
308
|
+
"properties": {
|
|
309
|
+
"title": "Breaking the Mold of Boredom",
|
|
310
|
+
"content": "i feel like i'm boring...",
|
|
311
|
+
"type": "note",
|
|
312
|
+
"tags": ["self-discovery", "societal norms", "breaking free"],
|
|
313
|
+
"author_id": "MnOyIarhz5b8n06TsTovM582NSG2",
|
|
314
|
+
"spaces": ["the_void"],
|
|
315
|
+
"published_at": "2026-02-16T21:44:39Z",
|
|
316
|
+
// ... all other properties
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
---
|
|
322
|
+
|
|
323
|
+
## Impact Analysis
|
|
324
|
+
|
|
325
|
+
**Severity**: CRITICAL 🚨
|
|
326
|
+
|
|
327
|
+
**Affected Users**: ALL users who published memories since v2.4.0
|
|
328
|
+
|
|
329
|
+
**Data Loss**:
|
|
330
|
+
- All published memories are empty shells
|
|
331
|
+
- Content exists in user collections but not in public space
|
|
332
|
+
- Search returns no results (no content to match)
|
|
333
|
+
- Discovery completely broken
|
|
334
|
+
|
|
335
|
+
**Workaround**: None - memories must be re-published after fix
|
|
336
|
+
|
|
337
|
+
**Migration**:
|
|
338
|
+
- Option 1: Users re-publish memories manually
|
|
339
|
+
- Option 2: Create migration script to re-publish all memories
|
|
340
|
+
- Option 3: Backfill from user collections (requires tracking original IDs)
|
|
341
|
+
|
|
342
|
+
---
|
|
343
|
+
|
|
344
|
+
## Common Issues and Solutions
|
|
345
|
+
|
|
346
|
+
### Issue 1: TypeScript error about returnProperties
|
|
347
|
+
|
|
348
|
+
**Cause**: Type definition might not include all properties
|
|
349
|
+
**Solution**: Use `as any` if needed or update type definition
|
|
350
|
+
|
|
351
|
+
### Issue 2: Some properties still missing
|
|
352
|
+
|
|
353
|
+
**Cause**: Property list incomplete
|
|
354
|
+
**Solution**: Check schema.ts for all property names
|
|
355
|
+
|
|
356
|
+
### Issue 3: Old memories still empty
|
|
357
|
+
|
|
358
|
+
**Cause**: This fix only affects new publications
|
|
359
|
+
**Solution**: Users must re-publish or run migration script
|
|
360
|
+
|
|
361
|
+
---
|
|
362
|
+
|
|
363
|
+
## Resources
|
|
364
|
+
|
|
365
|
+
- [Weaviate v3 Query API](https://weaviate.io/developers/weaviate/api/graphql/get)
|
|
366
|
+
- [Memory Schema](../src/weaviate/schema.ts)
|
|
367
|
+
- [Space Schema](../src/weaviate/space-schema.ts)
|
|
368
|
+
- [Other fetchObjectById Examples](../src/tools/)
|
|
369
|
+
|
|
370
|
+
---
|
|
371
|
+
|
|
372
|
+
## Notes
|
|
373
|
+
|
|
374
|
+
- **This is more critical than Task 62** (response storage)
|
|
375
|
+
- Task 62 affects audit trail, Task 63 affects core functionality
|
|
376
|
+
- Without this fix, the entire publish/space feature is broken
|
|
377
|
+
- This bug has been in production since shared spaces were released
|
|
378
|
+
- All published memories need to be re-published after fix
|
|
379
|
+
- Consider adding integration test to catch this in future
|
|
380
|
+
- ✅ Created `fetchMemoryWithAllProperties` helper function
|
|
381
|
+
- This prevents the bug from recurring in future code
|
|
382
|
+
- Consider migrating other tools to use the utility function
|
|
383
|
+
- Consider adding ESLint rule to prevent direct `fetchObjectById` usage
|
|
384
|
+
|
|
385
|
+
---
|
|
386
|
+
|
|
387
|
+
## Related Tasks
|
|
388
|
+
|
|
389
|
+
- **Task 62**: Fix confirmation response storage (audit trail)
|
|
390
|
+
- **Task 58**: Add comment unit tests
|
|
391
|
+
- **Task 59**: Update documentation
|
|
392
|
+
|
|
393
|
+
---
|
|
394
|
+
|
|
395
|
+
**Status**: Not Started
|
|
396
|
+
**Recommendation**: FIX IMMEDIATELY - This breaks core functionality
|
|
397
|
+
**Priority**: CRITICAL - Must be fixed before any other M12 tasks
|
package/dist/server-factory.js
CHANGED
|
@@ -565,6 +565,34 @@ function sanitizeUserId(userId) {
|
|
|
565
565
|
function getMemoryCollectionName(userId) {
|
|
566
566
|
return `Memory_${sanitizeUserId(userId)}`;
|
|
567
567
|
}
|
|
568
|
+
var ALL_MEMORY_PROPERTIES = [
|
|
569
|
+
"user_id",
|
|
570
|
+
"doc_type",
|
|
571
|
+
"type",
|
|
572
|
+
"title",
|
|
573
|
+
"content",
|
|
574
|
+
"tags",
|
|
575
|
+
"weight",
|
|
576
|
+
"base_weight",
|
|
577
|
+
"trust_level",
|
|
578
|
+
"context",
|
|
579
|
+
"location",
|
|
580
|
+
"relationships",
|
|
581
|
+
"created_at",
|
|
582
|
+
"updated_at",
|
|
583
|
+
"version",
|
|
584
|
+
"attribution",
|
|
585
|
+
"source_url",
|
|
586
|
+
"author",
|
|
587
|
+
"parent_id",
|
|
588
|
+
"thread_root_id",
|
|
589
|
+
"moderation_flags"
|
|
590
|
+
];
|
|
591
|
+
async function fetchMemoryWithAllProperties(collection, memoryId) {
|
|
592
|
+
return await collection.query.fetchObjectById(memoryId, {
|
|
593
|
+
returnProperties: ALL_MEMORY_PROPERTIES
|
|
594
|
+
});
|
|
595
|
+
}
|
|
568
596
|
|
|
569
597
|
// src/firestore/init.ts
|
|
570
598
|
init_config();
|
|
@@ -3833,11 +3861,15 @@ async function handlePublish(args, userId) {
|
|
|
3833
3861
|
memoryId: args.memory_id
|
|
3834
3862
|
});
|
|
3835
3863
|
const userCollection = weaviateClient.collections.get(collectionName);
|
|
3836
|
-
const memory = await userCollection
|
|
3864
|
+
const memory = await fetchMemoryWithAllProperties(userCollection, args.memory_id);
|
|
3837
3865
|
logger.debug("Memory fetch result", {
|
|
3838
3866
|
tool: "remember_publish",
|
|
3839
3867
|
found: !!memory,
|
|
3840
|
-
memoryId: args.memory_id
|
|
3868
|
+
memoryId: args.memory_id,
|
|
3869
|
+
hasProperties: !!memory?.properties,
|
|
3870
|
+
propertyCount: memory?.properties ? Object.keys(memory.properties).length : 0,
|
|
3871
|
+
hasTitle: !!memory?.properties?.title,
|
|
3872
|
+
hasContent: !!memory?.properties?.content
|
|
3841
3873
|
});
|
|
3842
3874
|
if (!memory) {
|
|
3843
3875
|
logger.info("Memory not found", {
|
|
@@ -4024,13 +4056,18 @@ async function executePublishMemory(request, userId) {
|
|
|
4024
4056
|
collectionName: getMemoryCollectionName(userId),
|
|
4025
4057
|
memoryId: request.payload.memory_id
|
|
4026
4058
|
});
|
|
4027
|
-
const originalMemory = await
|
|
4059
|
+
const originalMemory = await fetchMemoryWithAllProperties(
|
|
4060
|
+
userCollection,
|
|
4028
4061
|
request.payload.memory_id
|
|
4029
4062
|
);
|
|
4030
4063
|
logger.debug("Original memory fetch result", {
|
|
4031
4064
|
function: "executePublishMemory",
|
|
4032
4065
|
found: !!originalMemory,
|
|
4033
|
-
memoryId: request.payload.memory_id
|
|
4066
|
+
memoryId: request.payload.memory_id,
|
|
4067
|
+
hasProperties: !!originalMemory?.properties,
|
|
4068
|
+
propertyCount: originalMemory?.properties ? Object.keys(originalMemory.properties).length : 0,
|
|
4069
|
+
hasTitle: !!originalMemory?.properties?.title,
|
|
4070
|
+
hasContent: !!originalMemory?.properties?.content
|
|
4034
4071
|
});
|
|
4035
4072
|
if (!originalMemory) {
|
|
4036
4073
|
logger.info("Original memory not found", {
|
package/dist/server.js
CHANGED
|
@@ -611,6 +611,34 @@ function sanitizeUserId(userId) {
|
|
|
611
611
|
function getMemoryCollectionName(userId) {
|
|
612
612
|
return `Memory_${sanitizeUserId(userId)}`;
|
|
613
613
|
}
|
|
614
|
+
var ALL_MEMORY_PROPERTIES = [
|
|
615
|
+
"user_id",
|
|
616
|
+
"doc_type",
|
|
617
|
+
"type",
|
|
618
|
+
"title",
|
|
619
|
+
"content",
|
|
620
|
+
"tags",
|
|
621
|
+
"weight",
|
|
622
|
+
"base_weight",
|
|
623
|
+
"trust_level",
|
|
624
|
+
"context",
|
|
625
|
+
"location",
|
|
626
|
+
"relationships",
|
|
627
|
+
"created_at",
|
|
628
|
+
"updated_at",
|
|
629
|
+
"version",
|
|
630
|
+
"attribution",
|
|
631
|
+
"source_url",
|
|
632
|
+
"author",
|
|
633
|
+
"parent_id",
|
|
634
|
+
"thread_root_id",
|
|
635
|
+
"moderation_flags"
|
|
636
|
+
];
|
|
637
|
+
async function fetchMemoryWithAllProperties(collection, memoryId) {
|
|
638
|
+
return await collection.query.fetchObjectById(memoryId, {
|
|
639
|
+
returnProperties: ALL_MEMORY_PROPERTIES
|
|
640
|
+
});
|
|
641
|
+
}
|
|
614
642
|
|
|
615
643
|
// src/firestore/init.ts
|
|
616
644
|
init_config();
|
|
@@ -3901,11 +3929,15 @@ async function handlePublish(args, userId) {
|
|
|
3901
3929
|
memoryId: args.memory_id
|
|
3902
3930
|
});
|
|
3903
3931
|
const userCollection = weaviateClient.collections.get(collectionName);
|
|
3904
|
-
const memory = await userCollection
|
|
3932
|
+
const memory = await fetchMemoryWithAllProperties(userCollection, args.memory_id);
|
|
3905
3933
|
logger.debug("Memory fetch result", {
|
|
3906
3934
|
tool: "remember_publish",
|
|
3907
3935
|
found: !!memory,
|
|
3908
|
-
memoryId: args.memory_id
|
|
3936
|
+
memoryId: args.memory_id,
|
|
3937
|
+
hasProperties: !!memory?.properties,
|
|
3938
|
+
propertyCount: memory?.properties ? Object.keys(memory.properties).length : 0,
|
|
3939
|
+
hasTitle: !!memory?.properties?.title,
|
|
3940
|
+
hasContent: !!memory?.properties?.content
|
|
3909
3941
|
});
|
|
3910
3942
|
if (!memory) {
|
|
3911
3943
|
logger.info("Memory not found", {
|
|
@@ -4092,13 +4124,18 @@ async function executePublishMemory(request, userId) {
|
|
|
4092
4124
|
collectionName: getMemoryCollectionName(userId),
|
|
4093
4125
|
memoryId: request.payload.memory_id
|
|
4094
4126
|
});
|
|
4095
|
-
const originalMemory = await
|
|
4127
|
+
const originalMemory = await fetchMemoryWithAllProperties(
|
|
4128
|
+
userCollection,
|
|
4096
4129
|
request.payload.memory_id
|
|
4097
4130
|
);
|
|
4098
4131
|
logger.debug("Original memory fetch result", {
|
|
4099
4132
|
function: "executePublishMemory",
|
|
4100
4133
|
found: !!originalMemory,
|
|
4101
|
-
memoryId: request.payload.memory_id
|
|
4134
|
+
memoryId: request.payload.memory_id,
|
|
4135
|
+
hasProperties: !!originalMemory?.properties,
|
|
4136
|
+
propertyCount: originalMemory?.properties ? Object.keys(originalMemory.properties).length : 0,
|
|
4137
|
+
hasTitle: !!originalMemory?.properties?.title,
|
|
4138
|
+
hasContent: !!originalMemory?.properties?.content
|
|
4102
4139
|
});
|
|
4103
4140
|
if (!originalMemory) {
|
|
4104
4141
|
logger.info("Original memory not found", {
|
|
@@ -33,6 +33,22 @@ export declare function getTemplateCollectionName(userId: string): string;
|
|
|
33
33
|
* Get collection name for user's audit logs
|
|
34
34
|
*/
|
|
35
35
|
export declare function getAuditCollectionName(userId: string): string;
|
|
36
|
+
/**
|
|
37
|
+
* List of all memory properties to fetch
|
|
38
|
+
* Centralized to ensure consistency across all tools
|
|
39
|
+
*/
|
|
40
|
+
export declare const ALL_MEMORY_PROPERTIES: readonly ["user_id", "doc_type", "type", "title", "content", "tags", "weight", "base_weight", "trust_level", "context", "location", "relationships", "created_at", "updated_at", "version", "attribution", "source_url", "author", "parent_id", "thread_root_id", "moderation_flags"];
|
|
41
|
+
/**
|
|
42
|
+
* Fetch a memory object by ID with all properties
|
|
43
|
+
*
|
|
44
|
+
* This utility ensures all memory properties are fetched consistently
|
|
45
|
+
* across all tools, preventing bugs where properties are missing.
|
|
46
|
+
*
|
|
47
|
+
* @param collection - Weaviate collection
|
|
48
|
+
* @param memoryId - Memory ID to fetch
|
|
49
|
+
* @returns Memory object with all properties
|
|
50
|
+
*/
|
|
51
|
+
export declare function fetchMemoryWithAllProperties(collection: any, memoryId: string): Promise<any>;
|
|
36
52
|
/**
|
|
37
53
|
* Check if collection exists
|
|
38
54
|
*/
|
package/package.json
CHANGED
package/src/tools/confirm.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import type { Tool } from '@modelcontextprotocol/sdk/types.js';
|
|
9
9
|
import { confirmationTokenService, type ConfirmationRequest } from '../services/confirmation-token.service.js';
|
|
10
|
-
import { getWeaviateClient, getMemoryCollectionName } from '../weaviate/client.js';
|
|
10
|
+
import { getWeaviateClient, getMemoryCollectionName, fetchMemoryWithAllProperties } from '../weaviate/client.js';
|
|
11
11
|
import { ensurePublicCollection } from '../weaviate/space-schema.js';
|
|
12
12
|
import { handleToolError } from '../utils/error-handler.js';
|
|
13
13
|
import { logger } from '../utils/logger.js';
|
|
@@ -151,7 +151,8 @@ async function executePublishMemory(
|
|
|
151
151
|
memoryId: request.payload.memory_id,
|
|
152
152
|
});
|
|
153
153
|
|
|
154
|
-
const originalMemory = await
|
|
154
|
+
const originalMemory = await fetchMemoryWithAllProperties(
|
|
155
|
+
userCollection,
|
|
155
156
|
request.payload.memory_id
|
|
156
157
|
);
|
|
157
158
|
|
|
@@ -159,6 +160,10 @@ async function executePublishMemory(
|
|
|
159
160
|
function: 'executePublishMemory',
|
|
160
161
|
found: !!originalMemory,
|
|
161
162
|
memoryId: request.payload.memory_id,
|
|
163
|
+
hasProperties: !!originalMemory?.properties,
|
|
164
|
+
propertyCount: originalMemory?.properties ? Object.keys(originalMemory.properties).length : 0,
|
|
165
|
+
hasTitle: !!originalMemory?.properties?.title,
|
|
166
|
+
hasContent: !!originalMemory?.properties?.content,
|
|
162
167
|
});
|
|
163
168
|
|
|
164
169
|
if (!originalMemory) {
|
package/src/tools/publish.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import type { Tool } from '@modelcontextprotocol/sdk/types.js';
|
|
9
9
|
import { confirmationTokenService } from '../services/confirmation-token.service.js';
|
|
10
|
-
import { getWeaviateClient, getMemoryCollectionName } from '../weaviate/client.js';
|
|
10
|
+
import { getWeaviateClient, getMemoryCollectionName, fetchMemoryWithAllProperties } from '../weaviate/client.js';
|
|
11
11
|
import { isValidSpaceId } from '../weaviate/space-schema.js';
|
|
12
12
|
import { handleToolError } from '../utils/error-handler.js';
|
|
13
13
|
import { SUPPORTED_SPACES } from '../types/space-memory.js';
|
|
@@ -122,12 +122,16 @@ export async function handlePublish(
|
|
|
122
122
|
|
|
123
123
|
const userCollection = weaviateClient.collections.get(collectionName);
|
|
124
124
|
|
|
125
|
-
const memory = await userCollection
|
|
125
|
+
const memory = await fetchMemoryWithAllProperties(userCollection, args.memory_id);
|
|
126
126
|
|
|
127
127
|
logger.debug('Memory fetch result', {
|
|
128
128
|
tool: 'remember_publish',
|
|
129
129
|
found: !!memory,
|
|
130
130
|
memoryId: args.memory_id,
|
|
131
|
+
hasProperties: !!memory?.properties,
|
|
132
|
+
propertyCount: memory?.properties ? Object.keys(memory.properties).length : 0,
|
|
133
|
+
hasTitle: !!memory?.properties?.title,
|
|
134
|
+
hasContent: !!memory?.properties?.content,
|
|
131
135
|
});
|
|
132
136
|
|
|
133
137
|
if (!memory) {
|
package/src/weaviate/client.ts
CHANGED
|
@@ -139,6 +139,53 @@ export function getAuditCollectionName(userId: string): string {
|
|
|
139
139
|
return `Audit_${sanitizeUserId(userId)}`;
|
|
140
140
|
}
|
|
141
141
|
|
|
142
|
+
/**
|
|
143
|
+
* List of all memory properties to fetch
|
|
144
|
+
* Centralized to ensure consistency across all tools
|
|
145
|
+
*/
|
|
146
|
+
export const ALL_MEMORY_PROPERTIES = [
|
|
147
|
+
'user_id',
|
|
148
|
+
'doc_type',
|
|
149
|
+
'type',
|
|
150
|
+
'title',
|
|
151
|
+
'content',
|
|
152
|
+
'tags',
|
|
153
|
+
'weight',
|
|
154
|
+
'base_weight',
|
|
155
|
+
'trust_level',
|
|
156
|
+
'context',
|
|
157
|
+
'location',
|
|
158
|
+
'relationships',
|
|
159
|
+
'created_at',
|
|
160
|
+
'updated_at',
|
|
161
|
+
'version',
|
|
162
|
+
'attribution',
|
|
163
|
+
'source_url',
|
|
164
|
+
'author',
|
|
165
|
+
'parent_id',
|
|
166
|
+
'thread_root_id',
|
|
167
|
+
'moderation_flags',
|
|
168
|
+
] as const;
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Fetch a memory object by ID with all properties
|
|
172
|
+
*
|
|
173
|
+
* This utility ensures all memory properties are fetched consistently
|
|
174
|
+
* across all tools, preventing bugs where properties are missing.
|
|
175
|
+
*
|
|
176
|
+
* @param collection - Weaviate collection
|
|
177
|
+
* @param memoryId - Memory ID to fetch
|
|
178
|
+
* @returns Memory object with all properties
|
|
179
|
+
*/
|
|
180
|
+
export async function fetchMemoryWithAllProperties(
|
|
181
|
+
collection: any,
|
|
182
|
+
memoryId: string
|
|
183
|
+
) {
|
|
184
|
+
return await collection.query.fetchObjectById(memoryId, {
|
|
185
|
+
returnProperties: ALL_MEMORY_PROPERTIES,
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
|
|
142
189
|
/**
|
|
143
190
|
* Check if collection exists
|
|
144
191
|
*/
|