KAOS/code/internal/supervisor/supervisor.go
djuka b2ece9883b T07: Integracija — Supervisor struct sa end-to-end tokom
- 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>
2026-02-20 11:59:06 +00:00

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
}