Documentation
¶
Overview ¶
Package agent provides autonomous tool-calling agent functionality for the gains library.
An agent orchestrates a conversation loop where the model can request tool calls, which are automatically executed and the results fed back to the model until the model produces a final response without tool calls.
Basic Usage ¶
Create a registry, register tools with their handlers, then create an agent:
// Define tool arguments
type WeatherArgs struct {
Location string `json:"location" desc:"City name" required:"true"`
}
// Create registry and register tool
registry := tool.NewRegistry()
tool.MustRegisterFunc(registry, "get_weather", "Get current weather",
func(ctx context.Context, args WeatherArgs) (string, error) {
return fmt.Sprintf(`{"temp": 72, "location": %q}`, args.Location), nil
},
)
// Create agent
a := agent.New(client, registry)
// Run and get final result (blocking)
result, err := a.Run(ctx, messages, agent.WithMaxSteps(5))
Streaming Events ¶
Use RunStream() to receive events as the agent executes:
import "github.com/spetersoncode/gains/event"
events := a.RunStream(ctx, messages, agent.WithMaxSteps(5))
for e := range events {
switch e.Type {
case event.MessageDelta:
fmt.Print(e.Delta)
case event.ToolCallStart:
fmt.Printf("[Tool: %s]\n", e.ToolCall.Name)
case event.RunEnd:
fmt.Println("Done!")
}
}
Human-in-the-Loop Approval ¶
Use WithApprover to require approval before tool execution:
events := a.Run(ctx, messages,
agent.WithApprover(func(ctx context.Context, call gains.ToolCall) (bool, string) {
fmt.Printf("Approve %s? (y/n): ", call.Name)
var input string
fmt.Scanln(&input)
return input == "y", "User rejected"
}),
)
Configuration Options ¶
The agent supports various configuration options:
- WithMaxSteps(n): Limit iterations to prevent infinite loops (default: 10)
- WithTimeout(d): Set overall execution timeout
- WithHandlerTimeout(d): Set per-handler timeout (default: 30s)
- WithParallelToolCalls(bool): Enable/disable parallel tool execution (default: true)
- WithApprover(fn): Enable human-in-the-loop approval
- WithApprovalRequired(tools...): Require approval only for specific tools
- WithStopPredicate(fn): Custom termination condition
- WithChatOptions(opts...): Pass options to underlying ChatProvider
Termination Conditions ¶
The agent stops when any of these conditions are met:
- The model responds without tool calls (TerminationComplete)
- MaxSteps is reached (TerminationMaxSteps)
- Timeout is exceeded (TerminationTimeout)
- Context is cancelled (TerminationCancelled)
- StopPredicate returns true (TerminationCustom)
- All tool calls are rejected (TerminationRejected)
- An error occurs (TerminationError)
Index ¶
- Variables
- type Agent
- type ApproverFunc
- type Event
- type Option
- func WithApprovalRequired(tools ...string) Option
- func WithApprover(fn ApproverFunc) Option
- func WithChatOptions(opts ...ai.Option) Option
- func WithHandlerTimeout(d time.Duration) Option
- func WithMaxSteps(n int) Option
- func WithMaxTokens(n int) Option
- func WithModel(model ai.Model) Option
- func WithParallelToolCalls(enabled bool) Option
- func WithStopPredicate(fn StopFunc) Option
- func WithTemperature(t float64) Option
- func WithTimeout(d time.Duration) Option
- type Options
- type Result
- type StopFunc
- type TerminationReason
Constants ¶
This section is empty.
Variables ¶
var ( // ErrMaxStepsReached indicates the agent hit the step limit. ErrMaxStepsReached = errors.New("agent: maximum steps reached") // ErrAgentTimeout indicates the overall timeout was exceeded. ErrAgentTimeout = errors.New("agent: timeout exceeded") )
Sentinel errors for agent termination conditions.
Functions ¶
This section is empty.
Types ¶
type Agent ¶
type Agent struct {
// contains filtered or unexported fields
}
Agent orchestrates autonomous tool-calling conversations.
func (*Agent) Run ¶
Run executes the agent loop and returns the final result. This is a blocking call that runs until the agent completes.
type ApproverFunc ¶
ApproverFunc is called when a tool call requires approval. It returns true to approve the call, or false with a reason to reject it. The rejection reason is sent back to the model as an error result.
type Event ¶
Event is an alias to the unified event type. Agent events use these event.Type values:
- event.RunStart, event.RunEnd, event.RunError
- event.StepStart, event.StepEnd
- event.MessageStart, event.MessageDelta, event.MessageEnd
- event.ToolCallStart, event.ToolCallArgs, event.ToolCallEnd, event.ToolCallResult
- event.ToolCallApproved, event.ToolCallRejected, event.ToolCallExecuting
type Option ¶
type Option func(*Options)
Option is a functional option for configuring agent execution.
func WithApprovalRequired ¶
WithApprovalRequired specifies which tools require approval. If not called but WithApprover is used, all tools require approval. Call with specific tool names to only require approval for those tools.
func WithApprover ¶
func WithApprover(fn ApproverFunc) Option
WithApprover sets the human-in-the-loop approval function. The function is called before each tool execution and must return an approval decision.
func WithChatOptions ¶
WithChatOptions passes options through to the ChatProvider. These options are applied to every chat call made by the agent.
func WithHandlerTimeout ¶
WithHandlerTimeout sets the timeout for each individual tool handler. Default is 30 seconds. Set to 0 for no per-handler timeout.
func WithMaxSteps ¶
WithMaxSteps sets the maximum number of agent iterations. Default is 10. Set to 0 for unlimited (not recommended).
func WithMaxTokens ¶
WithMaxTokens is a convenience option to set max tokens for chat calls.
func WithParallelToolCalls ¶
WithParallelToolCalls enables or disables concurrent tool execution. Default is true.
func WithStopPredicate ¶
WithStopPredicate sets a custom termination condition. The predicate is called after each step with the step number and response. Return true to stop the agent.
func WithTemperature ¶
WithTemperature is a convenience option to set temperature for chat calls.
func WithTimeout ¶
WithTimeout sets a deadline for the entire agent execution.
type Options ¶
type Options struct {
// MaxSteps limits the number of agent iterations.
// Set to 0 for unlimited (not recommended). Default is 10.
MaxSteps int
// Timeout sets a deadline for the entire agent execution.
// A value of 0 means no timeout (context deadline applies).
Timeout time.Duration
// HandlerTimeout sets the timeout for each individual tool handler.
// A value of 0 means no per-handler timeout. Default is 30 seconds.
HandlerTimeout time.Duration
// ParallelToolCalls enables concurrent execution of multiple tool calls.
// Default is true.
ParallelToolCalls bool
// Approver enables human-in-the-loop approval for tool calls.
// If nil, all tool calls are automatically approved.
Approver ApproverFunc
// ApprovalRequired specifies which tool names require approval.
// If empty and Approver is set, all tools require approval.
// If non-empty, only the listed tools require approval.
ApprovalRequired []string
// StopPredicate is a custom termination condition.
// Called after each step; return true to stop the agent.
StopPredicate StopFunc
// ChatOptions are passed through to the underlying ChatProvider.
ChatOptions []ai.Option
}
Options contains configuration for agent execution.
func ApplyOptions ¶
ApplyOptions applies functional options to an Options struct with defaults.
type Result ¶
type Result struct {
// Response is the final response from the model.
Response *ai.Response
// Steps is the number of iterations completed.
Steps int
// Termination indicates why execution stopped.
Termination TerminationReason
// TotalUsage aggregates token usage across all steps.
TotalUsage ai.Usage
// Error contains any error that caused termination (if applicable).
Error error
// PendingClientToolCalls contains tool calls awaiting client execution.
// These are set when Termination is TerminationClientToolCall.
PendingClientToolCalls []ai.ToolCall
// contains filtered or unexported fields
}
Result represents the final outcome of an agent execution.
func (*Result) LastMessages ¶
LastMessages returns the last n messages from the conversation history. If n exceeds the total message count, all messages are returned.
func (*Result) MessageCount ¶
MessageCount returns the number of messages in the conversation history.
type StopFunc ¶
StopFunc is a custom predicate to determine if the agent should stop. It receives the current step number and the latest response. Return true to stop the agent.
type TerminationReason ¶
type TerminationReason string
TerminationReason indicates why the agent stopped execution.
const ( // TerminationComplete indicates normal completion (no more tool calls). TerminationComplete TerminationReason = "complete" // TerminationMaxSteps indicates the step limit was reached. TerminationMaxSteps TerminationReason = "max_steps" // TerminationTimeout indicates the context deadline was exceeded. TerminationTimeout TerminationReason = "timeout" // TerminationCustom indicates a custom stop predicate returned true. TerminationCustom TerminationReason = "custom" // TerminationRejected indicates all tool calls were rejected. TerminationRejected TerminationReason = "rejected" // TerminationError indicates an unrecoverable error occurred. TerminationError TerminationReason = "error" // TerminationCancelled indicates context cancellation. TerminationCancelled TerminationReason = "cancelled" // TerminationClientToolCall indicates the model called a client-side tool. // The frontend should execute the tool and resume with the result. TerminationClientToolCall TerminationReason = "client_tool_call" )