(workflow) add simple harness workflow for manual testing

This commit is contained in:
Test
2026-08-21 18:07:12 -07:00
parent 769e56d33d
commit 5b8d3df01e
17 changed files with 1080 additions and 44 deletions
+115 -1
View File
@@ -1,5 +1,119 @@
package main
import (
"context"
"flag"
"fmt"
"log"
"strings"
"time"
"go.temporal.io/sdk/client"
"github.com/rockliang/poimen/workflows/internal/config"
"github.com/rockliang/poimen/workflows/statemachine"
)
func main() {
// Empty stub - will be filled in T0.8
var (
repoPath = flag.String("repo", "", "target repo path")
remoteURL = flag.String("remote", "", "remote URL")
milestone = flag.String("milestone", "T0", "milestone ID")
dryRun = flag.Bool("dry-run", false, "disable git push/merge")
plannerModel = flag.String("planner-model", "ornith", "planner model ID")
judgeModel = flag.String("judge-model", "ornith", "judge model ID")
implementerModel = flag.String("implementer-model", "claude-sonnet-5", "implementer model ID")
)
flag.Parse()
// Validate required flags
if *repoPath == "" || *remoteURL == "" {
log.Fatalf("--repo and --remote flags are required")
}
// Load configuration
cfg, err := config.LoadConfig()
if err != nil {
log.Fatalf("failed to load config: %v", err)
}
// Connect to Temporal
c, err := client.Dial(client.Options{
HostPort: cfg.Temporal.HostPort,
Namespace: cfg.Temporal.Namespace,
})
if err != nil {
log.Fatalf("failed to connect to temporal: %v", err)
}
defer c.Close()
// Build OrchestratorInput
input := statemachine.OrchestratorInput{
TargetRepoPath: *repoPath,
RemoteURL: *remoteURL,
Milestone: *milestone,
DryRun: *dryRun,
MaxCyclesBeforeCAN: 100,
Config: statemachine.OrchestratorConfig{
SystemPrompt: "You are an expert software developer orchestrating multi-agent work.",
Skills: []statemachine.SkillRef{},
RolePrompts: map[string]statemachine.PromptSpec{
"planner": {
TemplateRef: "planner/default.tmpl",
Model: statemachine.ModelSpec{
ModelID: *plannerModel,
Thinking: "adaptive",
Effort: "high",
},
},
"judge": {
TemplateRef: "judge/default.tmpl",
Model: statemachine.ModelSpec{
ModelID: *judgeModel,
Thinking: "adaptive",
Effort: "high",
},
},
"implementer": {
TemplateRef: "implementer/default.tmpl",
Model: statemachine.ModelSpec{
ModelID: *implementerModel,
},
},
},
Tuning: statemachine.NewActivityTuning(),
},
}
// Start workflow
workflowID := "orch-" + strings.ReplaceAll(*repoPath, "/", "-")
run, err := c.ExecuteWorkflow(context.Background(), client.StartWorkflowOptions{
ID: workflowID,
TaskQueue: "default",
}, statemachine.OrchestratorWorkflow, input)
if err != nil {
log.Fatalf("failed to start workflow: %v", err)
}
fmt.Printf("\n=== Workflow Started ===\n")
fmt.Printf("Workflow ID: %s\n", workflowID)
fmt.Printf("Task Queue: default\n")
fmt.Printf("\n=== Model Configuration ===\n")
fmt.Printf("Planner Model: %s\n", *plannerModel)
fmt.Printf("Judge Model: %s\n", *judgeModel)
fmt.Printf("Implementer Model: %s\n", *implementerModel)
fmt.Printf("\n=== Monitoring ===\n")
fmt.Printf("Web UI: http://%s:8080/namespaces/%s/workflows/%s\n",
strings.Split(cfg.Temporal.HostPort, ":")[0], cfg.Temporal.Namespace, workflowID)
// Optionally wait for completion (with timeout)
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
defer cancel()
var result statemachine.OrchestratorOutput
if err := run.Get(ctx, &result); err != nil {
fmt.Printf("\nWorkflow initiated (execution in progress).\n")
fmt.Printf("Check the Web UI for real-time status updates.\n")
} else {
fmt.Printf("\nWorkflow completed: %+v\n", result)
}
}
+56 -1
View File
@@ -1,5 +1,60 @@
package main
import (
"fmt"
"log"
"go.temporal.io/sdk/client"
"go.temporal.io/sdk/worker"
"github.com/rockliang/poimen/workflows/action"
"github.com/rockliang/poimen/workflows/internal/config"
"github.com/rockliang/poimen/workflows/statemachine"
)
func main() {
// Empty stub - will be filled in T0.8
// Load configuration
cfg, err := config.LoadConfig()
if err != nil {
log.Fatalf("failed to load config: %v", err)
}
// Connect to Temporal
c, err := client.Dial(client.Options{
HostPort: cfg.Temporal.HostPort,
Namespace: cfg.Temporal.Namespace,
})
if err != nil {
log.Fatalf("failed to connect to temporal: %v", err)
}
defer c.Close()
// Create worker
w := worker.New(c, "default", worker.Options{})
if w == nil {
log.Fatalf("failed to create worker")
}
// Register all workflows
w.RegisterWorkflow(statemachine.OrchestratorWorkflow)
w.RegisterWorkflow(statemachine.TaskUnitWorkflow)
// Register all activities
w.RegisterActivity(action.CloneRepoActivity)
w.RegisterActivity(action.GitWorktreeAddActivity)
w.RegisterActivity(action.GitCommitActivity)
w.RegisterActivity(action.GitPushActivity)
w.RegisterActivity(action.GitSquashMergeActivity)
w.RegisterActivity(action.PrepareSkillsActivity)
w.RegisterActivity(action.PlanningActivity)
w.RegisterActivity(action.ImplementerActivity)
w.RegisterActivity(action.JudgeActivity)
// Note: RunIntegrationTestActivity and lessons activities will be registered when fully implemented
// w.RegisterActivity(action.UpdateLessonsActivity)
// w.RegisterActivity(action.ReadLessonsActivity)
// Run worker
fmt.Println("Starting worker on queue 'default'...")
if err := w.Run(worker.InterruptCh()); err != nil {
log.Fatalf("worker failed: %v", err)
}
}