Documentation
¶
Overview ¶
Package agentloop runs a single autonomous agent mission to completion: one model, a jailed toolset, a quality gate that must pass before the run can succeed, budgets that bound it, and a structured result that reports what happened. It is the building block for headless agent pipelines (eval_loop, archie workflows); orchestration across missions lives with the caller.
Index ¶
Constants ¶
const ( StopFinished = "finished" StopBudgetExhausted = "budget_exhausted" StopTimedOut = "timed_out" StopLoopBreak = "loop_break" StopGateParked = "gate_parked" StopGateFailedFinal = "gate_failed_final" StopModelBlocked = "model_blocked" StopIdle = "idle" // StopEndedWithoutFinish: the model stopped producing tool calls // after making changes but never called finish — the mission state // is unknown, so the run parks for review. StopEndedWithoutFinish = "ended_without_finish" )
Stop reasons reported in Result.StopReason.
const DefaultSystemTemplate = `` /* 808-byte string literal not displayed */
DefaultSystemTemplate is used when Config.SystemTmpl is empty. Callers with an opinionated role prompt (eval_loop's quality pass, archie's planner/builder) supply their own template.
Variables ¶
This section is empty.
Functions ¶
func TokenBudgetIs ¶
func TokenBudgetIs(maxTokens int) core.StopCondition
TokenBudgetIs returns a stop condition that halts once cumulative token usage across steps reaches maxTokens. Zero or negative disables it. Like all stop conditions it is evaluated between steps, so a run can overshoot by at most one model call.
Types ¶
type Config ¶
type Config struct {
// Runtime + ModelRef select the model ("provider/model"). Provider,
// when non-nil, bypasses the runtime (tests, custom providers) and
// Model names the model to request from it.
Runtime *runtime.Runtime
ModelRef string
Provider chat.Provider
Model string
// WorkDir is the directory the toolset is jailed to and gate
// commands run in.
WorkDir string
// SystemTmpl is a text/template rendered with PromptData. Empty
// selects DefaultSystemTemplate.
SystemTmpl string
// Mission is the task statement, injected into the first user message.
Mission string
// ExtraRules is free-form guidance appended to the rendered prompt.
ExtraRules string
// PreloadFiles are read from WorkDir and included in the initial
// context (the eval_loop "preload everything" strategy). Missing
// files are skipped with a log line.
PreloadFiles []string
// Notes, when non-nil, is loaded into the initial context and
// exposed to the model via a write_note tool.
Notes NotesStore
// Gate is the quality gate. An empty command list disables gating.
Gate GateConfig
// Preflight commands run before the loop; their output is injected
// as ground truth (toolchain versions, go fix -diff, ...).
Preflight []GateCommand
Budget Budget
// ReadOnly registers only read/grep/find (planner/analysis missions).
ReadOnly bool
// ProtectPaths, when non-nil, blocks write/edit on matching paths
// (relative, as the model supplies them) with an in-band refusal —
// an environmental constraint where a prompt rule would be advisory
// (e.g. a TDD fix stage protecting the committed repro tests).
ProtectPaths func(path string) bool
// Extra tools are merged into the toolset after the built-ins.
Extra core.ToolSet
Logger *slog.Logger
}
Config configures a single run.
type FileNotesStore ¶
type FileNotesStore struct{ Path string }
FileNotesStore is a NotesStore backed by a single file (eval_loop's AGENT_NOTES.md pattern).
type GateCommand ¶
GateCommand is one command in the quality gate, run in the work directory. ExpectFailure inverts success: the command must exit nonzero (a TDD repro stage requires the new tests to FAIL before the fix is written).
type GateConfig ¶
type GateConfig struct {
Commands []GateCommand
// MaxConsecutiveFailures parks the run after N failing gate cycles
// in a row. Zero means the default of 5.
MaxConsecutiveFailures int
}
GateConfig is the quality gate for a run: the command list that must pass after mutations, and how many consecutive failing cycles are tolerated before the run parks instead of flailing.
type NotesStore ¶
type NotesStore interface {
Load(ctx context.Context) (string, error)
Append(ctx context.Context, entry string) error
}
NotesStore is caller-side persistent memory across runs. Entries follow the eval_loop convention: every note must cite how it was verified (verified_by), and stores live outside the work tree so they neither pollute diffs nor vanish with the worktree.
type PromptData ¶
type PromptData struct {
WorkDir string
GateCommands []string // human-readable command lines, in gate order
ExtraRules string
ReadOnly bool
}
PromptData is what SystemTmpl is rendered with.
type Result ¶
type Result struct {
Status Status `json:"status"`
StopReason string `json:"stop_reason"`
Changes []string `json:"changes,omitempty"` // files written/edited, in first-touch order
Iterations int `json:"iterations"`
TokensUsed int `json:"tokens_used"`
Summary string `json:"summary,omitempty"` // from the finish tool
Detail string `json:"detail,omitempty"` // last gate failure / park explanation
}
Result is the structured outcome of a run. It is the caller's PR body, state-machine transition, and notes write-back in one place.
type Status ¶
type Status string
Status is the overall outcome of a run.
const ( // StatusPassed means the mission finished and the gate passed. StatusPassed Status = "passed" // StatusParked means the run stopped without a clean finish: gate // failures hit the cap, a budget ran out, the loop breaker fired, or // the model reported itself blocked. Parked runs carry the reason. StatusParked Status = "parked" // StatusIdle means the model ended the conversation without calling // finish and without changing anything. StatusIdle Status = "idle" )