@prmichaelsen/remember-mcp 3.14.12 → 3.14.15
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 +20 -0
- package/agent/milestones/milestone-18-performance-tuning.md +45 -0
- package/agent/progress.yaml +86 -2
- package/agent/tasks/task-77-parallelize-checkiffriend.md +62 -0
- package/agent/tasks/task-78-cache-checkiffriend.md +78 -0
- package/agent/tasks/task-79-memoize-core-services.md +75 -0
- package/agent/tasks/task-80-parallelize-startup-health-checks.md +57 -0
- package/agent/tasks/task-81-optimize-ghost-config-block-unblock.md +64 -0
- package/agent/tasks/task-82-native-weaviate-offset.md +69 -0
- package/agent/tasks/task-83-eliminate-redundant-validatetoken.md +53 -0
- package/agent/tasks/task-84-static-imports-server-factory.md +52 -0
- package/dist/core-services.d.ts +3 -1
- package/dist/server-factory.js +2662 -3186
- package/dist/server.js +53 -55
- package/dist/services/access-control.d.ts +5 -5
- package/dist/services/ghost-config.service.d.ts +2 -0
- package/package.json +2 -2
- package/src/core-services.ts +16 -2
- package/src/server-factory.ts +5 -3
- package/src/server.ts +5 -3
- package/src/services/access-control.spec.ts +11 -11
- package/src/services/access-control.ts +73 -7
- package/src/services/ghost-config.service.spec.ts +22 -15
- package/src/services/ghost-config.service.ts +9 -15
- package/src/tools/search-memory.ts +4 -6
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,26 @@ 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
|
+
## [3.14.14] - 2026-03-04
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- Parallelize `checkIfFriend` Firestore queries with `Promise.all` (task-77)
|
|
13
|
+
- Add 60-second TTL cache to `checkIfFriend` for friend status lookups (task-78)
|
|
14
|
+
- Memoize `createCoreServices` per userId to avoid per-request service instantiation (task-79)
|
|
15
|
+
- Parallelize startup health checks (`testWeaviateConnection` + `testFirestoreConnection`) (task-80)
|
|
16
|
+
- Optimize `blockUser`/`unblockUser` with `FieldValue.arrayUnion`/`arrayRemove` — eliminates read RPC (task-81)
|
|
17
|
+
- Use native Weaviate `offset` parameter in `search-memory` instead of JS `slice()` (task-82)
|
|
18
|
+
- Convert dynamic `import()` to static imports for ghost-config and access-control in server-factory (task-84)
|
|
19
|
+
|
|
20
|
+
## [3.14.13] - 2026-03-04
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
|
|
24
|
+
- Fix `resolveAccessorTrustLevel` call sites to match new async 3-param signature (ownerUserId added for friend detection)
|
|
25
|
+
- Rewrite `checkIfFriend` to use `queryDocuments` from firebase-admin-sdk-v8 (was using nonexistent `getFirestore()`)
|
|
26
|
+
- Update access-control tests to use async/await with ownerUserId parameter
|
|
27
|
+
|
|
8
28
|
## [3.14.0] - 2026-02-28
|
|
9
29
|
|
|
10
30
|
### Changed
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Milestone 18: Performance Tuning
|
|
2
|
+
|
|
3
|
+
**Status**: Not Started
|
|
4
|
+
**Priority**: Medium
|
|
5
|
+
**Estimated Weeks**: 1
|
|
6
|
+
**Dependencies**: None
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Objective
|
|
11
|
+
|
|
12
|
+
Optimize remember-mcp server performance by eliminating redundant database calls, adding caching for rarely-changing data, parallelizing independent operations, and reducing per-request overhead.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Success Criteria
|
|
17
|
+
|
|
18
|
+
- [ ] Ghost mode requests do not make redundant Firestore queries for friend status
|
|
19
|
+
- [ ] Core services are cached per-user instead of recreated on every tool call
|
|
20
|
+
- [ ] Server startup parallelizes independent health checks
|
|
21
|
+
- [ ] No functional regressions — all existing tests pass
|
|
22
|
+
- [ ] Measurable latency improvement for ghost mode access checks
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Tasks
|
|
27
|
+
|
|
28
|
+
| # | Task | Status | Est. Hours |
|
|
29
|
+
|---|------|--------|------------|
|
|
30
|
+
| 77 | Parallelize checkIfFriend Firestore queries | Not Started | 0.5 |
|
|
31
|
+
| 78 | Add TTL cache to checkIfFriend | Not Started | 1 |
|
|
32
|
+
| 79 | Memoize createCoreServices per userId | Not Started | 1 |
|
|
33
|
+
| 80 | Parallelize startup health checks | Not Started | 0.5 |
|
|
34
|
+
| 81 | Optimize ghost-config block/unblock with FieldValue | Not Started | 1 |
|
|
35
|
+
| 82 | Use native Weaviate offset in search-memory | Not Started | 0.5 |
|
|
36
|
+
| 83 | Eliminate redundant validateToken in confirm flow | Not Started | 1 |
|
|
37
|
+
| 84 | Convert dynamic imports to static in server-factory | Not Started | 0.5 |
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Notes
|
|
42
|
+
|
|
43
|
+
- Task 63 in remember-core covers Weaviate collection pooling (separate project)
|
|
44
|
+
- Credential provider stub async overhead (#9 from audit) and esbuild parallelization (#10) are too trivial to warrant tasks
|
|
45
|
+
- All changes are internal — no API changes for consumers
|
package/agent/progress.yaml
CHANGED
|
@@ -341,6 +341,17 @@ milestones:
|
|
|
341
341
|
3 tools deferred (search_memory, query_memory, ghost_config) — require core ghost/trust support.
|
|
342
342
|
See: agent/milestones/milestone-17-remember-core-migration.md
|
|
343
343
|
|
|
344
|
+
- id: M18
|
|
345
|
+
name: Performance Tuning
|
|
346
|
+
status: in_progress
|
|
347
|
+
progress: 87%
|
|
348
|
+
estimated_weeks: 1
|
|
349
|
+
tasks_completed: 7
|
|
350
|
+
tasks_total: 8
|
|
351
|
+
notes: |
|
|
352
|
+
Optimize server performance: parallel queries, caching, memoization.
|
|
353
|
+
See: agent/milestones/milestone-18-performance-tuning.md
|
|
354
|
+
|
|
344
355
|
tasks:
|
|
345
356
|
milestone_1:
|
|
346
357
|
- id: task-1
|
|
@@ -986,11 +997,84 @@ tasks:
|
|
|
986
997
|
✅ Removed empty src/constants/ and src/collections/ directories.
|
|
987
998
|
✅ Build passing, 390 tests (389 passed, 1 skipped).
|
|
988
999
|
|
|
1000
|
+
milestone_18:
|
|
1001
|
+
- id: task-77
|
|
1002
|
+
name: Parallelize checkIfFriend Firestore Queries
|
|
1003
|
+
status: completed
|
|
1004
|
+
completed_date: 2026-03-04
|
|
1005
|
+
file: agent/tasks/task-77-parallelize-checkiffriend.md
|
|
1006
|
+
estimated_hours: 0.5
|
|
1007
|
+
notes: |
|
|
1008
|
+
Run forward + reverse friend queries in Promise.all
|
|
1009
|
+
|
|
1010
|
+
- id: task-78
|
|
1011
|
+
name: Add TTL Cache to checkIfFriend
|
|
1012
|
+
status: completed
|
|
1013
|
+
completed_date: 2026-03-04
|
|
1014
|
+
file: agent/tasks/task-78-cache-checkiffriend.md
|
|
1015
|
+
estimated_hours: 1
|
|
1016
|
+
dependencies: [task-77]
|
|
1017
|
+
notes: |
|
|
1018
|
+
60s TTL cache for friend status lookups
|
|
1019
|
+
|
|
1020
|
+
- id: task-79
|
|
1021
|
+
name: Memoize createCoreServices per userId
|
|
1022
|
+
status: completed
|
|
1023
|
+
completed_date: 2026-03-04
|
|
1024
|
+
file: agent/tasks/task-79-memoize-core-services.md
|
|
1025
|
+
estimated_hours: 1
|
|
1026
|
+
notes: |
|
|
1027
|
+
Cache CoreServices instances per userId
|
|
1028
|
+
|
|
1029
|
+
- id: task-80
|
|
1030
|
+
name: Parallelize Startup Health Checks
|
|
1031
|
+
status: completed
|
|
1032
|
+
completed_date: 2026-03-04
|
|
1033
|
+
file: agent/tasks/task-80-parallelize-startup-health-checks.md
|
|
1034
|
+
estimated_hours: 0.5
|
|
1035
|
+
notes: |
|
|
1036
|
+
Promise.all for testWeaviateConnection + testFirestoreConnection
|
|
1037
|
+
|
|
1038
|
+
- id: task-81
|
|
1039
|
+
name: Optimize ghost-config block/unblock with FieldValue
|
|
1040
|
+
status: completed
|
|
1041
|
+
completed_date: 2026-03-04
|
|
1042
|
+
file: agent/tasks/task-81-optimize-ghost-config-block-unblock.md
|
|
1043
|
+
estimated_hours: 1
|
|
1044
|
+
notes: |
|
|
1045
|
+
Use FieldValue.arrayUnion/arrayRemove to skip read RPC
|
|
1046
|
+
|
|
1047
|
+
- id: task-82
|
|
1048
|
+
name: Use Native Weaviate Offset in search-memory
|
|
1049
|
+
status: completed
|
|
1050
|
+
completed_date: 2026-03-04
|
|
1051
|
+
file: agent/tasks/task-82-native-weaviate-offset.md
|
|
1052
|
+
estimated_hours: 0.5
|
|
1053
|
+
notes: |
|
|
1054
|
+
Pass offset to Weaviate instead of JS slice
|
|
1055
|
+
|
|
1056
|
+
- id: task-83
|
|
1057
|
+
name: Eliminate Redundant validateToken in Confirm Flow
|
|
1058
|
+
status: deferred
|
|
1059
|
+
file: agent/tasks/task-83-eliminate-redundant-validatetoken.md
|
|
1060
|
+
estimated_hours: 1
|
|
1061
|
+
notes: |
|
|
1062
|
+
Remove peek-then-consume double read
|
|
1063
|
+
|
|
1064
|
+
- id: task-84
|
|
1065
|
+
name: Convert Dynamic Imports to Static in server-factory
|
|
1066
|
+
status: completed
|
|
1067
|
+
completed_date: 2026-03-04
|
|
1068
|
+
file: agent/tasks/task-84-static-imports-server-factory.md
|
|
1069
|
+
estimated_hours: 0.5
|
|
1070
|
+
notes: |
|
|
1071
|
+
Static imports for ghost-config and access-control
|
|
1072
|
+
|
|
989
1073
|
documentation:
|
|
990
1074
|
design_documents: 31
|
|
991
|
-
milestone_documents:
|
|
1075
|
+
milestone_documents: 14
|
|
992
1076
|
pattern_documents: 7
|
|
993
|
-
task_documents:
|
|
1077
|
+
task_documents: 91
|
|
994
1078
|
|
|
995
1079
|
progress:
|
|
996
1080
|
planning: 100%
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Task 77: Parallelize checkIfFriend Firestore Queries
|
|
2
|
+
|
|
3
|
+
**Milestone**: M18 - Performance Tuning
|
|
4
|
+
**Estimated Time**: 0.5 hours
|
|
5
|
+
**Dependencies**: None
|
|
6
|
+
**Status**: Not Started
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Objective
|
|
11
|
+
|
|
12
|
+
Run the two directional friendship queries in `checkIfFriend` concurrently with `Promise.all` instead of sequentially, cutting worst-case latency from ~400ms to ~200ms.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Context
|
|
17
|
+
|
|
18
|
+
`src/services/access-control.ts` `checkIfFriend()` queries Firestore twice sequentially (owner→accessor, then accessor→owner). These are independent queries that can run in parallel.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Steps
|
|
23
|
+
|
|
24
|
+
### 1. Refactor checkIfFriend to use Promise.all
|
|
25
|
+
|
|
26
|
+
**File**: `src/services/access-control.ts`
|
|
27
|
+
|
|
28
|
+
Replace the sequential pattern:
|
|
29
|
+
```typescript
|
|
30
|
+
const results = await queryDocuments(...forward...);
|
|
31
|
+
if (results.length > 0) return true;
|
|
32
|
+
const reverseResults = await queryDocuments(...reverse...);
|
|
33
|
+
return reverseResults.length > 0;
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
With parallel:
|
|
37
|
+
```typescript
|
|
38
|
+
const [forward, reverse] = await Promise.all([
|
|
39
|
+
queryDocuments(...forward...),
|
|
40
|
+
queryDocuments(...reverse...),
|
|
41
|
+
]);
|
|
42
|
+
return forward.length > 0 || reverse.length > 0;
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### 2. Verify tests pass
|
|
46
|
+
|
|
47
|
+
Run `npx jest --testPathPattern=access-control`.
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Verification
|
|
52
|
+
|
|
53
|
+
- [ ] Both queries run in parallel via Promise.all
|
|
54
|
+
- [ ] All access-control tests pass
|
|
55
|
+
- [ ] TypeScript compiles without errors
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Expected Output
|
|
60
|
+
|
|
61
|
+
**Files Modified**:
|
|
62
|
+
- `src/services/access-control.ts`
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Task 78: Add TTL Cache to checkIfFriend
|
|
2
|
+
|
|
3
|
+
**Milestone**: M18 - Performance Tuning
|
|
4
|
+
**Estimated Time**: 1 hour
|
|
5
|
+
**Dependencies**: Task 77
|
|
6
|
+
**Status**: Not Started
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Objective
|
|
11
|
+
|
|
12
|
+
Cache friend status lookups with a short TTL so repeated ghost mode access checks for the same user pair don't hit Firestore on every memory.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Context
|
|
17
|
+
|
|
18
|
+
`checkIfFriend` is called from `resolveAccessorTrustLevel` → `checkMemoryAccess`, which runs per-memory in prompt/hybrid enforcement modes. Friend status rarely changes during a session. A 60-second TTL cache eliminates redundant Firestore reads.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Steps
|
|
23
|
+
|
|
24
|
+
### 1. Add TTL Map cache
|
|
25
|
+
|
|
26
|
+
**File**: `src/services/access-control.ts`
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
const friendCache = new Map<string, { result: boolean; expiresAt: number }>();
|
|
30
|
+
const FRIEND_CACHE_TTL_MS = 60_000; // 60 seconds
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### 2. Check cache before querying
|
|
34
|
+
|
|
35
|
+
In `checkIfFriend`, check both directions (key `a:b` and `b:a` are the same friendship):
|
|
36
|
+
```typescript
|
|
37
|
+
const key = [ownerUserId, accessorUserId].sort().join(':');
|
|
38
|
+
const cached = friendCache.get(key);
|
|
39
|
+
if (cached && Date.now() < cached.expiresAt) return cached.result;
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### 3. Store result in cache after query
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
friendCache.set(key, { result, expiresAt: Date.now() + FRIEND_CACHE_TTL_MS });
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### 4. Export cache invalidation for tests
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
export function invalidateFriendCache(): void {
|
|
52
|
+
friendCache.clear();
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### 5. Add tests
|
|
57
|
+
|
|
58
|
+
- Cache hit returns without Firestore call
|
|
59
|
+
- Cache expires after TTL
|
|
60
|
+
- `invalidateFriendCache()` clears cache
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Verification
|
|
65
|
+
|
|
66
|
+
- [ ] Repeated calls for same user pair don't hit Firestore
|
|
67
|
+
- [ ] Cache expires after 60 seconds
|
|
68
|
+
- [ ] invalidateFriendCache works
|
|
69
|
+
- [ ] All existing tests pass
|
|
70
|
+
- [ ] New cache tests pass
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Expected Output
|
|
75
|
+
|
|
76
|
+
**Files Modified**:
|
|
77
|
+
- `src/services/access-control.ts`
|
|
78
|
+
- `src/services/access-control.spec.ts`
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Task 79: Memoize createCoreServices per userId
|
|
2
|
+
|
|
3
|
+
**Milestone**: M18 - Performance Tuning
|
|
4
|
+
**Estimated Time**: 1 hour
|
|
5
|
+
**Dependencies**: None
|
|
6
|
+
**Status**: Not Started
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Objective
|
|
11
|
+
|
|
12
|
+
Cache `CoreServices` instances per `userId` so that repeated tool calls don't instantiate new `MemoryService`, `RelationshipService`, and `SpaceService` objects on every invocation.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Context
|
|
17
|
+
|
|
18
|
+
`src/core-services.ts` `createCoreServices(userId)` is called by every tool handler. Each call creates 3 new service instances and calls `getMemoryCollection(userId)` (which calls `client.collections.get()`). In factory mode, the server is scoped to one userId, making all these allocations pure overhead after the first call.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Steps
|
|
23
|
+
|
|
24
|
+
### 1. Add Map cache
|
|
25
|
+
|
|
26
|
+
**File**: `src/core-services.ts`
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
const coreServicesCache = new Map<string, CoreServices>();
|
|
30
|
+
|
|
31
|
+
export function createCoreServices(userId: string): CoreServices {
|
|
32
|
+
const cached = coreServicesCache.get(userId);
|
|
33
|
+
if (cached) return cached;
|
|
34
|
+
|
|
35
|
+
const collection = getMemoryCollection(userId);
|
|
36
|
+
const weaviateClient = getWeaviateClient();
|
|
37
|
+
|
|
38
|
+
const services: CoreServices = {
|
|
39
|
+
memory: new MemoryService(collection, userId, coreLogger),
|
|
40
|
+
relationship: new RelationshipService(collection, userId, coreLogger),
|
|
41
|
+
space: new SpaceService(weaviateClient, collection, userId, tokenService, coreLogger),
|
|
42
|
+
preferences: preferencesService,
|
|
43
|
+
token: tokenService,
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
coreServicesCache.set(userId, services);
|
|
47
|
+
return services;
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### 2. Export invalidation for tests
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
export function invalidateCoreServicesCache(): void {
|
|
55
|
+
coreServicesCache.clear();
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### 3. Verify all tests pass
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Verification
|
|
64
|
+
|
|
65
|
+
- [ ] Second call for same userId returns cached instance
|
|
66
|
+
- [ ] Different userIds get different instances
|
|
67
|
+
- [ ] All existing tests pass
|
|
68
|
+
- [ ] TypeScript compiles without errors
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Expected Output
|
|
73
|
+
|
|
74
|
+
**Files Modified**:
|
|
75
|
+
- `src/core-services.ts`
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Task 80: Parallelize Startup Health Checks
|
|
2
|
+
|
|
3
|
+
**Milestone**: M18 - Performance Tuning
|
|
4
|
+
**Estimated Time**: 0.5 hours
|
|
5
|
+
**Dependencies**: None
|
|
6
|
+
**Status**: Not Started
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Objective
|
|
11
|
+
|
|
12
|
+
Run `testWeaviateConnection()` and `testFirestoreConnection()` in parallel during server startup to reduce init latency.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Context
|
|
17
|
+
|
|
18
|
+
`src/server.ts` lines 61-63 run these two independent health checks sequentially. Each is a network round-trip (50-200ms). Running them in parallel saves the latency of the slower one.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Steps
|
|
23
|
+
|
|
24
|
+
### 1. Update server.ts
|
|
25
|
+
|
|
26
|
+
**File**: `src/server.ts`
|
|
27
|
+
|
|
28
|
+
Replace:
|
|
29
|
+
```typescript
|
|
30
|
+
const weaviateOk = await testWeaviateConnection();
|
|
31
|
+
const firestoreOk = await testFirestoreConnection();
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
With:
|
|
35
|
+
```typescript
|
|
36
|
+
const [weaviateOk, firestoreOk] = await Promise.all([
|
|
37
|
+
testWeaviateConnection(),
|
|
38
|
+
testFirestoreConnection(),
|
|
39
|
+
]);
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### 2. Verify startup works
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Verification
|
|
47
|
+
|
|
48
|
+
- [ ] Server starts successfully
|
|
49
|
+
- [ ] Both connection tests still run
|
|
50
|
+
- [ ] TypeScript compiles without errors
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Expected Output
|
|
55
|
+
|
|
56
|
+
**Files Modified**:
|
|
57
|
+
- `src/server.ts`
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Task 81: Optimize ghost-config block/unblock with FieldValue
|
|
2
|
+
|
|
3
|
+
**Milestone**: M18 - Performance Tuning
|
|
4
|
+
**Estimated Time**: 1 hour
|
|
5
|
+
**Dependencies**: None
|
|
6
|
+
**Status**: Not Started
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Objective
|
|
11
|
+
|
|
12
|
+
Replace read-modify-write pattern in `blockUser` and `unblockUser` with Firestore `FieldValue.arrayUnion` / `FieldValue.arrayRemove` to eliminate the read RPC.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Context
|
|
17
|
+
|
|
18
|
+
`src/services/ghost-config.service.ts` `blockUser()` and `unblockUser()` each:
|
|
19
|
+
1. Read the entire GhostConfig document from Firestore
|
|
20
|
+
2. Modify the `blocked_users` array in memory
|
|
21
|
+
3. Write the document back
|
|
22
|
+
|
|
23
|
+
Firestore's `FieldValue.arrayUnion/arrayRemove` can atomically add/remove array elements without reading first, halving the RPC count for these operations.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Steps
|
|
28
|
+
|
|
29
|
+
### 1. Update blockUser
|
|
30
|
+
|
|
31
|
+
**File**: `src/services/ghost-config.service.ts`
|
|
32
|
+
|
|
33
|
+
Replace read-modify-write with:
|
|
34
|
+
```typescript
|
|
35
|
+
await setDocument(collectionPath, docId, {
|
|
36
|
+
blocked_users: FieldValue.arrayUnion(targetUserId),
|
|
37
|
+
}, { merge: true });
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### 2. Update unblockUser
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
await setDocument(collectionPath, docId, {
|
|
44
|
+
blocked_users: FieldValue.arrayRemove(targetUserId),
|
|
45
|
+
}, { merge: true });
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### 3. Verify ghost-config tests pass
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Verification
|
|
53
|
+
|
|
54
|
+
- [ ] blockUser works without reading first
|
|
55
|
+
- [ ] unblockUser works without reading first
|
|
56
|
+
- [ ] All ghost-config tests pass
|
|
57
|
+
- [ ] TypeScript compiles without errors
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Expected Output
|
|
62
|
+
|
|
63
|
+
**Files Modified**:
|
|
64
|
+
- `src/services/ghost-config.service.ts`
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Task 82: Use Native Weaviate Offset in search-memory
|
|
2
|
+
|
|
3
|
+
**Milestone**: M18 - Performance Tuning
|
|
4
|
+
**Estimated Time**: 0.5 hours
|
|
5
|
+
**Dependencies**: None
|
|
6
|
+
**Status**: Not Started
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Objective
|
|
11
|
+
|
|
12
|
+
Pass `offset` directly to Weaviate's hybrid search query instead of fetching `limit + offset` results and slicing in JavaScript.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Context
|
|
17
|
+
|
|
18
|
+
`src/tools/search-memory.ts` currently fetches extra records and uses `slice(offset)` to implement pagination. Weaviate v3 API supports native `offset` in query options, which reduces network payload for paginated searches.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Steps
|
|
23
|
+
|
|
24
|
+
### 1. Update search query options
|
|
25
|
+
|
|
26
|
+
**File**: `src/tools/search-memory.ts`
|
|
27
|
+
|
|
28
|
+
Replace:
|
|
29
|
+
```typescript
|
|
30
|
+
const searchOptions: any = {
|
|
31
|
+
alpha: alpha,
|
|
32
|
+
limit: limit + offset,
|
|
33
|
+
};
|
|
34
|
+
// ...
|
|
35
|
+
const paginatedResults = results.objects.slice(offset);
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
With:
|
|
39
|
+
```typescript
|
|
40
|
+
const searchOptions: any = {
|
|
41
|
+
alpha: alpha,
|
|
42
|
+
limit: limit,
|
|
43
|
+
offset: offset,
|
|
44
|
+
};
|
|
45
|
+
// ... use results.objects directly
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### 2. Check if same pattern exists in other search tools
|
|
49
|
+
|
|
50
|
+
Check `query-memory.ts`, `search-space.ts`, `query-space.ts`, `find-similar.ts` for the same pattern.
|
|
51
|
+
|
|
52
|
+
### 3. Verify tests pass
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Verification
|
|
57
|
+
|
|
58
|
+
- [ ] Offset handled by Weaviate, not JS slice
|
|
59
|
+
- [ ] Pagination still works correctly
|
|
60
|
+
- [ ] All search-related tests pass
|
|
61
|
+
- [ ] TypeScript compiles without errors
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Expected Output
|
|
66
|
+
|
|
67
|
+
**Files Modified**:
|
|
68
|
+
- `src/tools/search-memory.ts`
|
|
69
|
+
- Possibly other search tool files
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Task 83: Eliminate Redundant validateToken in Confirm Flow
|
|
2
|
+
|
|
3
|
+
**Milestone**: M18 - Performance Tuning
|
|
4
|
+
**Estimated Time**: 1 hour
|
|
5
|
+
**Dependencies**: None
|
|
6
|
+
**Status**: Not Started
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Objective
|
|
11
|
+
|
|
12
|
+
Remove the redundant `validateToken` call in the confirm tool's delete_memory path, where `confirmRequest` already retrieves the full token payload.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Context
|
|
17
|
+
|
|
18
|
+
`src/tools/confirm.ts` calls `tokenService.validateToken()` to peek at the token action type, then immediately calls `tokenService.confirmRequest()` which reads the token again. For the delete_memory path, this is two sequential storage reads when one would suffice.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Steps
|
|
23
|
+
|
|
24
|
+
### 1. Analyze confirm.ts flow
|
|
25
|
+
|
|
26
|
+
Read `src/tools/confirm.ts` to understand all action type branches and whether `confirmRequest` returns sufficient data to eliminate the validate step.
|
|
27
|
+
|
|
28
|
+
### 2. Refactor to single call
|
|
29
|
+
|
|
30
|
+
If `confirmRequest` returns the full request payload on success, use it directly:
|
|
31
|
+
```typescript
|
|
32
|
+
const confirmed = await tokenService.confirmRequest(userId, args.token);
|
|
33
|
+
if (!confirmed) { return error; }
|
|
34
|
+
// Use confirmed.action to determine path
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### 3. Verify all confirm-related tests pass
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Verification
|
|
42
|
+
|
|
43
|
+
- [ ] Only one storage read per confirm call
|
|
44
|
+
- [ ] All action types still handled correctly
|
|
45
|
+
- [ ] All confirm/deny tests pass
|
|
46
|
+
- [ ] TypeScript compiles without errors
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Expected Output
|
|
51
|
+
|
|
52
|
+
**Files Modified**:
|
|
53
|
+
- `src/tools/confirm.ts`
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Task 84: Convert Dynamic Imports to Static in server-factory
|
|
2
|
+
|
|
3
|
+
**Milestone**: M18 - Performance Tuning
|
|
4
|
+
**Estimated Time**: 0.5 hours
|
|
5
|
+
**Dependencies**: None
|
|
6
|
+
**Status**: Not Started
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Objective
|
|
11
|
+
|
|
12
|
+
Replace dynamic `import()` calls for ghost-config and access-control modules in `server-factory.ts` with static top-level imports to eliminate async module resolution overhead on the hot path.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Context
|
|
17
|
+
|
|
18
|
+
`src/server-factory.ts` lines 177-179 use `await import(...)` for `ghost-config.service.js` and `access-control.js` even though both modules are statically available. Dynamic imports add unnecessary microtask overhead on every server-factory instantiation with ghost mode.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Steps
|
|
23
|
+
|
|
24
|
+
### 1. Move imports to top level
|
|
25
|
+
|
|
26
|
+
**File**: `src/server-factory.ts`
|
|
27
|
+
|
|
28
|
+
Add static imports at the top:
|
|
29
|
+
```typescript
|
|
30
|
+
import { getGhostConfig } from './services/ghost-config.service.js';
|
|
31
|
+
import { resolveAccessorTrustLevel } from './services/access-control.js';
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Remove the dynamic imports inside the `if (options.ghostMode)` block.
|
|
35
|
+
|
|
36
|
+
### 2. Verify tests pass
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Verification
|
|
41
|
+
|
|
42
|
+
- [ ] No dynamic imports for ghost-config or access-control
|
|
43
|
+
- [ ] Ghost mode still works correctly
|
|
44
|
+
- [ ] All server-factory tests pass
|
|
45
|
+
- [ ] TypeScript compiles without errors
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Expected Output
|
|
50
|
+
|
|
51
|
+
**Files Modified**:
|
|
52
|
+
- `src/server-factory.ts`
|
package/dist/core-services.d.ts
CHANGED
|
@@ -17,9 +17,11 @@ declare const coreLogger: Logger;
|
|
|
17
17
|
declare const tokenService: ConfirmationTokenService;
|
|
18
18
|
declare const preferencesService: PreferencesDatabaseService;
|
|
19
19
|
/**
|
|
20
|
-
* Create core services scoped to a specific user.
|
|
20
|
+
* Create (or return cached) core services scoped to a specific user.
|
|
21
21
|
* Call after databases have been initialized (initWeaviateClient + initFirestore).
|
|
22
22
|
*/
|
|
23
23
|
export declare function createCoreServices(userId: string): CoreServices;
|
|
24
|
+
/** Clear the core services cache (for tests or forced refresh) */
|
|
25
|
+
export declare function invalidateCoreServicesCache(): void;
|
|
24
26
|
export { coreLogger, tokenService, preferencesService };
|
|
25
27
|
//# sourceMappingURL=core-services.d.ts.map
|