Documentation
¶
Overview ¶
Package agent implements a tool-calling agent loop over ai.LLMProvider: it streams a model's response, executes any tool calls the model asked for via caller-supplied Handlers, feeds the results back, and repeats until the model stops calling tools or a configured limit is hit.
Index ¶
- type Handler
- type Loop
- func (l Loop) Name() string
- func (l Loop) Run(ctx context.Context, req ai.ChatRequest) iter.Seq2[ai.Event, error]
- func (l Loop) RunWithTranscript(ctx context.Context, req ai.ChatRequest) (iter.Seq2[ai.Event, error], func() []ai.Message)
- func (l Loop) Stream(ctx context.Context, req ai.ChatRequest) iter.Seq2[ai.Event, error]
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Handler ¶
Handler executes one tool call. A non-nil error is an INFRASTRUCTURE failure (network down, panic-equivalent, programmer error) and aborts the whole Run with a fatal error; a tool-level failure (bad arguments, the underlying operation failed in an expected way) is reported by returning an ai.ToolResult with IsError true and a nil error, so the model can see and react to it.
type Loop ¶
type Loop struct {
Provider ai.LLMProvider
Handlers map[string]Handler
MaxSteps int
MaxToolCalls int
}
Loop drives a tool-calling agent over Provider. The zero value is not ready to use — Provider is required; MaxSteps/MaxToolCalls default to 8/16 when left zero.
Loop itself holds NO mutable run state (r1 review, M9: it used to embed a sync.Mutex + the last run's transcript directly, which made a Loop value unsafe to copy — go vet's copylocks check, and worse, two Loop values produced by copying one after a Run would share/race on that internal state). A Loop value is now freely copyable and reusable across concurrent Runs: each Run/RunWithTranscript call keeps its own transcript entirely in a closure-local variable.
func (Loop) Run ¶
Run streams every step's events in order (text deltas, tool.call, tool.result, usage) and ends with exactly one of:
- a final ai.EventCompleted carrying the SUMMED usage across every step, or
- a fatal error pair, per the ai.LLMProvider contract (an exceeded MaxSteps/MaxToolCalls limit is reported as ai.Error{Code: "limit"}).
Run alone does not expose the transcript it built (see RunWithTranscript for that); use it when only the streamed events matter, e.g. Loop used purely as an ai.LLMProvider.
func (Loop) RunWithTranscript ¶
func (l Loop) RunWithTranscript(ctx context.Context, req ai.ChatRequest) (iter.Seq2[ai.Event, error], func() []ai.Message)
RunWithTranscript is Run plus an accessor for the transcript (including the tool-call/tool-result messages appended between steps, and the final step's own assistant reply) this specific call is building, for session persistence. The accessor is safe to call at any time, including concurrently with draining the returned iterator (e.g. to show a live "assistant is thinking" partial transcript) — it always returns a defensive copy of whatever has been appended so far.