@prmichaelsen/remember-mcp 3.15.7 → 3.16.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/publish.yml +55 -0
- package/CHANGELOG.md +20 -0
- package/agent/design/local.unified-internal-memory-tools.md +325 -0
- package/agent/milestones/milestone-20-unified-internal-memory-tools.md +58 -0
- package/agent/progress.yaml +115 -1
- package/agent/tasks/milestone-20-unified-internal-memory-tools/task-212-add-internal-context-type.md +54 -0
- package/agent/tasks/milestone-20-unified-internal-memory-tools/task-213-update-server-factory-internal-context.md +117 -0
- package/agent/tasks/milestone-20-unified-internal-memory-tools/task-214-create-tag-builder-utility.md +50 -0
- package/agent/tasks/milestone-20-unified-internal-memory-tools/task-215-create-unified-internal-memory-tools.md +65 -0
- package/agent/tasks/milestone-20-unified-internal-memory-tools/task-216-update-default-search-filters.md +46 -0
- package/agent/tasks/milestone-20-unified-internal-memory-tools/task-217-delete-standalone-ghost-tools.md +46 -0
- package/agent/tasks/milestone-20-unified-internal-memory-tools/task-218-add-tests-unified-internal-tools.md +66 -0
- package/dist/e2e-helpers.d.ts +1 -1
- package/dist/server-factory.d.ts +17 -41
- package/dist/server-factory.js +420 -149
- package/dist/server.js +202 -20
- package/dist/tools/{create-ghost-memory.d.ts → create-internal-memory.d.ts} +7 -9
- package/dist/tools/internal-tools.spec.d.ts +2 -0
- package/dist/tools/{query-ghost-memory.d.ts → query-internal-memory.d.ts} +6 -6
- package/dist/tools/{search-ghost-memory-by.d.ts → search-internal-memory-by.d.ts} +6 -6
- package/dist/tools/{search-ghost-memory.d.ts → search-internal-memory.d.ts} +6 -6
- package/dist/tools/{update-ghost-memory.d.ts → update-internal-memory.d.ts} +6 -6
- package/dist/types/auth.d.ts +22 -8
- package/dist/utils/internal-tags.d.ts +14 -0
- package/dist/utils/internal-tags.spec.d.ts +2 -0
- package/package.json +2 -3
- package/src/e2e-helpers.ts +4 -2
- package/src/ghost-persona.e2e.ts +18 -17
- package/src/server-factory.ts +117 -55
- package/src/tools/create-internal-memory.ts +105 -0
- package/src/tools/find-similar.ts +2 -2
- package/src/tools/internal-tools.spec.ts +312 -0
- package/src/tools/query-internal-memory.ts +73 -0
- package/src/tools/query-memory.ts +15 -12
- package/src/tools/search-by.spec.ts +6 -2
- package/src/tools/search-by.ts +6 -6
- package/src/tools/{search-ghost-memory-by.ts → search-internal-memory-by.ts} +34 -27
- package/src/tools/search-internal-memory.ts +87 -0
- package/src/tools/search-memory.ts +15 -12
- package/src/tools/search-space.ts +1 -0
- package/src/tools/{update-ghost-memory.ts → update-internal-memory.ts} +23 -17
- package/src/types/auth.ts +22 -8
- package/src/utils/internal-tags.spec.ts +104 -0
- package/src/utils/internal-tags.ts +46 -0
- package/dist/tools/ghost-tools.spec.d.ts +0 -2
- package/src/tools/create-ghost-memory.ts +0 -103
- package/src/tools/ghost-tools.spec.ts +0 -361
- package/src/tools/query-ghost-memory.ts +0 -63
- package/src/tools/search-ghost-memory.ts +0 -73
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
name: Publish to npm
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [mainline]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
publish:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
permissions:
|
|
11
|
+
contents: read
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
with:
|
|
15
|
+
fetch-depth: 2
|
|
16
|
+
|
|
17
|
+
- uses: actions/setup-node@v4
|
|
18
|
+
with:
|
|
19
|
+
node-version: 20
|
|
20
|
+
registry-url: https://registry.npmjs.org
|
|
21
|
+
|
|
22
|
+
- name: Install dependencies
|
|
23
|
+
run: npm ci
|
|
24
|
+
|
|
25
|
+
- name: Build
|
|
26
|
+
run: npm run build
|
|
27
|
+
|
|
28
|
+
- name: Test
|
|
29
|
+
run: npm test
|
|
30
|
+
|
|
31
|
+
- name: Check if version changed
|
|
32
|
+
id: version
|
|
33
|
+
run: |
|
|
34
|
+
CURRENT=$(node -p "require('./package.json').version")
|
|
35
|
+
PREVIOUS=$(git show HEAD~1:package.json 2>/dev/null | node -p "JSON.parse(require('fs').readFileSync('/dev/stdin','utf8')).version" 2>/dev/null || echo "")
|
|
36
|
+
if [ "$CURRENT" != "$PREVIOUS" ]; then
|
|
37
|
+
echo "changed=true" >> "$GITHUB_OUTPUT"
|
|
38
|
+
echo "version=$CURRENT" >> "$GITHUB_OUTPUT"
|
|
39
|
+
else
|
|
40
|
+
echo "changed=false" >> "$GITHUB_OUTPUT"
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
- name: Publish
|
|
44
|
+
if: steps.version.outputs.changed == 'true'
|
|
45
|
+
run: npm publish --access public
|
|
46
|
+
env:
|
|
47
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
48
|
+
|
|
49
|
+
- name: Summary
|
|
50
|
+
if: steps.version.outputs.changed == 'true'
|
|
51
|
+
run: echo "Published @prmichaelsen/remember-mcp@${{ steps.version.outputs.version }} to npm"
|
|
52
|
+
|
|
53
|
+
- name: Skip
|
|
54
|
+
if: steps.version.outputs.changed != 'true'
|
|
55
|
+
run: echo "Version unchanged, skipping publish"
|
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.16.0] - 2026-03-08
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- `normalizeOptions()` in server-factory — maps flat mcp-auth extras (`internal_type`, `ghost_owner`, etc.) into structured `ServerOptions.internalContext`
|
|
13
|
+
- `createServer` now accepts either structured `ServerOptions` or flat `Record<string, string>` extras from mcp-auth
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- Replace `GhostModeContext` and `AuthContext.ghostMode` with unified `InternalContext` on `AuthContext.internalContext`
|
|
18
|
+
- `InternalContext` supports ghost (user/space/group) and agent session types via platform HTTP headers
|
|
19
|
+
- Server factory maps `X-Internal-Type`, `X-Ghost-Type`, `X-Ghost-Space`, `X-Ghost-Group` headers into `InternalContext`
|
|
20
|
+
- Trust resolution moved into `InternalContext` construction (accessor_trust_level)
|
|
21
|
+
- All search/query tools (`search-memory`, `query-memory`, `search-by`) rewired from `ghostMode` to `internalContext`
|
|
22
|
+
|
|
23
|
+
### Removed
|
|
24
|
+
|
|
25
|
+
- Delete 5 standalone ghost tool files (`create-ghost-memory`, `update-ghost-memory`, `search-ghost-memory`, `query-ghost-memory`, `search-ghost-memory-by`) and `ghost-tools.spec.ts` — replaced by unified `remember_*_internal_memory` tools
|
|
26
|
+
- Remove ghost tool imports, tool list entries, and switch cases from server-factory
|
|
27
|
+
|
|
8
28
|
## [3.15.7] - 2026-03-07
|
|
9
29
|
|
|
10
30
|
### Changed
|
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
# Unified Internal Memory Tool Suite
|
|
2
|
+
|
|
3
|
+
**Concept**: Replace separate ghost/agent tool suites with 5 unified `remember_*_internal_memory` tools whose behavior is driven by HTTP headers
|
|
4
|
+
**Created**: 2026-03-07
|
|
5
|
+
**Status**: Design Specification
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
This document describes the design for a unified internal memory tool suite that replaces separate ghost and agent tool implementations. Instead of maintaining 5 ghost tools + 5 agent tools (10 total), we define 5 `remember_*_internal_memory` tools whose behavior is determined by platform-sent HTTP headers (`X-Internal-Type`, `X-Ghost-Type`, etc.).
|
|
12
|
+
|
|
13
|
+
The design also addresses ghost source isolation — the problem that a single user's collection can contain ghost memories from multiple distinct ghost conversations (different user ghosts, space ghosts, group ghosts), and these need to be distinguishable via tags.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Problem Statement
|
|
18
|
+
|
|
19
|
+
1. **Tool proliferation**: Ghost tools hardcode `content_type: 'ghost'` and ghost-specific tags. Adding an equivalent agent tool suite means 5 more tools (10 total), with significant code duplication.
|
|
20
|
+
|
|
21
|
+
2. **Ghost source isolation**: A user's collection can hold ghost memories from multiple ghost conversations. Bob might talk to alice's ghost, carol's ghost, and the music-lovers space ghost — all producing `content_type: 'ghost'` memories in bob's collection. The current `ghost:{accessor_user_id}` tag is redundant (bob is always the accessor in his own collection) and doesn't distinguish which ghost the memory came from.
|
|
22
|
+
|
|
23
|
+
3. **Agent memories needed**: AI agent observations need a parallel storage pattern (`content_type: 'agent'`) with similar create/search/query tools, excluded from default user searches.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Solution
|
|
28
|
+
|
|
29
|
+
### Unified Tools (5 replacing 10+)
|
|
30
|
+
|
|
31
|
+
Five `remember_*_internal_memory` tools that derive their behavior from server-side context set via HTTP headers:
|
|
32
|
+
|
|
33
|
+
| Tool | Purpose |
|
|
34
|
+
|------|---------|
|
|
35
|
+
| `remember_create_internal_memory` | Create ghost or agent memory |
|
|
36
|
+
| `remember_update_internal_memory` | Update ghost or agent memory |
|
|
37
|
+
| `remember_search_internal_memory` | Semantic search ghost or agent memories |
|
|
38
|
+
| `remember_query_internal_memory` | Query ghost or agent memories |
|
|
39
|
+
| `remember_search_internal_memory_by` | Structured browse/sort ghost or agent memories |
|
|
40
|
+
|
|
41
|
+
The platform (agentbase.me) sends headers indicating the conversation context. The tools error if no internal context headers are present — they cannot be used as normal memory tools.
|
|
42
|
+
|
|
43
|
+
### Ghost Source Isolation via Tags
|
|
44
|
+
|
|
45
|
+
Each ghost memory gets tags identifying its source:
|
|
46
|
+
|
|
47
|
+
| Ghost type | Tags |
|
|
48
|
+
|------------|------|
|
|
49
|
+
| User ghost (alice) | `ghost`, `ghost_type:user`, `ghost_owner:user:alice` |
|
|
50
|
+
| Space ghost (music-lovers) | `ghost`, `ghost_type:space`, `ghost_owner:space:music-lovers` |
|
|
51
|
+
| Group ghost (band-mates) | `ghost`, `ghost_type:group`, `ghost_owner:group:band-mates` |
|
|
52
|
+
| Agent | `agent` |
|
|
53
|
+
|
|
54
|
+
The old `ghost:{accessor_user_id}` tag is dropped (redundant in accessor's own collection).
|
|
55
|
+
|
|
56
|
+
### Ghost Memory Storage Model
|
|
57
|
+
|
|
58
|
+
Ghost memories are always written to the **accessor's** (conversing user's) collection. When bob talks to alice's ghost, memories go in bob's collection. These are metadata for the ghost to understand how to interact with bob long-term. This applies uniformly to user ghosts, space ghosts, and group ghosts.
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Implementation
|
|
63
|
+
|
|
64
|
+
### 1. Platform Headers
|
|
65
|
+
|
|
66
|
+
The platform sends these headers based on conversation type:
|
|
67
|
+
|
|
68
|
+
| Header | Values | Purpose |
|
|
69
|
+
|--------|--------|---------|
|
|
70
|
+
| `X-Internal-Type` | `ghost`, `agent` | Which internal content type (drives unified tool behavior) |
|
|
71
|
+
| `X-Ghost-Owner` | `alice` (already exists) | Whose ghost (user ghosts) |
|
|
72
|
+
| `X-Ghost-Type` | `user`, `space`, `group` | What kind of ghost (required, not inferred) |
|
|
73
|
+
| `X-Ghost-Space` | `music-lovers` | Space ID (space ghosts only) |
|
|
74
|
+
| `X-Ghost-Group` | `band-mates` | Group ID (group ghosts only) |
|
|
75
|
+
|
|
76
|
+
Header combinations by conversation type:
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
# User ghost (bob talking to alice's ghost)
|
|
80
|
+
X-Internal-Type: ghost
|
|
81
|
+
X-Ghost-Owner: alice
|
|
82
|
+
X-Ghost-Type: user
|
|
83
|
+
|
|
84
|
+
# Space ghost (bob talking to music-lovers space ghost)
|
|
85
|
+
X-Internal-Type: ghost
|
|
86
|
+
X-Ghost-Type: space
|
|
87
|
+
X-Ghost-Space: music-lovers
|
|
88
|
+
|
|
89
|
+
# Group ghost (bob talking to band-mates group ghost)
|
|
90
|
+
X-Internal-Type: ghost
|
|
91
|
+
X-Ghost-Type: group
|
|
92
|
+
X-Ghost-Group: band-mates
|
|
93
|
+
|
|
94
|
+
# Agent (bob's personal agent)
|
|
95
|
+
X-Internal-Type: agent
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### 2. Server Context
|
|
99
|
+
|
|
100
|
+
`mcp-auth` extracts `X-*` headers into `extras` (snake_case). The server factory maps these into `InternalContext`:
|
|
101
|
+
|
|
102
|
+
```typescript
|
|
103
|
+
// types/auth.ts
|
|
104
|
+
export interface InternalContext {
|
|
105
|
+
type: 'ghost' | 'agent';
|
|
106
|
+
ghost_type?: 'user' | 'space' | 'group';
|
|
107
|
+
ghost_space?: string;
|
|
108
|
+
ghost_group?: string;
|
|
109
|
+
// Absorbed from former GhostModeContext:
|
|
110
|
+
owner_user_id?: string; // ghost owner (user ghosts)
|
|
111
|
+
accessor_user_id: string; // who is conversing
|
|
112
|
+
accessor_trust_level?: number; // resolved trust (ghost only)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export interface AuthContext {
|
|
116
|
+
accessToken: string | null;
|
|
117
|
+
credentials: UserCredentials | null;
|
|
118
|
+
internalContext?: InternalContext;
|
|
119
|
+
// ghostMode is removed — absorbed into internalContext
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Server factory mapping (ghostMode removed — all context on internalContext):
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
serverFactory: async (accessToken, userId, extras) => {
|
|
127
|
+
const internalType = extras?.internal_type as string | undefined;
|
|
128
|
+
let internalContext: InternalContext | undefined;
|
|
129
|
+
|
|
130
|
+
if (internalType) {
|
|
131
|
+
const ghostOwner = extras?.ghost_owner as string | undefined;
|
|
132
|
+
let accessorTrustLevel: number | undefined;
|
|
133
|
+
|
|
134
|
+
if (internalType === 'ghost' && ghostOwner) {
|
|
135
|
+
const ghostConfig = await getGhostConfig(ghostOwner);
|
|
136
|
+
accessorTrustLevel = await resolveAccessorTrustLevel(ghostConfig, ghostOwner, userId);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
internalContext = {
|
|
140
|
+
type: internalType as 'ghost' | 'agent',
|
|
141
|
+
ghost_type: extras?.ghost_type as 'user' | 'space' | 'group' | undefined,
|
|
142
|
+
ghost_space: extras?.ghost_space as string | undefined,
|
|
143
|
+
ghost_group: extras?.ghost_group as string | undefined,
|
|
144
|
+
owner_user_id: ghostOwner,
|
|
145
|
+
accessor_user_id: userId,
|
|
146
|
+
accessor_trust_level: accessorTrustLevel,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return await createRememberServer(accessToken, userId, { internalContext });
|
|
151
|
+
},
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### 3. Tag Builder
|
|
155
|
+
|
|
156
|
+
```typescript
|
|
157
|
+
function buildInternalTags(authContext: AuthContext): string[] {
|
|
158
|
+
const ctx = authContext.internalContext;
|
|
159
|
+
if (!ctx) return [];
|
|
160
|
+
|
|
161
|
+
if (ctx.type === 'agent') {
|
|
162
|
+
return ['agent'];
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const tags = ['ghost'];
|
|
166
|
+
|
|
167
|
+
switch (ctx.ghost_type) {
|
|
168
|
+
case 'user':
|
|
169
|
+
tags.push('ghost_type:user');
|
|
170
|
+
if (ctx.owner_user_id) {
|
|
171
|
+
tags.push(`ghost_owner:user:${ctx.owner_user_id}`);
|
|
172
|
+
}
|
|
173
|
+
break;
|
|
174
|
+
case 'space':
|
|
175
|
+
tags.push('ghost_type:space');
|
|
176
|
+
if (ctx.ghost_space) {
|
|
177
|
+
tags.push(`ghost_owner:space:${ctx.ghost_space}`);
|
|
178
|
+
}
|
|
179
|
+
break;
|
|
180
|
+
case 'group':
|
|
181
|
+
tags.push('ghost_type:group');
|
|
182
|
+
if (ctx.ghost_group) {
|
|
183
|
+
tags.push(`ghost_owner:group:${ctx.ghost_group}`);
|
|
184
|
+
}
|
|
185
|
+
break;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
return tags;
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### 4. Search Auto-Scoping
|
|
193
|
+
|
|
194
|
+
Search tools auto-scope to the current ghost source via headers. When alice's ghost searches bob's collection, it auto-filters to `ghost_owner:user:alice` — it cannot see memories from carol's ghost or space ghosts. No override is allowed.
|
|
195
|
+
|
|
196
|
+
```typescript
|
|
197
|
+
// In search/query handlers
|
|
198
|
+
const ctx = authContext.internalContext;
|
|
199
|
+
if (!ctx) {
|
|
200
|
+
throw new Error('Internal context required. X-Internal-Type header must be set.');
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
const typeTags = buildInternalTags(authContext);
|
|
204
|
+
const scopeTags = typeTags.filter(t => t !== 'ghost' && t !== 'agent');
|
|
205
|
+
|
|
206
|
+
const filters = {
|
|
207
|
+
...args.filters,
|
|
208
|
+
types: [ctx.type],
|
|
209
|
+
tags: [...(args.filters?.tags ?? []), ...scopeTags],
|
|
210
|
+
};
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### 5. Content Type
|
|
214
|
+
|
|
215
|
+
- `'agent'` must be added to the `ContentType` enum in remember-core
|
|
216
|
+
- Default searches (`remember_search_memory`, etc.) must exclude both `ghost` and `agent` content types
|
|
217
|
+
|
|
218
|
+
### 6. Agent Auto-Tags
|
|
219
|
+
|
|
220
|
+
Agent memories get the `agent` tag. An optional `agent:conversation:{conversationId}` tag is supported for future session isolation but not actively used yet.
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## Benefits
|
|
225
|
+
|
|
226
|
+
- **Fewer tools**: 5 tools instead of 10+, reducing LLM tool choice complexity
|
|
227
|
+
- **Context-driven**: Platform determines behavior via headers — LLM can't pick wrong type
|
|
228
|
+
- **Ghost isolation**: Tags distinguish memories from different ghost conversations
|
|
229
|
+
- **Extensible**: New internal types can be added via headers without new tool suites
|
|
230
|
+
- **Consistent**: Ghost and agent memories follow same create/search/query pattern
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
## Trade-offs
|
|
235
|
+
|
|
236
|
+
- **Implicit behavior**: Tool behavior changes based on headers, not visible in tool schema. Mitigated by tools erroring without headers.
|
|
237
|
+
- **Header dependency**: Platform must send correct headers. Mitigated by non-blocking rollout — platform updates in parallel.
|
|
238
|
+
- **Lost legacy data**: Existing ghost memories lack new source tags and won't be backfilled. Acceptable given minimal existing data.
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
## Dependencies
|
|
243
|
+
|
|
244
|
+
- **remember-core**: Add `'agent'` to `ContentType` enum
|
|
245
|
+
- **remember-mcp-server**: Map new headers into `InternalContext` on `ServerOptions`
|
|
246
|
+
- **agentbase.me (platform)**: Send `X-Internal-Type`, `X-Ghost-Type`, `X-Ghost-Space`, `X-Ghost-Group` headers
|
|
247
|
+
- **mcp-auth**: Already supports `X-*` header extraction (no changes needed)
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
## Testing Strategy
|
|
252
|
+
|
|
253
|
+
- **Unit tests**: Tag builder produces correct tags for each ghost type and agent
|
|
254
|
+
- **Unit tests**: Search auto-scoping applies correct filters
|
|
255
|
+
- **Unit tests**: Tools error when no `internalContext` is present
|
|
256
|
+
- **Integration tests**: End-to-end create → search with ghost source isolation (alice's ghost memories don't leak into carol's ghost searches)
|
|
257
|
+
- **Integration tests**: Default search tools exclude `agent` and `ghost` content types
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## Migration Path
|
|
262
|
+
|
|
263
|
+
1. Add `InternalContext` to `AuthContext` and `ServerOptions` in remember-mcp
|
|
264
|
+
2. Add `'agent'` to `ContentType` enum in remember-core
|
|
265
|
+
3. Create 5 unified `remember_*_internal_memory` tools
|
|
266
|
+
4. Delete existing 5 standalone ghost tools
|
|
267
|
+
5. Update default search filters to exclude `agent` content type
|
|
268
|
+
6. Platform starts sending new headers (`X-Internal-Type`, `X-Ghost-Type`, `X-Ghost-Space`, `X-Ghost-Group`)
|
|
269
|
+
|
|
270
|
+
Steps 1-5 are remember-mcp changes. Step 6 is platform work done in parallel (non-blocking).
|
|
271
|
+
|
|
272
|
+
---
|
|
273
|
+
|
|
274
|
+
## Key Design Decisions
|
|
275
|
+
|
|
276
|
+
### Ghost Memory Architecture
|
|
277
|
+
|
|
278
|
+
| Decision | Choice | Rationale |
|
|
279
|
+
|---|---|---|
|
|
280
|
+
| Ghost memory collection target | Accessor's collection (always) | Ghost memories are metadata for understanding the conversation partner long-term |
|
|
281
|
+
| Ghost source tag scheme | `ghost_owner:{type}:{id}` | Consistent pattern across user/space/group ghosts |
|
|
282
|
+
| Drop `ghost:{accessor_user_id}` tag | Yes | Redundant — accessor is always the collection owner |
|
|
283
|
+
| `X-Ghost-Type: user` requirement | Required (not inferred) | Clarity and future-proofing |
|
|
284
|
+
| Search auto-scoping | Based on headers, no override | Each ghost only sees its own memories |
|
|
285
|
+
|
|
286
|
+
### Tool Architecture
|
|
287
|
+
|
|
288
|
+
| Decision | Choice | Rationale |
|
|
289
|
+
|---|---|---|
|
|
290
|
+
| Unified vs separate tools | Unified (5 tools, header-driven) | Fewer tools, context-driven, extensible |
|
|
291
|
+
| No-context behavior | Error | Prevents misuse as normal memory tools |
|
|
292
|
+
| Agent content_type | `'agent'` | Follows ghost pattern |
|
|
293
|
+
| Exclude agent from default search | Yes | Matches ghost exclusion pattern |
|
|
294
|
+
| Agent auto-tags | `agent` + optional `agent:conversation:{id}` | Simple now, extensible later |
|
|
295
|
+
|
|
296
|
+
### Migration
|
|
297
|
+
|
|
298
|
+
| Decision | Choice | Rationale |
|
|
299
|
+
|---|---|---|
|
|
300
|
+
| Existing ghost tools | Delete | Clean break, no aliases |
|
|
301
|
+
| Existing ghost memories | No backfill (acceptable loss) | Minimal existing data |
|
|
302
|
+
| Platform header rollout | Non-blocking | Platform ships headers in parallel |
|
|
303
|
+
|
|
304
|
+
### Space & Group Ghosts
|
|
305
|
+
|
|
306
|
+
| Decision | Choice | Rationale |
|
|
307
|
+
|---|---|---|
|
|
308
|
+
| Space ghost personality | Synthesized from published space memories | Represents the collective space identity |
|
|
309
|
+
| Space ghost search scope | Space published memories + accessor's ghost memories | Published for knowledge, ghost memories for conversation continuity |
|
|
310
|
+
| Group vs space ghost implementation | Same, different source tag | No meaningful behavioral difference |
|
|
311
|
+
|
|
312
|
+
---
|
|
313
|
+
|
|
314
|
+
## Future Considerations
|
|
315
|
+
|
|
316
|
+
- **Conversation-level agent isolation**: `agent:conversation:{conversationId}` tag is reserved for future use
|
|
317
|
+
- **Ghost memory backfill**: If needed later, existing ghost memories could be tagged based on `ghost:{userId}` → `ghost_owner:user:{userId}` mapping
|
|
318
|
+
- **Space ghost persona configuration**: Currently synthesized from published memories; could become configurable via space settings
|
|
319
|
+
- **Cross-ghost search**: Currently disallowed; could be enabled for admin/diagnostic purposes
|
|
320
|
+
|
|
321
|
+
---
|
|
322
|
+
|
|
323
|
+
**Status**: Design Specification
|
|
324
|
+
**Recommendation**: Implement in remember-mcp and remember-core, coordinate with platform for header rollout
|
|
325
|
+
**Related Documents**: [clarification-4-internal-memory-tool-suite.md](../clarifications/clarification-4-internal-memory-tool-suite.md), [tool-suite-refinement.draft.md](../drafts/tool-suite-refinement.draft.md), [local.ghost-persona-system.md](local.ghost-persona-system.md)
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Milestone 20: Unified Internal Memory Tools
|
|
2
|
+
|
|
3
|
+
**Goal**: Replace separate ghost/agent tool suites with 5 unified `remember_*_internal_memory` tools driven by HTTP headers, with ghost source isolation via `ghost_owner:{type}:{id}` tags
|
|
4
|
+
|
|
5
|
+
**Started**: -
|
|
6
|
+
**Status**: Not Started
|
|
7
|
+
**Estimated Duration**: 1-2 weeks
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Overview
|
|
12
|
+
|
|
13
|
+
Consolidate 5 standalone ghost tools + future agent tools into 5 unified internal memory tools. Behavior is determined by platform-sent HTTP headers (`X-Internal-Type`, `X-Ghost-Type`, etc.), not by which tool is called. Ghost source isolation tags (`ghost_owner:user:alice`, `ghost_owner:space:music-lovers`) replace the redundant `ghost:{accessor_user_id}` tag.
|
|
14
|
+
|
|
15
|
+
## Deliverables
|
|
16
|
+
|
|
17
|
+
1. `InternalContext` type added to `AuthContext`
|
|
18
|
+
2. `'agent'` content type added to remember-core
|
|
19
|
+
3. Tag builder utility (`buildInternalTags`)
|
|
20
|
+
4. Server factory header mapping for new `X-*` headers
|
|
21
|
+
5. 5 unified `remember_*_internal_memory` tools
|
|
22
|
+
6. Existing 5 ghost tools deleted
|
|
23
|
+
7. Default search filters updated to exclude `agent` content type
|
|
24
|
+
8. Unit + integration tests
|
|
25
|
+
|
|
26
|
+
## Success Criteria
|
|
27
|
+
|
|
28
|
+
- [ ] 5 unified tools registered and functional
|
|
29
|
+
- [ ] Ghost memories tagged with `ghost_type:{type}` + `ghost_owner:{type}:{id}`
|
|
30
|
+
- [ ] Agent memories tagged with `agent` and `content_type: 'agent'`
|
|
31
|
+
- [ ] Search auto-scopes to current ghost source (no cross-ghost leakage)
|
|
32
|
+
- [ ] Tools error when no `X-Internal-Type` header is present
|
|
33
|
+
- [ ] Default user searches exclude both `ghost` and `agent` content types
|
|
34
|
+
- [ ] Old ghost tools deleted (no aliases)
|
|
35
|
+
- [ ] All existing tests pass, new tests cover unified tools
|
|
36
|
+
|
|
37
|
+
## Tasks
|
|
38
|
+
|
|
39
|
+
| ID | Name | Est. Hours | Status |
|
|
40
|
+
|----|------|-----------|--------|
|
|
41
|
+
| task-212 | Add InternalContext type and agent content type | 2-3 | not_started |
|
|
42
|
+
| task-213 | Update server factory for internal context headers | 2-3 | not_started |
|
|
43
|
+
| task-214 | Create tag builder utility | 2-3 | not_started |
|
|
44
|
+
| task-215 | Create unified internal memory tools | 6-8 | not_started |
|
|
45
|
+
| task-216 | Update default search filters for agent exclusion | 2-3 | not_started |
|
|
46
|
+
| task-217 | Delete standalone ghost tools | 1-2 | not_started |
|
|
47
|
+
| task-218 | Add unit and integration tests | 4-6 | not_started |
|
|
48
|
+
|
|
49
|
+
## Dependencies
|
|
50
|
+
|
|
51
|
+
- remember-core: Add `'agent'` to `ContentType` enum (may need core PR)
|
|
52
|
+
- Platform (agentbase.me): Send new headers (non-blocking, parallel work)
|
|
53
|
+
|
|
54
|
+
## Design Reference
|
|
55
|
+
|
|
56
|
+
- [Unified Internal Memory Tools](../design/local.unified-internal-memory-tools.md)
|
|
57
|
+
- [Ghost Persona System](../design/local.ghost-persona-system.md)
|
|
58
|
+
- [Clarification 4](../clarifications/clarification-4-internal-memory-tool-suite.md)
|
package/agent/progress.yaml
CHANGED
|
@@ -5,7 +5,7 @@ project:
|
|
|
5
5
|
version: 3.15.4
|
|
6
6
|
started: 2026-02-11
|
|
7
7
|
status: in_progress
|
|
8
|
-
current_milestone:
|
|
8
|
+
current_milestone: M20
|
|
9
9
|
last_updated: 2026-03-07
|
|
10
10
|
|
|
11
11
|
milestones:
|
|
@@ -366,6 +366,21 @@ milestones:
|
|
|
366
366
|
See: agent/milestones/milestone-19-new-search-ghost-tools.md
|
|
367
367
|
Design: remember-core/agent/design/local.new-search-tools.md (authoritative)
|
|
368
368
|
|
|
369
|
+
- id: M20
|
|
370
|
+
name: Unified Internal Memory Tools
|
|
371
|
+
status: in_progress
|
|
372
|
+
progress: 100%
|
|
373
|
+
status: completed
|
|
374
|
+
estimated_weeks: 1-2
|
|
375
|
+
tasks_completed: 7
|
|
376
|
+
tasks_total: 7
|
|
377
|
+
notes: |
|
|
378
|
+
Replace 5 standalone ghost tools + future agent tools with 5 unified
|
|
379
|
+
remember_*_internal_memory tools. Header-driven behavior via X-Internal-Type.
|
|
380
|
+
Ghost source isolation via ghost_owner:{type}:{id} tags.
|
|
381
|
+
See: agent/milestones/milestone-20-unified-internal-memory-tools.md
|
|
382
|
+
Design: agent/design/local.unified-internal-memory-tools.md
|
|
383
|
+
|
|
369
384
|
tasks:
|
|
370
385
|
milestone_1:
|
|
371
386
|
- id: task-1
|
|
@@ -2294,3 +2309,102 @@ task_20_completion:
|
|
|
2294
2309
|
completed_date: null
|
|
2295
2310
|
notes: |
|
|
2296
2311
|
API docs, architecture docs, usage examples.
|
|
2312
|
+
|
|
2313
|
+
milestone_20:
|
|
2314
|
+
- id: task-212
|
|
2315
|
+
name: Add InternalContext Type and Agent Content Type
|
|
2316
|
+
status: completed
|
|
2317
|
+
file: agent/tasks/milestone-20-unified-internal-memory-tools/task-212-add-internal-context-type.md
|
|
2318
|
+
estimated_hours: 2-3
|
|
2319
|
+
actual_hours: null
|
|
2320
|
+
completed_date: 2026-03-08
|
|
2321
|
+
notes: |
|
|
2322
|
+
✅ InternalContext interface added to types/auth.ts
|
|
2323
|
+
✅ GhostModeContext removed, fields absorbed into InternalContext
|
|
2324
|
+
✅ AuthContext.ghostMode replaced by AuthContext.internalContext
|
|
2325
|
+
|
|
2326
|
+
- id: task-213
|
|
2327
|
+
name: Update Server Factory — Replace ghostMode with InternalContext
|
|
2328
|
+
status: completed
|
|
2329
|
+
file: agent/tasks/milestone-20-unified-internal-memory-tools/task-213-update-server-factory-internal-context.md
|
|
2330
|
+
estimated_hours: 3-5
|
|
2331
|
+
actual_hours: null
|
|
2332
|
+
completed_date: 2026-03-08
|
|
2333
|
+
dependencies: [task-212]
|
|
2334
|
+
notes: |
|
|
2335
|
+
✅ server-factory.ts: ghostMode → internalContext with trust resolution
|
|
2336
|
+
✅ search-memory.ts, query-memory.ts, search-by.ts: rewired to internalContext
|
|
2337
|
+
✅ e2e-helpers.ts: updated ghost auth context
|
|
2338
|
+
✅ All test fixtures updated, 439 tests passing, TypeScript clean
|
|
2339
|
+
|
|
2340
|
+
- id: task-214
|
|
2341
|
+
name: Create Tag Builder Utility
|
|
2342
|
+
status: completed
|
|
2343
|
+
file: agent/tasks/milestone-20-unified-internal-memory-tools/task-214-create-tag-builder-utility.md
|
|
2344
|
+
estimated_hours: 2-3
|
|
2345
|
+
actual_hours: null
|
|
2346
|
+
completed_date: 2026-03-08
|
|
2347
|
+
dependencies: [task-212]
|
|
2348
|
+
notes: |
|
|
2349
|
+
✅ buildInternalTags utility in src/utils/internal-tags.ts
|
|
2350
|
+
✅ 8 unit tests covering all tag permutations
|
|
2351
|
+
|
|
2352
|
+
- id: task-215
|
|
2353
|
+
name: Create Unified Internal Memory Tools
|
|
2354
|
+
status: completed
|
|
2355
|
+
file: agent/tasks/milestone-20-unified-internal-memory-tools/task-215-create-unified-internal-memory-tools.md
|
|
2356
|
+
estimated_hours: 6-8
|
|
2357
|
+
actual_hours: null
|
|
2358
|
+
completed_date: 2026-03-08
|
|
2359
|
+
dependencies: [task-212, task-213, task-214]
|
|
2360
|
+
notes: |
|
|
2361
|
+
✅ 5 unified tools: create, update, search, query, search-by
|
|
2362
|
+
✅ Auto-tags via buildInternalTags, auto-scoping via scope tags
|
|
2363
|
+
✅ Error without internalContext
|
|
2364
|
+
✅ Registered in server-factory (34 tools total)
|
|
2365
|
+
✅ 447 tests passing, TypeScript clean
|
|
2366
|
+
|
|
2367
|
+
- id: task-216
|
|
2368
|
+
name: Update Default Search Filters for Agent Exclusion
|
|
2369
|
+
status: completed
|
|
2370
|
+
file: agent/tasks/milestone-20-unified-internal-memory-tools/task-216-update-default-search-filters.md
|
|
2371
|
+
estimated_hours: 2-3
|
|
2372
|
+
actual_hours: null
|
|
2373
|
+
completed_date: 2026-03-08
|
|
2374
|
+
dependencies: [task-212]
|
|
2375
|
+
notes: |
|
|
2376
|
+
✅ search-memory, query-memory: agent excluded alongside ghost
|
|
2377
|
+
✅ find-similar: post-filter excludes agent
|
|
2378
|
+
✅ search-space: agent excluded from space searches
|
|
2379
|
+
✅ 447 tests passing
|
|
2380
|
+
|
|
2381
|
+
- id: task-217
|
|
2382
|
+
name: Delete Standalone Ghost Tools
|
|
2383
|
+
status: completed
|
|
2384
|
+
file: agent/tasks/milestone-20-unified-internal-memory-tools/task-217-delete-standalone-ghost-tools.md
|
|
2385
|
+
estimated_hours: 1-2
|
|
2386
|
+
actual_hours: 1
|
|
2387
|
+
completed_date: '2026-03-08'
|
|
2388
|
+
dependencies: [task-215]
|
|
2389
|
+
notes: |
|
|
2390
|
+
✅ Deleted 5 ghost tool files + ghost-tools.spec.ts
|
|
2391
|
+
✅ Removed imports, tool list entries, and switch cases from server-factory
|
|
2392
|
+
✅ Rewrote ghost-persona.e2e.ts to use unified internal tools
|
|
2393
|
+
✅ Updated tag assertions for ghost source isolation
|
|
2394
|
+
✅ TypeScript compiles clean, 414 tests pass
|
|
2395
|
+
|
|
2396
|
+
- id: task-218
|
|
2397
|
+
name: Add Unit and Integration Tests
|
|
2398
|
+
status: completed
|
|
2399
|
+
file: agent/tasks/milestone-20-unified-internal-memory-tools/task-218-add-tests-unified-internal-tools.md
|
|
2400
|
+
estimated_hours: 4-6
|
|
2401
|
+
actual_hours: 1
|
|
2402
|
+
completed_date: '2026-03-08'
|
|
2403
|
+
dependencies: [task-214, task-215, task-216, task-217]
|
|
2404
|
+
notes: |
|
|
2405
|
+
✅ 8 tag builder unit tests (task-214, internal-tags.spec.ts)
|
|
2406
|
+
✅ 22 unified tool unit tests (internal-tools.spec.ts)
|
|
2407
|
+
✅ Context validation, content_type derivation, auto-scoping, tag merging
|
|
2408
|
+
✅ Ghost source isolation verified (scope tags filter per ghost type)
|
|
2409
|
+
✅ Agent exclusion from default search verified (task-216)
|
|
2410
|
+
✅ 436 total tests passing
|
package/agent/tasks/milestone-20-unified-internal-memory-tools/task-212-add-internal-context-type.md
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Task 212: Add InternalContext Type and Agent Content Type
|
|
2
|
+
|
|
3
|
+
**Milestone**: M20 — Unified Internal Memory Tools
|
|
4
|
+
**Status**: Not Started
|
|
5
|
+
**Estimated Hours**: 2-3
|
|
6
|
+
**Dependencies**: None
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Objective
|
|
11
|
+
|
|
12
|
+
Add the `InternalContext` interface to `src/types/auth.ts` and add `'agent'` to the `ContentType` enum in remember-core. These are foundational types required by all subsequent tasks.
|
|
13
|
+
|
|
14
|
+
## Context
|
|
15
|
+
|
|
16
|
+
The unified internal tool suite needs a server-side context object (`InternalContext`) that captures header-derived information about whether the current session is ghost or agent, and what type of ghost. The `'agent'` content type parallels the existing `'ghost'` content type.
|
|
17
|
+
|
|
18
|
+
## Design Reference
|
|
19
|
+
|
|
20
|
+
- [Unified Internal Memory Tools — Section 2: Server Context](../design/local.unified-internal-memory-tools.md)
|
|
21
|
+
|
|
22
|
+
## Steps
|
|
23
|
+
|
|
24
|
+
1. Add `InternalContext` interface to `src/types/auth.ts` (absorbs all former `GhostModeContext` fields):
|
|
25
|
+
```typescript
|
|
26
|
+
export interface InternalContext {
|
|
27
|
+
type: 'ghost' | 'agent';
|
|
28
|
+
ghost_type?: 'user' | 'space' | 'group';
|
|
29
|
+
ghost_space?: string;
|
|
30
|
+
ghost_group?: string;
|
|
31
|
+
owner_user_id?: string; // ghost owner (user ghosts)
|
|
32
|
+
accessor_user_id: string; // who is conversing
|
|
33
|
+
accessor_trust_level?: number; // resolved trust (ghost only)
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
2. Replace `ghostMode?: GhostModeContext` with `internalContext?: InternalContext` on `AuthContext`
|
|
38
|
+
|
|
39
|
+
3. Remove `GhostModeContext` interface (superseded by `InternalContext`)
|
|
40
|
+
|
|
41
|
+
4. Add `'agent'` to the `ContentType` enum/type in remember-core:
|
|
42
|
+
- If remember-core owns the enum, submit a PR to remember-core
|
|
43
|
+
- If remember-mcp extends it locally, add it to the local extension
|
|
44
|
+
|
|
45
|
+
5. Export `InternalContext` from the types module
|
|
46
|
+
|
|
47
|
+
## Verification
|
|
48
|
+
|
|
49
|
+
- [ ] `InternalContext` interface exists in `src/types/auth.ts` with all absorbed ghostMode fields
|
|
50
|
+
- [ ] `GhostModeContext` removed
|
|
51
|
+
- [ ] `AuthContext.ghostMode` replaced by `AuthContext.internalContext`
|
|
52
|
+
- [ ] `'agent'` is a valid `ContentType` value
|
|
53
|
+
- [ ] TypeScript compiles without errors
|
|
54
|
+
- [ ] Existing tests still pass (no breaking changes)
|