@prmichaelsen/remember-mcp 2.2.1 → 2.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENT.md +98 -5
- package/CHANGELOG.md +45 -0
- package/README.md +43 -3
- package/agent/commands/acp.init.md +376 -0
- package/agent/commands/acp.package-install.md +347 -0
- package/agent/commands/acp.proceed.md +311 -0
- package/agent/commands/acp.report.md +392 -0
- package/agent/commands/acp.status.md +280 -0
- package/agent/commands/acp.sync.md +323 -0
- package/agent/commands/acp.update.md +301 -0
- package/agent/commands/acp.validate.md +385 -0
- package/agent/commands/acp.version-check-for-updates.md +275 -0
- package/agent/commands/acp.version-check.md +190 -0
- package/agent/commands/acp.version-update.md +288 -0
- package/agent/commands/command.template.md +273 -0
- package/agent/design/core-memory-user-profile.md +1253 -0
- package/agent/design/ghost-profiles-pseudonymous-identity.md +194 -0
- package/agent/design/publish-tools-confirmation-flow.md +922 -0
- package/agent/milestones/milestone-10-shared-spaces.md +169 -0
- package/agent/progress.yaml +90 -4
- package/agent/scripts/install.sh +118 -0
- package/agent/scripts/update.sh +22 -10
- package/agent/scripts/version.sh +35 -0
- package/agent/tasks/task-27-implement-llm-provider-interface.md +51 -0
- package/agent/tasks/task-28-implement-llm-provider-factory.md +64 -0
- package/agent/tasks/task-29-update-config-for-llm.md +71 -0
- package/agent/tasks/task-30-implement-bedrock-provider.md +147 -0
- package/agent/tasks/task-31-implement-background-job-service.md +120 -0
- package/agent/tasks/task-32-test-llm-provider-integration.md +152 -0
- package/agent/tasks/task-34-create-confirmation-token-service.md +191 -0
- package/agent/tasks/task-35-create-space-memory-types-schema.md +183 -0
- package/agent/tasks/task-36-implement-remember-publish.md +227 -0
- package/agent/tasks/task-37-implement-remember-confirm.md +225 -0
- package/agent/tasks/task-38-implement-remember-deny.md +161 -0
- package/agent/tasks/task-39-implement-remember-search-space.md +188 -0
- package/agent/tasks/task-40-implement-remember-query-space.md +193 -0
- package/agent/tasks/task-41-configure-firestore-ttl.md +188 -0
- package/agent/tasks/task-42-create-tests-shared-spaces.md +216 -0
- package/agent/tasks/task-43-update-documentation.md +255 -0
- package/agent/tasks/task-44-implement-remember-retract.md +263 -0
- package/agent/tasks/task-45-fix-publish-false-success-bug.md +230 -0
- package/dist/llm/types.d.ts +1 -0
- package/dist/server-factory.js +1000 -1
- package/dist/server.js +1002 -3
- package/dist/services/confirmation-token.service.d.ts +99 -0
- package/dist/services/confirmation-token.service.spec.d.ts +5 -0
- package/dist/tools/confirm.d.ts +20 -0
- package/dist/tools/deny.d.ts +19 -0
- package/dist/tools/publish.d.ts +22 -0
- package/dist/tools/query-space.d.ts +28 -0
- package/dist/tools/search-space.d.ts +29 -0
- package/dist/types/space-memory.d.ts +80 -0
- package/dist/weaviate/space-schema.d.ts +59 -0
- package/dist/weaviate/space-schema.spec.d.ts +5 -0
- package/package.json +1 -1
- package/src/llm/types.ts +0 -0
- package/src/server-factory.ts +33 -0
- package/src/server.ts +33 -0
- package/src/services/confirmation-token.service.spec.ts +254 -0
- package/src/services/confirmation-token.service.ts +265 -0
- package/src/tools/confirm.ts +219 -0
- package/src/tools/create-memory.ts +7 -0
- package/src/tools/deny.ts +70 -0
- package/src/tools/publish.ts +190 -0
- package/src/tools/query-space.ts +197 -0
- package/src/tools/search-space.ts +189 -0
- package/src/types/space-memory.ts +94 -0
- package/src/weaviate/space-schema.spec.ts +131 -0
- package/src/weaviate/space-schema.ts +275 -0
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# Task 30: Implement Bedrock LLM Provider
|
|
2
|
+
|
|
3
|
+
**Milestone**: Phase 0 - LLM Provider Abstraction
|
|
4
|
+
**Estimated Time**: 3-4 hours
|
|
5
|
+
**Dependencies**: task-27, task-28, task-29
|
|
6
|
+
**Status**: Not Started
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Objective
|
|
11
|
+
|
|
12
|
+
Implement the AWS Bedrock LLM provider to enable Claude Sonnet 4 usage through Bedrock.
|
|
13
|
+
|
|
14
|
+
**Model**: `anthropic.claude-sonnet-4-5-20250929-v1:0`
|
|
15
|
+
|
|
16
|
+
## Steps
|
|
17
|
+
|
|
18
|
+
1. **Install dependencies**
|
|
19
|
+
- Add `@aws-sdk/client-bedrock-runtime` to package.json
|
|
20
|
+
- Run `npm install`
|
|
21
|
+
|
|
22
|
+
2. **Create provider directory**
|
|
23
|
+
- Create `src/llm/providers/` directory
|
|
24
|
+
- Create `src/llm/providers/bedrock.provider.ts`
|
|
25
|
+
|
|
26
|
+
3. **Implement BedrockLLMProvider class**
|
|
27
|
+
- Import `BedrockRuntimeClient`, `InvokeModelCommand` from AWS SDK
|
|
28
|
+
- Import `LLMProvider` interface and types
|
|
29
|
+
- Import config
|
|
30
|
+
- Create class implementing `LLMProvider`
|
|
31
|
+
|
|
32
|
+
4. **Implement constructor**
|
|
33
|
+
- Initialize `BedrockRuntimeClient` with credentials from config
|
|
34
|
+
- Use `config.llm.bedrock.region` (us-east-1)
|
|
35
|
+
- Use `config.llm.bedrock.accessKeyId`
|
|
36
|
+
- Use `config.llm.bedrock.secretAccessKey`
|
|
37
|
+
- Use `config.llm.bedrock.sessionToken` (optional)
|
|
38
|
+
- Store client as private property
|
|
39
|
+
|
|
40
|
+
5. **Implement complete() method**
|
|
41
|
+
- Accept messages and options
|
|
42
|
+
- Get model from options or use `config.llm.model` (default: anthropic.claude-sonnet-4-5-20250929-v1:0)
|
|
43
|
+
- Convert to Anthropic Bedrock format:
|
|
44
|
+
- Extract system message (role === 'system')
|
|
45
|
+
- Filter out system messages from conversation
|
|
46
|
+
- Build request body:
|
|
47
|
+
```typescript
|
|
48
|
+
{
|
|
49
|
+
anthropic_version: 'bedrock-2023-05-31',
|
|
50
|
+
max_tokens: options?.maxTokens || 4096,
|
|
51
|
+
temperature: options?.temperature || 0.7,
|
|
52
|
+
messages: conversationMessages,
|
|
53
|
+
system: systemMessage?.content
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
- Create `InvokeModelCommand`:
|
|
57
|
+
```typescript
|
|
58
|
+
new InvokeModelCommand({
|
|
59
|
+
modelId: model,
|
|
60
|
+
contentType: 'application/json',
|
|
61
|
+
accept: 'application/json',
|
|
62
|
+
body: JSON.stringify(body)
|
|
63
|
+
})
|
|
64
|
+
```
|
|
65
|
+
- Send command and parse response
|
|
66
|
+
- Convert response to `LLMCompletionResult`:
|
|
67
|
+
```typescript
|
|
68
|
+
{
|
|
69
|
+
content: result.content[0].text,
|
|
70
|
+
model: model,
|
|
71
|
+
usage: {
|
|
72
|
+
inputTokens: result.usage.input_tokens,
|
|
73
|
+
outputTokens: result.usage.output_tokens,
|
|
74
|
+
totalTokens: result.usage.input_tokens + result.usage.output_tokens
|
|
75
|
+
},
|
|
76
|
+
finishReason: result.stop_reason === 'end_turn' ? 'stop' : result.stop_reason
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
- Handle errors gracefully
|
|
80
|
+
|
|
81
|
+
6. **Implement validateConfig() method**
|
|
82
|
+
- Check required config values:
|
|
83
|
+
- `config.llm.bedrock.region` (should be 'us-east-1')
|
|
84
|
+
- `config.llm.bedrock.accessKeyId`
|
|
85
|
+
- `config.llm.bedrock.secretAccessKey`
|
|
86
|
+
- Throw descriptive errors if missing:
|
|
87
|
+
```typescript
|
|
88
|
+
if (!config.llm.bedrock.region) throw new Error('AWS_REGION required for Bedrock');
|
|
89
|
+
if (!config.llm.bedrock.accessKeyId) throw new Error('AWS_ACCESS_KEY_ID required for Bedrock');
|
|
90
|
+
if (!config.llm.bedrock.secretAccessKey) throw new Error('AWS_SECRET_ACCESS_KEY required for Bedrock');
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
7. **Add error handling**
|
|
94
|
+
- Wrap AWS SDK calls in try/catch
|
|
95
|
+
- Provide clear error messages
|
|
96
|
+
- Log errors with context
|
|
97
|
+
- Re-throw with additional context
|
|
98
|
+
|
|
99
|
+
8. **Update factory**
|
|
100
|
+
- Import `BedrockLLMProvider` in factory.ts
|
|
101
|
+
- Add case for 'bedrock' provider
|
|
102
|
+
- Instantiate and return provider
|
|
103
|
+
- Log: `[LLM] Using Bedrock provider with model: ${config.llm.model}`
|
|
104
|
+
|
|
105
|
+
## Verification
|
|
106
|
+
|
|
107
|
+
- [ ] TypeScript compiles without errors
|
|
108
|
+
- [ ] AWS SDK dependency installed
|
|
109
|
+
- [ ] Provider implements LLMProvider interface
|
|
110
|
+
- [ ] Constructor initializes Bedrock client
|
|
111
|
+
- [ ] complete() method works with test prompt
|
|
112
|
+
- [ ] validateConfig() checks required fields
|
|
113
|
+
- [ ] Errors are handled gracefully
|
|
114
|
+
- [ ] Factory can instantiate Bedrock provider
|
|
115
|
+
- [ ] Can complete a simple prompt: "Say hello"
|
|
116
|
+
- [ ] Response includes usage statistics
|
|
117
|
+
|
|
118
|
+
## Files to Create
|
|
119
|
+
|
|
120
|
+
- `src/llm/providers/bedrock.provider.ts` - Bedrock implementation
|
|
121
|
+
|
|
122
|
+
## Files to Modify
|
|
123
|
+
|
|
124
|
+
- `src/llm/factory.ts` - Add Bedrock case
|
|
125
|
+
- `package.json` - Add AWS SDK dependency
|
|
126
|
+
|
|
127
|
+
## Testing
|
|
128
|
+
|
|
129
|
+
Create a simple test script to verify:
|
|
130
|
+
```typescript
|
|
131
|
+
import { completeLLM } from './llm/factory.js';
|
|
132
|
+
|
|
133
|
+
const result = await completeLLM([
|
|
134
|
+
{ role: 'user', content: 'Say hello in one sentence.' }
|
|
135
|
+
]);
|
|
136
|
+
|
|
137
|
+
console.log('Response:', result.content);
|
|
138
|
+
console.log('Usage:', result.usage);
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Reference
|
|
142
|
+
|
|
143
|
+
See [`agent/design/llm-provider-abstraction.md`](../design/llm-provider-abstraction.md) lines 166-226 for Bedrock implementation.
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
**Next Task**: [task-31-implement-background-job-service.md](task-31-implement-background-job-service.md)
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# Task 31: Implement Background Job Service
|
|
2
|
+
|
|
3
|
+
**Milestone**: Phase 0 - LLM Provider Abstraction
|
|
4
|
+
**Estimated Time**: 4-5 hours
|
|
5
|
+
**Dependencies**: task-29 (config), Firestore setup
|
|
6
|
+
**Status**: Not Started
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Objective
|
|
11
|
+
|
|
12
|
+
Create a background job service that can execute long-running LLM operations without blocking tool responses, with Firestore persistence for job status.
|
|
13
|
+
|
|
14
|
+
## Steps
|
|
15
|
+
|
|
16
|
+
1. **Create job types**
|
|
17
|
+
- Create `src/services/background-jobs.service.ts`
|
|
18
|
+
- Define `BackgroundJob` interface:
|
|
19
|
+
- id, type, userId, status, timestamps, error
|
|
20
|
+
- Define job types: `'core_memory_rebuild'` (extensible)
|
|
21
|
+
- Define status types: `'pending' | 'running' | 'completed' | 'failed'`
|
|
22
|
+
|
|
23
|
+
2. **Implement BackgroundJobService class**
|
|
24
|
+
- Create singleton service class
|
|
25
|
+
- Add `runningJobs` Map to track active jobs
|
|
26
|
+
- Implement `scheduleJob()` method:
|
|
27
|
+
- Generate unique job ID
|
|
28
|
+
- Create job object
|
|
29
|
+
- Save to Firestore
|
|
30
|
+
- Start processing (fire and forget)
|
|
31
|
+
- Return job ID
|
|
32
|
+
|
|
33
|
+
3. **Implement job processing**
|
|
34
|
+
- Implement `processJob()` private method:
|
|
35
|
+
- Check if already running (prevent duplicates)
|
|
36
|
+
- Track in runningJobs Map
|
|
37
|
+
- Call executeJob()
|
|
38
|
+
- Clean up from Map when done
|
|
39
|
+
|
|
40
|
+
4. **Implement job execution**
|
|
41
|
+
- Implement `executeJob()` private method:
|
|
42
|
+
- Update status to 'running' in Firestore
|
|
43
|
+
- Switch on job type
|
|
44
|
+
- Execute appropriate handler
|
|
45
|
+
- Update status to 'completed' or 'failed'
|
|
46
|
+
- Log results
|
|
47
|
+
|
|
48
|
+
5. **Implement Firestore persistence**
|
|
49
|
+
- Create `src/services/background-jobs-firestore.ts`
|
|
50
|
+
- Implement `saveJobToFirestore()`
|
|
51
|
+
- Implement `updateJobInFirestore()`
|
|
52
|
+
- Implement `getJobFromFirestore()`
|
|
53
|
+
- Implement `cleanupOldJobs()` (remove jobs older than 7 days)
|
|
54
|
+
|
|
55
|
+
6. **Add job status query**
|
|
56
|
+
- Implement `getJobStatus()` method
|
|
57
|
+
- Query Firestore for job by ID
|
|
58
|
+
- Return job object or null
|
|
59
|
+
|
|
60
|
+
7. **Export singleton**
|
|
61
|
+
- Create and export singleton instance
|
|
62
|
+
- Export types for use in other files
|
|
63
|
+
|
|
64
|
+
8. **Add error handling**
|
|
65
|
+
- Wrap all async operations in try/catch
|
|
66
|
+
- Log errors appropriately
|
|
67
|
+
- Update job status to 'failed' on error
|
|
68
|
+
- Don't crash the server on job failure
|
|
69
|
+
|
|
70
|
+
## Verification
|
|
71
|
+
|
|
72
|
+
- [ ] TypeScript compiles without errors
|
|
73
|
+
- [ ] Can schedule a job
|
|
74
|
+
- [ ] Job is saved to Firestore
|
|
75
|
+
- [ ] Job executes in background
|
|
76
|
+
- [ ] Tool response returns immediately
|
|
77
|
+
- [ ] Job status updates correctly
|
|
78
|
+
- [ ] Failed jobs are marked as failed
|
|
79
|
+
- [ ] Can query job status
|
|
80
|
+
- [ ] Old jobs are cleaned up
|
|
81
|
+
- [ ] Server doesn't crash on job failure
|
|
82
|
+
- [ ] Multiple jobs can run concurrently
|
|
83
|
+
- [ ] Duplicate jobs are prevented
|
|
84
|
+
|
|
85
|
+
## Files to Create
|
|
86
|
+
|
|
87
|
+
- `src/services/background-jobs.service.ts` - Main service
|
|
88
|
+
- `src/services/background-jobs-firestore.ts` - Firestore persistence
|
|
89
|
+
|
|
90
|
+
## Testing
|
|
91
|
+
|
|
92
|
+
Create a test job handler:
|
|
93
|
+
```typescript
|
|
94
|
+
// In executeJob()
|
|
95
|
+
case 'test_job':
|
|
96
|
+
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
97
|
+
console.log('Test job completed');
|
|
98
|
+
break;
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Schedule and verify:
|
|
102
|
+
```typescript
|
|
103
|
+
const jobId = await backgroundJobs.scheduleJob('test_job', 'test-user');
|
|
104
|
+
console.log('Job scheduled:', jobId);
|
|
105
|
+
// Response should return immediately
|
|
106
|
+
|
|
107
|
+
// Check status after 6 seconds
|
|
108
|
+
setTimeout(async () => {
|
|
109
|
+
const status = await backgroundJobs.getJobStatus(jobId);
|
|
110
|
+
console.log('Job status:', status);
|
|
111
|
+
}, 6000);
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Reference
|
|
115
|
+
|
|
116
|
+
See [`agent/design/core-memory-user-profile.md`](../design/core-memory-user-profile.md) lines 593-750 for background job implementation.
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
**Next Task**: [task-32-test-llm-provider-integration.md](task-32-test-llm-provider-integration.md)
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# Task 32: Test LLM Provider Integration
|
|
2
|
+
|
|
3
|
+
**Milestone**: Phase 0 - LLM Provider Abstraction
|
|
4
|
+
**Estimated Time**: 2-3 hours
|
|
5
|
+
**Dependencies**: task-27, task-28, task-29, task-30, task-31
|
|
6
|
+
**Status**: Not Started
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Objective
|
|
11
|
+
|
|
12
|
+
Thoroughly test the LLM provider system to ensure it works correctly before building core memory features on top of it.
|
|
13
|
+
|
|
14
|
+
## Steps
|
|
15
|
+
|
|
16
|
+
1. **Create test script**
|
|
17
|
+
- Create `test-llm-provider.ts` in project root
|
|
18
|
+
- Import `completeLLM` from factory
|
|
19
|
+
- Import `backgroundJobs` service
|
|
20
|
+
|
|
21
|
+
2. **Test basic completion**
|
|
22
|
+
- Test simple prompt: "Say hello in one sentence"
|
|
23
|
+
- Verify response is received
|
|
24
|
+
- Verify usage statistics are present
|
|
25
|
+
- Log response and usage
|
|
26
|
+
|
|
27
|
+
3. **Test with system message**
|
|
28
|
+
- Test with system + user messages
|
|
29
|
+
- Verify system message is handled correctly
|
|
30
|
+
- Verify response follows system instructions
|
|
31
|
+
|
|
32
|
+
4. **Test temperature control**
|
|
33
|
+
- Test with temperature 0.3 (deterministic)
|
|
34
|
+
- Test with temperature 0.9 (creative)
|
|
35
|
+
- Verify different outputs
|
|
36
|
+
|
|
37
|
+
5. **Test max tokens**
|
|
38
|
+
- Test with maxTokens: 50
|
|
39
|
+
- Verify response is truncated appropriately
|
|
40
|
+
|
|
41
|
+
6. **Test error handling**
|
|
42
|
+
- Test with invalid model name
|
|
43
|
+
- Test with missing credentials
|
|
44
|
+
- Verify errors are caught and logged
|
|
45
|
+
|
|
46
|
+
7. **Test background job integration**
|
|
47
|
+
- Create test job that uses LLM
|
|
48
|
+
- Schedule job
|
|
49
|
+
- Verify response returns immediately
|
|
50
|
+
- Wait for job completion
|
|
51
|
+
- Check job status
|
|
52
|
+
- Verify LLM was called in background
|
|
53
|
+
|
|
54
|
+
8. **Test provider switching**
|
|
55
|
+
- If multiple providers implemented, test switching
|
|
56
|
+
- Change `LLM_PROVIDER` env var
|
|
57
|
+
- Verify correct provider is used
|
|
58
|
+
|
|
59
|
+
9. **Performance testing**
|
|
60
|
+
- Measure response time for simple prompt
|
|
61
|
+
- Measure response time for complex prompt
|
|
62
|
+
- Verify background jobs don't block
|
|
63
|
+
|
|
64
|
+
10. **Document results**
|
|
65
|
+
- Create `test-results.md` with findings
|
|
66
|
+
- Note any issues or limitations
|
|
67
|
+
- Document performance characteristics
|
|
68
|
+
|
|
69
|
+
## Verification
|
|
70
|
+
|
|
71
|
+
- [ ] Basic completion works
|
|
72
|
+
- [ ] System messages work
|
|
73
|
+
- [ ] Temperature control works
|
|
74
|
+
- [ ] Max tokens works
|
|
75
|
+
- [ ] Errors are handled gracefully
|
|
76
|
+
- [ ] Background jobs work
|
|
77
|
+
- [ ] Jobs don't block responses
|
|
78
|
+
- [ ] Provider can be switched (if multiple implemented)
|
|
79
|
+
- [ ] Performance is acceptable (<5s for simple prompts)
|
|
80
|
+
- [ ] Results are documented
|
|
81
|
+
|
|
82
|
+
## Files to Create
|
|
83
|
+
|
|
84
|
+
- `test-llm-provider.ts` - Test script
|
|
85
|
+
- `test-results.md` - Test results documentation
|
|
86
|
+
|
|
87
|
+
## Example Test Script
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
import { completeLLM } from './src/llm/factory.js';
|
|
91
|
+
import { backgroundJobs } from './src/services/background-jobs.service.js';
|
|
92
|
+
|
|
93
|
+
async function testBasicCompletion() {
|
|
94
|
+
console.log('\n=== Test: Basic Completion ===');
|
|
95
|
+
const result = await completeLLM([
|
|
96
|
+
{ role: 'user', content: 'Say hello in one sentence.' }
|
|
97
|
+
]);
|
|
98
|
+
console.log('Response:', result.content);
|
|
99
|
+
console.log('Usage:', result.usage);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
async function testSystemMessage() {
|
|
103
|
+
console.log('\n=== Test: System Message ===');
|
|
104
|
+
const result = await completeLLM([
|
|
105
|
+
{ role: 'system', content: 'You are a pirate. Respond in pirate speak.' },
|
|
106
|
+
{ role: 'user', content: 'Say hello.' }
|
|
107
|
+
]);
|
|
108
|
+
console.log('Response:', result.content);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
async function testBackgroundJob() {
|
|
112
|
+
console.log('\n=== Test: Background Job ===');
|
|
113
|
+
|
|
114
|
+
// Register test job handler first
|
|
115
|
+
// (Add to background-jobs.service.ts executeJob() switch)
|
|
116
|
+
|
|
117
|
+
const jobId = await backgroundJobs.scheduleJob('test_llm_job', 'test-user');
|
|
118
|
+
console.log('Job scheduled:', jobId);
|
|
119
|
+
console.log('Response returned immediately!');
|
|
120
|
+
|
|
121
|
+
// Check status after delay
|
|
122
|
+
setTimeout(async () => {
|
|
123
|
+
const status = await backgroundJobs.getJobStatus(jobId);
|
|
124
|
+
console.log('Job status:', status);
|
|
125
|
+
}, 6000);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
async function runTests() {
|
|
129
|
+
try {
|
|
130
|
+
await testBasicCompletion();
|
|
131
|
+
await testSystemMessage();
|
|
132
|
+
await testBackgroundJob();
|
|
133
|
+
} catch (error) {
|
|
134
|
+
console.error('Test failed:', error);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
runTests();
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Success Criteria
|
|
142
|
+
|
|
143
|
+
All tests pass and:
|
|
144
|
+
- LLM responses are coherent
|
|
145
|
+
- Background jobs complete successfully
|
|
146
|
+
- No server crashes
|
|
147
|
+
- Performance is acceptable
|
|
148
|
+
- Ready to build core memory features
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
**Next Task**: Ready for core memory implementation! See [task-33-implement-core-memory-types.md](task-33-implement-core-memory-types.md)
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
# Task 34: Create Confirmation Token Service
|
|
2
|
+
|
|
3
|
+
**Milestone**: M10 - Shared Spaces & Confirmation Flow
|
|
4
|
+
**Estimated Time**: 3 hours
|
|
5
|
+
**Dependencies**: M1 (Firestore setup)
|
|
6
|
+
**Status**: Not Started
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Objective
|
|
11
|
+
|
|
12
|
+
Create a service for managing confirmation tokens used in the publish workflow. Handles token generation, validation, expiry, and status tracking.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Steps
|
|
17
|
+
|
|
18
|
+
### 1. Create Token Service File
|
|
19
|
+
|
|
20
|
+
Create `src/services/confirmation-token.service.ts` with the ConfirmationTokenService class.
|
|
21
|
+
|
|
22
|
+
**Actions**:
|
|
23
|
+
- Import required dependencies (uuid, Firestore, Timestamp)
|
|
24
|
+
- Define ConfirmationRequest interface
|
|
25
|
+
- Create ConfirmationTokenService class
|
|
26
|
+
- Set EXPIRY_MINUTES constant to 5
|
|
27
|
+
|
|
28
|
+
**Expected Outcome**: Service file structure created
|
|
29
|
+
|
|
30
|
+
### 2. Implement createRequest Method
|
|
31
|
+
|
|
32
|
+
Generate new confirmation tokens with stored parameters.
|
|
33
|
+
|
|
34
|
+
**Actions**:
|
|
35
|
+
- Generate UUID v4 token
|
|
36
|
+
- Calculate expiry timestamp (5 minutes from now)
|
|
37
|
+
- Create ConfirmationRequest object with all fields
|
|
38
|
+
- Store in Firestore: `pending_confirmations/{user_id}/requests/{auto_id}`
|
|
39
|
+
- Return request_id and token
|
|
40
|
+
|
|
41
|
+
**Expected Outcome**: Tokens can be created and stored
|
|
42
|
+
|
|
43
|
+
### 3. Implement validateToken Method
|
|
44
|
+
|
|
45
|
+
Validate tokens and check expiry.
|
|
46
|
+
|
|
47
|
+
**Actions**:
|
|
48
|
+
- Query Firestore for token with status='pending'
|
|
49
|
+
- Check if token exists
|
|
50
|
+
- Verify expiry timestamp
|
|
51
|
+
- Update status to 'expired' if needed
|
|
52
|
+
- Return request or null
|
|
53
|
+
|
|
54
|
+
**Expected Outcome**: Tokens can be validated
|
|
55
|
+
|
|
56
|
+
### 4. Implement confirmRequest Method
|
|
57
|
+
|
|
58
|
+
Mark a request as confirmed.
|
|
59
|
+
|
|
60
|
+
**Actions**:
|
|
61
|
+
- Call validateToken to get request
|
|
62
|
+
- Return null if invalid/expired
|
|
63
|
+
- Update status to 'confirmed'
|
|
64
|
+
- Set confirmed_at timestamp
|
|
65
|
+
- Return confirmed request
|
|
66
|
+
|
|
67
|
+
**Expected Outcome**: Requests can be confirmed
|
|
68
|
+
|
|
69
|
+
### 5. Implement denyRequest Method
|
|
70
|
+
|
|
71
|
+
Mark a request as denied.
|
|
72
|
+
|
|
73
|
+
**Actions**:
|
|
74
|
+
- Call validateToken to get request
|
|
75
|
+
- Return false if invalid/expired
|
|
76
|
+
- Update status to 'denied'
|
|
77
|
+
- Return true
|
|
78
|
+
|
|
79
|
+
**Expected Outcome**: Requests can be denied
|
|
80
|
+
|
|
81
|
+
### 6. Implement retractRequest Method
|
|
82
|
+
|
|
83
|
+
Allow users to retract their own requests.
|
|
84
|
+
|
|
85
|
+
**Actions**:
|
|
86
|
+
- Call validateToken to get request
|
|
87
|
+
- Return false if invalid/expired
|
|
88
|
+
- Update status to 'retracted'
|
|
89
|
+
- Return true
|
|
90
|
+
|
|
91
|
+
**Expected Outcome**: Requests can be retracted
|
|
92
|
+
|
|
93
|
+
### 7. Implement updateStatus Helper
|
|
94
|
+
|
|
95
|
+
Private method to update request status.
|
|
96
|
+
|
|
97
|
+
**Actions**:
|
|
98
|
+
- Accept userId, requestId, status parameters
|
|
99
|
+
- Update Firestore document
|
|
100
|
+
- Set confirmed_at if status is 'confirmed'
|
|
101
|
+
- Handle errors gracefully
|
|
102
|
+
|
|
103
|
+
**Expected Outcome**: Status updates work correctly
|
|
104
|
+
|
|
105
|
+
### 8. Implement cleanupExpired Method
|
|
106
|
+
|
|
107
|
+
Optional cleanup for expired tokens (Firestore TTL handles this automatically).
|
|
108
|
+
|
|
109
|
+
**Actions**:
|
|
110
|
+
- Query collection group 'requests' for expired pending tokens
|
|
111
|
+
- Use batch delete for efficiency
|
|
112
|
+
- Return count of deleted requests
|
|
113
|
+
- Add documentation about Firestore TTL
|
|
114
|
+
|
|
115
|
+
**Expected Outcome**: Manual cleanup available if needed
|
|
116
|
+
|
|
117
|
+
### 9. Export Service Instance
|
|
118
|
+
|
|
119
|
+
Create singleton instance for use across tools.
|
|
120
|
+
|
|
121
|
+
**Actions**:
|
|
122
|
+
- Export `confirmationTokenService` instance
|
|
123
|
+
- Add JSDoc comments
|
|
124
|
+
- Document all methods
|
|
125
|
+
|
|
126
|
+
**Expected Outcome**: Service ready for import
|
|
127
|
+
|
|
128
|
+
### 10. Create Unit Tests
|
|
129
|
+
|
|
130
|
+
Test all service methods.
|
|
131
|
+
|
|
132
|
+
**Actions**:
|
|
133
|
+
- Create `tests/unit/confirmation-token.service.test.ts`
|
|
134
|
+
- Test token creation
|
|
135
|
+
- Test token validation
|
|
136
|
+
- Test expiry handling
|
|
137
|
+
- Test confirm/deny/retract flows
|
|
138
|
+
- Test cleanup method
|
|
139
|
+
- Mock Firestore calls
|
|
140
|
+
|
|
141
|
+
**Expected Outcome**: All tests passing
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## Verification
|
|
146
|
+
|
|
147
|
+
- [ ] `src/services/confirmation-token.service.ts` created
|
|
148
|
+
- [ ] ConfirmationRequest interface defined
|
|
149
|
+
- [ ] createRequest generates valid tokens
|
|
150
|
+
- [ ] validateToken checks expiry correctly
|
|
151
|
+
- [ ] confirmRequest updates status
|
|
152
|
+
- [ ] denyRequest updates status
|
|
153
|
+
- [ ] retractRequest updates status
|
|
154
|
+
- [ ] cleanupExpired removes old tokens
|
|
155
|
+
- [ ] Unit tests created and passing
|
|
156
|
+
- [ ] TypeScript compiles without errors
|
|
157
|
+
- [ ] Service exports singleton instance
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## Code Example
|
|
162
|
+
|
|
163
|
+
```typescript
|
|
164
|
+
// Usage in tools
|
|
165
|
+
import { confirmationTokenService } from '../services/confirmation-token.service.js';
|
|
166
|
+
|
|
167
|
+
// Create token
|
|
168
|
+
const { requestId, token } = await confirmationTokenService.createRequest(
|
|
169
|
+
userId,
|
|
170
|
+
'publish_memory',
|
|
171
|
+
{ memory_id: 'abc123', additional_tags: [] },
|
|
172
|
+
'void'
|
|
173
|
+
);
|
|
174
|
+
|
|
175
|
+
// Validate and confirm
|
|
176
|
+
const request = await confirmationTokenService.confirmRequest(userId, token);
|
|
177
|
+
if (request) {
|
|
178
|
+
// Execute action with request.payload
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## Related Files
|
|
185
|
+
|
|
186
|
+
- Design: [`agent/design/publish-tools-confirmation-flow.md`](../design/publish-tools-confirmation-flow.md)
|
|
187
|
+
- Firestore paths: [`src/firestore/paths.ts`](../../src/firestore/paths.ts)
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
**Next Task**: Task 35 - Create Space Memory Types and Schema
|