refactor: rename action→activity, statemachine→workflow, remove HTTP API layer
- action/ → activity/ (Temporal activities) - statemachine/ → workflow/ (Temporal workflows) - Removed internal/api/ and cmd/server/ (api-gw handles HTTP, Temporal is the API) - Created pkg/types/types.go as single source of truth for all shared types - Extracted CallRoleLLM helper (DRY: implementer/planner/judge shared pattern) - Fixed circular import: workflow_graph_query uses string activity names - Fixed logger.logf → logger.Info/Warn (method didn't exist) - Fixed routing types: added Branches, Activity, BackoffSeconds, TaskActivity - Fixed db.Canvas.Name, db.Client→DB, GetWorkflow→FetchWorkflow - Removed unused imports - All tests pass, build clean, vet clean
This commit is contained in:
@@ -1,125 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"sync"
|
||||
"syscall"
|
||||
|
||||
"go.temporal.io/sdk/client"
|
||||
"go.temporal.io/sdk/worker"
|
||||
|
||||
"github.com/rockliang/poimen/workflows/action"
|
||||
"github.com/rockliang/poimen/workflows/internal/api"
|
||||
"github.com/rockliang/poimen/workflows/internal/config"
|
||||
"github.com/rockliang/poimen/workflows/pkg/db"
|
||||
"github.com/rockliang/poimen/workflows/statemachine"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var (
|
||||
apiPort = flag.Int("port", 8080, "HTTP API port")
|
||||
verbose = flag.Bool("verbose", false, "verbose logging")
|
||||
)
|
||||
flag.Parse()
|
||||
|
||||
logger := log.New(os.Stdout, "[poimen-server] ", log.LstdFlags|log.Lshortfile)
|
||||
|
||||
// Load configuration
|
||||
cfg, err := config.LoadConfig()
|
||||
if err != nil {
|
||||
logger.Fatalf("failed to load config: %v", err)
|
||||
}
|
||||
|
||||
// Connect to database (memory-db via K8s CNPG)
|
||||
logger.Println("connecting to database...")
|
||||
database, err := db.New(os.Getenv("DATABASE_URL"))
|
||||
if err != nil {
|
||||
logger.Fatalf("failed to connect to database: %v", err)
|
||||
}
|
||||
defer database.Close()
|
||||
logger.Println("✓ Connected to database")
|
||||
|
||||
// Connect to Temporal
|
||||
logger.Printf("connecting to Temporal at %s", cfg.Temporal.HostPort)
|
||||
c, err := client.Dial(client.Options{
|
||||
HostPort: cfg.Temporal.HostPort,
|
||||
Namespace: cfg.Temporal.Namespace,
|
||||
})
|
||||
if err != nil {
|
||||
logger.Fatalf("failed to connect to temporal: %v", err)
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
logger.Println("✓ Connected to Temporal")
|
||||
|
||||
// Create and start Temporal worker
|
||||
w := worker.New(c, "default", worker.Options{})
|
||||
|
||||
// Register RoutingWorkflow
|
||||
w.RegisterWorkflow(statemachine.RoutingWorkflow)
|
||||
|
||||
// Register activities
|
||||
w.RegisterActivity(action.CloneRepoActivity)
|
||||
w.RegisterActivity(action.AnalyzeCodeActivity)
|
||||
w.RegisterActivity(action.SecurityScanActivity)
|
||||
w.RegisterActivity(action.GenerateReportActivity)
|
||||
w.RegisterActivity(action.DeploymentPreCheckActivity)
|
||||
w.RegisterActivity(action.NotifyStatusActivity)
|
||||
w.RegisterActivity(action.ApproveWorkflowActivity)
|
||||
w.RegisterActivity(action.ArchiveResultsActivity)
|
||||
w.RegisterActivity(action.RetrieveMemoryActivity)
|
||||
w.RegisterActivity(action.AssumeRoleActivity)
|
||||
w.RegisterActivity(action.LLMInferenceActivity)
|
||||
w.RegisterActivity(action.LLMBatchInferenceActivity)
|
||||
w.RegisterActivity(action.CanvasReasonerActivity)
|
||||
|
||||
var wg sync.WaitGroup
|
||||
errChan := make(chan error, 2)
|
||||
|
||||
// Start Temporal worker
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
logger.Println("starting Temporal worker...")
|
||||
if err := w.Run(worker.InterruptCh()); err != nil {
|
||||
errChan <- err
|
||||
}
|
||||
}()
|
||||
|
||||
// Start HTTP API server
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
server := api.NewServer(database, c, logger)
|
||||
logger.Printf("starting API server on port %d", *apiPort)
|
||||
if err := server.Start(*apiPort); err != nil {
|
||||
errChan <- err
|
||||
}
|
||||
}()
|
||||
|
||||
// Wait for interrupt signal
|
||||
sigChan := make(chan os.Signal, 1)
|
||||
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
|
||||
|
||||
go func() {
|
||||
sig := <-sigChan
|
||||
logger.Printf("received signal: %v", sig)
|
||||
w.Stop()
|
||||
}()
|
||||
|
||||
// Monitor for errors
|
||||
go func() {
|
||||
err := <-errChan
|
||||
if err != nil {
|
||||
logger.Printf("error: %v", err)
|
||||
w.Stop()
|
||||
}
|
||||
}()
|
||||
|
||||
wg.Wait()
|
||||
logger.Println("✓ Server stopped gracefully")
|
||||
}
|
||||
+15
-15
@@ -11,12 +11,12 @@ import (
|
||||
"time"
|
||||
|
||||
"go.temporal.io/sdk/client"
|
||||
"github.com/rockliang/poimen/workflows/action/llm"
|
||||
"github.com/rockliang/poimen/workflows/activity/llm"
|
||||
"github.com/rockliang/poimen/workflows/internal/config"
|
||||
"github.com/rockliang/poimen/workflows/internal/health"
|
||||
"github.com/rockliang/poimen/workflows/internal/logging"
|
||||
"github.com/rockliang/poimen/workflows/internal/routing"
|
||||
"github.com/rockliang/poimen/workflows/statemachine"
|
||||
"github.com/rockliang/poimen/workflows/workflow"
|
||||
)
|
||||
|
||||
func main() {
|
||||
@@ -89,20 +89,20 @@ func main() {
|
||||
|
||||
|
||||
// Build OrchestratorInput
|
||||
input := statemachine.OrchestratorInput{
|
||||
input := workflow.OrchestratorInput{
|
||||
TargetRepoPath: *repoPath,
|
||||
RemoteURL: *remoteURL,
|
||||
Milestone: *milestone,
|
||||
DryRun: *dryRun,
|
||||
MaxCyclesBeforeCAN: 100,
|
||||
PiProvider: *piProvider,
|
||||
Config: statemachine.OrchestratorConfig{
|
||||
Config: workflow.OrchestratorConfig{
|
||||
SystemPrompt: "You are an expert software developer orchestrating multi-agent work.",
|
||||
Skills: []statemachine.SkillRef{},
|
||||
RolePrompts: map[string]statemachine.PromptSpec{
|
||||
Skills: []workflow.SkillRef{},
|
||||
RolePrompts: map[string]workflow.PromptSpec{
|
||||
"planner": {
|
||||
TemplateRef: "planner/default.tmpl",
|
||||
Model: statemachine.ModelSpec{
|
||||
Model: workflow.ModelSpec{
|
||||
ModelID: *plannerModel,
|
||||
Thinking: "adaptive",
|
||||
Effort: "high",
|
||||
@@ -110,7 +110,7 @@ func main() {
|
||||
},
|
||||
"judge": {
|
||||
TemplateRef: "judge/default.tmpl",
|
||||
Model: statemachine.ModelSpec{
|
||||
Model: workflow.ModelSpec{
|
||||
ModelID: *judgeModel,
|
||||
Thinking: "adaptive",
|
||||
Effort: "high",
|
||||
@@ -118,12 +118,12 @@ func main() {
|
||||
},
|
||||
"implementer": {
|
||||
TemplateRef: "implementer/default.tmpl",
|
||||
Model: statemachine.ModelSpec{
|
||||
Model: workflow.ModelSpec{
|
||||
ModelID: *implementerModel,
|
||||
},
|
||||
},
|
||||
},
|
||||
Tuning: statemachine.NewActivityTuning(),
|
||||
Tuning: workflow.NewActivityTuning(),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -144,7 +144,7 @@ func main() {
|
||||
run, err := c.ExecuteWorkflow(context.Background(), client.StartWorkflowOptions{
|
||||
ID: workflowID,
|
||||
TaskQueue: "poimen-taskqueue",
|
||||
}, statemachine.OrchestratorWorkflow, input)
|
||||
}, workflow.OrchestratorWorkflow, input)
|
||||
if err != nil {
|
||||
logging.Fatal("failed to start workflow", logging.Err(err))
|
||||
}
|
||||
@@ -164,7 +164,7 @@ func main() {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
|
||||
defer cancel()
|
||||
|
||||
var result statemachine.OrchestratorOutput
|
||||
var result workflow.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")
|
||||
@@ -267,12 +267,12 @@ func runRoutingWorkflow(c client.Client, routeMsg, specFile string, isCron, dryR
|
||||
}
|
||||
|
||||
workflowID := "routing-" + spec.Name + "-" + time.Now().Format("20060102-150405")
|
||||
input := statemachine.RoutingWorkflowInput{Spec: spec}
|
||||
input := workflow.RoutingWorkflowInput{Spec: spec}
|
||||
|
||||
run, err := c.ExecuteWorkflow(ctx, client.StartWorkflowOptions{
|
||||
ID: workflowID,
|
||||
TaskQueue: "poimen-taskqueue",
|
||||
}, statemachine.RoutingWorkflow, input)
|
||||
}, workflow.RoutingWorkflow, input)
|
||||
if err != nil {
|
||||
logging.Fatal("failed to start routing workflow", logging.Err(err))
|
||||
}
|
||||
@@ -285,7 +285,7 @@ func runRoutingWorkflow(c client.Client, routeMsg, specFile string, isCron, dryR
|
||||
waitCtx, cancel := context.WithTimeout(ctx, 30*time.Second)
|
||||
defer cancel()
|
||||
|
||||
var result statemachine.RoutingWorkflowOutput
|
||||
var result workflow.RoutingWorkflowOutput
|
||||
if err := run.Get(waitCtx, &result); err != nil {
|
||||
fmt.Printf("\nWorkflow running (check Temporal UI for status)\n")
|
||||
} else {
|
||||
|
||||
+37
-37
@@ -11,11 +11,11 @@ import (
|
||||
|
||||
"go.temporal.io/sdk/client"
|
||||
"go.temporal.io/sdk/worker"
|
||||
"github.com/rockliang/poimen/workflows/action"
|
||||
"github.com/rockliang/poimen/workflows/activity"
|
||||
"github.com/rockliang/poimen/workflows/internal/config"
|
||||
"github.com/rockliang/poimen/workflows/internal/health"
|
||||
"github.com/rockliang/poimen/workflows/internal/logging"
|
||||
"github.com/rockliang/poimen/workflows/statemachine"
|
||||
"github.com/rockliang/poimen/workflows/workflow"
|
||||
)
|
||||
|
||||
func main() {
|
||||
@@ -48,56 +48,56 @@ func main() {
|
||||
}
|
||||
|
||||
// Register all workflows
|
||||
w.RegisterWorkflow(statemachine.OrchestratorWorkflow)
|
||||
w.RegisterWorkflow(statemachine.TaskUnitWorkflow)
|
||||
w.RegisterWorkflow(statemachine.TestWorkflow)
|
||||
w.RegisterWorkflow(statemachine.RoutingWorkflow)
|
||||
w.RegisterWorkflow(statemachine.WorkflowGraphQuery)
|
||||
w.RegisterWorkflow(workflow.OrchestratorWorkflow)
|
||||
w.RegisterWorkflow(workflow.TaskUnitWorkflow)
|
||||
w.RegisterWorkflow(workflow.TestWorkflow)
|
||||
w.RegisterWorkflow(workflow.RoutingWorkflow)
|
||||
w.RegisterWorkflow(workflow.WorkflowGraphQuery)
|
||||
|
||||
// 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.GitDiffActivity)
|
||||
w.RegisterActivity(action.PrepareSkillsActivity)
|
||||
w.RegisterActivity(action.PlanningActivity)
|
||||
w.RegisterActivity(action.ImplementerActivity)
|
||||
w.RegisterActivity(action.JudgeActivity)
|
||||
w.RegisterActivity(activity.CloneRepoActivity)
|
||||
w.RegisterActivity(activity.GitWorktreeAddActivity)
|
||||
w.RegisterActivity(activity.GitCommitActivity)
|
||||
w.RegisterActivity(activity.GitPushActivity)
|
||||
w.RegisterActivity(activity.GitSquashMergeActivity)
|
||||
w.RegisterActivity(activity.GitDiffActivity)
|
||||
w.RegisterActivity(activity.PrepareSkillsActivity)
|
||||
w.RegisterActivity(activity.PlanningActivity)
|
||||
w.RegisterActivity(activity.ImplementerActivity)
|
||||
w.RegisterActivity(activity.JudgeActivity)
|
||||
// Integration and lessons activities - register when fully tested
|
||||
w.RegisterActivity(action.RunIntegrationTestActivity)
|
||||
// w.RegisterActivity(action.UpdateLessonsActivity)
|
||||
// w.RegisterActivity(action.ReadLessonsActivity)
|
||||
w.RegisterActivity(activity.RunIntegrationTestActivity)
|
||||
// w.RegisterActivity(activity.UpdateLessonsActivity)
|
||||
// w.RegisterActivity(activity.ReadLessonsActivity)
|
||||
|
||||
// Routing workflow activities
|
||||
w.RegisterActivity(action.LLMRouterActivity)
|
||||
w.RegisterActivity(action.ValidateWorkflowSpecActivity)
|
||||
w.RegisterActivity(action.ValidateCronWorkflowSpecActivity)
|
||||
w.RegisterActivity(activity.LLMRouterActivity)
|
||||
w.RegisterActivity(activity.ValidateWorkflowSpecActivity)
|
||||
w.RegisterActivity(activity.ValidateCronWorkflowSpecActivity)
|
||||
|
||||
// Analysis activities
|
||||
w.RegisterActivity(action.AnalyzeCodeActivity)
|
||||
w.RegisterActivity(action.SecurityScanActivity)
|
||||
w.RegisterActivity(action.GenerateReportActivity)
|
||||
w.RegisterActivity(activity.AnalyzeCodeActivity)
|
||||
w.RegisterActivity(activity.SecurityScanActivity)
|
||||
w.RegisterActivity(activity.GenerateReportActivity)
|
||||
|
||||
// Notification and utility activities
|
||||
w.RegisterActivity(action.NotifyStatusActivity)
|
||||
w.RegisterActivity(action.ArchiveResultsActivity)
|
||||
w.RegisterActivity(action.DeploymentPreCheckActivity)
|
||||
w.RegisterActivity(action.ApproveWorkflowActivity)
|
||||
w.RegisterActivity(activity.NotifyStatusActivity)
|
||||
w.RegisterActivity(activity.ArchiveResultsActivity)
|
||||
w.RegisterActivity(activity.DeploymentPreCheckActivity)
|
||||
w.RegisterActivity(activity.ApproveWorkflowActivity)
|
||||
|
||||
// Authentication activities
|
||||
w.RegisterActivity(action.AssumeRoleActivity)
|
||||
w.RegisterActivity(activity.AssumeRoleActivity)
|
||||
|
||||
// Memory activities
|
||||
w.RegisterActivity(action.RetrieveMemoryActivity)
|
||||
w.RegisterActivity(activity.RetrieveMemoryActivity)
|
||||
|
||||
// GraphRAG activities
|
||||
w.RegisterActivity(action.FetchCanvasRelationsActivity)
|
||||
w.RegisterActivity(action.QueryGraphRAGActivity)
|
||||
w.RegisterActivity(action.CanvasReasonerActivity)
|
||||
w.RegisterActivity(action.IndexGraphRAGActivity)
|
||||
w.RegisterActivity(action.CanvasCompatibilityActivity)
|
||||
w.RegisterActivity(activity.FetchCanvasRelationsActivity)
|
||||
w.RegisterActivity(activity.QueryGraphRAGActivity)
|
||||
w.RegisterActivity(activity.CanvasReasonerActivity)
|
||||
w.RegisterActivity(activity.IndexGraphRAGActivity)
|
||||
w.RegisterActivity(activity.CanvasCompatibilityActivity)
|
||||
|
||||
// Initialize health checker
|
||||
healthChecker := health.NewChecker(c)
|
||||
|
||||
Reference in New Issue
Block a user