Documentation
¶
Index ¶
- func AgentLoop(ctx context.Context, prompts []AgentMessage, agentCtx AgentContext, ...) <-chan Event
- func AgentLoopContinue(ctx context.Context, agentCtx AgentContext, config LoopConfig) <-chan Event
- func IsContextOverflow(err error) bool
- func ReactivateDeferred(tools []Tool, msgs []AgentMessage)
- func ReportToolProgress(ctx context.Context, progress ProgressPayload)
- func WithToolProgress(ctx context.Context, fn ToolProgressFunc) context.Context
- type Agent
- func (a *Agent) Abort()
- func (a *Agent) AbortSilent()
- func (a *Agent) BuildLLMMessages() []Message
- func (a *Agent) ClearAllQueues()
- func (a *Agent) ClearFollowUpQueue()
- func (a *Agent) ClearMessages()
- func (a *Agent) ClearSteeringQueue()
- func (a *Agent) ContextUsage() *ContextUsage
- func (a *Agent) Continue() error
- func (a *Agent) ExportMessages() []Message
- func (a *Agent) FollowUp(msg AgentMessage)
- func (a *Agent) HasQueuedMessages() bool
- func (a *Agent) ImportMessages(msgs []Message) error
- func (a *Agent) Inject(msg AgentMessage) (InjectResult, error)
- func (a *Agent) Messages() []AgentMessage
- func (a *Agent) Prompt(input string) error
- func (a *Agent) PromptMessages(msgs ...AgentMessage) error
- func (a *Agent) Reset()
- func (a *Agent) SetContextWindow(n int)
- func (a *Agent) SetMessages(msgs []AgentMessage) error
- func (a *Agent) SetModel(m ChatModel)
- func (a *Agent) SetSystemBlocks(blocks []SystemBlock)
- func (a *Agent) SetSystemPrompt(s string)
- func (a *Agent) SetThinkingLevel(level ThinkingLevel)
- func (a *Agent) SetTools(tools ...Tool)
- func (a *Agent) State() AgentState
- func (a *Agent) Steer(msg AgentMessage)
- func (a *Agent) Subscribe(fn func(Event)) func()
- func (a *Agent) TotalUsage() Usage
- func (a *Agent) WaitForIdle()
- type AgentContext
- type AgentMessage
- type AgentOption
- func WithContextEstimate(fn ContextEstimateFn) AgentOption
- func WithContextPipeline(...) AgentOption
- func WithContextWindow(n int) AgentOption
- func WithConvertToLLM(fn func([]AgentMessage) []Message) AgentOption
- func WithFollowUpMode(mode QueueMode) AgentOption
- func WithGetApiKey(fn func(provider string) (string, error)) AgentOption
- func WithMaxRetries(n int) AgentOption
- func WithMaxRetryDelay(d time.Duration) AgentOption
- func WithMaxToolConcurrency(n int) AgentOption
- func WithMaxToolErrors(n int) AgentOption
- func WithMaxTurns(n int) AgentOption
- func WithMiddlewares(mw ...ToolMiddleware) AgentOption
- func WithModel(model ChatModel) AgentOption
- func WithSessionID(id string) AgentOption
- func WithSteeringMode(mode QueueMode) AgentOption
- func WithStreamFn(fn StreamFn) AgentOption
- func WithSystemBlocks(blocks []SystemBlock) AgentOption
- func WithSystemPrompt(prompt string) AgentOption
- func WithThinkingBudgets(budgets map[ThinkingLevel]int) AgentOption
- func WithThinkingLevel(level ThinkingLevel) AgentOption
- func WithToolApproval(fn ToolApprovalFunc) AgentOption
- func WithTools(tools ...Tool) AgentOption
- func WithTransformContext(fn func(ctx context.Context, msgs []AgentMessage) ([]AgentMessage, error)) AgentOption
- type AgentState
- type BackgroundTask
- type CallConfig
- type CallOption
- type ChatModel
- type ContentBlock
- type ContentTool
- type ContentType
- type ContextEstimateFn
- type ContextUsage
- type Cost
- type DeferActivator
- type DeferFilter
- type EndReason
- type Event
- type EventStream
- type EventType
- type FuncTool
- type ImageData
- type InjectDisposition
- type InjectResult
- type LLMRequest
- type LLMResponse
- type LoopConfig
- type Message
- func AbortMsg(text, phase string) Message
- func CollectMessages(msgs []AgentMessage) []Message
- func DefaultConvertToLLM(msgs []AgentMessage) []Message
- func RepairMessageSequence(msgs []Message) []Message
- func SystemMsg(text string) Message
- func ToolResultMsg(toolCallID string, content json.RawMessage, isError bool) Message
- func UserMsg(text string) Message
- type Previewer
- type ProgressPayload
- type ProgressPayloadKind
- type ProviderNamer
- type ProxyEvent
- type ProxyEventType
- type ProxyModel
- func (p *ProxyModel) Generate(ctx context.Context, messages []Message, tools []ToolSpec, opts ...CallOption) (*LLMResponse, error)
- func (p *ProxyModel) GenerateStream(ctx context.Context, messages []Message, tools []ToolSpec, opts ...CallOption) (<-chan StreamEvent, error)
- func (p *ProxyModel) SupportsTools() bool
- type ProxyStreamFn
- type QueueMode
- type RetryInfo
- type Role
- type RunSummary
- type StopReason
- type StreamEvent
- type StreamEventType
- type StreamFn
- type SubAgentConfig
- type SubAgentTool
- func (t *SubAgentTool) BackgroundTasks() []BackgroundTask
- func (t *SubAgentTool) Description() string
- func (t *SubAgentTool) Execute(ctx context.Context, args json.RawMessage) (json.RawMessage, error)
- func (t *SubAgentTool) Label() string
- func (t *SubAgentTool) Name() string
- func (t *SubAgentTool) Schema() map[string]any
- func (t *SubAgentTool) SetBgOutputFactory(fn func(taskID, agentName string) (io.WriteCloser, string, error))
- func (t *SubAgentTool) SetCreateModel(fn func(name string) (ChatModel, error))
- func (t *SubAgentTool) SetNotifyFn(fn func(AgentMessage))
- func (t *SubAgentTool) StopAllBackgroundTasks() int
- func (t *SubAgentTool) StopBackgroundTask(id string) bool
- type SwappableModel
- func (m *SwappableModel) Current() ChatModel
- func (m *SwappableModel) Generate(ctx context.Context, messages []Message, tools []ToolSpec, opts ...CallOption) (*LLMResponse, error)
- func (m *SwappableModel) GenerateStream(ctx context.Context, messages []Message, tools []ToolSpec, opts ...CallOption) (<-chan StreamEvent, error)
- func (m *SwappableModel) ProviderName() string
- func (m *SwappableModel) SupportsTools() bool
- func (m *SwappableModel) Swap(next ChatModel)
- type SystemBlock
- type ThinkingLevel
- type Tool
- type ToolApprovalDecision
- type ToolApprovalFunc
- type ToolApprovalRequest
- type ToolApprovalResult
- type ToolCall
- type ToolExecUpdateKind
- type ToolExecuteFunc
- type ToolLabeler
- type ToolMiddleware
- type ToolProgressFunc
- type ToolResult
- type ToolSpec
- type Usage
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AgentLoop ¶
func AgentLoop(ctx context.Context, prompts []AgentMessage, agentCtx AgentContext, config LoopConfig) <-chan Event
AgentLoop starts an agent loop with new prompt messages. Prompts are added to context and events are emitted for them.
func AgentLoopContinue ¶
func AgentLoopContinue(ctx context.Context, agentCtx AgentContext, config LoopConfig) <-chan Event
AgentLoopContinue continues from existing context without adding new messages. The last message in context must convert to user or tool role via ConvertToLLM.
func IsContextOverflow ¶
IsContextOverflow reports whether the error indicates a context window overflow.
func ReactivateDeferred ¶ added in v1.5.2
func ReactivateDeferred(tools []Tool, msgs []AgentMessage)
ReactivateDeferred scans restored messages for tool_reference blocks and pre-activates them via the DeferActivator found in tools. This must be called after restoring a session to avoid "Tool reference not found" errors.
func ReportToolProgress ¶
func ReportToolProgress(ctx context.Context, progress ProgressPayload)
ReportToolProgress reports structured progress during tool execution. Silently ignored if no callback is registered in the context.
func WithToolProgress ¶
func WithToolProgress(ctx context.Context, fn ToolProgressFunc) context.Context
WithToolProgress injects a progress callback into the context.
Types ¶
type Agent ¶
type Agent struct {
// contains filtered or unexported fields
}
Agent is a stateful wrapper around the agent loop. It consumes loop events to update internal state, just like any external listener.
func NewAgent ¶
func NewAgent(opts ...AgentOption) *Agent
NewAgent creates a new Agent with the given options.
func (*Agent) Abort ¶
func (a *Agent) Abort()
Abort cancels the current execution and emits an abort marker message so the LLM knows the user interrupted.
func (*Agent) AbortSilent ¶ added in v1.5.1
func (a *Agent) AbortSilent()
AbortSilent cancels the current execution without emitting an abort marker. Use for programmatic cancellation (e.g. plan mode transitions) where the cancellation is not a user interruption.
func (*Agent) BuildLLMMessages ¶ added in v1.5.6
BuildLLMMessages constructs the message list exactly as the agent loop would for an LLM call: system blocks/prompt → converted conversation messages. This enables external callers (e.g., prompt suggestion) to make background LLM calls that share the same message prefix for prompt cache hits.
func (*Agent) ClearAllQueues ¶
func (a *Agent) ClearAllQueues()
ClearAllQueues removes all queued steering and follow-up messages.
func (*Agent) ClearFollowUpQueue ¶
func (a *Agent) ClearFollowUpQueue()
ClearFollowUpQueue removes all queued follow-up messages.
func (*Agent) ClearMessages ¶
func (a *Agent) ClearMessages()
ClearMessages resets the message history.
func (*Agent) ClearSteeringQueue ¶
func (a *Agent) ClearSteeringQueue()
ClearSteeringQueue removes all queued steering messages.
func (*Agent) ContextUsage ¶
func (a *Agent) ContextUsage() *ContextUsage
ContextUsage returns an estimate of the current context window occupancy. Returns nil if contextWindow or contextEstimateFn is not configured.
func (*Agent) Continue ¶
Continue resumes from the current context without adding new messages. If the last message is from assistant, it dequeues steering/follow-up
func (*Agent) ExportMessages ¶
ExportMessages returns concrete Messages for serialization.
func (*Agent) FollowUp ¶
func (a *Agent) FollowUp(msg AgentMessage)
FollowUp queues a message to be processed after the agent finishes.
func (*Agent) HasQueuedMessages ¶
HasQueuedMessages reports whether any steering or follow-up messages are queued.
func (*Agent) ImportMessages ¶
ImportMessages replaces message history from deserialized Messages.
func (*Agent) Inject ¶ added in v1.5.7
func (a *Agent) Inject(msg AgentMessage) (InjectResult, error)
Inject delivers a message as soon as the current agent state allows.
Semantics:
- running: enqueue into steeringQ for the current run
- idle with assistant tail: enqueue then synchronously Continue()
- other idle states: enqueue for a later run
func (*Agent) Messages ¶
func (a *Agent) Messages() []AgentMessage
Messages returns the current message history.
func (*Agent) PromptMessages ¶
func (a *Agent) PromptMessages(msgs ...AgentMessage) error
PromptMessages starts a new conversation turn with arbitrary AgentMessages.
func (*Agent) Reset ¶
func (a *Agent) Reset()
Reset clears all state and queues. If the agent is running, it cancels and waits first.
func (*Agent) SetContextWindow ¶ added in v1.5.2
SetContextWindow updates the context window size (in tokens).
func (*Agent) SetMessages ¶
func (a *Agent) SetMessages(msgs []AgentMessage) error
SetMessages replaces the message history (e.g. to restore a previous conversation). The agent must not be running.
func (*Agent) SetSystemBlocks ¶ added in v1.5.2
func (a *Agent) SetSystemBlocks(blocks []SystemBlock)
SetSystemBlocks sets a multi-block system prompt with per-block cache control. Takes precedence over SetSystemPrompt. Clears the single-string prompt.
func (*Agent) SetSystemPrompt ¶
SetSystemPrompt changes the system prompt (single-string mode). Clears any multi-block system prompt set via SetSystemBlocks.
func (*Agent) SetThinkingLevel ¶
func (a *Agent) SetThinkingLevel(level ThinkingLevel)
SetThinkingLevel changes the reasoning depth. Takes effect on the next turn.
func (*Agent) State ¶
func (a *Agent) State() AgentState
State returns a snapshot of the agent's current state.
func (*Agent) Steer ¶
func (a *Agent) Steer(msg AgentMessage)
Steer queues a steering message to interrupt the agent mid-run. Delivered after the current tool execution; remaining tools are skipped.
func (*Agent) Subscribe ¶
Subscribe registers a listener for agent events. Returns an unsubscribe function.
func (*Agent) TotalUsage ¶
TotalUsage returns the cumulative token usage across all turns.
func (*Agent) WaitForIdle ¶
func (a *Agent) WaitForIdle()
WaitForIdle blocks until the agent finishes the current run.
type AgentContext ¶
type AgentContext struct {
SystemPrompt string // single-string system prompt (legacy)
SystemBlocks []SystemBlock // multi-block system prompt with cache control (takes precedence)
Messages []AgentMessage
Tools []Tool
}
AgentContext holds the immutable context for a single agent loop invocation.
type AgentMessage ¶
type AgentMessage interface {
GetRole() Role
GetTimestamp() time.Time
TextContent() string
ThinkingContent() string
HasToolCalls() bool
}
AgentMessage is the app-layer message abstraction. Message implements this interface. Users can define custom types (e.g. status notifications, UI hints) that flow through the context pipeline but get filtered out by ConvertToLLM.
func Collect ¶ added in v1.5.1
func Collect(events <-chan Event) ([]AgentMessage, error)
Collect consumes all events from the channel and returns the final messages. Blocks until the channel is closed. Returns any error from EventError events.
func ToAgentMessages ¶
func ToAgentMessages(msgs []Message) []AgentMessage
ToAgentMessages converts a Message slice to AgentMessage slice. Use this to restore conversation history from deserialized Messages.
type AgentOption ¶
type AgentOption func(*Agent)
AgentOption configures an Agent.
func WithContextEstimate ¶
func WithContextEstimate(fn ContextEstimateFn) AgentOption
WithContextEstimate sets the context token estimation function. Use memory.ContextEstimateAdapter for the default hybrid estimation.
func WithContextPipeline ¶
func WithContextPipeline( transform func(ctx context.Context, msgs []AgentMessage) ([]AgentMessage, error), convert func([]AgentMessage) []Message, ) AgentOption
WithContextPipeline sets both TransformContext and ConvertToLLM in one call. This is the recommended way to configure context compaction:
agentcore.WithContextPipeline(
memory.NewCompaction(cfg),
memory.CompactionConvertToLLM,
)
func WithContextWindow ¶
func WithContextWindow(n int) AgentOption
WithContextWindow sets the model's context window size in tokens. Used by ContextUsage() to calculate context occupancy percentage.
func WithConvertToLLM ¶
func WithConvertToLLM(fn func([]AgentMessage) []Message) AgentOption
WithConvertToLLM sets the message conversion function.
func WithFollowUpMode ¶
func WithFollowUpMode(mode QueueMode) AgentOption
WithFollowUpMode sets the follow-up queue drain mode. QueueModeAll (default) delivers all queued follow-up messages at once. QueueModeOneAtATime delivers one per turn.
func WithGetApiKey ¶
func WithGetApiKey(fn func(provider string) (string, error)) AgentOption
WithGetApiKey sets a dynamic API key resolver called before each LLM call. The provider parameter identifies which provider is being called (e.g. "openai", "anthropic"). Enables per-provider key resolution, key rotation, OAuth short-lived tokens, and multi-tenant scenarios.
func WithMaxRetries ¶
func WithMaxRetries(n int) AgentOption
WithMaxRetries sets the LLM call retry limit for retryable errors.
func WithMaxRetryDelay ¶ added in v1.5.1
func WithMaxRetryDelay(d time.Duration) AgentOption
WithMaxRetryDelay caps the wait time between LLM retries. Applies to both exponential backoff and server-requested Retry-After delays. Default: 60s.
func WithMaxToolConcurrency ¶ added in v1.5.1
func WithMaxToolConcurrency(n int) AgentOption
WithMaxToolConcurrency sets the maximum number of tools executed in parallel. 0 or 1 = sequential (default). >1 enables concurrent tool execution.
func WithMaxToolErrors ¶
func WithMaxToolErrors(n int) AgentOption
WithMaxToolErrors sets the consecutive failure threshold per tool. After reaching this limit, the tool is disabled for the rest of the loop. 0 means unlimited (no circuit breaker).
func WithMaxTurns ¶
func WithMaxTurns(n int) AgentOption
WithMaxTurns sets the max turns safety limit.
func WithMiddlewares ¶ added in v1.5.1
func WithMiddlewares(mw ...ToolMiddleware) AgentOption
WithMiddlewares sets tool execution middlewares. Each middleware wraps the tool.Execute call. First middleware is outermost.
func WithSessionID ¶
func WithSessionID(id string) AgentOption
WithSessionID sets a session identifier for provider-level caching. Forwarded to providers that support session-based prompt caching.
func WithSteeringMode ¶
func WithSteeringMode(mode QueueMode) AgentOption
WithSteeringMode sets the steering queue drain mode. QueueModeAll (default) delivers all queued steering messages at once. QueueModeOneAtATime delivers one per turn, letting the agent respond to each individually.
func WithStreamFn ¶
func WithStreamFn(fn StreamFn) AgentOption
WithStreamFn sets a custom LLM call function (for proxy/mock).
func WithSystemBlocks ¶ added in v1.5.2
func WithSystemBlocks(blocks []SystemBlock) AgentOption
WithSystemBlocks sets a multi-block system prompt with per-block cache control. Takes precedence over WithSystemPrompt.
func WithSystemPrompt ¶
func WithSystemPrompt(prompt string) AgentOption
WithSystemPrompt sets the system prompt (single-string mode).
func WithThinkingBudgets ¶
func WithThinkingBudgets(budgets map[ThinkingLevel]int) AgentOption
WithThinkingBudgets sets per-level thinking token budgets. Each ThinkingLevel maps to a max thinking token count.
func WithThinkingLevel ¶
func WithThinkingLevel(level ThinkingLevel) AgentOption
WithThinkingLevel sets the reasoning depth for models that support it.
func WithToolApproval ¶ added in v1.5.6
func WithToolApproval(fn ToolApprovalFunc) AgentOption
WithToolApproval sets a runtime approval callback called before tool execution.
func WithTransformContext ¶
func WithTransformContext(fn func(ctx context.Context, msgs []AgentMessage) ([]AgentMessage, error)) AgentOption
WithTransformContext sets the context transform function.
type AgentState ¶
type AgentState struct {
SystemPrompt string
Messages []AgentMessage
Tools []Tool
IsRunning bool
StreamMessage AgentMessage // partial message being streamed, nil when idle
PendingToolCalls map[string]struct{} // tool call IDs currently executing
TotalUsage Usage // cumulative token usage across all turns
Error string
}
AgentState is a snapshot of the agent's current state.
type BackgroundTask ¶ added in v1.5.3
type BackgroundTask struct {
ID string
Agent string // agent config name
Description string
Prompt string // original task prompt
Status string // "running" | "completed" | "failed"
StartedAt time.Time
EndedAt time.Time
OutputFile string // path to output file on disk
Error string
Progress []string // tool call history: "Tool(args...)"
TokensIn int
TokensOut int
ToolCount int
// contains filtered or unexported fields
}
BackgroundTask tracks a background sub-agent's lifecycle. Output is written to a persistent file (OutputFile) with a symlink in the tasks dir.
type CallConfig ¶
type CallConfig struct {
ThinkingLevel ThinkingLevel
ThinkingBudget int // max thinking tokens, 0 = use provider default
APIKey string // per-call API key override, empty = use model default
SessionID string // provider session caching identifier
MaxTokens int // per-call max tokens override, 0 = use model default
}
CallConfig holds per-call configuration resolved from CallOptions.
func ResolveCallConfig ¶
func ResolveCallConfig(opts []CallOption) CallConfig
ResolveCallConfig applies options and returns the resolved config.
type CallOption ¶
type CallOption func(*CallConfig)
CallOption configures per-call LLM parameters.
func WithAPIKey ¶
func WithAPIKey(key string) CallOption
WithAPIKey overrides the API key for a single LLM call. Enables key rotation, OAuth short-lived tokens, and multi-tenant scenarios.
func WithCallSessionID ¶
func WithCallSessionID(id string) CallOption
WithCallSessionID sets a session identifier for a single LLM call.
func WithMaxTokens ¶ added in v1.5.1
func WithMaxTokens(tokens int) CallOption
WithMaxTokens overrides the max output tokens for a single LLM call.
func WithThinking ¶
func WithThinking(level ThinkingLevel) CallOption
WithThinking sets the thinking level for a single LLM call.
func WithThinkingBudget ¶
func WithThinkingBudget(tokens int) CallOption
WithThinkingBudget sets the max thinking tokens for a single LLM call.
type ChatModel ¶
type ChatModel interface {
Generate(ctx context.Context, messages []Message, tools []ToolSpec, opts ...CallOption) (*LLMResponse, error)
GenerateStream(ctx context.Context, messages []Message, tools []ToolSpec, opts ...CallOption) (<-chan StreamEvent, error)
SupportsTools() bool
}
ChatModel is the LLM provider interface.
type ContentBlock ¶
type ContentBlock struct {
Type ContentType `json:"type"`
Text string `json:"text,omitempty"`
Thinking string `json:"thinking,omitempty"`
ToolCall *ToolCall `json:"tool_call,omitempty"`
Image *ImageData `json:"image,omitempty"`
ToolName string `json:"tool_name,omitempty"` // tool_reference: referenced tool name
}
ContentBlock is a tagged union for message content. Exactly one payload field is populated, matching the Type value.
func ImageBlock ¶
func ImageBlock(data, mimeType string) ContentBlock
func ImageURLBlock ¶ added in v1.5.1
func ImageURLBlock(url string) ContentBlock
func TextBlock ¶
func TextBlock(text string) ContentBlock
func ThinkingBlock ¶
func ThinkingBlock(thinking string) ContentBlock
func ToolCallBlock ¶
func ToolCallBlock(tc ToolCall) ContentBlock
func ToolRefBlock ¶ added in v1.5.2
func ToolRefBlock(toolName string) ContentBlock
type ContentTool ¶ added in v1.5.1
type ContentTool interface {
ExecuteContent(ctx context.Context, args json.RawMessage) ([]ContentBlock, error)
}
ContentTool is an optional interface for tools that return rich content (e.g., images). When a tool implements ContentTool, the agent loop calls ExecuteContent instead of Execute, enabling multi-block responses with text + image content blocks.
type ContentType ¶
type ContentType string
ContentType identifies the kind of content in a ContentBlock.
const ( ContentText ContentType = "text" ContentThinking ContentType = "thinking" ContentToolCall ContentType = "toolCall" ContentImage ContentType = "image" ContentToolRef ContentType = "tool_reference" )
type ContextEstimateFn ¶
type ContextEstimateFn func(msgs []AgentMessage) (tokens, usageTokens, trailingTokens int)
ContextEstimateFn estimates the current context token consumption from messages. Returns total tokens, tokens from LLM Usage, and estimated trailing tokens.
type ContextUsage ¶
type ContextUsage struct {
Tokens int `json:"tokens"` // estimated total tokens in context
ContextWindow int `json:"context_window"` // model's context window size
Percent float64 `json:"percent"` // tokens / contextWindow * 100
UsageTokens int `json:"usage_tokens"` // from last LLM-reported Usage
TrailingTokens int `json:"trailing_tokens"` // chars/4 estimate for trailing messages
}
ContextUsage represents the current context window occupancy estimate.
type Cost ¶ added in v1.5.1
type Cost struct {
Input float64 `json:"input"`
Output float64 `json:"output"`
CacheRead float64 `json:"cache_read"`
CacheWrite float64 `json:"cache_write"`
Total float64 `json:"total"`
}
Cost tracks monetary cost for a single LLM call in USD.
type DeferActivator ¶ added in v1.5.2
type DeferActivator interface {
DeferFilter
Activate(names ...string)
}
DeferActivator is an optional extension of DeferFilter that supports pre-activating deferred tools (e.g. when restoring a session whose history contains tool_reference blocks for previously activated tools).
type DeferFilter ¶ added in v1.5.2
type DeferFilter interface {
// IsDeferred reports whether the tool is deferred and not yet activated.
// Unactivated deferred tools are excluded from the API request entirely.
IsDeferred(toolName string) bool
// WasDeferred reports whether the tool was originally in the deferred set
// (regardless of activation). Activated deferred tools are sent with
// defer_loading: true.
WasDeferred(toolName string) bool
}
DeferFilter controls deferred tool loading for the LLM. When a tool in the agent's tool list implements DeferFilter:
- IsDeferred returns true → tool schema is excluded from the API request
- WasDeferred returns true → tool schema is sent with defer_loading: true
Unactivated deferred tools are excluded entirely. Once activated via tool_reference, they are sent with defer_loading: true so the API server manages their context loading. Tools remain registered for execution regardless — only their API visibility changes.
IsDeferred is also used by the system prompt builder to exclude unactivated tools from the tool description section (they appear in <available-deferred-tools> by name only).
type EndReason ¶ added in v1.5.7
type EndReason string
EndReason describes why a single agent run stopped.
type Event ¶
type Event struct {
Type EventType
Message AgentMessage // for message_start/update/end, turn_end
Delta string // text delta for message_update
ToolID string // for tool_exec_*
Tool string // tool name for tool_exec_*
ToolLabel string // human-readable tool label (from ToolLabeler)
Args json.RawMessage // tool args for tool_exec_start/tool_exec_update
Result json.RawMessage // tool result for tool_exec_end and preview updates
Progress *ProgressPayload
UpdateKind ToolExecUpdateKind
IsError bool // tool error flag for tool_exec_end
ApprovalDecision ToolApprovalDecision
ApprovalReason string
Preview json.RawMessage
ToolResults []ToolResult // for turn_end: all tool results from this turn
Err error // for error events
NewMessages []AgentMessage // for agent_end: messages added during this loop
RetryInfo *RetryInfo // for retry events
Summary *RunSummary // for agent_end: factual run summary
}
Event is a lifecycle event emitted by the agent loop. This is the single output channel for all lifecycle information.
type EventStream ¶ added in v1.5.1
type EventStream struct {
// contains filtered or unexported fields
}
EventStream wraps an event channel to provide both real-time iteration and deferred result collection.
Usage:
stream := agentcore.NewEventStream(AgentLoop(...))
for ev := range stream.Events() {
// handle real-time events
}
msgs, err := stream.Result()
func NewEventStream ¶ added in v1.5.1
func NewEventStream(source <-chan Event) *EventStream
NewEventStream creates an EventStream that reads from the source channel. Events are forwarded to an internal channel for iteration. The final result is captured from EventAgentEnd.
func (*EventStream) Done ¶ added in v1.5.1
func (s *EventStream) Done() <-chan struct{}
Done returns a channel that is closed when the stream finishes.
func (*EventStream) Events ¶ added in v1.5.1
func (s *EventStream) Events() <-chan Event
Events returns the event channel for real-time iteration. The channel is closed when the source is exhausted.
func (*EventStream) Result ¶ added in v1.5.1
func (s *EventStream) Result() ([]AgentMessage, error)
Result blocks until the stream is done and returns the final messages. Returns the error from the last EventError, if any.
type EventType ¶
type EventType string
EventType identifies agent lifecycle event types.
const ( EventAgentStart EventType = "agent_start" EventAgentEnd EventType = "agent_end" EventTurnStart EventType = "turn_start" EventTurnEnd EventType = "turn_end" EventMessageStart EventType = "message_start" EventMessageUpdate EventType = "message_update" EventMessageEnd EventType = "message_end" EventToolExecStart EventType = "tool_exec_start" EventToolExecUpdate EventType = "tool_exec_update" EventToolExecEnd EventType = "tool_exec_end" EventToolApprovalRequest EventType = "tool_approval_request" EventToolApprovalResolved EventType = "tool_approval_resolved" EventRetry EventType = "retry" EventError EventType = "error" )
type FuncTool ¶
type FuncTool struct {
// contains filtered or unexported fields
}
FuncTool wraps a function as a Tool (convenience helper).
func NewFuncTool ¶
func (*FuncTool) Description ¶
func (*FuncTool) Execute ¶
func (t *FuncTool) Execute(ctx context.Context, args json.RawMessage) (json.RawMessage, error)
type ImageData ¶
type ImageData struct {
Data string `json:"data,omitempty"`
URL string `json:"url,omitempty"`
MimeType string `json:"mime_type,omitempty"`
}
ImageData holds image content as base64 data or a URL. When URL is set, providers pass it directly (no download/encoding needed). When Data is set, it is sent as a base64 data URL with MimeType. MimeType is required for base64 mode, optional for URL mode (provider infers it).
type InjectDisposition ¶ added in v1.5.7
type InjectDisposition string
InjectDisposition describes how an injected message was delivered.
const ( InjectSteeredCurrentRun InjectDisposition = "steered_current_run" InjectResumedIdleRun InjectDisposition = "resumed_idle_run" InjectQueued InjectDisposition = "queued" )
type InjectResult ¶ added in v1.5.7
type InjectResult struct {
Disposition InjectDisposition
}
InjectResult reports the delivery outcome of Agent.Inject.
type LLMRequest ¶
LLMRequest is the request passed to StreamFn.
type LLMResponse ¶
type LLMResponse struct {
Message Message
}
LLMResponse is the response from StreamFn.
type LoopConfig ¶
type LoopConfig struct {
Model ChatModel
StreamFn StreamFn // nil = use Model directly
MaxTurns int // safety limit, default 10
MaxRetries int // LLM call retry limit for retryable errors, default 3
MaxToolErrors int // consecutive tool failure threshold per tool, 0 = unlimited
ThinkingLevel ThinkingLevel // reasoning depth
// Two-stage pipeline: TransformContext -> ConvertToLLM
TransformContext func(ctx context.Context, msgs []AgentMessage) ([]AgentMessage, error)
ConvertToLLM func(msgs []AgentMessage) []Message
// CheckToolApproval is called after validation/preview and before execution.
// Returning nil means no approval was required.
// Returning a non-nil result applies the approval decision immediately.
CheckToolApproval ToolApprovalFunc
// GetApiKey resolves the API key before each LLM call.
// The provider parameter identifies which provider is being called (e.g. "openai", "anthropic").
// Enables per-provider key resolution, key rotation, OAuth tokens, and multi-tenant scenarios.
// When nil or returns empty string, the model's default key is used.
GetApiKey func(provider string) (string, error)
// ThinkingBudgets maps each ThinkingLevel to a max thinking token count.
// When set, the resolved budget is passed to the model alongside the level.
ThinkingBudgets map[ThinkingLevel]int
// SessionID enables provider-level session caching (e.g. Anthropic prompt cache).
SessionID string
// Steering: called after each tool execution to check for user interruptions.
GetSteeringMessages func() []AgentMessage
// FollowUp: called when the agent would otherwise stop.
GetFollowUpMessages func() []AgentMessage
// MaxRetryDelay caps the wait time between retries (including server-requested Retry-After).
// Default: 60s. Set to prevent excessively long waits from overloaded providers.
MaxRetryDelay time.Duration
// Middlewares are applied around each tool execution (outermost first).
// Use for logging, timing, argument/result modification, etc.
Middlewares []ToolMiddleware
// MaxToolConcurrency limits parallel tool execution.
// 0 or 1 = sequential (default, backward compatible).
// >1 = up to N tools execute concurrently within a single turn.
MaxToolConcurrency int
// ShouldEmitAbortMarker reports whether an abort marker message should be
// emitted when the context is cancelled. When nil or returns false, the
// cancellation is silent (legacy behavior). Set by Agent.Abort().
ShouldEmitAbortMarker func() bool
}
LoopConfig configures the agent loop.
type Message ¶
type Message struct {
Role Role `json:"role"`
Content []ContentBlock `json:"content"`
StopReason StopReason `json:"stop_reason,omitempty"`
Usage *Usage `json:"usage,omitempty"`
Metadata map[string]any `json:"metadata,omitempty"`
Timestamp time.Time `json:"timestamp"`
}
Message is an LLM-level message with structured content blocks.
func AbortMsg ¶ added in v1.5.1
AbortMsg creates an assistant abort marker message. phase is "inference" or "tool_execution".
func CollectMessages ¶
func CollectMessages(msgs []AgentMessage) []Message
CollectMessages extracts concrete Messages from an AgentMessage slice, dropping custom types. Use this to serialize conversation history.
func DefaultConvertToLLM ¶
func DefaultConvertToLLM(msgs []AgentMessage) []Message
DefaultConvertToLLM filters AgentMessages to LLM-compatible Messages. Custom message types are dropped; only user/assistant/system/tool messages pass through.
func RepairMessageSequence ¶
RepairMessageSequence ensures tool call / tool result pairs are complete. Orphaned tool calls (no matching result) get a synthetic error result inserted. Orphaned tool results (no matching call) are removed. This prevents LLM providers from rejecting malformed message sequences.
func ToolResultMsg ¶
func ToolResultMsg(toolCallID string, content json.RawMessage, isError bool) Message
ToolResultMsg creates a tool result message.
func (Message) GetTimestamp ¶
func (Message) HasToolCalls ¶
HasToolCalls reports whether any tool call blocks exist.
func (Message) TextContent ¶
TextContent returns the concatenated text from all text blocks.
func (Message) ThinkingContent ¶
ThinkingContent returns the concatenated thinking text.
type Previewer ¶ added in v1.5.1
type Previewer interface {
Preview(ctx context.Context, args json.RawMessage) (json.RawMessage, error)
}
Previewer is an optional interface for tools that can compute a preview (e.g., diff) before execution. The agent loop calls Preview and emits the result as EventToolExecUpdate so the UI can display it before the tool runs.
type ProgressPayload ¶ added in v1.5.7
type ProgressPayload struct {
Kind ProgressPayloadKind `json:"kind"`
Agent string `json:"agent,omitempty"`
Tool string `json:"tool,omitempty"`
Summary string `json:"summary,omitempty"`
Delta string `json:"delta,omitempty"`
Thinking string `json:"thinking,omitempty"`
Message string `json:"message,omitempty"`
Turn int `json:"turn,omitempty"`
Attempt int `json:"attempt,omitempty"`
MaxRetries int `json:"max_retries,omitempty"`
IsError bool `json:"is_error,omitempty"`
Args json.RawMessage `json:"args,omitempty"`
Meta json.RawMessage `json:"meta,omitempty"`
}
ProgressPayload is the structured progress envelope emitted by tools.
type ProgressPayloadKind ¶ added in v1.5.7
type ProgressPayloadKind string
ProgressPayloadKind distinguishes structured progress update semantics.
const ( ProgressToolStart ProgressPayloadKind = "tool_start" ProgressToolDelta ProgressPayloadKind = "tool_delta" ProgressThinking ProgressPayloadKind = "thinking" ProgressSummary ProgressPayloadKind = "summary" ProgressToolError ProgressPayloadKind = "tool_error" ProgressTurnCounter ProgressPayloadKind = "turn_counter" ProgressRetry ProgressPayloadKind = "retry" )
type ProviderNamer ¶
type ProviderNamer interface {
ProviderName() string
}
ProviderNamer is an optional interface for ChatModel implementations to expose their provider name (e.g. "openai", "anthropic", "gemini"). Used by the agent loop to pass provider context to GetApiKey callbacks.
type ProxyEvent ¶
type ProxyEvent struct {
Type ProxyEventType `json:"type"`
Delta string `json:"delta,omitempty"`
ToolCallID string `json:"tool_call_id,omitempty"`
ToolName string `json:"tool_name,omitempty"`
StopReason StopReason `json:"stop_reason,omitempty"`
Usage *Usage `json:"usage,omitempty"`
Err error `json:"-"`
}
ProxyEvent is a bandwidth-optimized event from a remote proxy server. The client reconstructs the full message incrementally from these deltas.
type ProxyEventType ¶
type ProxyEventType string
ProxyEventType identifies proxy streaming event types. Proxy events are bandwidth-optimized: they carry only deltas, not the full partial message on each event.
const ( ProxyEventTextDelta ProxyEventType = "text_delta" ProxyEventThinkingDelta ProxyEventType = "thinking_delta" ProxyEventToolCallStart ProxyEventType = "toolcall_start" ProxyEventToolCallDelta ProxyEventType = "toolcall_delta" ProxyEventDone ProxyEventType = "done" ProxyEventError ProxyEventType = "error" )
type ProxyModel ¶
type ProxyModel struct {
// contains filtered or unexported fields
}
ProxyModel implements ChatModel by forwarding to a remote proxy server. It reconstructs streaming events from bandwidth-optimized ProxyEvents.
Usage:
proxy := agentcore.NewProxyModel(myProxyFn) agent := agentcore.NewAgent(agentcore.WithModel(proxy))
func NewProxyModel ¶
func NewProxyModel(fn ProxyStreamFn) *ProxyModel
NewProxyModel creates a ChatModel that delegates to a proxy stream function.
func (*ProxyModel) Generate ¶
func (p *ProxyModel) Generate(ctx context.Context, messages []Message, tools []ToolSpec, opts ...CallOption) (*LLMResponse, error)
Generate collects the full streamed response synchronously.
func (*ProxyModel) GenerateStream ¶
func (p *ProxyModel) GenerateStream(ctx context.Context, messages []Message, tools []ToolSpec, opts ...CallOption) (<-chan StreamEvent, error)
GenerateStream converts proxy events into standard StreamEvents.
func (*ProxyModel) SupportsTools ¶
func (p *ProxyModel) SupportsTools() bool
SupportsTools reports that the proxy can handle tool calls.
type ProxyStreamFn ¶
type ProxyStreamFn func(ctx context.Context, req *LLMRequest) (<-chan ProxyEvent, error)
ProxyStreamFn makes an LLM call through a remote proxy and returns a channel of bandwidth-optimized ProxyEvents.
type QueueMode ¶
type QueueMode string
QueueMode controls how steering/follow-up queues are drained.
type RunSummary ¶ added in v1.5.7
RunSummary captures loop facts that are known at the end of a run. It intentionally excludes higher-level policy judgments.
type StopReason ¶
type StopReason string
StopReason indicates why the LLM stopped generating.
const ( StopReasonStop StopReason = "stop" StopReasonLength StopReason = "length" StopReasonToolUse StopReason = "toolUse" StopReasonError StopReason = "error" StopReasonAborted StopReason = "aborted" )
type StreamEvent ¶
type StreamEvent struct {
Type StreamEventType
ContentIndex int // which content block is being updated
Delta string // text/thinking/toolcall argument delta
Message Message // partial (during streaming) or final (done)
StopReason StopReason // finish reason (for done events)
Err error // for error events
}
StreamEvent is a streaming event from the LLM.
type StreamEventType ¶
type StreamEventType string
StreamEventType identifies LLM streaming event types.
const ( // Text content streaming StreamEventTextStart StreamEventType = "text_start" StreamEventTextDelta StreamEventType = "text_delta" StreamEventTextEnd StreamEventType = "text_end" // Thinking/reasoning streaming StreamEventThinkingStart StreamEventType = "thinking_start" StreamEventThinkingDelta StreamEventType = "thinking_delta" StreamEventThinkingEnd StreamEventType = "thinking_end" // Tool call streaming StreamEventToolCallStart StreamEventType = "toolcall_start" StreamEventToolCallDelta StreamEventType = "toolcall_delta" StreamEventToolCallEnd StreamEventType = "toolcall_end" // Terminal events StreamEventDone StreamEventType = "done" StreamEventError StreamEventType = "error" )
type StreamFn ¶
type StreamFn func(ctx context.Context, req *LLMRequest) (*LLMResponse, error)
StreamFn is an injectable LLM call function. When nil, the loop uses model.Generate / model.GenerateStream directly.
type SubAgentConfig ¶
type SubAgentConfig struct {
Name string
Description string
// Model is resolved when each sub-agent run starts. Wrappers that swap
// the underlying model at runtime are supported and take effect on the
// next sub-agent run.
Model ChatModel
SystemPrompt string
Tools []Tool
StreamFn StreamFn
MaxTurns int
// Optional two-stage context pipeline (same as Agent-level).
// When set, enables automatic context compaction for long-running sub-agents.
TransformContext func(ctx context.Context, msgs []AgentMessage) ([]AgentMessage, error)
ConvertToLLM func(msgs []AgentMessage) []Message
}
SubAgentConfig defines a sub-agent's identity and capabilities.
type SubAgentTool ¶
type SubAgentTool struct {
// contains filtered or unexported fields
}
SubAgentTool implements the Tool interface. The main agent calls this tool to delegate tasks to specialized sub-agents with isolated contexts.
func NewSubAgentTool ¶
func NewSubAgentTool(agents ...SubAgentConfig) *SubAgentTool
NewSubAgentTool creates a subagent tool from a set of agent configs.
func (*SubAgentTool) BackgroundTasks ¶ added in v1.5.3
func (t *SubAgentTool) BackgroundTasks() []BackgroundTask
BackgroundTasks returns a snapshot of all background tasks.
func (*SubAgentTool) Description ¶
func (t *SubAgentTool) Description() string
func (*SubAgentTool) Execute ¶
func (t *SubAgentTool) Execute(ctx context.Context, args json.RawMessage) (json.RawMessage, error)
func (*SubAgentTool) Label ¶
func (t *SubAgentTool) Label() string
func (*SubAgentTool) Name ¶
func (t *SubAgentTool) Name() string
func (*SubAgentTool) Schema ¶
func (t *SubAgentTool) Schema() map[string]any
func (*SubAgentTool) SetBgOutputFactory ¶ added in v1.5.3
func (t *SubAgentTool) SetBgOutputFactory(fn func(taskID, agentName string) (io.WriteCloser, string, error))
SetBgOutputFactory sets the factory that creates output writers for background tasks. The factory receives the task ID and agent name, returns a writer, file path, and error. If not set, background output is not persisted.
func (*SubAgentTool) SetCreateModel ¶ added in v1.5.1
func (t *SubAgentTool) SetCreateModel(fn func(name string) (ChatModel, error))
SetCreateModel sets the factory for resolving model names (e.g. "haiku", "gpt-4o-mini") to ChatModel instances at runtime. Enables LLM to override the default model per call.
func (*SubAgentTool) SetNotifyFn ¶ added in v1.5.1
func (t *SubAgentTool) SetNotifyFn(fn func(AgentMessage))
SetNotifyFn sets the callback invoked when a background task completes. Typically bound to Agent.FollowUp so the main agent receives the result as a follow-up message.
func (*SubAgentTool) StopAllBackgroundTasks ¶ added in v1.5.3
func (t *SubAgentTool) StopAllBackgroundTasks() int
StopAllBackgroundTasks cancels all running background tasks.
func (*SubAgentTool) StopBackgroundTask ¶ added in v1.5.3
func (t *SubAgentTool) StopBackgroundTask(id string) bool
StopBackgroundTask cancels a running background task by ID.
type SwappableModel ¶ added in v1.5.7
type SwappableModel struct {
// contains filtered or unexported fields
}
SwappableModel wraps a ChatModel and allows replacing the underlying model at runtime. Swaps take effect on the next call.
func NewSwappableModel ¶ added in v1.5.7
func NewSwappableModel(initial ChatModel) *SwappableModel
func (*SwappableModel) Current ¶ added in v1.5.7
func (m *SwappableModel) Current() ChatModel
func (*SwappableModel) Generate ¶ added in v1.5.7
func (m *SwappableModel) Generate(ctx context.Context, messages []Message, tools []ToolSpec, opts ...CallOption) (*LLMResponse, error)
func (*SwappableModel) GenerateStream ¶ added in v1.5.7
func (m *SwappableModel) GenerateStream(ctx context.Context, messages []Message, tools []ToolSpec, opts ...CallOption) (<-chan StreamEvent, error)
func (*SwappableModel) ProviderName ¶ added in v1.5.7
func (m *SwappableModel) ProviderName() string
func (*SwappableModel) SupportsTools ¶ added in v1.5.7
func (m *SwappableModel) SupportsTools() bool
func (*SwappableModel) Swap ¶ added in v1.5.7
func (m *SwappableModel) Swap(next ChatModel)
type SystemBlock ¶ added in v1.5.2
type SystemBlock struct {
Text string `json:"text"`
CacheControl string `json:"cache_control,omitempty"` // e.g. "ephemeral"
}
SystemBlock is one segment of a multi-part system prompt. Use with AgentContext.SystemBlocks for per-block cache control.
type ThinkingLevel ¶
type ThinkingLevel string
ThinkingLevel configures the reasoning depth for models that support it.
const ( ThinkingOff ThinkingLevel = "off" ThinkingMinimal ThinkingLevel = "minimal" ThinkingLow ThinkingLevel = "low" ThinkingMedium ThinkingLevel = "medium" ThinkingHigh ThinkingLevel = "high" ThinkingXHigh ThinkingLevel = "xhigh" )
type Tool ¶
type Tool interface {
Name() string
Description() string
Schema() map[string]any
Execute(ctx context.Context, args json.RawMessage) (json.RawMessage, error)
}
Tool defines the minimal tool interface. Timeout control goes through context.Context. Tools can report execution progress via ReportToolProgress(ctx, payload).
type ToolApprovalDecision ¶ added in v1.5.6
type ToolApprovalDecision string
ToolApprovalDecision describes the outcome of a runtime approval check.
const ( ToolApprovalAllowOnce ToolApprovalDecision = "allow_once" ToolApprovalAllowSession ToolApprovalDecision = "allow_session" ToolApprovalAllowAlways ToolApprovalDecision = "allow_always" ToolApprovalDeny ToolApprovalDecision = "deny" )
type ToolApprovalFunc ¶ added in v1.5.6
type ToolApprovalFunc func(ctx context.Context, req ToolApprovalRequest) (*ToolApprovalResult, error)
ToolApprovalFunc is called before tool execution when a runtime approval system is configured. Returning nil means "no approval needed". Returning a non-nil result applies the decision immediately.
type ToolApprovalRequest ¶ added in v1.5.6
type ToolApprovalRequest struct {
Call ToolCall
ToolLabel string
Summary string
Reason string
Preview []byte
}
ToolApprovalRequest is sent to an approval callback before a tool executes. Approval systems can use Summary/Reason/Preview to present higher-signal UI.
type ToolApprovalResult ¶ added in v1.5.6
type ToolApprovalResult struct {
Approved bool
Decision ToolApprovalDecision
Reason string
}
ToolApprovalResult is returned by a runtime approval callback.
type ToolCall ¶
type ToolCall struct {
ID string `json:"id"`
Name string `json:"name"`
Args json.RawMessage `json:"args"`
}
ToolCall represents a tool invocation request from the LLM.
type ToolExecUpdateKind ¶ added in v1.5.1
type ToolExecUpdateKind string
ToolExecUpdateKind distinguishes update payload semantics for tool_exec_update events.
const ( ToolExecUpdatePreview ToolExecUpdateKind = "preview" ToolExecUpdateProgress ToolExecUpdateKind = "progress" )
type ToolExecuteFunc ¶ added in v1.5.1
type ToolExecuteFunc func(ctx context.Context, args json.RawMessage) (json.RawMessage, error)
ToolExecuteFunc is the function signature for tool execution. Used as the "next" parameter in middleware chains.
type ToolLabeler ¶
type ToolLabeler interface {
Label() string
}
ToolLabeler is an optional interface for tools to provide a human-readable label.
type ToolMiddleware ¶ added in v1.5.1
type ToolMiddleware func(ctx context.Context, call ToolCall, next ToolExecuteFunc) (json.RawMessage, error)
ToolMiddleware wraps tool execution with cross-cutting concerns. Call next to continue the chain; skip next to short-circuit execution. Example: logging, timing, argument/result modification, audit.
type ToolProgressFunc ¶
type ToolProgressFunc func(progress ProgressPayload)
ToolProgressFunc is a callback for reporting tool execution progress. Tools call ReportToolProgress to emit partial results during long operations.
type ToolResult ¶
type ToolResult struct {
ToolCallID string `json:"tool_call_id"`
ToolName string `json:"-"` // internal: for toolErrors tracking
Content json.RawMessage `json:"content,omitempty"`
ContentBlocks []ContentBlock `json:"-"` // rich content (images); not serialized
IsError bool `json:"is_error,omitempty"`
Details any `json:"details,omitempty"` // optional metadata for UI display/logging
}
ToolResult represents a tool execution outcome.
type ToolSpec ¶
type ToolSpec struct {
Name string `json:"name"`
Description string `json:"description"`
Parameters any `json:"parameters"`
DeferLoading bool `json:"defer_loading,omitempty"`
}
ToolSpec describes a tool for the LLM (name + description + JSON schema).
type Usage ¶
type Usage struct {
Input int `json:"input"`
Output int `json:"output"`
CacheRead int `json:"cache_read"`
CacheWrite int `json:"cache_write"`
TotalTokens int `json:"total_tokens"`
Cost *Cost `json:"cost,omitempty"`
}
Usage tracks token consumption for a single LLM call.
Field semantics:
- Input: prompt tokens sent to the model (includes cached tokens for some providers)
- Output: completion tokens generated (includes reasoning tokens if applicable)
- CacheRead: tokens served from prompt cache (Anthropic: cache_read_input_tokens)
- CacheWrite: tokens written to prompt cache (Anthropic: cache_creation_input_tokens)
- TotalTokens: provider-reported total, typically Input + Output
- Cost: monetary cost computed from model pricing (nil if pricing unavailable)