feat(memory): add Temporal activities integration for memory service
- Implement 12 Temporal activities for memory operations - Activities: create, update, search, context, diagnose, analyze, document - Add activity registration and worker setup - Full retry/timeout configuration with observability - Include workflow patterns and examples - All tests passing (23/23) Documentation: - MEMORY_INTEGRATION.md: High-level integration guide - MEMORY_ACTIVITIES.md: Complete activities reference - REGISTERED_ACTIVITIES.md: Registry and calling conventions
This commit is contained in:
@@ -0,0 +1,327 @@
|
||||
# Registered Memory Service Activities
|
||||
|
||||
## Summary
|
||||
|
||||
**Total Activities Registered**: 12
|
||||
**Package**: `github.com/rockliang/poimen/workflows/internal/memory`
|
||||
**Registration Method**: `RegisterMemoryActivities(worker, service)`
|
||||
**Task Queue**: `poimen-taskqueue`
|
||||
**Namespace**: `poimen-harness`
|
||||
|
||||
---
|
||||
|
||||
## Registered Activities List
|
||||
|
||||
### 1. CreateKnowledgeActivity
|
||||
- **Function**: `CreateKnowledgeActivity(ctx context.Context, record *KnowledgeRecord) (string, error)`
|
||||
- **Input**: `KnowledgeRecord` (level, title, content, source, metadata)
|
||||
- **Output**: Knowledge ID (string)
|
||||
- **Timeout**: 1 minute (default)
|
||||
- **Retries**: 3 attempts (default)
|
||||
- **Purpose**: Create L1/L2/reference knowledge records
|
||||
- **Call in Workflow**: `memory.ExecuteCreateKnowledge(ctx, record, opts)`
|
||||
|
||||
---
|
||||
|
||||
### 2. UpdateKnowledgeActivity
|
||||
- **Function**: `UpdateKnowledgeActivity(ctx context.Context, record *KnowledgeRecord) (string, error)`
|
||||
- **Input**: `KnowledgeRecord` (with ID)
|
||||
- **Output**: Knowledge ID (string)
|
||||
- **Timeout**: 1 minute
|
||||
- **Retries**: 3 attempts
|
||||
- **Purpose**: Update existing knowledge records
|
||||
- **Call in Workflow**: `memory.ExecuteUpdateKnowledge(ctx, record, opts)` (not implemented yet)
|
||||
|
||||
---
|
||||
|
||||
### 3. SearchKnowledgeActivity
|
||||
- **Function**: `SearchKnowledgeActivity(ctx context.Context, query string, opts *RetrievalOptions) ([]KnowledgeRecord, error)`
|
||||
- **Input**: Query string + retrieval options (limit, levelFilter, floor, scope)
|
||||
- **Output**: Array of `KnowledgeRecord`
|
||||
- **Timeout**: 2 minutes
|
||||
- **Retries**: 3 attempts
|
||||
- **Purpose**: Hybrid search (semantic + lexical)
|
||||
- **Call in Workflow**: `memory.ExecuteSearchKnowledge(ctx, query, opts, activityOpts)`
|
||||
|
||||
---
|
||||
|
||||
### 4. GetContextActivity
|
||||
- **Function**: `GetContextActivity(ctx context.Context, tool, task string, budget int) (*ServiceContext, error)`
|
||||
- **Input**: Tool name, task name, budget (bytes)
|
||||
- **Output**: `ServiceContext` (tier, lessons, skills, budget)
|
||||
- **Timeout**: 2 minutes
|
||||
- **Retries**: 3 attempts
|
||||
- **Purpose**: Three-tier retrieval (signature → vector → reference)
|
||||
- **Call in Workflow**: `memory.ExecuteGetContext(ctx, tool, task, budget, opts)`
|
||||
|
||||
---
|
||||
|
||||
### 5. GetVaultActivity
|
||||
- **Function**: `GetVaultActivity(ctx context.Context) ([]VaultInfo, error)`
|
||||
- **Input**: None
|
||||
- **Output**: Array of `VaultInfo` (path, title, level, updatedAt, recordCount)
|
||||
- **Timeout**: 1 minute
|
||||
- **Retries**: 3 attempts
|
||||
- **Purpose**: Browse vault files and structure
|
||||
- **Call in Workflow**: Use via service: `service.GetVault(ctx)`
|
||||
|
||||
---
|
||||
|
||||
### 6. HealthCheckActivity
|
||||
- **Function**: `HealthCheckActivity(ctx context.Context) (bool, error)`
|
||||
- **Input**: None
|
||||
- **Output**: Boolean (healthy or not)
|
||||
- **Timeout**: 30 seconds
|
||||
- **Retries**: 3 attempts
|
||||
- **Purpose**: Check memory service availability
|
||||
- **Call in Workflow**: `memory.ExecuteHealthCheck(ctx, opts)`
|
||||
|
||||
---
|
||||
|
||||
### 7. LearnFromExecutionActivity
|
||||
- **Function**: `LearnFromExecutionActivity(ctx context.Context, taskID string, result string, tags []string) (string, error)`
|
||||
- **Input**: Task ID, execution result, tags (optional)
|
||||
- **Output**: Knowledge record ID
|
||||
- **Timeout**: 1 minute
|
||||
- **Retries**: 3 attempts
|
||||
- **Purpose**: Learn from task execution results
|
||||
- **Call in Workflow**: `memory.ExecuteLearnFromExecution(ctx, taskID, result, tags, opts)`
|
||||
|
||||
---
|
||||
|
||||
### 8. DiagnoseIssueActivity
|
||||
- **Function**: `DiagnoseIssueActivity(ctx context.Context, tool, issue string) ([]string, error)`
|
||||
- **Input**: Tool name, issue description
|
||||
- **Output**: Array of recommendation strings
|
||||
- **Timeout**: 1 minute
|
||||
- **Retries**: 3 attempts
|
||||
- **Purpose**: Diagnose issues using memory context
|
||||
- **Call in Workflow**: `memory.ExecuteDiagnoseIssue(ctx, tool, issue, opts)`
|
||||
|
||||
---
|
||||
|
||||
### 9. AnalyzeErrorActivity
|
||||
- **Function**: `AnalyzeErrorActivity(ctx context.Context, errorMsg string) ([]KnowledgeRecord, error)`
|
||||
- **Input**: Error message
|
||||
- **Output**: Array of `KnowledgeRecord` (solutions)
|
||||
- **Timeout**: 1 minute
|
||||
- **Retries**: 3 attempts
|
||||
- **Purpose**: Analyze errors and find recovery paths
|
||||
- **Call in Workflow**: `memory.ExecuteAnalyzeError(ctx, errorMsg, opts)`
|
||||
|
||||
---
|
||||
|
||||
### 10. DocumentDecisionActivity
|
||||
- **Function**: `DocumentDecisionActivity(ctx context.Context, decisionType, decision, reasoning string) (string, error)`
|
||||
- **Input**: Decision type, decision, reasoning
|
||||
- **Output**: Knowledge record ID
|
||||
- **Timeout**: 1 minute
|
||||
- **Retries**: 3 attempts
|
||||
- **Purpose**: Record workflow decisions (L2 knowledge)
|
||||
- **Call in Workflow**: `memory.ExecuteDocumentDecision(ctx, decisionType, decision, reasoning, opts)`
|
||||
|
||||
---
|
||||
|
||||
### 11. SearchAndApplyActivity
|
||||
- **Function**: `SearchAndApplyActivity(ctx context.Context, query string, selector func(record *KnowledgeRecord) bool) ([]string, error)`
|
||||
- **Input**: Query string, optional selector function
|
||||
- **Output**: Array of applied content strings
|
||||
- **Timeout**: 1 minute
|
||||
- **Retries**: 3 attempts
|
||||
- **Purpose**: Search knowledge and apply selective results
|
||||
- **Call in Workflow**: Use via service
|
||||
|
||||
---
|
||||
|
||||
### 12. RefreshMemoryActivity
|
||||
- **Function**: `RefreshMemoryActivity(ctx context.Context) (map[string]interface{}, error)`
|
||||
- **Input**: None
|
||||
- **Output**: Map with vault stats and health
|
||||
- **Timeout**: 1 minute
|
||||
- **Retries**: 3 attempts
|
||||
- **Purpose**: Periodic memory context refresh
|
||||
- **Call in Workflow**: `memory.ExecuteRefreshMemory(ctx, opts)`
|
||||
|
||||
---
|
||||
|
||||
## Registration Code
|
||||
|
||||
```go
|
||||
// In cmd/worker/main.go or similar
|
||||
import "github.com/rockliang/poimen/workflows/internal/memory"
|
||||
|
||||
func setupWorker() {
|
||||
// Create memory service
|
||||
memoryService := memory.NewService(
|
||||
os.Getenv("MEMORY_SERVICE_URL"),
|
||||
os.Getenv("MEMORY_SERVICE_TOKEN"),
|
||||
"poimen",
|
||||
)
|
||||
|
||||
// Register all memory activities
|
||||
memory.RegisterMemoryActivities(workerInstance, memoryService)
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Activity Naming Convention
|
||||
|
||||
Temporal activity names (as seen in logs/UI):
|
||||
|
||||
```
|
||||
- CreateKnowledgeActivity → createKnowledgeActivity
|
||||
- UpdateKnowledgeActivity → updateKnowledgeActivity
|
||||
- SearchKnowledgeActivity → searchKnowledgeActivity
|
||||
- GetContextActivity → getContextActivity
|
||||
- GetVaultActivity → getVaultActivity
|
||||
- HealthCheckActivity → healthCheckActivity
|
||||
- LearnFromExecutionActivity → learnFromExecutionActivity
|
||||
- DiagnoseIssueActivity → diagnoseIssueActivity
|
||||
- AnalyzeErrorActivity → analyzeErrorActivity
|
||||
- DocumentDecisionActivity → documentDecisionActivity
|
||||
- SearchAndApplyActivity → searchAndApplyActivity
|
||||
- RefreshMemoryActivity → refreshMemoryActivity
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Default Retry Policy
|
||||
|
||||
```
|
||||
InitialInterval: 1 second
|
||||
BackoffCoefficient: 2.0
|
||||
MaximumInterval: 30 seconds
|
||||
MaximumAttempts: 3
|
||||
NonRetryableErrors: (empty - all errors retry)
|
||||
```
|
||||
|
||||
**Timeline**: 1s → 2s → 4s → fail
|
||||
|
||||
---
|
||||
|
||||
## Default Timeouts
|
||||
|
||||
| Activity | Schedule-to-Close | Start-to-Close |
|
||||
|----------|-------------------|----------------|
|
||||
| CreateKnowledge | 2 min | 1 min |
|
||||
| SearchKnowledge | 3 min | 2 min |
|
||||
| GetContext | 3 min | 2 min |
|
||||
| DiagnoseIssue | 2 min | 1 min |
|
||||
| AnalyzeError | 2 min | 1 min |
|
||||
| LearnFromExecution | 2 min | 1 min |
|
||||
| DocumentDecision | 2 min | 1 min |
|
||||
| HealthCheck | 1 min | 30s |
|
||||
| GetVault | 2 min | 1 min |
|
||||
| RefreshMemory | 2 min | 1 min |
|
||||
|
||||
---
|
||||
|
||||
## How to List Activities at Runtime
|
||||
|
||||
### Option 1: Check Logs
|
||||
```bash
|
||||
kubectl -n poimen logs -f deployment/poimen-worker | grep "ActivityType"
|
||||
```
|
||||
|
||||
### Option 2: In Workflow Test
|
||||
```go
|
||||
suite := &testsuite.WorkflowTestSuite{}
|
||||
env := suite.NewTestActivityEnvironment()
|
||||
|
||||
activities := memory.NewActivities(service)
|
||||
env.RegisterActivity(activities.CreateKnowledgeActivity)
|
||||
// ... etc
|
||||
|
||||
// Run test - activities are registered
|
||||
```
|
||||
|
||||
### Option 3: Via Temporal CLI (when connected)
|
||||
```bash
|
||||
temporal task-queue describe --namespace poimen-harness --task-queue poimen-taskqueue
|
||||
```
|
||||
|
||||
### Option 4: Temporal Web UI
|
||||
```
|
||||
http://temporal.riotpiao.com (or local Temporal UI)
|
||||
→ Namespace: poimen-harness
|
||||
→ Task Queue: poimen-taskqueue
|
||||
→ View registered worker versions with activities
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Activity Flow Diagram
|
||||
|
||||
```
|
||||
Workflow
|
||||
↓
|
||||
ExecuteCreateKnowledge(ctx, record, opts)
|
||||
↓
|
||||
Temporal Worker polls poimen-taskqueue
|
||||
↓
|
||||
CreateKnowledgeActivity runs with retry policy
|
||||
↓
|
||||
Memory Service HTTP call (with Bearer token)
|
||||
↓
|
||||
Result → Workflow continues
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Integration with Worker
|
||||
|
||||
```go
|
||||
// cmd/worker/main.go
|
||||
|
||||
func main() {
|
||||
c, _ := client.Dial(client.Options{
|
||||
HostPort: "temporal-frontend.temporal:7233",
|
||||
Namespace: "poimen-harness",
|
||||
})
|
||||
defer c.Close()
|
||||
|
||||
w := worker.New(c, "poimen-taskqueue", worker.Options{})
|
||||
|
||||
// Register memory activities
|
||||
memSvc := memory.NewService(
|
||||
"http://memory-service:8080",
|
||||
os.Getenv("MEMORY_TOKEN"),
|
||||
"poimen",
|
||||
)
|
||||
memory.RegisterMemoryActivities(w, memSvc)
|
||||
|
||||
// Start worker
|
||||
w.Start()
|
||||
defer w.Stop()
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Summary Table
|
||||
|
||||
| # | Activity | Input | Output | Timeout |
|
||||
|---|----------|-------|--------|---------|
|
||||
| 1 | CreateKnowledge | KnowledgeRecord | string | 1m |
|
||||
| 2 | UpdateKnowledge | KnowledgeRecord | string | 1m |
|
||||
| 3 | SearchKnowledge | string, opts | []KnowledgeRecord | 2m |
|
||||
| 4 | GetContext | tool, task, budget | ServiceContext | 2m |
|
||||
| 5 | GetVault | — | []VaultInfo | 1m |
|
||||
| 6 | HealthCheck | — | bool | 30s |
|
||||
| 7 | LearnFromExecution | taskID, result, tags | string | 1m |
|
||||
| 8 | DiagnoseIssue | tool, issue | []string | 1m |
|
||||
| 9 | AnalyzeError | errorMsg | []KnowledgeRecord | 1m |
|
||||
| 10 | DocumentDecision | type, decision, reason | string | 1m |
|
||||
| 11 | SearchAndApply | query, selector | []string | 1m |
|
||||
| 12 | RefreshMemory | — | map[string]interface{} | 1m |
|
||||
|
||||
---
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. ✅ Activities defined & registered
|
||||
2. ✅ All 12 activities implemented
|
||||
3. 🔄 Deploy worker to cluster
|
||||
4. 🔄 Verify registration in Temporal UI
|
||||
5. 🔄 Use in workflows
|
||||
Reference in New Issue
Block a user