agents

package
v0.10.6 Latest Latest
Warning

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

Go to latest
Published: Sep 7, 2026 License: MIT Imports: 19 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AcquireSlot

func AcquireSlot(ctx context.Context, a Agent) error

AcquireSlot blocks until a test slot is available for the agent or the context is cancelled. Returns a non-nil error if the context expires before a slot opens.

func DefaultDroidModel added in v0.5.0

func DefaultDroidModel() string

DefaultDroidModel returns the default model string for Droid BYOK configuration. Format is "custom:<baseModelID>" which the Droid API expects for custom model selection.

func Register

func Register(a Agent)

func RegisterGate

func RegisterGate(name string, defaultMax int)

RegisterGate sets a concurrency limit for an agent's tests. Tests call AcquireSlot/ReleaseSlot to respect this limit. The limit can be overridden via E2E_CONCURRENT_TEST_LIMIT.

func ReleaseSlot

func ReleaseSlot(a Agent)

ReleaseSlot frees a test slot for the agent.

Types

type Agent

type Agent interface {
	Name() string
	// Binary returns the CLI binary name (e.g. "claude", "gemini").
	Binary() string
	EntireAgent() string
	PromptPattern() string
	// TimeoutMultiplier returns a factor applied to per-test timeouts.
	// Slower agents (e.g. Gemini) return values > 1.
	TimeoutMultiplier() float64
	RunPrompt(ctx context.Context, dir string, prompt string, opts ...Option) (Output, error)
	StartSession(ctx context.Context, dir string) (Session, error)
	// Bootstrap performs one-time CI setup (auth config, warmup, etc.).
	// Called before any tests run. Implementations should be idempotent.
	Bootstrap() error
	// IsTransientError returns true if the error from RunPrompt looks like
	// a transient API failure (e.g. 500, rate limit, network error) that
	// is worth retrying.
	IsTransientError(out Output, err error) bool
}

func All

func All() []Agent

type Claude

type Claude struct{}

func (*Claude) Binary

func (c *Claude) Binary() string

func (*Claude) Bootstrap

func (c *Claude) Bootstrap() error

func (*Claude) EntireAgent

func (c *Claude) EntireAgent() string

func (*Claude) IsTransientError

func (c *Claude) IsTransientError(out Output, _ error) bool

func (*Claude) Name

func (c *Claude) Name() string

func (*Claude) PromptPattern

func (c *Claude) PromptPattern() string

func (*Claude) RunPrompt

func (c *Claude) RunPrompt(ctx context.Context, dir string, prompt string, opts ...Option) (Output, error)

func (*Claude) StartSession

func (c *Claude) StartSession(ctx context.Context, dir string) (Session, error)

func (*Claude) TimeoutMultiplier

func (c *Claude) TimeoutMultiplier() float64

type Codex added in v0.5.2

type Codex struct{}

Codex implements the E2E Agent interface for OpenAI's Codex CLI.

func (*Codex) Binary added in v0.5.2

func (c *Codex) Binary() string

func (*Codex) Bootstrap added in v0.5.2

func (c *Codex) Bootstrap() error

func (*Codex) EntireAgent added in v0.5.2

func (c *Codex) EntireAgent() string

func (*Codex) IsTransientError added in v0.5.2

func (c *Codex) IsTransientError(out Output, err error) bool

func (*Codex) Name added in v0.5.2

func (c *Codex) Name() string

func (*Codex) PromptPattern added in v0.5.2

func (c *Codex) PromptPattern() string

func (*Codex) ResumeSession added in v0.5.4

func (c *Codex) ResumeSession(ctx context.Context, dir, home, sessionID string) (Session, error)

func (*Codex) RunPrompt added in v0.5.2

func (c *Codex) RunPrompt(ctx context.Context, dir string, prompt string, opts ...Option) (Output, error)

func (*Codex) StartSession added in v0.5.2

func (c *Codex) StartSession(ctx context.Context, dir string) (Session, error)

func (*Codex) TimeoutMultiplier added in v0.5.2

func (c *Codex) TimeoutMultiplier() float64

type CodexSession added in v0.5.4

type CodexSession struct {
	*TmuxSession
	// contains filtered or unexported fields
}

func (*CodexSession) Home added in v0.5.4

func (s *CodexSession) Home() string

type CopilotCLI added in v0.5.0

type CopilotCLI struct{}

func (*CopilotCLI) Binary added in v0.5.0

func (c *CopilotCLI) Binary() string

func (*CopilotCLI) Bootstrap added in v0.5.0

func (c *CopilotCLI) Bootstrap() error

func (*CopilotCLI) EntireAgent added in v0.5.0

func (c *CopilotCLI) EntireAgent() string

func (*CopilotCLI) IsTransientError added in v0.5.0

func (c *CopilotCLI) IsTransientError(out Output, err error) bool

func (*CopilotCLI) Name added in v0.5.0

func (c *CopilotCLI) Name() string

func (*CopilotCLI) PromptPattern added in v0.5.0

func (c *CopilotCLI) PromptPattern() string

func (*CopilotCLI) RunPrompt added in v0.5.0

func (c *CopilotCLI) RunPrompt(ctx context.Context, dir string, prompt string, opts ...Option) (Output, error)

func (*CopilotCLI) StartSession added in v0.5.0

func (c *CopilotCLI) StartSession(ctx context.Context, dir string) (Session, error)

func (*CopilotCLI) TimeoutMultiplier added in v0.5.0

func (c *CopilotCLI) TimeoutMultiplier() float64

type CopilotSession added in v0.5.2

type CopilotSession struct {
	*TmuxSession
}

CopilotSession wraps TmuxSession to handle Copilot CLI's dual input modes. Copilot CLI can be in "Chat" mode (Enter submits) or "Edit" mode (Ctrl+S submits). After completing a prompt, copilot may return to either mode non-deterministically. This wrapper detects Edit mode after sending Enter and falls back to Ctrl+S if needed.

func (*CopilotSession) Send added in v0.5.2

func (cs *CopilotSession) Send(input string) error

type CursorCLI added in v0.5.0

type CursorCLI struct{}

CursorCLI implements the E2E Agent interface for the Cursor Agent CLI binary. The CLI binary is called "agent" and uses Cursor's hooks system via .cursor/hooks.json. It maps to the same Entire agent as Cursor IDE ("cursor").

All E2E interactions use interactive (tmux) mode so that the full hook lifecycle fires (sessionStart, beforeSubmitPrompt, stop, sessionEnd). Headless (-p) mode skips beforeSubmitPrompt and stop hooks.

func (*CursorCLI) Binary added in v0.5.0

func (a *CursorCLI) Binary() string

func (*CursorCLI) Bootstrap added in v0.5.0

func (a *CursorCLI) Bootstrap() error

func (*CursorCLI) EntireAgent added in v0.5.0

func (a *CursorCLI) EntireAgent() string

func (*CursorCLI) IsTransientError added in v0.5.0

func (a *CursorCLI) IsTransientError(out Output, err error) bool

func (*CursorCLI) Name added in v0.5.0

func (a *CursorCLI) Name() string

func (*CursorCLI) PromptPattern added in v0.5.0

func (a *CursorCLI) PromptPattern() string

PromptPattern returns a regex matching Cursor's ready-state prompt markers. Cursor has used multiple startup/completion markers across releases.

func (*CursorCLI) RunPrompt added in v0.5.0

func (a *CursorCLI) RunPrompt(ctx context.Context, dir string, prompt string, opts ...Option) (Output, error)

func (*CursorCLI) StartSession added in v0.5.0

func (a *CursorCLI) StartSession(ctx context.Context, dir string) (Session, error)

func (*CursorCLI) TimeoutMultiplier added in v0.5.0

func (a *CursorCLI) TimeoutMultiplier() float64

type Droid added in v0.4.9

type Droid struct{}

Droid implements the Agent interface for Factory AI Droid.

func (*Droid) Binary added in v0.4.9

func (d *Droid) Binary() string

func (*Droid) Bootstrap added in v0.4.9

func (d *Droid) Bootstrap() error

func (*Droid) EntireAgent added in v0.4.9

func (d *Droid) EntireAgent() string

func (*Droid) IsTransientError added in v0.4.9

func (d *Droid) IsTransientError(out Output, err error) bool

func (*Droid) Name added in v0.4.9

func (d *Droid) Name() string

func (*Droid) PromptPattern added in v0.4.9

func (d *Droid) PromptPattern() string

func (*Droid) RunPrompt added in v0.4.9

func (d *Droid) RunPrompt(ctx context.Context, dir string, prompt string, opts ...Option) (Output, error)

func (*Droid) StartSession added in v0.4.9

func (d *Droid) StartSession(ctx context.Context, dir string) (Session, error)

func (*Droid) TimeoutMultiplier added in v0.4.9

func (d *Droid) TimeoutMultiplier() float64

type ExternalAgent added in v0.5.1

type ExternalAgent interface {
	IsExternalAgent() bool
}

ExternalAgent is an optional interface for agents discovered via the external agent protocol (entire-agent-* binaries). SetupRepo uses this to pre-configure external_agents in settings before running `entire enable`.

type Gemini

type Gemini struct{}

func (*Gemini) Binary

func (g *Gemini) Binary() string

func (*Gemini) Bootstrap

func (g *Gemini) Bootstrap() error

func (*Gemini) EntireAgent

func (g *Gemini) EntireAgent() string

func (*Gemini) IsTransientError

func (g *Gemini) IsTransientError(out Output, err error) bool

func (*Gemini) Name

func (g *Gemini) Name() string

func (*Gemini) PromptPattern

func (g *Gemini) PromptPattern() string

func (*Gemini) RunPrompt

func (g *Gemini) RunPrompt(ctx context.Context, dir string, prompt string, opts ...Option) (Output, error)

func (*Gemini) StartSession

func (g *Gemini) StartSession(_ context.Context, dir string) (Session, error)

func (*Gemini) TimeoutMultiplier

func (g *Gemini) TimeoutMultiplier() float64

type Option

type Option func(*runConfig)

func WithPromptTimeout

func WithPromptTimeout(d time.Duration) Option

type Output

type Output struct {
	Command  string
	Stdout   string
	Stderr   string
	ExitCode int
}

type Pi added in v0.6.2

type Pi struct{}

Pi implements the E2E Agent interface for the Pi coding agent.

func (*Pi) Binary added in v0.6.2

func (p *Pi) Binary() string

func (*Pi) Bootstrap added in v0.6.2

func (p *Pi) Bootstrap() error

func (*Pi) EntireAgent added in v0.6.2

func (p *Pi) EntireAgent() string

func (*Pi) IsTransientError added in v0.6.2

func (p *Pi) IsTransientError(out Output, _ error) bool

func (*Pi) Name added in v0.6.2

func (p *Pi) Name() string

func (*Pi) PromptPattern added in v0.6.2

func (p *Pi) PromptPattern() string

func (*Pi) RunPrompt added in v0.6.2

func (p *Pi) RunPrompt(ctx context.Context, dir string, prompt string, opts ...Option) (Output, error)

func (*Pi) StartSession added in v0.6.2

func (p *Pi) StartSession(_ context.Context, dir string) (Session, error)

func (*Pi) TimeoutMultiplier added in v0.6.2

func (p *Pi) TimeoutMultiplier() float64

type PiSession added in v0.6.2

type PiSession struct {
	*TmuxSession
	// contains filtered or unexported fields
}

PiSession exposes the per-test isolated Pi home so test fixtures can inspect or clean it up.

func (*PiSession) Home added in v0.6.2

func (s *PiSession) Home() string

type RepoSeeder added in v0.10.6

type RepoSeeder interface {
	SeedRepo(dir string) error
}

RepoSeeder is implemented by an agent that needs files planted in a fresh test repo before it first runs there. SetupRepo calls SeedRepo once the repo exists and `entire enable` has written the agent's own config into it.

Seeding is best-effort by contract: an agent that cannot seed should return nil and leave the repo alone, so the tests degrade to whatever the agent does for itself rather than failing on setup.

type RogerRoger added in v0.5.1

type RogerRoger struct{}

RogerRoger implements the Agent interface using a deterministic external agent binary that creates files and fires hooks without making any API calls. Unlike built-in agents (Vogon, Claude Code, etc.), roger-roger is discovered via the external agent protocol (entire-agent-roger-roger binary in $PATH).

func (*RogerRoger) Binary added in v0.5.1

func (r *RogerRoger) Binary() string

func (*RogerRoger) Bootstrap added in v0.5.1

func (r *RogerRoger) Bootstrap() error

func (*RogerRoger) EntireAgent added in v0.5.1

func (r *RogerRoger) EntireAgent() string

func (*RogerRoger) IsExternalAgent added in v0.5.1

func (r *RogerRoger) IsExternalAgent() bool

IsExternalAgent returns true — roger-roger is discovered via the external agent protocol.

func (*RogerRoger) IsTransientError added in v0.5.1

func (r *RogerRoger) IsTransientError(_ Output, _ error) bool

func (*RogerRoger) Name added in v0.5.1

func (r *RogerRoger) Name() string

func (*RogerRoger) PromptPattern added in v0.5.1

func (r *RogerRoger) PromptPattern() string

func (*RogerRoger) RunPrompt added in v0.5.1

func (r *RogerRoger) RunPrompt(ctx context.Context, dir string, prompt string, opts ...Option) (Output, error)

func (*RogerRoger) StartSession added in v0.5.1

func (r *RogerRoger) StartSession(_ context.Context, dir string) (Session, error)

func (*RogerRoger) TimeoutMultiplier added in v0.5.1

func (r *RogerRoger) TimeoutMultiplier() float64

type Session

type Session interface {
	Send(input string) error
	WaitFor(pattern string, timeout time.Duration) (string, error)
	Capture() string
	Close() error
}

type TmuxSession

type TmuxSession struct {
	// contains filtered or unexported fields
}

TmuxSession implements Session using tmux for PTY-based interactive agents.

func NewTmuxSession

func NewTmuxSession(name string, dir string, unsetEnv []string, command string, args ...string) (*TmuxSession, error)

NewTmuxSession creates a new tmux session running the given command in dir. unsetEnv lists environment variable names to strip from the session.

The command is wrapped with `env` to propagate PATH from the current process. tmux sessions inherit the tmux server's environment (not the client's), so without this, binaries added to PATH by the test runner (e.g., freshly built `entire` and `vogon`) would not be found inside the session.

func (*TmuxSession) Capture

func (s *TmuxSession) Capture() string

func (*TmuxSession) Close

func (s *TmuxSession) Close() error

func (*TmuxSession) IsPaneDead added in v0.5.0

func (s *TmuxSession) IsPaneDead() bool

IsPaneDead returns true if the process inside the tmux pane has exited. This relies on the remain-on-exit option being set (which NewTmuxSession does).

func (*TmuxSession) OnClose

func (s *TmuxSession) OnClose(fn func())

OnClose registers a function to run when the session is closed.

func (*TmuxSession) Quit added in v0.10.0

func (s *TmuxSession) Quit(timeout time.Duration) error

Quit asks the foreground program to exit the way a user would — by sending Ctrl+C — and waits for the process to actually exit. It sends Ctrl+C again each poll because some TUIs (Codex among them) treat a single Ctrl+C as "cancel the current turn" and need a second press to quit, and that gesture is version-dependent. If the process has still not exited by timeout it falls back to a hard kill: callers use Quit when they need the process gone (e.g. to release a lock it holds) and must not hang on an agent that changed its quit keybinding. Like Terminate, it does NOT run the OnClose cleanups, so a caller that needs a registered resource torn down owns that itself.

func (*TmuxSession) Send

func (s *TmuxSession) Send(input string) error

func (*TmuxSession) SendKeys

func (s *TmuxSession) SendKeys(keys ...string) error

SendKeys sends raw tmux key names without appending Enter.

func (*TmuxSession) Terminate added in v0.10.0

func (s *TmuxSession) Terminate() error

Terminate kills the tmux session (and the process it runs) WITHOUT running the registered OnClose cleanups. Use it when the process must die but a resource it registered for teardown — e.g. an isolated HOME that a later step in the same test still reads — has to outlive the process. Callers that bypass Close this way own the surviving resource's cleanup themselves.

func (*TmuxSession) WaitFor

func (s *TmuxSession) WaitFor(pattern string, timeout time.Duration) (string, error)

type Vogon added in v0.5.0

type Vogon struct{}

Vogon implements the Agent interface using a deterministic binary that creates files and fires hooks without making any API calls. Named after the Vogons from The Hitchhiker's Guide to the Galaxy.

func (*Vogon) Binary added in v0.5.0

func (v *Vogon) Binary() string

func (*Vogon) Bootstrap added in v0.5.0

func (v *Vogon) Bootstrap() error

func (*Vogon) EntireAgent added in v0.5.0

func (v *Vogon) EntireAgent() string

func (*Vogon) IsTransientError added in v0.5.0

func (v *Vogon) IsTransientError(_ Output, _ error) bool

func (*Vogon) Name added in v0.5.0

func (v *Vogon) Name() string

func (*Vogon) PromptPattern added in v0.5.0

func (v *Vogon) PromptPattern() string

func (*Vogon) RunPrompt added in v0.5.0

func (v *Vogon) RunPrompt(ctx context.Context, dir string, prompt string, opts ...Option) (Output, error)

func (*Vogon) StartSession added in v0.5.0

func (v *Vogon) StartSession(_ context.Context, dir string) (Session, error)

func (*Vogon) TimeoutMultiplier added in v0.5.0

func (v *Vogon) TimeoutMultiplier() float64

func (*Vogon) WriteSessionTranscript added in v0.6.0

func (v *Vogon) WriteSessionTranscript(ctx context.Context, dir string, extraEnv []string, sessionID, userPrompt, assistantMessage string) (Output, error)

WriteSessionTranscript creates a deterministic vogon session transcript without firing hooks or mutating the repository. Attach E2E tests use this to prepare a session that `entire attach` can import.

Jump to

Keyboard shortcuts

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