Help us shape the future of Go! Take the 2026 Go Developer Survey

agent

package module
v0.7.0 Latest Latest
Warning

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

Go to latest
Published: Oct 27, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var DefaultModel = ai.Model[ai.API]{
	ID:            "unknown",
	Name:          "unknown",
	API:           ai.API("unknown"),
	Provider:      ai.Provider("unknown"),
	BaseURL:       "",
	Reasoning:     false,
	Input:         []string{},
	ContextWindow: 0,
	MaxTokens:     0,
	Cost: ai.Cost{
		Input:      decimal.Zero,
		Output:     decimal.Zero,
		CacheRead:  decimal.Zero,
		CacheWrite: decimal.Zero,
		Total:      decimal.Zero,
	},
}
View Source
var EmptyUsage = ai.Usage{
	Input:      0,
	Output:     0,
	CacheRead:  0,
	CacheWrite: 0,
	Total:      0,
	Cost: ai.Cost{
		Input:      decimal.Zero,
		Output:     decimal.Zero,
		CacheRead:  decimal.Zero,
		CacheWrite: decimal.Zero,
		Total:      decimal.Zero,
	},
}

Functions

func AgentLoop

func AgentLoop(
	prompts []AgentMessage,
	context AgentContext,
	config AgentLoopConfig,
	signal context.Context,
	streamFn *StreamFn,
) (*ai.EventStream[AgentEvent, []AgentMessage], error)

func AgentLoopContinue

func AgentLoopContinue(
	context AgentContext,
	config AgentLoopConfig,
	signal context.Context,
	streamFn *StreamFn,
) (*ai.EventStream[AgentEvent, []AgentMessage], error)

func AssistantErrorMessage

func AssistantErrorMessage(ctx context.Context, model ai.Model[ai.API], err error) ai.AssistantMessage

AssistantErrorMessage converts a StreamFn startup error into the assistant message shape expected by the agent loop. The loop should emit this as a normal message_start/message_end, followed by turn_end and agent_end.

func CreateAgentStream

func CreateAgentStream() *ai.EventStream[AgentEvent, []AgentMessage]

func CreateToolResultMessage

func CreateToolResultMessage(
	finalized FinalizedToolCallOutcome,
) *ai.ToolResultMessage

func DefaultConvertToLLM

func DefaultConvertToLLM(messages []AgentMessage) []ai.Message

func DefaultStreamFn

func DefaultStreamFn(
	ctx context.Context,
	model ai.Model[ai.API],
	modelContext ai.ModelContext,
	options *ai.SimpleStreamOptions,
) (*ai.AssistantMessageEventStream, error)

DefaultStreamFn adapts the lower-level ai.StreamSimple function to the agent-level StreamFn contract.

func EmitToolExecutionEnd

func EmitToolExecutionEnd(
	finalized FinalizedToolCallOutcome,
	emit AgentEventSink,
) error

func EmitToolResultMessage

func EmitToolResultMessage(
	toolResultMessage ai.ToolResultMessage,
	emit AgentEventSink,
) error

func IsAbortError

func IsAbortError(ctx context.Context, err error) bool

func PrepareToolCallArguments

func PrepareToolCallArguments(tool AgentTool[any, any], toolCall ai.ToolCall) (ai.ToolCall, error)

func RunLoop

func RunLoop(
	currentContext AgentContext,
	newMessages *[]AgentMessage,
	config AgentLoopConfig,
	signal context.Context,
	emit AgentEventSink,
	streamFn *StreamFn,
) error

func ShouldTerminateToolBatch

func ShouldTerminateToolBatch(finalizedCalls []FinalizedToolCallOutcome) bool

Types

type ActiveRun

type ActiveRun struct {
	Ctx    context.Context
	Cancel context.CancelFunc
	Done   chan struct{}
}

type AfterToolCallContext

type AfterToolCallContext[TDetails any] struct {
	/** The assistant message that requested the tool call. */
	AssistantMessage ai.AssistantMessage
	/** The raw tool call block from `assistantMessage.content`. */
	ToolCall ai.ToolCall
	/** Validated tool arguments for the target tool schema. */
	Args any
	/** The executed tool result before any `afterToolCall` overrides are applied. */
	Result AgentToolResult[TDetails]
	/** Whether the executed tool result is currently treated as an error. */
	IsError bool
	/** Current agent context at the time the tool call is prepared. */
	Context AgentContext
}

type AfterToolCallResult

type AfterToolCallResult struct {
	Content   *[]ai.ToolResultContent
	Details   *any
	IsError   *bool
	Terminate *bool
}

*

  • Partial override returned from `afterToolCall`. *
  • Merge semantics are field-by-field:
  • - `content`: if provided, replaces the tool result content array in full
  • - `details`: if provided, replaces the tool result details value in full
  • - `isError`: if provided, replaces the tool result error flag
  • - `terminate`: if provided, replaces the early-termination hint *
  • Omitted fields keep the original executed tool result values.
  • There is no deep merge for `content` or `details`.

type Agent

type Agent struct {
	ConvertToLLM     ConvertToLLMFunc
	TransformContext TransformContextFunc
	StreamFn         StreamFn
	ResolveAuth      func(ctx context.Context, model ai.Model[ai.API]) (ai.ModelAuth, error)

	OnPayload  func(payload any, model ai.Model[ai.API]) (any, error)
	OnResponse func(response ai.ProviderResponse, model ai.Model[ai.API]) error

	BeforeToolCall  func(context.Context, BeforeToolCallContext) (*BeforeToolCallResult, error)
	AfterToolCall   func(context.Context, AfterToolCallContext[any]) (*AfterToolCallResult, error)
	PrepareNextTurn func(context.Context, PrepareNextTurnContext) (*AgentLoopTurnUpdate, error)

	SessionID       *string
	ThinkingBudgets *ai.ThinkingBudgets
	Transport       ai.Transport
	MaxRetryDelayMs *int64
	ToolExecution   ToolExecutionMode
	// contains filtered or unexported fields
}

func NewAgent

func NewAgent(options *AgentOptions) *Agent

func (*Agent) Abort

func (a *Agent) Abort()

func (*Agent) ClearAllQueues

func (a *Agent) ClearAllQueues()

func (*Agent) ClearFollowUpQueue

func (a *Agent) ClearFollowUpQueue()

func (*Agent) ClearSteeringQueue

func (a *Agent) ClearSteeringQueue()

func (*Agent) Continue

func (a *Agent) Continue(ctx context.Context) error

func (*Agent) FollowUp

func (a *Agent) FollowUp(message AgentMessage)

func (*Agent) FollowUpMode

func (a *Agent) FollowUpMode() QueueMode

func (*Agent) HasQueuedMessages

func (a *Agent) HasQueuedMessages() bool

func (*Agent) PromptMessage

func (a *Agent) PromptMessage(ctx context.Context, message AgentMessage) error

func (*Agent) PromptMessages

func (a *Agent) PromptMessages(ctx context.Context, messages []AgentMessage) error

func (*Agent) PromptText

func (a *Agent) PromptText(ctx context.Context, text string, images ...ai.ImageContent) error

func (*Agent) ReplaceMessages added in v0.3.0

func (a *Agent) ReplaceMessages(messages []AgentMessage) error

ReplaceMessages replaces the conversation transcript while the agent is idle. The top-level slice is copied so later changes to the input do not change agent state.

func (*Agent) Reset

func (a *Agent) Reset()

func (*Agent) SetFollowUpMode

func (a *Agent) SetFollowUpMode(mode QueueMode)

func (*Agent) SetSteeringMode

func (a *Agent) SetSteeringMode(mode QueueMode)

func (*Agent) SetTools added in v0.7.0

func (a *Agent) SetTools(tools []AgentTool[any, any])

SetTools replaces the agent's tools. The top-level slice is copied. A run in progress keeps the tools it started with unless PrepareNextTurn gives its next turn these.

func (*Agent) Signal

func (a *Agent) Signal() context.Context

func (*Agent) State

func (a *Agent) State() AgentState

func (*Agent) Steer

func (a *Agent) Steer(message AgentMessage)

func (*Agent) SteeringMode

func (a *Agent) SteeringMode() QueueMode

func (*Agent) Subscribe

func (a *Agent) Subscribe(listener AgentListener) func()

func (*Agent) TakeQueuedMessages added in v0.3.0

func (a *Agent) TakeQueuedMessages() []AgentMessage

TakeQueuedMessages removes and returns every queued message, steering messages first, so a caller can deliver them some other way.

func (*Agent) WaitForIdle

func (a *Agent) WaitForIdle()

type AgentContext

type AgentContext struct {
	/** System prompt included with the request. */
	SystemPrompt string
	/** Transcript visible to the model. */
	Messages []AgentMessage
	/** Tools available for this run. */
	Tools []AgentTool[any, any]
}

* Context snapshot passed into the low-level agent loop.

type AgentEvent

type AgentEvent interface {
	EventType() string
}

type AgentEventSink

type AgentEventSink func(event AgentEvent) error

type AgentListener

type AgentListener func(event AgentEvent, ctx context.Context) error

type AgentLoopConfig

type AgentLoopConfig struct {
	ai.SimpleStreamOptions
	Model               ai.Model[ai.API]
	Stream              StreamFn             `json:"-"`
	ConvertToLLM        ConvertToLLMFunc     `json:"convert_to_llm"`
	TransformContext    TransformContextFunc `json:"transform_context"`
	ResolveAuth         func(ctx context.Context, model ai.Model[ai.API]) (ai.ModelAuth, error)
	ShouldStopAfterTurn func(ctx ShouldStopAfterTurnContext) bool
	// PrepareNextTurn runs after a turn completes and before the next one
	// starts, and may change the next turn, for example its tools. An error
	// ends the run.
	PrepareNextTurn     func(ctx context.Context, turn PrepareNextTurnContext) (*AgentLoopTurnUpdate, error)
	GetSteeringMessages func(ctx context.Context) []AgentMessage
	GetFollowUpMessages func(ctx context.Context) []AgentMessage
	ToolExecution       *ToolExecutionMode
	BeforeToolCall      func(ctx context.Context, call BeforeToolCallContext) (*BeforeToolCallResult, error)
	AfterToolCall       func(ctx context.Context, call AfterToolCallContext[any]) (*AfterToolCallResult, error)
}

type AgentLoopTurnUpdate added in v0.7.0

type AgentLoopTurnUpdate struct {
	// Context for the next provider request, such as one with other tools.
	Context *AgentContext
	// Messages to append before the next provider request, with normal
	// lifecycle events.
	Messages []AgentMessage
	// Model for the next provider request.
	Model *ai.Model[ai.API]
	// ThinkingLevel for the next provider request.
	ThinkingLevel *ai.ModelThinkingLevel
}

AgentLoopTurnUpdate changes the next turn of a run. Nil fields keep the current value.

type AgentMessage

type AgentMessage interface {
	AgentMessageType() string
}

AgentMessage is the union of LLM message types (user, assistant, system) and custom messages. This allows custom messages to be added while still maintaining type safety and compatibility with the LLM message types.

func RunAgentLoop

func RunAgentLoop(
	prompts []AgentMessage,
	context AgentContext,
	config AgentLoopConfig,
	signal context.Context,
	emit AgentEventSink,
	streamFn *StreamFn,
) ([]AgentMessage, error)

func RunAgentLoopContinue

func RunAgentLoopContinue(
	context AgentContext,
	config AgentLoopConfig,
	signal context.Context,
	emit AgentEventSink,
	streamFn *StreamFn,
) ([]AgentMessage, error)

type AgentOptions

type AgentOptions struct {
	InitialState *InitialAgentState

	ConvertToLLM     ConvertToLLMFunc
	TransformContext TransformContextFunc
	StreamFn         StreamFn

	// ResolveAuth returns the auth for each model request. It runs before
	// every request, so it can refresh tokens. An error ends the turn with an
	// error message instead of calling the model.
	ResolveAuth func(ctx context.Context, model ai.Model[ai.API]) (ai.ModelAuth, error)

	OnPayload  func(payload any, model ai.Model[ai.API]) (any, error)
	OnResponse func(response ai.ProviderResponse, model ai.Model[ai.API]) error

	BeforeToolCall func(
		ctx context.Context,
		call BeforeToolCallContext,
	) (*BeforeToolCallResult, error)

	AfterToolCall func(
		ctx context.Context,
		call AfterToolCallContext[any],
	) (*AfterToolCallResult, error)

	// PrepareNextTurn runs before every turn of a run but the first, and may
	// change it; see AgentLoopConfig.PrepareNextTurn.
	PrepareNextTurn func(ctx context.Context, turn PrepareNextTurnContext) (*AgentLoopTurnUpdate, error)

	SteeringMode QueueMode
	FollowUpMode QueueMode

	SessionID       *string
	ThinkingBudgets *ai.ThinkingBudgets
	Transport       ai.Transport
	MaxRetryDelayMs *int64
	ToolExecution   ToolExecutionMode
}

type AgentState

type AgentState struct {
	SystemPrompt  string
	Model         ai.Model[ai.API]
	ThinkingLevel ai.ModelThinkingLevel

	Tools    []AgentTool[any, any]
	Messages []AgentMessage

	IsStreaming      bool
	StreamingMessage AgentMessage
	PendingToolCalls map[string]struct{}
	ErrorMessage     string
}

func CreateMutableAgentState

func CreateMutableAgentState(initial *InitialAgentState) AgentState

type AgentTool

type AgentTool[TParameters any, TDetails any] struct {
	ai.Tool
	Label string
	// Optional compatibility shim for raw tool-call arguments before validation.
	PrepareArguments func(args any) (TParameters, error)
	/**
	 * Execute the tool call. Return an error on failure, or a result with
	 * IsError set; do not only describe the failure in `content`.
	 */
	Execute func(
		ctx context.Context,
		toolCallID string,
		params TParameters,
		onUpdate AgentToolUpdateCallback[TDetails],
	) (AgentToolResult[TDetails], error)
	ToolExecutionMode *ToolExecutionMode
	// Annotations are optional hints about the tool's behavior, for apps
	// that ask before running some tools. The model does not see them.
	Annotations *ToolAnnotations
}

type AgentToolResult

type AgentToolResult[TDetails any] struct {
	Content []ai.ToolResultContent
	Details TDetails
	// IsError reports a failure without returning an error. The model sees
	// Content as an error result, like a returned error, but Content keeps
	// its images and Details are kept for the UI.
	IsError   bool
	Terminate *bool
}

func CreateErrorToolResult

func CreateErrorToolResult(message string) AgentToolResult[any]

type AgentToolUpdateCallback

type AgentToolUpdateCallback[TDetails any] func(partialResult AgentToolResult[TDetails])

type BeforeToolCallContext

type BeforeToolCallContext struct {
	/** The assistant message that requested the tool call. */
	AssistantMessage ai.AssistantMessage
	/** The raw tool call block from `assistantMessage.content`. */
	ToolCall ai.ToolCall
	/** Validated tool arguments for the target tool schema. */
	Args any
	/** Current agent context at the time the tool call is prepared. */
	Context AgentContext
}

type BeforeToolCallResult

type BeforeToolCallResult struct {
	Block  *bool
	Reason *string
}

Result returned from `beforeToolCall`.

Returning `{ block: true }` prevents the tool from executing. The loop emits an error tool result instead. `reason` becomes the text shown in that error result. If omitted, a default blocked message is used.

type ConvertToLLMFunc

type ConvertToLLMFunc func(messages []AgentMessage) []ai.Message

type EndEvent

type EndEvent struct {
	Type     string         `json:"type"`
	Messages []AgentMessage `json:"messages"`
}

func (EndEvent) EventType

func (EndEvent) EventType() string

type ExecutedToolCallBatch

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

func ExecuteToolCalls

func ExecuteToolCalls(
	currentContext AgentContext,
	assistantMessage ai.AssistantMessage,
	config AgentLoopConfig,
	signal context.Context,
	emit AgentEventSink,
) (ExecutedToolCallBatch, error)

func ExecuteToolCallsParallel

func ExecuteToolCallsParallel(
	currentContext AgentContext,
	assistantMessage ai.AssistantMessage,
	toolCalls []ai.ToolCall,
	config AgentLoopConfig,
	signal context.Context,
	emit AgentEventSink,
) (ExecutedToolCallBatch, error)

func ExecuteToolCallsSequential

func ExecuteToolCallsSequential(
	currentContext AgentContext,
	assistantMessage ai.AssistantMessage,
	toolCalls []ai.ToolCall,
	config AgentLoopConfig,
	signal context.Context,
	emit AgentEventSink,
) (ExecutedToolCallBatch, error)

type ExecutedToolCallOutcome

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

func ExecutePreparedToolCall

func ExecutePreparedToolCall(
	prepared PreparedToolCall,
	signal context.Context,
	emit AgentEventSink,
) (ExecutedToolCallOutcome, error)

type FinalizedToolCallEntryFunc

type FinalizedToolCallEntryFunc func() (FinalizedToolCallOutcome, error)

type FinalizedToolCallOutcome

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

func FinalizeExecutedToolCall

func FinalizeExecutedToolCall(
	currentContext AgentContext,
	assistantMessage ai.AssistantMessage,
	prepared PreparedToolCall,
	executed ExecutedToolCallOutcome,
	config *AgentLoopConfig,
	signal context.Context,
) FinalizedToolCallOutcome

type ImmediateToolOutcome

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

func (ImmediateToolOutcome) EventType

func (ImmediateToolOutcome) EventType() string

type InitialAgentState

type InitialAgentState struct {
	SystemPrompt  *string
	Model         *ai.Model[ai.API]
	ThinkingLevel *ai.ModelThinkingLevel
	Tools         []AgentTool[any, any]
	Messages      []AgentMessage
}

type MessageEndEvent

type MessageEndEvent struct {
	Type      string       `json:"type"`
	MessageID string       `json:"messageId"`
	Message   AgentMessage `json:"message"`
}

func (MessageEndEvent) EventType

func (MessageEndEvent) EventType() string

type MessageStartEvent

type MessageStartEvent struct {
	Type      string       `json:"type"`
	MessageID string       `json:"messageId"`
	Message   AgentMessage `json:"message"`
}

func (MessageStartEvent) EventType

func (MessageStartEvent) EventType() string

type MessageUpdateEvent

type MessageUpdateEvent struct {
	Type                  string       `json:"type"`
	MessageID             string       `json:"messageId"`
	Message               AgentMessage `json:"message"`
	AssistantMessageEvent ai.AssistantMessageEvent
}

func (MessageUpdateEvent) EventType

func (MessageUpdateEvent) EventType() string

type PendingMessageQueue

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

func NewPendingMessageQueue

func NewPendingMessageQueue(mode QueueMode) *PendingMessageQueue

func (*PendingMessageQueue) Clear

func (q *PendingMessageQueue) Clear()

func (*PendingMessageQueue) Drain

func (q *PendingMessageQueue) Drain() []AgentMessage

func (*PendingMessageQueue) Enqueue

func (q *PendingMessageQueue) Enqueue(message AgentMessage)

func (*PendingMessageQueue) HasItems

func (q *PendingMessageQueue) HasItems() bool

func (*PendingMessageQueue) Mode

func (q *PendingMessageQueue) Mode() QueueMode

func (*PendingMessageQueue) SetMode

func (q *PendingMessageQueue) SetMode(mode QueueMode)

func (*PendingMessageQueue) TakeAll added in v0.3.0

func (q *PendingMessageQueue) TakeAll() []AgentMessage

TakeAll removes and returns every queued message, regardless of mode.

type PrepareNextTurnContext added in v0.7.0

type PrepareNextTurnContext = ShouldStopAfterTurnContext

PrepareNextTurnContext is the turn that just completed, passed to PrepareNextTurn before the next one starts.

type PreparedToolCall

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

func (PreparedToolCall) EventType

func (PreparedToolCall) EventType() string

type PreparedToolCallResult

type PreparedToolCallResult interface {
	EventType() string
}

func PrepareToolCall

func PrepareToolCall(
	currentContext AgentContext,
	assistantMessage ai.AssistantMessage,
	toolCall ai.ToolCall,
	config AgentLoopConfig,
	signal context.Context,
) PreparedToolCallResult

type QueueMode

type QueueMode string
const (
	QueueModeAll        QueueMode = "all"
	QueueModeOneAtATime QueueMode = "one-at-a-time"
)

type ShouldStopAfterTurnContext

type ShouldStopAfterTurnContext struct {
	Message     ai.AssistantMessage
	ToolResults []ai.ToolResultMessage
	Context     AgentContext
	NewMessages []AgentMessage
}

type StartEvent

type StartEvent struct {
	Type string `json:"type"`
}

func (StartEvent) EventType

func (StartEvent) EventType() string

type StreamFn

type StreamFn func(
	ctx context.Context,
	model ai.Model[ai.API],
	modelContext ai.ModelContext,
	options *ai.SimpleStreamOptions,
) (*ai.AssistantMessageEventStream, error)

StreamFn starts an assistant message stream.

It may return an error when no stream could be created, such as invalid configuration, an unsupported model/provider, missing credentials, or request construction failure. If a non-nil stream is returned, callers should consume it; runtime/provider/transport failures after stream creation are reported by the stream events and Result method.

type ToolAnnotations added in v0.7.0

type ToolAnnotations struct {
	// ReadOnlyHint: the tool does not change its environment.
	ReadOnlyHint *bool `json:"readOnlyHint,omitempty"`
	// DestructiveHint: the tool may make destructive changes, not only
	// additive ones.
	DestructiveHint *bool `json:"destructiveHint,omitempty"`
	// IdempotentHint: calling the tool again with the same arguments has no
	// further effect.
	IdempotentHint *bool `json:"idempotentHint,omitempty"`
	// OpenWorldHint: the tool interacts with an open world of external
	// entities, such as the web.
	OpenWorldHint *bool `json:"openWorldHint,omitempty"`
}

ToolAnnotations are hints about a tool's behavior, such as those of MCP tools. Nil means unknown. They are hints: do not rely on them for security.

type ToolExecutionEndEvent

type ToolExecutionEndEvent struct {
	Type       string `json:"type"`
	ToolCallID string `json:"tool_call_id"`
	ToolName   string `json:"tool_name"`
	Result     any    `json:"result"`
	IsError    bool   `json:"is_error"`
}

func (ToolExecutionEndEvent) EventType

func (ToolExecutionEndEvent) EventType() string

type ToolExecutionMode

type ToolExecutionMode string
const (
	ToolExecutionModeSequential ToolExecutionMode = "sequential"
	ToolExecutionModeParallel   ToolExecutionMode = "parallel"
)

type ToolExecutionStartEvent

type ToolExecutionStartEvent struct {
	Type       string `json:"type"`
	ToolCallID string `json:"tool_call_id"`
	ToolName   string `json:"tool_name"`
	ToolArgs   any    `json:"tool_args"`
}

func (ToolExecutionStartEvent) EventType

func (ToolExecutionStartEvent) EventType() string

type ToolExecutionUpdateEvent

type ToolExecutionUpdateEvent struct {
	Type          string `json:"type"`
	ToolCallID    string `json:"tool_call_id"`
	ToolName      string `json:"tool_name"`
	ToolArgs      any    `json:"tool_args"`
	PartialResult any    `json:"partial_result"`
}

func (ToolExecutionUpdateEvent) EventType

func (ToolExecutionUpdateEvent) EventType() string

type TransformContextFunc

type TransformContextFunc func(ctx context.Context, messages []AgentMessage) []AgentMessage

type TurnEndEvent

type TurnEndEvent struct {
	Type        string                 `json:"type"`
	Message     AgentMessage           `json:"message"`
	ToolResults []ai.ToolResultMessage `json:"tool_results"`
}

func (TurnEndEvent) EventType

func (TurnEndEvent) EventType() string

type TurnStartEvent

type TurnStartEvent struct {
	Type string `json:"type"`
}

func (TurnStartEvent) EventType

func (TurnStartEvent) EventType() string

Jump to

Keyboard shortcuts

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