types

package
v0.6.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 18, 2026 License: MIT Imports: 7 Imported by: 0

Documentation

Overview

Package types defines the per-agent abstraction interfaces for `entire review`.

AgentReviewer is the contract every supported agent (claude-code, codex, gemini, future additions) implements in its own package. The orchestrator in cmd/entire/cli/review/run.go consumes this interface, never importing concrete agent packages — that's how new agents land as additive files without touching shared code.

Events flow as a stream: implementations spawn the agent process, parse stdout into a sequence of typed Events (Started, AssistantText, ToolCall, Tokens, Finished, RunError), and surface them via Process.Events. Per-agent quirks (codex's JSONL envelope shape, gemini's stdin requirement, claude's argv shape) are entirely encapsulated inside each agent's adapter — shared code only sees the cleaned event stream.

Living in a subpackage (not the review root package) avoids import cycles: per-agent reviewers and the orchestrator both depend on these types without depending on each other.

Package types — see reviewer.go for package-level rationale.

sink.go defines the consumer-side abstractions for review runs: Sink (event consumer interface), RunSummary (post-run record), AgentRun (per-agent post-run data), and AgentStatus (terminal state enum).

Package types — see reviewer.go for package-level rationale.

template.go provides ReviewerTemplate, a struct that implements AgentReviewer using two caller-supplied functions: BuildCmd (per-agent argv/env construction) and Parser (per-agent stdout-to-Event stream).

All three currently-supported agents (claude-code, codex, gemini) share the Start/Process/Wait/Events scaffolding. Only the build-cmd step and the stdout parser genuinely differ. The template owns the shared lifecycle (spawn → pipe stdout → run parser → forward events → close on exit); each agent supplies the two unique pieces.

Index

Constants

This section is empty.

Variables

View Source
var ErrTemplateMisconfigured = errors.New("ReviewerTemplate misconfigured")

ErrTemplateMisconfigured is returned by ReviewerTemplate.Start when one of the required fields (AgentName, BuildCmd, Parser) is unset, or when BuildCmd returns nil. Use errors.Is to detect this in tests or higher layers (e.g., a multi-agent orchestrator that needs to skip a misconfigured agent rather than crashing the whole run).

Functions

This section is empty.

Types

type AgentReviewer

type AgentReviewer interface {
	// Name returns the agent's registry key (e.g., "claude-code", "codex",
	// "gemini"). Stable identifier; do not change after release without
	// updating settings migration.
	Name() string

	// Start spawns the agent with the given run configuration. The returned
	// Process exposes streaming events via Events() and a Wait() that returns
	// when the process exits.
	//
	// Implementations MUST set the ENTIRE_REVIEW_* env vars on the spawned
	// child process (see cmd/entire/cli/review/env.go) so the agent's
	// lifecycle hooks adopt the session as a review session.
	//
	// Errors from Start indicate failure to construct or launch the process
	// (e.g., binary not on PATH at exec.Cmd.Start time, invalid argv). Once
	// Start returns nil, errors during the run flow through Process.Events
	// (as RunError) and Process.Wait.
	Start(ctx context.Context, run RunConfig) (Process, error)
}

AgentReviewer drives a single agent's review run.

type AgentRun

type AgentRun struct {
	Name   string
	Status AgentStatus
	Tokens Tokens

	// Buffer accumulates the full event log per agent for post-hoc
	// rendering (DumpSink, TUI dump, synthesis).
	//
	// TODO(memory): At review lengths typical today (~100s of events,
	// ~few KB) this is fine. If profiling shows reviews regularly
	// exceed ~10MB of buffered events or ~10000 events, swap to a
	// token-budgeted ring or stream events to sinks incrementally
	// and drop the buffer.
	Buffer []Event

	StartedAt time.Time
	Duration  time.Duration
	Err       error
}

AgentRun is per-agent post-run data.

type AgentStatus

type AgentStatus int

AgentStatus is the terminal state for an agent.

const (
	AgentStatusUnknown AgentStatus = iota
	AgentStatusSucceeded
	AgentStatusFailed
	AgentStatusCancelled
)

func (AgentStatus) String

func (s AgentStatus) String() string

String returns a human-readable status (used in dump output and TUI).

type AssistantText

type AssistantText struct {
	Text string
}

AssistantText is narrative output from the agent (the actual review response, not tool-call chrome or session metadata).

type Event

type Event interface {
	// contains filtered or unexported methods
}

Event is the sealed sum type emitted by Process.Events. The unexported isEvent method prevents external packages from adding event variants; adding a new event requires updating this file (and every consumer's type switch — that's intentional, since a new event variant is a contract change).

type Finished

type Finished struct {
	Success bool
}

Finished signals the agent has produced its final output and the event stream is about to end. Success indicates the agent self-reported a clean task completion. Success=false means the agent finished its event stream but signaled it did not complete the review task — distinct from process exit failure (which surfaces via Process.Wait, not as an event).

Adapters typically emit this once at the bottom of the event stream, before the channel closes.

type Process

type Process interface {
	// Events returns a channel that emits structured events as the agent
	// produces output. The channel is closed when the process exits — cleanly,
	// with error, or via context cancellation. Consumers should range over it.
	Events() <-chan Event

	// Wait blocks until the process exits and returns:
	//   - nil on clean exit (exit code 0)
	//   - ctx.Err() on cancellation
	//   - an error wrapping *exec.ExitError on non-zero exit
	//   - other error types for I/O or pipe failures
	//
	// Wait must be called exactly once per Process. It is safe to call Wait
	// after the Events channel has closed. Consumers must drain Events until
	// close before calling Wait; otherwise an implementation that forwards
	// parsed events from another goroutine may block while sending.
	Wait() error
}

Process represents a running agent review.

type ProcessError

type ProcessError struct {
	AgentName string
	Err       error
	Stderr    string
}

ProcessError wraps a process failure with bounded stderr diagnostics. Unwrap preserves the underlying error, so callers can still use errors.As for *exec.ExitError or errors.Is for lower-level sentinels.

func (*ProcessError) Error

func (e *ProcessError) Error() string

func (*ProcessError) Unwrap

func (e *ProcessError) Unwrap() error

type ReviewerTemplate

type ReviewerTemplate struct {
	// AgentName is returned by Name(). Stable identifier per agent.
	AgentName string

	// BuildCmd constructs the *exec.Cmd to spawn the agent process,
	// including argv, stdin (if any), and ENTIRE_REVIEW_* env vars.
	// The command MUST NOT have started yet; the template will call Start.
	BuildCmd func(ctx context.Context, cfg RunConfig) *exec.Cmd

	// Parser converts the agent's stdout stream into a sequence of Events.
	// The returned channel must close when stdout closes. Implementations
	// must emit Started first, Finished{Success: ...} or RunError last,
	// and check scanner.Err() before emitting Finished{Success: true}.
	Parser func(stdout io.Reader) <-chan Event
}

ReviewerTemplate implements AgentReviewer for agents whose only per-agent quirks are argv/env construction and stdout parsing. Both fields must be set before Start is called; nil values cause Start to panic immediately.

func (*ReviewerTemplate) Name

func (t *ReviewerTemplate) Name() string

Name returns the agent's stable identifier.

func (*ReviewerTemplate) Start

func (t *ReviewerTemplate) Start(ctx context.Context, cfg RunConfig) (Process, error)

Start spawns the agent process, wires stdout through the parser, and returns a Process whose Events channel streams the parsed event sequence.

Returns ErrTemplateMisconfigured if AgentName, BuildCmd, or Parser is unset, or if BuildCmd returns nil. These are programmer errors but failing fast with a typed error is friendlier than a downstream nil deref — and it keeps Start from panicking inside a multi-agent fan-out (CU8) where one misconfigured template would otherwise kill the whole run.

type RunConfig

type RunConfig struct {
	// PromptOverride, when non-empty, is the exact prompt sent to the agent.
	// It preserves settings.ReviewConfig.Prompt's existing verbatim-override
	// contract: configured skills are still recorded as structured metadata,
	// but they are not prepended to the prompt text.
	PromptOverride string

	// Skills are skill invocation strings passed to the agent verbatim.
	Skills []string

	// AlwaysPrompt is the per-agent always-prompt configured in settings.
	// Concatenated with Skills + PerRunPrompt + a scope clause to form the
	// composed agent prompt.
	AlwaysPrompt string

	// PerRunPrompt is optional textarea input from a single invocation.
	PerRunPrompt string

	// ScopeBaseRef is the git ref the review is scoped against (mainline by
	// default — origin/HEAD → origin/main → origin/master → main → master —
	// or whatever `--base` overrides it to). Used to compose the scope clause
	// and as the base for `git diff` operations the agent may perform.
	ScopeBaseRef string

	// CheckpointContext is best-effort context derived from checkpoints in the
	// branch review scope. It is appended to generated prompts so every agent
	// can use checkpoint IDs, file summaries, and transcript lookup commands
	// while reviewing. PromptOverride remains verbatim and does not receive
	// this context.
	CheckpointContext string

	// StartingSHA is HEAD at invocation time, propagated to the lifecycle
	// hook via ENTIRE_REVIEW_STARTING_SHA so checkpoint metadata records
	// the commit that was reviewed.
	StartingSHA string

	// EnrichSummary optionally updates the completed run summary before sinks
	// receive RunFinished. It is used for post-process data such as token
	// totals that are only available after agent lifecycle hooks flush state.
	//
	// Timing: called on the orchestrator goroutine after every per-agent
	// goroutine has exited, immediately before Sink.RunFinished is fanned
	// out. The full RunSummary is consumed; any field the callback
	// returns reaches the sinks.
	//
	// Contract: nil is valid (no enrichment). The callback must not block on
	// a sink (deadlock), must not panic (no orchestrator-side recovery), and
	// should honor ctx for cancellation when doing I/O.
	EnrichSummary func(context.Context, RunSummary) RunSummary

	// EnrichAgentRun optionally updates a single agent run after that agent
	// exits, before the overall multi-agent run has necessarily completed.
	//
	// Timing: called on the per-agent forwarding goroutine in RunMulti,
	// after proc.Wait() returns and after any synthetic RunError is queued.
	// Only the returned Tokens field is consumed (emitted as a synthetic
	// Tokens event so sinks see live token totals before sibling agents
	// finish); other field changes are discarded. Returning Tokens{In:0,
	// Out:0} suppresses emission entirely.
	//
	// Contract: nil is valid (no enrichment). The callback must be
	// goroutine-safe across N agents and must not block on a sink. A panic
	// is recovered; no synthetic Tokens event is emitted on panic.
	EnrichAgentRun func(context.Context, AgentRun) AgentRun
}

RunConfig is the immutable per-run configuration passed to AgentReviewer.Start.

All fields are optional from a marshalling standpoint (zero value is valid), but Skills is typically non-empty in practice — it carries the skill invocations (e.g., "/pr-review-toolkit:review-pr") the configured agent should run.

type RunError

type RunError struct {
	Err error
}

RunError reports a non-fatal error during the run (e.g., hook failure, transient stream parse error). Fatal errors that stop the agent surface via Process.Wait, not as events.

type RunSummary

type RunSummary struct {
	StartedAt  time.Time
	FinishedAt time.Time

	// Cancelled is true iff the orchestrator's run context was cancelled
	// during the run (or before it started). For single-agent runs this
	// is equivalent to AgentRuns[0].Status == AgentStatusCancelled. Under
	// multi-agent runs (CU8), Cancelled means "the run as a whole was
	// cancelled" — individual AgentRuns may have other terminal states
	// if they finished before cancellation propagated.
	Cancelled bool

	AgentRuns []AgentRun
}

RunSummary is the post-run record passed to all sinks.

type Sink

type Sink interface {
	// AgentEvent is called for every event emitted by an agent's
	// process during the run. Events are delivered in-order within a
	// single agent; across agents (CU8 multi-agent) the orchestrator
	// serializes calls so sinks see one event at a time.
	AgentEvent(agent string, ev Event)

	// RunFinished is called once when the run terminates (cleanly,
	// failed, or cancelled). Sinks that only act post-run (DumpSink,
	// synthesis sink) implement only this method (with a no-op
	// AgentEvent).
	RunFinished(summary RunSummary)
}

Sink consumes events from a review run. Sinks are passed to the orchestrator at construction time; selecting which sinks compose is the caller's job (TUI vs. non-TTY, synthesis on/off).

Concurrency: AgentEvent and RunFinished are guaranteed to be invoked from a single goroutine — the orchestrator serializes calls even under multi-agent runs (CU8 fans events from N agents into one dispatch loop). Sinks need not internally synchronize.

Sinks MUST NOT block. AgentEvent runs on the dispatch goroutine; a slow sink stalls the entire run and starves all other sinks.

type Started

type Started struct{}

Started signals the agent has begun the review. Adapters typically emit this once at the top of the event stream.

type Tokens

type Tokens struct {
	In  int
	Out int
}

Tokens reports cumulative token counts (running totals, not deltas). Adapters may emit multiple Tokens events during a run; each emission supersedes the prior, so consumers should overwrite (not sum) on receipt. Adapters that only receive aggregate shutdown totals should emit at most one final Tokens event rather than inventing deltas.

type ToolCall

type ToolCall struct {
	Name string
	Args string
}

ToolCall reports a tool invocation by the agent. Args is an opaque adapter-defined string — typically JSON for agents that emit structured tool input (e.g., claude-code), or a single-line summary for those that don't (e.g., codex). Shared consumers should treat Args as display-only and not parse it; structured tool data is intentionally not part of this contract.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL