agent/pkg/agentic/dispatch_sync.go
Virgil 06ae13d92b fix(ax): align remaining comments with AX principles
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-31 04:33:36 +00:00

97 lines
2.5 KiB
Go

// SPDX-License-Identifier: EUPL-1.2
package agentic
import (
"context"
"time"
core "dappco.re/go/core"
)
// input := agentic.DispatchSyncInput{Repo: "go-crypt", Agent: "codex:gpt-5.3-codex-spark", Task: "fix it", Issue: 7}
type DispatchSyncInput struct {
Org string
Repo string
Agent string
Task string
Issue int
}
// if result.OK { core.Print(nil, "done: %s", result.Status) }
// if !result.OK { core.Print(nil, "%v", result.Error) }
type DispatchSyncResult struct {
OK bool
Status string
Error error
PRURL string
}
// result := prep.DispatchSync(ctx, input)
func (s *PrepSubsystem) DispatchSync(ctx context.Context, input DispatchSyncInput) DispatchSyncResult {
// Prep workspace
prepInput := PrepInput{
Org: input.Org,
Repo: input.Repo,
Task: input.Task,
Agent: input.Agent,
Issue: input.Issue,
}
prepContext, cancel := context.WithTimeout(ctx, 5*time.Minute)
defer cancel()
_, prepOut, err := s.prepWorkspace(prepContext, nil, prepInput)
if err != nil {
return DispatchSyncResult{Error: core.E("agentic.DispatchSync", "prep workspace failed", err)}
}
if !prepOut.Success {
return DispatchSyncResult{Error: core.E("agentic.DispatchSync", "prep failed", nil)}
}
workspaceDir := prepOut.WorkspaceDir
prompt := prepOut.Prompt
core.Print(nil, " workspace: %s", workspaceDir)
core.Print(nil, " branch: %s", prepOut.Branch)
// Spawn agent directly — no queue, no concurrency check
pid, processID, _, err := s.spawnAgent(input.Agent, prompt, workspaceDir)
if err != nil {
return DispatchSyncResult{Error: core.E("agentic.DispatchSync", "spawn agent failed", err)}
}
core.Print(nil, " pid: %d", pid)
core.Print(nil, " waiting for completion...")
var runtime *core.Core
if s.ServiceRuntime != nil {
runtime = s.Core()
}
// Poll for process exit
ticker := time.NewTicker(3 * time.Second)
defer ticker.Stop()
for {
select {
case <-ctx.Done():
return DispatchSyncResult{Error: core.E("agentic.DispatchSync", "cancelled", ctx.Err())}
case <-ticker.C:
if pid > 0 && !ProcessAlive(runtime, processID, pid) {
// Process exited — read final status
result := ReadStatusResult(workspaceDir)
st, ok := workspaceStatusValue(result)
if !ok {
err, _ := result.Value.(error)
return DispatchSyncResult{Error: core.E("agentic.DispatchSync", "can't read final status", err)}
}
return DispatchSyncResult{
OK: st.Status == "completed",
Status: st.Status,
PRURL: st.PRURL,
}
}
}
}
}