Documentation
¶
Overview ¶
Package agent provides LLM agents built on the runtime loop, composable as sub-agents, and a Runner that persists conversations in sessions.
Tool call pipeline ¶
New installs its loop middleware in this order: input guardrails, hooks (WithHooks), skills (WithSkills), the middleware of WithMiddleware in the order given, the permission policy (WithPermissions), handoffs, context engineering, and finally tool and output guardrails. Each tool call the model requests then passes through these steps:
- BeforeTool, in that order: PreToolUse hooks, the allowed and disallowed tools of an active skill, the WithMiddleware middleware, the permission policy, the handoff check, and tool input guardrails. Each stage sees the arguments as earlier stages rewrote them and may allow the call, ask for approval or deny it. The most restrictive decision wins whatever the order, so a hook that allows a call does not lift a permission rule's ask or deny, and the first denial skips the remaining stages. The permission policy also receives the decision so far, which changes its result in dontAsk mode. A tool input guardrail that trips ends the run instead of denying the call.
- Approval, when a stage asked, or when no stage decided and the tool requires approval (tool.Info.RequiresApproval, per call for a tool.CallApprover). The Approver of WithApprover decides; without one the run is interrupted and resumed with the approvals. An allowed call skips approval.
- RevalidateTool, when an approval changed the arguments: the permission policy, tool input guardrails and any other loop.ToolRevalidator check them again. BeforeTool, including hooks, does not run again.
- Execution. The arguments are validated against the tool's schema, then the call runs inside the WrapTool middleware, the first in the order above outermost, so tool output guardrails wrap the call most closely. Inside those wrappers run the tool middleware of WithToolMiddleware, the first outermost, and then the tool.
- AfterTool, in reverse order: the guardrails first, which end the run if a tool output guardrail tripped during execution, then the permission policy, the WithMiddleware middleware, skills, and PostToolUse or PostToolUseFailure hooks last. Denied calls pass AfterTool too, but fire no hooks.
Choose the mechanism by purpose:
- permission.Policy (WithPermissions): rules and modes for tools, paths and commands, with remembered approvals.
- hook.Manager (WithHooks): Claude Code compatible command and HTTP hooks, for policies kept outside the program.
- Tool guardrails (WithToolGuardrail): checks whose failure must stop the run, on the arguments that will run and the result the tool returned.
- A loop.Middleware with BeforeTool (WithMiddleware): policies written in Go. Middleware that enforces an argument policy must also implement loop.ToolRevalidator.
- tool.Middleware (WithToolMiddleware): execution concerns such as timeouts and output truncation that need no access to the run; use a loop.ToolWrapper when the wrapper needs it.
- WithApprover, tool.CallApprover or tool.Info.RequiresApproval: which calls need approval and who grants it.
Index ¶
- Constants
- Variables
- func AgentVerifier(a Agent) hook.Verifier
- func AsTool(a Agent, opts ToolOptions) tool.Tool
- func AskAs[T any](ctx context.Context, a Agent, prompt string) (T, error)
- func ContextWithSessionState(ctx context.Context, st *session.State) context.Context
- func HookVerifier(m model.Model, opts ...Option) hook.Verifier
- func MemoryProvider(m memory.Memory, scope string, limit int) actx.Provider
- func NestHandoffHistory(msgs []*model.Message) []*model.Message
- func RemoveToolCalls(msgs []*model.Message) []*model.Message
- func RenderTemplate(ctx context.Context, s string) (string, error)
- func SessionState(ctx context.Context) (*session.State, bool)
- type Agent
- type Checkpoint
- type Config
- type Discarder
- type Event
- type Handoff
- type HandoffOption
- type HistoryProvider
- type HookProvider
- type Input
- type Instruction
- type InstructionFunc
- type InstructionOption
- type LLMAgent
- func (a *LLMAgent) Ask(ctx context.Context, prompt string) (string, error)
- func (a *LLMAgent) Description() string
- func (a *LLMAgent) Discard(ctx context.Context, runID string) error
- func (a *LLMAgent) FileHistory() builtin.History
- func (a *LLMAgent) Hooks() *hook.Manager
- func (a *LLMAgent) Name() string
- func (a *LLMAgent) Resume(ctx context.Context, runID string, approvals map[string]loop.Approval) iter.Seq2[*loop.Event, error]
- func (a *LLMAgent) ResumeState(ctx context.Context, st *loop.State, approvals map[string]loop.Approval) iter.Seq2[*loop.Event, error]
- func (a *LLMAgent) Run(ctx context.Context, in *Input) iter.Seq2[*loop.Event, error]
- func (a *LLMAgent) Runtime() *loop.Runtime
- func (a *LLMAgent) Tools() *tool.Registry
- type Option
- func WithApprover(a loop.Approver) Option
- func WithBudget(f func(model.Usage) error) Option
- func WithCheckpointer(cp loop.Checkpointer) Option
- func WithConcurrentSubAgents() Option
- func WithContext(cfg actx.Config) Option
- func WithContextProvider(ps ...actx.Provider) Option
- func WithDeps[T any](v T) Option
- func WithDescription(d string) Option
- func WithFileHistory(h builtin.History) Option
- func WithHandoff(a Agent, opts ...HandoffOption) Option
- func WithHandoffs(agents ...Agent) Option
- func WithHook(event hook.EventType, matcher string, h hook.Hook) Option
- func WithHooks(m *hook.Manager) Option
- func WithInputGuardrail(g guard.InputGuardrail, opts ...guard.InputOption) Option
- func WithInstructionFiles(dir string) Option
- func WithInstructionTemplate() Option
- func WithInstructions(s string) Option
- func WithInstructionsFunc(f InstructionFunc, opts ...InstructionOption) Option
- func WithLimits(l loop.Limits) Option
- func WithLogger(l *slog.Logger) Option
- func WithMaxDepth(n int) Option
- func WithMaxHandoffs(n int) Option
- func WithMaxTokens(n int) Option
- func WithMaxTurns(n int) Option
- func WithMemory(m memory.Memory, scope string, recall int) Option
- func WithMemoryScopeFunc(m memory.Memory, scope memory.ScopeFunc, recall int) Option
- func WithMiddleware(mws ...loop.Middleware) Option
- func WithModel(m model.Model) Option
- func WithOutput[T any](opts ...OutputOption) Option
- func WithOutputGuardrail(g guard.OutputGuardrail, opts ...guard.OutputOption) Option
- func WithParallelism(n int) Option
- func WithPermissions(p *permission.Policy) Option
- func WithProviderOptions(provider string, opts map[string]any) Option
- func WithReasoning(r *model.Reasoning) Option
- func WithResponseFormat(f *model.ResponseFormat) Option
- func WithSeed(seed int) Option
- func WithSkillAgents(agents ...Agent) Option
- func WithSkillConfig(c skill.Config) Option
- func WithSkillRegistry(r *skill.Registry) Option
- func WithSkills(skills ...skill.Skill) Option
- func WithStopAtTools(names ...string) Option
- func WithStopWhen(conds ...loop.StopCondition) Option
- func WithStreaming() Option
- func WithSubAgentEvents() Option
- func WithSubAgents(agents ...Agent) Option
- func WithTemperature(t float64) Option
- func WithToolChoice(tc *model.ToolChoice) Option
- func WithToolGuardrail(g guard.ToolGuardrail) Option
- func WithToolMiddleware(mws ...tool.Middleware) Option
- func WithTools(tools ...tool.Tool) Option
- func WithTopP(p float64) Option
- func WithoutMemoryTools() Option
- type OutputOption
- type Result
- type Resumer
- type RewindMode
- type RewindResult
- type RunOption
- type Runner
- func (r *Runner) Checkpoints(ctx context.Context, sessionID string) ([]Checkpoint, error)
- func (r *Runner) Clear(ctx context.Context, sessionID string) (string, error)
- func (r *Runner) Discard(ctx context.Context, sessionID string) error
- func (r *Runner) EndSession(ctx context.Context, sessionID, reason string) error
- func (r *Runner) Fork(ctx context.Context, sessionID string) (string, error)
- func (r *Runner) Resume(ctx context.Context, sessionID string, approvals map[string]loop.Approval, ...) iter.Seq2[*loop.Event, error]
- func (r *Runner) Rewind(ctx context.Context, sessionID, checkpointID string, mode RewindMode) (*RewindResult, error)
- func (r *Runner) Run(ctx context.Context, sessionID string, msg *model.Message, opts ...RunOption) iter.Seq2[*loop.Event, error]
- func (r *Runner) RunText(ctx context.Context, sessionID, text string, opts ...RunOption) (*loop.Result, error)
- func (r *Runner) Store() session.Store
- type StateResumer
- type ToolOptions
Constants ¶
const ActiveAgentKey = "agentx.active_agent"
ActiveAgentKey is the session state key holding the name of the agent a Runner's session was last handed off to, which handles the session's next message; see WithHandoffs. It is absent while the Runner's own agent is active. Delete it to return the session to that agent.
const CheckpointsKey = "agentx.checkpoints"
CheckpointsKey is the session state key holding the checkpoints of a session; see Runner.Checkpoints.
const DefaultMaxDepth = 5
DefaultMaxDepth bounds how deeply sub-agents can be nested: a sub-agent of a top-level agent is at depth 1, its own sub-agents at depth 2.
const DefaultMaxHandoffs = 10
DefaultMaxHandoffs bounds the handoffs of a run; see WithMaxHandoffs.
const FailedRunKey = "agentx.failed_run"
FailedRunKey is the session state key holding the ID of the session's last run if it failed, for example on a provider outage. Unlike an interrupted run, it does not block new runs: Runner.Resume continues it, and the next Run gives it up.
const HandoffToolPrefix = "transfer_to_"
HandoffToolPrefix starts the names of handoff tools.
const MaxCheckpoints = 100
MaxCheckpoints is the number of the most recent checkpoints a Runner keeps for each session, as Claude Code keeps file snapshots for the 100 most recent checkpoints of a session.
const PendingRunKey = "agentx.pending_run"
PendingRunKey is the session state key holding the ID of an interrupted run.
const SessionValuesKey = "agentx.session_values"
SessionValuesKey is the session state key holding the session-scoped run values, those whose keys start with loop.SessionValuePrefix. The Runner saves them when a run ends and passes them to the session's next runs, so middleware can keep state for a session, such as remembered permission grants.
Variables ¶
var ErrCannotRewind = errors.New("agent: cannot rewind")
ErrCannotRewind is returned by Runner.Rewind for a checkpoint that cannot be rewound in the mode asked: the agent has no file history to rewind the code, or the checkpoint's message is no longer in the conversation.
var ErrSessionBusy = errors.New("agent: the session is busy")
ErrSessionBusy is returned by Runner.Rewind while the session has a run or another operation of the Runner in progress.
Functions ¶
func AgentVerifier ¶
AgentVerifier returns a hook.Verifier for hook.Agent hooks that runs a on each check's prompt, without history, and returns its final answer. The hook's model name is ignored.
func AskAs ¶
AskAs runs a on a single prompt without history and decodes its final answer as T. Configure a with WithOutput[T], so the model answers in JSON matching T.
func ContextWithSessionState ¶
ContextWithSessionState returns a context in which SessionState returns st. A Runner does this for the runs of its sessions; use it to give runs started without a Runner a state, for example for WithInstructionTemplate.
func HookVerifier ¶
HookVerifier returns a hook.Verifier for hook.Agent hooks that runs a new agent on m for each check: it is built with opts, has instructions for the task and at most 50 turns, as in Claude Code, and its final answer is the verdict. A model name set on the hook overrides the request's model. Give it the tools it may use with WithTools, typically read-only ones such as builtin.ReadOnlyTools.
func MemoryProvider ¶
MemoryProvider recalls memories relevant to each input and adds them as a reminder.
func NestHandoffHistory ¶
NestHandoffHistory is a handoff input filter that replaces the conversation with a single user message holding a transcript of it in a <CONVERSATION HISTORY> block, like the OpenAI Agents SDK's nest_handoff_history. The agent handed off to then sees the earlier turns, including tool calls and results, as context rather than as its own. Images and other binary content are noted, not copied; the transcript is not redacted.
func RemoveToolCalls ¶
RemoveToolCalls is a handoff input filter that removes tool calls and their results from the conversation, and assistant messages left empty, like the OpenAI Agents SDK's remove_all_tools. Use it when the agent handed off to should not see the work of the previous one, or has no tools, which some providers require when the conversation holds tool calls.
func RenderTemplate ¶
RenderTemplate fills the placeholders of s from the session state of ctx; see SessionState and ContextWithSessionState. {key} is replaced with the value of key: a string as it is, any other value as JSON. It is an error if the state, or a state at all, is missing for {key}; {key?} is replaced with nothing then. Keys start with a letter or underscore, followed by letters, digits and _ . : -, so braces around anything else, such as JSON, stay as they are. {{ and }} stand for literal { and }, for example {{key}} for the text {key}.
func SessionState ¶
SessionState returns the session state carried by ctx and reports false if none is present. Tools, hooks, middleware and instruction functions can use it to share per-session values.
A Runner supplies its session's state and saves it when the run ends, including failures and interruptions. Sub-agents and handoff targets share the same state. Its operations are safe for concurrent use, with the value-sharing rules of session.State. Store JSON values for persistence and leave keys starting with "agentx." to the Runner.
Types ¶
type Agent ¶
type Agent interface {
Name() string
Description() string
Run(ctx context.Context, in *Input) iter.Seq2[*loop.Event, error]
}
Agent runs tasks and reports progress as runtime events.
func Ref ¶
Ref returns a reference to the agent named name, for WithHandoffs, so agents can hand off to each other although each must be built before the agents that hand off to it. The reference resolves, when the model hands off, to the agent of that name among the agents the run's first agent hands off to, directly or through others, including that agent itself. description describes the agent to the model. A reference cannot run on its own.
type Checkpoint ¶
type Checkpoint struct {
// ID identifies the checkpoint. It is the ID of the run, which the
// run's events carry in Event.RunID.
ID string
// Index is the position of the run's user message in the session's
// messages, or -1 if it is no longer there, for example after
// compaction, so that only the code can be rewound.
Index int
// Message is the run's original user input before context and middleware
// augmentation, if Index is not -1.
Message *model.Message
// Time is when the run started.
Time time.Time
// Agent names the agent the session's message went to when the run
// started: the agent of ActiveAgentKey, or "" for the Runner's own
// agent. Rewinding the conversation makes it active again, so the
// conversation continues with the agent that had it before handoffs.
Agent string
// Changes are the file changes saved to the agent's file history
// during the run, oldest first.
Changes []builtin.FileChange
// Code reports whether rewinding the code to the checkpoint would
// restore files: the file history keeps the checkpoint and changes
// saved since.
Code bool
}
Checkpoint is a point of a session that Runner.Rewind can return to: the start of a run, before its user message, like the checkpoint Claude Code creates for each prompt. See https://code.claude.com/docs/en/checkpointing.
type Config ¶
type Config struct {
loop.Settings
Description string
Tools []tool.Tool
// Skills are advertised in the system prompt and loaded with the skill
// tool.
Skills *skill.Registry
// SkillConfig configures how skills run; see skill.Config. The agent
// fills in what it leaves empty: Fork runs context: fork skills as
// sub-agents (see WithSkillAgents), Effort defaults to Reasoning's,
// and HookOptions.Model to Model.
SkillConfig skill.Config
// SkillAgents are the agents context: fork skills can name in their
// agent field.
SkillAgents []Agent
// Memory enables long-term memory tools and automatic recall.
Memory memory.Memory
// MemoryScope scopes memory reads and writes, for example to a user.
MemoryScope string
// MemoryScopeFunc, if set, chooses the scope of each run instead of
// MemoryScope, for an agent that serves several users.
MemoryScopeFunc memory.ScopeFunc
// MemoryRecall is the number of memories recalled automatically for each
// input. Zero disables automatic recall; the tools remain available.
MemoryRecall int
// DisableMemoryTools hides the memory tools from the model.
DisableMemoryTools bool
// SubAgents are exposed to the model as tools named after the agents.
SubAgents []Agent
Hooks *hook.Manager
// Middlewares extend the agent loop. They run after the hook and skill
// middleware and before the permission policy and the context
// middleware.
Middlewares []loop.Middleware
// Permissions decides tool calls with rules and modes; see
// WithPermissions. It runs after Middlewares, so it sees their
// decisions.
Permissions *permission.Policy
// Context configures context engineering. The agent adds its own
// providers for skills and memory.
Context actx.Config
ContextProviders []actx.Provider
// SubAgentEvents forwards the events of sub-agents; see
// ToolOptions.Events.
SubAgentEvents bool
// ConcurrentSubAgents lets sub-agent calls run concurrently; see
// ToolOptions.Concurrent.
ConcurrentSubAgents bool
// MaxDepth bounds sub-agent nesting; see ToolOptions.MaxDepth.
MaxDepth int
// FileHistory is the history Runner.Rewind restores files from; see
// WithFileHistory.
FileHistory builtin.History
// Handoffs are the agents the model can hand the run off to; see
// WithHandoffs. MaxHandoffs bounds the handoffs of a run started on
// this agent; zero means DefaultMaxHandoffs.
Handoffs []Handoff
MaxHandoffs int
// Guardrails check the input, output and tool calls of runs; see
// WithInputGuardrail.
Guardrails guard.Config
// Deps add default dependencies to the context of runs; see WithDeps.
Deps []func(context.Context) context.Context
// InstructionFuncs extend Instructions for each run or turn; see
// WithInstructionsFunc.
InstructionFuncs []Instruction
// InstructionTemplate fills {key} placeholders in Instructions from
// the session state; see WithInstructionTemplate.
InstructionTemplate bool
// contains filtered or unexported fields
}
Config configures an LLMAgent. Build it with options passed to New.
The embedded loop.Settings configure the agent's runtime: its name, model, request options, approver, checkpointer, limits and stop conditions. The agent adds its handoff tools to StopAtTools.
type Discarder ¶
Discarder is implemented by agents that can delete the saved state of a run that will not be resumed.
type Event ¶ added in v1.1.0
Event is an event of an agent run, as Agent.Run and Runner.Run stream them; see loop.Event. The alias lets code that only runs agents use the agent package alone.
type Handoff ¶
type Handoff struct {
// Agent receives the run.
Agent Agent
// ToolName is the name of the tool that hands off; it defaults to
// "transfer_to_" and the agent's name.
ToolName string
// Description describes the tool; it defaults to one built from the
// agent's description.
Description string
// InputFilter, if set, rewrites the conversation the agent sees, up
// to and including the handoff call's result, for example with
// RemoveToolCalls or NestHandoffHistory. It gets a copy of the
// messages and must not modify them. It applies to the model requests
// of the run, not to the conversation saved, so later runs of a
// session see all of it.
InputFilter func([]*model.Message) []*model.Message
// contains filtered or unexported fields
}
Handoff is an agent the model can hand a run off to; see WithHandoffs.
type HandoffOption ¶
type HandoffOption func(*Handoff)
HandoffOption configures a handoff.
func HandoffDescription ¶
func HandoffDescription(d string) HandoffOption
HandoffDescription describes the handoff's tool to the model.
func HandoffInput ¶
func HandoffInput[T any](fn func(ctx context.Context, in T) error) HandoffOption
HandoffInput makes the model send arguments of type T, whose schema is derived with tool.SchemaOf, when it hands off, such as a reason or a priority, like the OpenAI Agents SDK's input_type. fn, if not nil, is called with them before the handoff; an error refuses the handoff and is reported to the model. The arguments are added to the input of the agent that takes over and reported in loop.Handoff.Input.
func HandoffInputFilter ¶
func HandoffInputFilter(f func([]*model.Message) []*model.Message) HandoffOption
HandoffInputFilter sets the handoff's Handoff.InputFilter.
func HandoffName ¶
func HandoffName(name string) HandoffOption
HandoffName names the handoff's tool.
type HistoryProvider ¶
HistoryProvider is implemented by agents with a file history, such as an LLMAgent built with WithFileHistory. A Runner starts a checkpoint of the history for each run and restores files from it in Rewind.
type HookProvider ¶
HookProvider is implemented by agents with a hook manager, such as LLMAgent. A Runner dispatches the SessionStart and SessionEnd events of its sessions to it. For the context of SessionStart hooks to reach the model, the agent's runs must use hook.Middleware with the same manager.
type Input ¶
type Input struct {
// Message is the new user message.
Message *model.Message
// History is the conversation before Message.
History []*model.Message
SessionID string
RunID string
NewSession bool
// MaxTurns, if positive, and Limits, if non-nil, override the agent's
// turn limit and usage limits for this run.
MaxTurns int
Limits *loop.Limits
// Values are the initial run values; see loop.Request.Values.
Values map[string]string
// Skill, if set, is a skill the user invokes at the start of the run,
// as with /name arguments in Claude Code; see RunSkill and
// skill.WithCall.
Skill *skill.Call
// Agent, if set, names the agent of the handoff graph that handles the
// input instead of this one, as a Runner sets it to the session's
// active agent; see WithHandoffs and Result.Agent.
Agent string
// Deps add dependencies to the context of the run; see RunDeps.
Deps []func(context.Context) context.Context
}
Input is the input of an agent run.
type Instruction ¶
type Instruction struct {
Func InstructionFunc
// EveryTurn evaluates Func before each model call instead of once per
// run.
EveryTurn bool
}
Instruction is a function that extends an agent's instructions; see WithInstructionsFunc.
type InstructionFunc ¶
InstructionFunc returns instructions for a run, for example from the run's dependencies (loop.Deps) or session state (SessionState). An error fails the run.
type InstructionOption ¶
type InstructionOption func(*Instruction)
InstructionOption configures an instruction function.
func EveryTurn ¶
func EveryTurn() InstructionOption
EveryTurn evaluates an instruction function before each model call, for instructions that change during a run, such as ones that depend on session state that tools write. Its text is added to each request without being saved in the run's system prompt. Instructions that change between calls defeat the providers' prompt caching of what follows them, so prefer the default of once per run.
type LLMAgent ¶
type LLMAgent struct {
// contains filtered or unexported fields
}
LLMAgent is an agent driven by a language model.
func (*LLMAgent) Ask ¶
Ask runs the agent on a single prompt without history and returns its final answer.
func (*LLMAgent) Description ¶
Description implements Agent.
func (*LLMAgent) Discard ¶
Discard implements Discarder by deleting the run's checkpoint, in the checkpointers of the agents it hands off to too.
func (*LLMAgent) FileHistory ¶
FileHistory returns the agent's file history, or nil if it has none.
func (*LLMAgent) Hooks ¶
Hooks returns the agent's hook manager, or nil if it has no hooks. A Runner dispatches its SessionStart and SessionEnd events to it.
func (*LLMAgent) Resume ¶
func (a *LLMAgent) Resume(ctx context.Context, runID string, approvals map[string]loop.Approval) iter.Seq2[*loop.Event, error]
Resume implements Resumer. It requires a checkpointer. With handoffs, the run resumes on the agent that was running it, found in the checkpointers of the agents the agent hands off to.
func (*LLMAgent) ResumeState ¶
func (a *LLMAgent) ResumeState(ctx context.Context, st *loop.State, approvals map[string]loop.Approval) iter.Seq2[*loop.Event, error]
ResumeState implements StateResumer. With handoffs, the run resumes on the agent the state names.
func (*LLMAgent) Run ¶
Run implements Agent. A run the model hands off continues on the agent it hands off to; see WithHandoffs.
type Option ¶
type Option func(*Config)
Option configures an agent.
func WithApprover ¶
WithApprover decides tool approvals synchronously.
func WithBudget ¶
WithBudget ends a run with loop.StatusLimitExceeded when f returns an error for the run's usage so far, for example a cost limit. f is called before each model call and each batch of tool calls.
func WithCheckpointer ¶
func WithCheckpointer(cp loop.Checkpointer) Option
WithCheckpointer persists run state for resumption.
func WithConcurrentSubAgents ¶
func WithConcurrentSubAgents() Option
WithConcurrentSubAgents lets calls of the agent's sub-agents run in parallel with each other and with adjacent read-only calls, bounded by WithParallelism. By default sub-agents run one at a time, since they may have side effects whose order matters. Sub-agents interrupted for approval together are resumed together.
func WithContext ¶
WithContext configures context engineering.
func WithContextProvider ¶
WithContextProvider adds a context provider.
func WithDeps ¶
WithDeps gives the agent's runs v as their dependency of type T, which tools, hooks, middleware and instruction functions read with loop.Deps[T]. It is a default: a dependency of type T that the run's context already carries, from loop.WithDeps or RunDeps, takes precedence. Sub-agents and agents the run is handed off to see the dependencies of the run that started them, and their own defaults for other types. Dependencies are not saved with checkpoints or sessions; see loop.WithDeps.
func WithDescription ¶
WithDescription describes the agent to parent agents.
func WithFileHistory ¶
WithFileHistory gives the agent the file history its file tools save to, the same as builtin.Config.History, so a Runner starts a checkpoint of it for each run and Runner.Rewind can restore the files; see builtin.FileHistory.
func WithHandoff ¶
func WithHandoff(a Agent, opts ...HandoffOption) Option
WithHandoff is like WithHandoffs for a single agent with options.
func WithHandoffs ¶
WithHandoffs lets the model hand the run off to agents, in the style of the OpenAI Agents SDK's handoffs and Google ADK's agent transfer. Each agent appears as a tool named "transfer_to_" and its name. When the model calls one, the calls of its turn run, the agent's part of the run ends, and the run continues on the agent handed off to, with its own instructions, tools, middleware, guardrails and limits: it sees the conversation so far, and a note about the handoff as its input, and emits a loop.EventHandoff before its events. The run keeps its ID, usage and turn count, so limits apply to the whole run, and Result.Agent names the agent that ran last. Only the first handoff call of a turn hands off; the others are denied. A run is handed off at most WithMaxHandoffs times.
Handoff tools are read-only (tool.Info.ReadOnly): a call only checks the handoff, which happens after the turn, so permission plan mode allows it.
The agent handed off to does not run its input guardrails, and its UserPromptSubmit hooks see the note as the prompt. PreToolUse and PostToolUse hooks with a matcher such as "transfer_to_.*" observe and can deny handoffs.
A Runner remembers the agent its session was handed off to (see ActiveAgentKey) and sends the session's next message to it. An interrupted run resumes on the agent that was running; agents that hand off to each other should share a checkpointer. To hand off to an agent that is built later, such as back to this one, use Ref.
func WithHooks ¶
WithHooks adds the hooks of a manager, including its FailClosed setting. They are copied into the agent's own manager, so m is not modified by other options, and hooks registered in m later are not added.
func WithInputGuardrail ¶
func WithInputGuardrail(g guard.InputGuardrail, opts ...guard.InputOption) Option
WithInputGuardrail checks the input of the agent's new runs with g; a tripped guardrail ends the run with loop.StatusBlocked and loop.Result.Guardrail set. Guardrails run one after another before the run starts, before hooks see the input; guard.Parallel runs g concurrently with the first model call instead. Input guardrails do not run for the agent a run is handed off to, whose input was checked.
func WithInstructionFiles ¶
WithInstructionFiles adds the instruction files, such as AGENTS.md, of dir and its parents up to the project root to the system prompt, with the defaults of actx.InstructionFiles.
func WithInstructionTemplate ¶
func WithInstructionTemplate() Option
WithInstructionTemplate fills placeholders in the static instructions of WithInstructions from the session state when a run starts, like Google ADK's {key} templating; see RenderTemplate. A required key that the state lacks fails the run. Text of WithInstructionsFunc is not templated, as ADK's instruction providers are not.
func WithInstructions ¶
WithInstructions sets the base system prompt.
func WithInstructionsFunc ¶
func WithInstructionsFunc(f InstructionFunc, opts ...InstructionOption) Option
WithInstructionsFunc adds instructions that f returns, in the style of Pydantic AI's @agent.instructions and the OpenAI Agents SDK's dynamic instructions. By default f runs once when a run starts, after the hooks accepted its input, and its text follows the static instructions of WithInstructions, and the text of earlier functions, separated by a blank line; the system prompt then stays the same for the whole run, which keeps it cacheable, and a resumed run reuses it. Empty text adds nothing. EveryTurn evaluates f before each model call instead. The text is used as it is; see RenderTemplate to fill in session state.
When a run is handed off, the instructions of the agent it is handed off to apply.
func WithLimits ¶
WithLimits bounds the usage of each run; Input.Limits overrides it for a run. See loop.Limits.
func WithMaxDepth ¶
WithMaxDepth bounds how deeply sub-agents can be nested below the agent; the default is DefaultMaxDepth. A sub-agent call beyond it returns an error result to the model.
func WithMaxHandoffs ¶
WithMaxHandoffs bounds the handoffs of the runs started on the agent; the default is DefaultMaxHandoffs. A handoff beyond it is refused with an error result to the model.
func WithMaxTokens ¶
WithMaxTokens bounds output tokens per model call.
func WithMemory ¶
WithMemory enables long-term memory. recall is the number of memories recalled automatically for each input; zero disables automatic recall. Every run of the agent reads and writes memories in scope; an agent that serves several users, such as one behind a server, chooses the scope per run with WithMemoryScopeFunc instead.
func WithMemoryScopeFunc ¶
WithMemoryScopeFunc enables long-term memory like WithMemory, with the scope of each recall and memory tool call taken from its context by scope, for example the user an HTTP middleware authenticated and stored in the request context the server runs the agent with. When scope fails, the recall or the tool call fails, so memories never leak across users whose scope is unknown.
func WithMiddleware ¶
func WithMiddleware(mws ...loop.Middleware) Option
WithMiddleware adds runtime middleware, for example from the middleware package.
func WithOutput ¶
func WithOutput[T any](opts ...OutputOption) Option
WithOutput makes the agent answer with JSON matching the schema of T, which must be a struct type or a pointer to one; New fails otherwise. The schema, derived with tool.SchemaOf, is requested as the response format unless WithResponseFormat sets one, and the final answer is validated against it. Decode the answer with loop.Result.DecodeAs or use AskAs. See loop.Output for retries and failures.
func WithOutputGuardrail ¶
func WithOutputGuardrail(g guard.OutputGuardrail, opts ...guard.OutputOption) Option
WithOutputGuardrail checks the final answer of the agent's runs with g, after Stop hooks let the run finish. A tripped guardrail ends the run with loop.StatusBlocked and an empty Output, and the conversation keeps loop.WithheldAnswer in place of the answer. guard.HoldOutput also holds the answer's events until the guardrails pass. When a run is handed off, the output guardrails of the agent that answers apply.
func WithParallelism ¶
WithParallelism bounds concurrent calls of read-only and concurrent tools.
func WithPermissions ¶
func WithPermissions(p *permission.Policy) Option
WithPermissions decides tool calls with a permission policy: rules and modes in Claude Code's syntax, see the permission package. The policy runs after the hooks, skills and WithMiddleware middleware, whatever the order of the options, so its deny and ask decisions hold whatever they allow; see the package documentation. A later WithPermissions replaces the policy, and nil removes it.
func WithProviderOptions ¶ added in v1.1.0
WithProviderOptions passes provider-specific request fields to the provider adapter named provider, such as "openai" or "anthropic"; see model.Request.ProviderOptions. Options for the same provider merge, later keys replacing earlier ones.
func WithReasoning ¶
WithReasoning configures model reasoning.
func WithResponseFormat ¶
func WithResponseFormat(f *model.ResponseFormat) Option
WithResponseFormat requests structured output.
func WithSeed ¶ added in v1.1.0
WithSeed asks providers that support it for deterministic sampling; see model.Request.Seed.
func WithSkillAgents ¶
WithSkillAgents makes agents available to context: fork skills, whose agent field names one of them. Without a match, general-purpose, Explore and Plan run on a new agent with the agent's model, tools and approver; see Config.SkillAgents.
func WithSkillConfig ¶
WithSkillConfig configures how the agent's skills run, for example enabling command injection with skill.Config.Shell; see Config.SkillConfig.
func WithSkillRegistry ¶
WithSkillRegistry adds the skills of a registry. They are copied into the agent's own registry, so r is not modified by other options, and skills registered in r later are not added.
func WithStopAtTools ¶
WithStopAtTools ends a run as completed once one of the named tools returns a result that is not an error; the result's content is the run's output, and the model is not called again.
func WithStopWhen ¶
func WithStopWhen(conds ...loop.StopCondition) Option
WithStopWhen ends a run as completed when any condition holds after a turn's tool calls have run. See loop.StopCondition.
func WithStreaming ¶
func WithStreaming() Option
WithStreaming streams model output as delta events.
func WithSubAgentEvents ¶
func WithSubAgentEvents() Option
WithSubAgentEvents forwards the events of the agent's sub-agents, and of their sub-agents, to the consumer of its runs. Forwarded events have a Depth above zero and ParentCallID set to the call that started the sub-agent; consumers that switch on Event.Type should check Depth. The sub-agents' events are not forwarded by default.
func WithSubAgents ¶
WithSubAgents exposes agents as tools.
func WithTemperature ¶
WithTemperature sets the sampling temperature.
func WithToolChoice ¶
func WithToolChoice(tc *model.ToolChoice) Option
WithToolChoice constrains tool use.
func WithToolGuardrail ¶
func WithToolGuardrail(g guard.ToolGuardrail) Option
WithToolGuardrail checks the agent's tool calls before they run and their results after; see guard.ToolGuardrail. A tripped guardrail ends the run with loop.StatusBlocked.
func WithToolMiddleware ¶
func WithToolMiddleware(mws ...tool.Middleware) Option
WithToolMiddleware adds tool middleware.
func WithoutMemoryTools ¶
func WithoutMemoryTools() Option
WithoutMemoryTools hides the memory tools from the model.
type OutputOption ¶
OutputOption configures the output of WithOutput.
func OutputName ¶
func OutputName(name string) OutputOption
OutputName names the output schema for providers. It defaults to the name of T if that is a valid name, otherwise to "output".
func OutputRetries ¶
func OutputRetries(n int) OutputOption
OutputRetries sets how often an answer that does not match the output schema is sent back to the model; see loop.Output.Retries.
type Result ¶ added in v1.1.0
Result is the outcome of an agent run, as loop.Collect returns it; see loop.Result.
type Resumer ¶
type Resumer interface {
Resume(ctx context.Context, runID string, approvals map[string]loop.Approval) iter.Seq2[*loop.Event, error]
}
Resumer is implemented by agents that can resume interrupted runs.
type RewindMode ¶
type RewindMode int
RewindMode selects what Runner.Rewind restores.
const ( // RewindCode restores the files the tools changed since the // checkpoint and keeps the conversation. RewindCode RewindMode = 1 << iota // RewindConversation removes the checkpoint's user message and the // messages after it from the session and keeps the files. RewindConversation // RewindBoth restores the files and the conversation. RewindBoth = RewindCode | RewindConversation )
type RewindResult ¶
type RewindResult struct {
// Message is the original user input of the removed run, before context
// and middleware augmentation, to send again or edit, as Claude Code
// restores the prompt into the input.
Message *model.Message
// Restored are the restored files and Skipped the changed files that
// were not restored; see builtin.Restoration.
Restored []builtin.FileChange
Skipped []builtin.FileChange
// Undo is the file history checkpoint holding the files' state before
// the rewind; restoring it with History.Restore undoes the code
// rewind.
Undo string
}
RewindResult is the result of Runner.Rewind.
type RunOption ¶
type RunOption func(*Input)
RunOption configures a single run of a Runner.
func RunDeps ¶
RunDeps gives one run v as its dependency of type T, overriding the agent's default from WithDeps; see loop.Deps. It is not saved: pass it again to Runner.Resume when resuming the run.
func RunLimits ¶
RunLimits overrides the agent's usage limits for one run; see Input.Limits. Resuming the run keeps them.
func RunMaxTurns ¶
RunMaxTurns overrides the agent's turn limit for one run; see Input.MaxTurns. Resuming the run keeps it.
type Runner ¶
type Runner struct {
// contains filtered or unexported fields
}
Runner runs an agent against persistent sessions. Runs on the same session are serialized.
If the agent may not checkpoint its runs, the Runner keeps a copy of the state of each session's interrupted run in memory, so Resume can continue it. A copy is kept until the session's next run ends or the run is discarded; sessions that are abandoned while interrupted keep theirs for the Runner's lifetime.
If the agent has hooks (see HookProvider), the Runner fires SessionStart once per session: with source "startup" for a new session, "resume" the first time it runs or resumes an existing one, and "clear" or "fork" for sessions made by Clear and Fork. EndSession fires SessionEnd, after which the session starts again. The Runner remembers the sessions it started until they end.
func (*Runner) Checkpoints ¶
Checkpoints returns the checkpoints of a session, oldest first: one for each of its last MaxCheckpoints runs that added a user message, except those removed by rewinding the conversation. With a file history (see HistoryProvider), each lists the files changed during its run.
func (*Runner) Clear ¶
Clear ends a session with reason "clear" and starts a new, empty one in its place, like Claude Code's /clear. It returns the new session's ID; the old session stays in the store. The first run of the new session fires SessionStart with source "clear". SessionEnd hook errors are returned with the new ID.
func (*Runner) Discard ¶
Discard gives up the interrupted run of a session, for example when its checkpoint was lost, or else its failed run. Its pending tool calls are answered as not run, so the session can continue with Run, and the agent's checkpoint of the run is deleted if the agent implements Discarder.
func (*Runner) EndSession ¶
EndSession ends a session, like Claude Code does when you exit, run /clear or switch sessions: it runs the agent's SessionEnd hooks with reason, such as "clear", "logout", "prompt_input_exit" or "other" (the default), and Event.Messages holding the conversation. The hooks cannot prevent it and share a time budget; see hook.SessionEndTimeout. Context still queued for the session is dropped.
The session stays in the store: a later Run or Resume continues it and fires SessionStart with source "resume". EndSession waits for a run of the session in progress. It returns the hooks' errors.
func (*Runner) Fork ¶
Fork copies the conversation and state of a session into a new session and returns its ID, like Claude Code's --fork-session. An interrupted or failed run is not copied: its pending tool calls are answered as not run in the copy. The first run of the new session fires SessionStart with source "fork".
The checkpoints and the agent's file history are copied too, so either session can be rewound to the checkpoints before the fork, and later changes are recorded only for the session that made them. Both sessions still work on the same files: rewinding the code of one changes the files the other sees.
func (*Runner) Resume ¶
func (r *Runner) Resume(ctx context.Context, sessionID string, approvals map[string]loop.Approval, opts ...RunOption) iter.Seq2[*loop.Event, error]
Resume continues the interrupted run of a session or, if it has none, its failed run; see FailedRunKey. Failed runs are resumed from the agent's checkpoint. Interrupted runs are too, or, if the agent has no checkpointer, from the state this Runner kept in memory when the run was interrupted.
Of the options, only RunDeps applies: dependencies are not saved with the run, so pass them again. The run keeps its other settings.
func (*Runner) Rewind ¶
func (r *Runner) Rewind(ctx context.Context, sessionID, checkpointID string, mode RewindMode) (*RewindResult, error)
Rewind returns a session to a checkpoint listed by Checkpoints, like Claude Code's /rewind (https://code.claude.com/docs/en/checkpointing). mode selects what is restored:
- RewindCode restores files tracked since the checkpoint from the agent's file history (see HistoryProvider and builtin.Config.History). Files that cannot be restored are reported in RewindResult.Skipped; failures trigger an attempt to undo changes already applied. Untracked files are left alone, but later changes to tracked files, including changes by bash or another session, can be overwritten. The restored files are forgotten by the tools' FileTracker, so the model reads them again before changing them.
- RewindConversation removes the checkpoint's user message and the messages after it, and the later checkpoints, from the session. RewindResult.Message holds the original input to send again. The agent that was active at the checkpoint (Checkpoint.Agent) becomes active again, undoing later handoffs. The rest of the session state, such as values set with SessionState and session-scoped run values like remembered permission grants, is not rewound, as Claude Code keeps permissions across a rewind.
Rewind refuses with ErrSessionBusy while a run of the session or another operation of this Runner on it is in progress, with ErrCannotRewind when mode cannot be rewound to the checkpoint, and refuses a session with an interrupted run: resume it or discard it first. A failed run is given up, as by the next Run. The file history is kept: a later rewind to an earlier checkpoint still restores the files, and RewindResult.Undo undoes the code rewind. If saving the session fails after the files were restored, Rewind attempts to undo the code rewind and includes any undo failure in the returned error.
func (*Runner) Run ¶
func (r *Runner) Run(ctx context.Context, sessionID string, msg *model.Message, opts ...RunOption) iter.Seq2[*loop.Event, error]
Run sends a message in a session and returns the run's events. An empty sessionID starts a new session; its ID is reported in the events. Options such as RunLimits apply to this run only. The message goes to the agent the session was last handed off to, if any; see ActiveAgentKey. The run's tools and instruction functions reach the session's state with SessionState.
The session is saved when the run ends, including when it is interrupted. If the caller stops iterating early, the run is cancelled and the session is saved once it has ended.
type StateResumer ¶
type StateResumer interface {
ResumeState(ctx context.Context, st *loop.State, approvals map[string]loop.Approval) iter.Seq2[*loop.Event, error]
}
StateResumer is implemented by agents that can resume a run from its state, without a checkpoint. Sub-agents are resumed this way.
type ToolOptions ¶
type ToolOptions struct {
// Name is the tool name. It defaults to the agent's name. Hooks match
// the agent's name either way.
Name string
// Description is the tool description. It defaults to the agent's
// description, with a note that the agent cannot see the conversation.
Description string
// Hooks receives SubagentStart and SubagentStop events.
Hooks *hook.Manager
// Events forwards the sub-agent's events to the consumer of the calling
// run, tagged with loop.Event.Depth and ParentCallID. Sub-agents of
// the sub-agent then forward theirs too. See loop.ForwardEvent.
Events bool
// Concurrent lets calls run in parallel with adjacent calls of
// concurrent or read-only tools; see tool.Concurrent. SubagentStart
// and SubagentStop hooks of sub-agents running concurrently may run
// concurrently.
Concurrent bool
// MaxDepth bounds how deeply the sub-agent may be nested; zero means
// DefaultMaxDepth. The smallest bound of the agents above a sub-agent
// applies. A call that would exceed it returns an error result.
MaxDepth int
}
ToolOptions configures the tool that runs an agent as a sub-agent; see AsTool. The zero value gives the defaults.