Files
orchestra/internal/herdr/adapter.go
T
2026-07-26 19:07:03 +04:00

63 lines
1.9 KiB
Go

package herdr
import (
"context"
"fmt"
"time"
)
type Adapter interface {
Lease(context.Context, string, string) (Session, error)
Bootstrap(context.Context, Session, string) error
Release(context.Context, Session) (string, error)
Kill(context.Context, Session) error
Occupancy(Session) (float64, error)
}
type CLIAdapter struct {
Client *Client
Harness string
Window int64
Usage func(string) (Usage, error)
}
func (a CLIAdapter) Lease(ctx context.Context, task, worktree string) (Session, error) {
if a.Client == nil {
return Session{}, fmt.Errorf("adapter: client required")
}
var s Session
e := a.Client.Call(ctx, "pane.create", map[string]string{"harness": a.Harness, "task_id": task, "worktree": worktree}, &s)
s.Harness = a.Harness
s.Worktree = worktree
return s, e
}
func (a CLIAdapter) Bootstrap(ctx context.Context, s Session, ref string) error {
return a.Client.Prompt(ctx, s.PaneID, fmt.Sprintf("Read handoff %s, validate the anchor and TASK.md, then continue.", ref), time.Minute)
}
func (a CLIAdapter) Release(ctx context.Context, s Session) (string, error) {
var r struct {
Ref string `json:"handoff_ref"`
}
e := a.Client.Call(ctx, "pane.release", s, &r)
return r.Ref, e
}
func (a CLIAdapter) Kill(ctx context.Context, s Session) error {
return a.Client.Call(ctx, "pane.kill", s, nil)
}
func (a CLIAdapter) Occupancy(s Session) (float64, error) {
if a.Usage == nil {
return 0, fmt.Errorf("adapter: usage reader required")
}
u, e := a.Usage(s.PaneID)
return Fraction(u, a.Window), e
}
var Claude = func(c *Client, w int64) CLIAdapter {
return CLIAdapter{Client: c, Harness: "claude", Window: w, Usage: ClaudeUsage}
}
var Codex = func(c *Client, w int64) CLIAdapter {
return CLIAdapter{Client: c, Harness: "codex", Window: w, Usage: CodexUsage}
}
var OpenCode = func(c *Client, w int64) CLIAdapter {
return CLIAdapter{Client: c, Harness: "opencode", Window: w, Usage: OpenCodeUsage}
}