ci / test (push) Successful in 2m12s
- Add RoutingWorkflow: generic state machine executor for WorkflowSpec - Add LLM Router: natural language → WorkflowSpec generation - Add RetrieveMemoryActivity: query poimen-memory for context - Add activities: AnalyzeCode, SecurityScan, GenerateReport, Notify, etc. - Add agent-prompts/router: LLM prompt documentation - Extend starter with --route flag for routing workflows - Remove orchestrator job (trigger via API/message instead) - Clean up: move docs to Desktop, add .gitignore for *.md
123 lines
3.0 KiB
Go
123 lines
3.0 KiB
Go
// Example: WaitForTaskComplete pattern
|
|
// Use case: External service submits implementation task, waits for result
|
|
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
"go.temporal.io/sdk/client"
|
|
)
|
|
|
|
// WaitForTaskComplete - the core pattern
|
|
//
|
|
// 1. Build workflow spec for the task
|
|
// 2. Submit to Temporal
|
|
// 3. Block until completion or timeout
|
|
// 4. Return result
|
|
func WaitForTaskComplete(
|
|
c client.Client,
|
|
taskID string,
|
|
repo string,
|
|
timeout time.Duration,
|
|
) (map[string]interface{}, error) {
|
|
|
|
ctx := context.Background()
|
|
|
|
// Build spec for implementation task
|
|
spec := map[string]interface{}{
|
|
"name": fmt.Sprintf("implement-%s", taskID),
|
|
"input": map[string]interface{}{
|
|
"taskId": taskID,
|
|
"repo": repo,
|
|
},
|
|
"states": []map[string]interface{}{
|
|
{
|
|
"name": "Clone",
|
|
"type": "Task",
|
|
"resource": "CloneRepoActivity",
|
|
"parameters": map[string]interface{}{
|
|
"repo": repo,
|
|
},
|
|
"next": "Analyze",
|
|
},
|
|
{
|
|
"name": "Analyze",
|
|
"type": "Task",
|
|
"resource": "AnalyzeCodeActivity",
|
|
"parameters": map[string]interface{}{
|
|
"path": "${Clone.output.path}",
|
|
},
|
|
"next": "SecurityScan",
|
|
},
|
|
{
|
|
"name": "SecurityScan",
|
|
"type": "Task",
|
|
"resource": "SecurityScanActivity",
|
|
"parameters": map[string]interface{}{
|
|
"path": "${Clone.output.path}",
|
|
},
|
|
"next": "Report",
|
|
},
|
|
{
|
|
"name": "Report",
|
|
"type": "Task",
|
|
"resource": "GenerateReportActivity",
|
|
"parameters": map[string]interface{}{
|
|
"analysisResult": "${Analyze.output}",
|
|
"securityResult": "${SecurityScan.output}",
|
|
},
|
|
"end": true,
|
|
},
|
|
},
|
|
}
|
|
|
|
// Submit workflow
|
|
workflowID := fmt.Sprintf("%s-%d", taskID, time.Now().UnixNano())
|
|
run, err := c.ExecuteWorkflow(ctx, client.StartWorkflowOptions{
|
|
ID: workflowID,
|
|
TaskQueue: "poimen-taskqueue",
|
|
}, "RoutingWorkflow", map[string]interface{}{"spec": spec})
|
|
if err != nil {
|
|
return nil, fmt.Errorf("submit failed: %w", err)
|
|
}
|
|
|
|
fmt.Printf("[%s] Workflow started: %s\n", taskID, workflowID)
|
|
|
|
// Wait for completion
|
|
waitCtx, cancel := context.WithTimeout(ctx, timeout)
|
|
defer cancel()
|
|
|
|
var result map[string]interface{}
|
|
if err := run.Get(waitCtx, &result); err != nil {
|
|
return nil, fmt.Errorf("workflow failed: %w", err)
|
|
}
|
|
|
|
fmt.Printf("[%s] Workflow completed: %s\n", taskID, result["status"])
|
|
return result, nil
|
|
}
|
|
|
|
// Example usage in another service:
|
|
//
|
|
// func (s *MyService) ImplementTask(taskID string) error {
|
|
// c, _ := client.Dial(client.Options{
|
|
// HostPort: "temporal-frontend.temporal:7233",
|
|
// Namespace: "poimen-harness",
|
|
// })
|
|
// defer c.Close()
|
|
//
|
|
// result, err := WaitForTaskComplete(c, taskID, "https://github.com/...", 30*time.Minute)
|
|
// if err != nil {
|
|
// return err
|
|
// }
|
|
//
|
|
// // Process result
|
|
// if result["status"] == "COMPLETED" {
|
|
// report := result["stepResults"].(map[string]interface{})["Report"]
|
|
// // Use report...
|
|
// }
|
|
// return nil
|
|
// }
|