- Supervisor struct: NewSupervisor, Run, RunNext, execute - E2E tok: scan → find → active → run → verify → report → review - cmdRun u CLI koristi Supervisor - 8 e2e testova sa mock agentom, 67 ukupno — svi prolaze - T06 premešten u done/ Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
97 lines
2.4 KiB
Go
97 lines
2.4 KiB
Go
// Package supervisor implements the KAOS supervisor process
|
|
// that orchestrates agent execution and task management.
|
|
package supervisor
|
|
|
|
import (
|
|
"fmt"
|
|
"path/filepath"
|
|
|
|
"github.com/dal/kaos/internal/config"
|
|
)
|
|
|
|
// Supervisor orchestrates task execution, verification, and reporting.
|
|
type Supervisor struct {
|
|
Config *config.Config
|
|
TasksDir string
|
|
CodeDir string
|
|
ReportsDir string
|
|
CmdBuilder CommandBuilder
|
|
}
|
|
|
|
// NewSupervisor creates a Supervisor from configuration.
|
|
func NewSupervisor(cfg *config.Config) *Supervisor {
|
|
return &Supervisor{
|
|
Config: cfg,
|
|
TasksDir: cfg.TasksDir,
|
|
CodeDir: cfg.ProjectPath,
|
|
ReportsDir: filepath.Join(cfg.TasksDir, "reports"),
|
|
}
|
|
}
|
|
|
|
// Run executes a specific task by ID through the full pipeline:
|
|
// scan → find → move to active → run → verify → report → move to review.
|
|
func (s *Supervisor) Run(taskID string) error {
|
|
tasks, err := ScanTasks(s.TasksDir)
|
|
if err != nil {
|
|
return fmt.Errorf("scan tasks: %w", err)
|
|
}
|
|
|
|
task := FindTask(tasks, taskID)
|
|
if task == nil {
|
|
return fmt.Errorf("task %s nije pronađen", taskID)
|
|
}
|
|
|
|
if task.Status != "ready" {
|
|
return fmt.Errorf("task %s nije u ready/ (trenutno: %s)", taskID, task.Status)
|
|
}
|
|
|
|
return s.execute(task)
|
|
}
|
|
|
|
// RunNext finds the next ready task with satisfied dependencies and runs it.
|
|
func (s *Supervisor) RunNext() error {
|
|
tasks, err := ScanTasks(s.TasksDir)
|
|
if err != nil {
|
|
return fmt.Errorf("scan tasks: %w", err)
|
|
}
|
|
|
|
task := NextTask(tasks)
|
|
if task == nil {
|
|
return fmt.Errorf("nema taskova spremnih za rad")
|
|
}
|
|
|
|
return s.execute(task)
|
|
}
|
|
|
|
// execute runs the full pipeline for a task.
|
|
func (s *Supervisor) execute(task *Task) error {
|
|
// Move to active
|
|
if err := MoveTask(s.TasksDir, task.ID, "ready", "active"); err != nil {
|
|
return fmt.Errorf("premesti u active/: %w", err)
|
|
}
|
|
|
|
// Run the task
|
|
result := RunTask(*task, s.CodeDir, s.Config.Timeout, s.CmdBuilder)
|
|
|
|
// Verify
|
|
verify := Verify(s.CodeDir)
|
|
|
|
// Write report
|
|
_, err := WriteReport(*task, result, verify, s.ReportsDir)
|
|
if err != nil {
|
|
// Don't fail the pipeline for report errors, but log it
|
|
fmt.Printf("Upozorenje: greška pri pisanju izveštaja: %v\n", err)
|
|
}
|
|
|
|
// Move to review (regardless of pass/fail)
|
|
if err := MoveTask(s.TasksDir, task.ID, "active", "review"); err != nil {
|
|
return fmt.Errorf("premesti u review/: %w", err)
|
|
}
|
|
|
|
if !verify.AllPassed {
|
|
return fmt.Errorf("verifikacija neuspešna za %s", task.ID)
|
|
}
|
|
|
|
return nil
|
|
}
|