fix(ax): align runner and monitor usage examples

Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
Virgil 2026-03-29 22:53:38 +00:00
parent 07f255fca1
commit f8cd0ff11a
3 changed files with 36 additions and 11 deletions

View file

@ -556,7 +556,7 @@ func TestQueue_DrainQueue_Good_FrozenDoesNothing(t *testing.T) {
// --- shutdownNow (Ugly — deep layout with queued status) ---
func TestPrep_Shutdown_ShutdownNow_Ugly(t *testing.T) {
func TestShutdown_ShutdownNow_Ugly_DeepLayout(t *testing.T) {
// shutdownNow delegates to runner.kill Action — queue clearing is now
// handled by the runner service. Verify delegation with deep-layout workspaces.
root := t.TempDir()

View file

@ -79,6 +79,8 @@ func resultString(r core.Result) (string, bool) {
}
// MonitorOptions configures the monitor service.
//
// opts := monitor.MonitorOptions{}
type MonitorOptions struct{}
// Subsystem implements mcp.Subsystem for background monitoring.
@ -134,7 +136,8 @@ func (m *Subsystem) handleAgentCompleted(ev messages.AgentCompleted) {
// Options configures the monitor interval.
//
// monitor.New(monitor.Options{Interval: 30 * time.Second})
// opts := monitor.Options{Interval: 30 * time.Second}
// mon := monitor.New(opts)
type Options struct {
// Interval between checks (default: 2 minutes)
Interval time.Duration
@ -203,13 +206,19 @@ func (m *Subsystem) Start(ctx context.Context) {
}()
}
// OnStartup implements core.Startable — starts the monitoring loop.
// OnStartup starts the monitoring loop for a registered service.
//
// r := mon.OnStartup(context.Background())
// core.Println(r.OK)
func (m *Subsystem) OnStartup(ctx context.Context) core.Result {
m.Start(ctx)
return core.Result{OK: true}
}
// OnShutdown implements core.Stoppable — stops the monitoring loop.
// OnShutdown stops the monitoring loop through the Core lifecycle hook.
//
// r := mon.OnShutdown(context.Background())
// core.Println(r.OK)
func (m *Subsystem) OnShutdown(ctx context.Context) core.Result {
_ = m.Shutdown(ctx)
return core.Result{OK: true}
@ -226,7 +235,9 @@ func (m *Subsystem) Shutdown(_ context.Context) error {
return nil
}
// Poke triggers an immediate check cycle (legacy — prefer AgentStarted/AgentCompleted).
// Poke triggers an immediate check cycle.
//
// mon.Poke()
func (m *Subsystem) Poke() {
select {
case m.poke <- struct{}{}:

View file

@ -19,6 +19,8 @@ import (
)
// Options configures the runner service.
//
// opts := runner.Options{}
type Options struct{}
// Service is the agent dispatch runner.
@ -106,15 +108,22 @@ func (s *Service) OnStartup(ctx context.Context) core.Result {
}
// OnShutdown freezes the queue.
//
// r := svc.OnShutdown(context.Background())
// if r.OK {
// core.Println(svc.IsFrozen())
// }
func (s *Service) OnShutdown(_ context.Context) core.Result {
s.frozen = true
return core.Result{OK: true}
}
// HandleIPCEvents catches agent lifecycle events from other services.
// HandleIPCEvents applies runner side-effects for IPC messages.
//
// AgentCompleted → push channel notification + poke queue
// PokeQueue → drain queue
// svc.HandleIPCEvents(c, messages.PokeQueue{})
// svc.HandleIPCEvents(c, messages.AgentCompleted{
// Agent: "codex", Repo: "go-io", Workspace: "core/go-io/task-5", Status: "completed",
// })
func (s *Service) HandleIPCEvents(c *core.Core, msg core.Message) core.Result {
switch ev := msg.(type) {
case messages.AgentStarted:
@ -396,9 +405,14 @@ func (s *Service) hydrateWorkspaces() {
// --- Types ---
// AgentNotification is the channel push payload for agent status updates.
// Field order is guaranteed by json tags — status and repo appear first
// so truncated notifications are still readable.
// AgentNotification is the channel payload sent on `agent.status`.
//
// n := runner.AgentNotification{
// Status: "started", Repo: "go-io", Agent: "codex", Workspace: "core/go-io/task-5", Running: 1, Limit: 2,
// }
//
// Field order is guaranteed by json tags so truncated notifications still show
// status and repo first.
type AgentNotification struct {
Status string `json:"status"`
Repo string `json:"repo"`