Documentation
¶
Overview ¶
Package llm is a unified, provider-neutral API for large language models.
It speaks two wire protocols, OpenAI Chat Completions and Anthropic Messages, behind one set of types. The same conversation can be sent to any model on either protocol, and the target model can change between turns; the library re-adapts the history for each request. It is a stateless translation layer: it decides what to send for a request and how to interpret the streamed response, and leaves history storage, context compaction, and tool-loop orchestration to the caller.
Entry points ¶
Stream returns a channel of Event values; Complete consumes that stream and returns the final AssistantMessage. Both dispatch to the adapter registered for the model's protocol. The package keeps a default client; NewClient returns an isolated one with the built-in adapters registered.
model := llm.GetModel("anthropic", "claude-opus-4-8")
msg, err := llm.Complete(ctx, model, input, llm.StreamOptions{})
Building a request ¶
A Context holds the system prompt, the message history, and the available tools. Messages are provider-neutral and serialize to self-describing JSON, so a conversation can be persisted and replayed later against any model:
- UserMessage, AssistantMessage, ToolResultMessage
- content blocks: TextContent, ThinkingContent, ImageContent, ToolCall
Text-only models that receive image content have it downgraded to a placeholder automatically.
Options ¶
StreamOptions carries settings shared by every protocol — API key, temperature, max tokens, headers, retries, timeout — plus observation hooks, OnRequest (the exact serialized request body) and OnResponse (status and headers), and RewriteRequest, which replaces the serialized body before it is sent. Each is invoked once per attempt including retries.
Reasoning is a provider-neutral effort level (ModelThinkingLevel: off, minimal, low, medium, high, xhigh). Each adapter maps it to that provider's native form (Anthropic adaptive or budget thinking; the OpenAI-compatible reasoning fields) and clamps it to what the model supports. It is ignored by non-reasoning models.
Settings with no neutral equivalent live on a protocol-specific extension supplied through StreamOptions.ProtocolOptions and validated against the target protocol before the request is sent:
- AnthropicStreamOptions: ThinkingDisplay (summarized or omitted) and a native Anthropic ToolChoice (AnthropicToolChoiceAuto, AnthropicToolChoiceAny, AnthropicToolChoiceNone, or AnthropicToolChoiceTool).
- OpenAICompletionsStreamOptions: a native OpenAI ToolChoice (OpenAIToolChoiceAuto, OpenAIToolChoiceNone, OpenAIToolChoiceRequired, or OpenAIToolChoiceFunction).
Streaming ¶
Event values report incremental progress: text, reasoning, and tool-call blocks each emit start, delta, and end events, followed by a single terminal EventDone (carrying the final message) or EventError. Every event carries a Partial snapshot of the message assembled so far. Tool-call arguments are parsed best-effort at end of stream; validate them and wait for EventDone before executing any call.
Typed tools ¶
NewTool and MustTool derive a provider-compatible JSON Schema from a Go struct, and DecodeToolCall decodes a returned call back into that struct. Malformed or truncated argument JSON degrades to a best-effort value and is reported in AssistantMessage.Diagnostics rather than failing the response.
Results ¶
AssistantMessage holds the response content, a StopReason, token Usage with per-category cost, and any non-fatal Diagnostics. CalculateCost prices a usage record against a model.
Switching models ¶
TransformMessages adapts a stored history for a target model before replay: it downgrades unsupported images, preserves reasoning signatures for the same model while downgrading or dropping them across models, normalizes tool-call identifiers, and repairs unanswered tool calls. Stream and Complete apply it automatically. IsContextOverflow reports whether a response exceeded the model's context window.
Models ¶
LookupModel and GetModel resolve models from the built-in catalog; GetProviders and GetModels enumerate it. SupportedThinkingLevels and ClampThinkingLevel report and adjust a model's reasoning levels. A caller may also construct a Model directly, pointing BaseURL at any OpenAI-compatible or Anthropic-compatible endpoint.
Custom protocols ¶
A genuinely different wire protocol is added by implementing ProtocolAdapter and registering it: build a Registry with NewRegistry, add the built-ins with RegisterBuiltins and the custom adapter with Registry.Register, then construct a client with NewClientWithRegistry. NewStreamWriter gives the adapter the same event-stream machinery the built-ins use.
Index ¶
- Constants
- func DecodeToolCall[T any](tool ToolDefinition, call ToolCall) (T, error)
- func GetProviders() []string
- func IsContextOverflow(message AssistantMessage, contextWindow int64) bool
- func ParseToolArguments(raw string) map[string]any
- func RegisterBuiltins(registry *Registry)
- func Stream(ctx context.Context, model Model, input Context, options StreamOptions) (<-chan Event, error)
- func ValidateToolArguments(tool ToolDefinition, toolCall ToolCall) (map[string]any, error)
- func ValidateToolCall(tools []ToolDefinition, toolCall ToolCall) (map[string]any, error)
- type AnthropicMessagesCompatibility
- type AnthropicStreamOptions
- type AnthropicToolChoice
- type AnthropicToolChoiceMode
- type AnthropicToolChoiceTool
- type ArgumentsMode
- type AssistantContent
- type AssistantMessage
- type Client
- type Context
- type Diagnostic
- type Event
- type EventType
- type ImageContent
- type Message
- type Model
- type ModelCompatibility
- type ModelCost
- type ModelInput
- type ModelThinkingLevel
- type OpenAICompletionsCompatibility
- type OpenAICompletionsStreamOptions
- type OpenAIToolChoice
- type OpenAIToolChoiceFunction
- type OpenAIToolChoiceMode
- type Protocol
- type ProtocolAdapter
- type ProtocolStreamOptions
- type ProviderEnv
- type Registry
- type StopReason
- type StreamOptions
- type StreamWriter
- type TextContent
- type ThinkingContent
- type ThinkingDisplay
- type ToolCall
- type ToolDefinition
- type ToolResultContent
- type ToolResultMessage
- type Usage
- type UsageCost
- type UserContent
- type UserMessage
Constants ¶
const ( ProtocolOpenAICompletions = core.ProtocolOpenAICompletions ProtocolAnthropicMessages = core.ProtocolAnthropicMessages Text = core.Text Image = core.Image ModelThinkingOff = core.ModelThinkingOff ModelThinkingMinimal = core.ModelThinkingMinimal ModelThinkingLow = core.ModelThinkingLow ModelThinkingMedium = core.ModelThinkingMedium ModelThinkingHigh = core.ModelThinkingHigh ModelThinkingXHigh = core.ModelThinkingXHigh ThinkingDisplaySummarized = core.ThinkingDisplaySummarized ThinkingDisplayOmitted = core.ThinkingDisplayOmitted AnthropicToolChoiceAuto = core.AnthropicToolChoiceAuto AnthropicToolChoiceAny = core.AnthropicToolChoiceAny AnthropicToolChoiceNone = core.AnthropicToolChoiceNone OpenAIToolChoiceAuto = core.OpenAIToolChoiceAuto OpenAIToolChoiceNone = core.OpenAIToolChoiceNone OpenAIToolChoiceRequired = core.OpenAIToolChoiceRequired StopReasonStop = core.StopReasonStop StopReasonLength = core.StopReasonLength StopReasonToolUse = core.StopReasonToolUse StopReasonError = core.StopReasonError StopReasonAborted = core.StopReasonAborted EventStart = core.EventStart EventTextStart = core.EventTextStart EventTextDelta = core.EventTextDelta EventTextEnd = core.EventTextEnd EventThinkingStart = core.EventThinkingStart EventThinkingDelta = core.EventThinkingDelta EventThinkingEnd = core.EventThinkingEnd EventToolCallStart = core.EventToolCallStart EventToolCallDelta = core.EventToolCallDelta EventToolCallEnd = core.EventToolCallEnd EventDone = core.EventDone EventError = core.EventError )
const ( ArgumentsStrict = core.ArgumentsStrict ArgumentsRepaired = core.ArgumentsRepaired ArgumentsPartial = core.ArgumentsPartial ArgumentsInvalid = core.ArgumentsInvalid DiagnosticToolArgumentsRecovered = core.DiagnosticToolArgumentsRecovered )
Variables ¶
This section is empty.
Functions ¶
func DecodeToolCall ¶
func DecodeToolCall[T any](tool ToolDefinition, call ToolCall) (T, error)
DecodeToolCall validates and coerces call arguments with tool's schema, then decodes them into T. The original ToolCall is not modified.
func GetProviders ¶
func GetProviders() []string
GetProviders returns the provider IDs in the built-in model catalog.
func IsContextOverflow ¶
func IsContextOverflow(message AssistantMessage, contextWindow int64) bool
IsContextOverflow reports whether a response indicates a context overflow.
func ParseToolArguments ¶
ParseToolArguments parses streamed tool argument JSON on a best-effort basis, repairing malformed string escapes and closing truncated input. It always returns a non-nil map, falling back to an empty object when nothing can be salvaged, so a recoverable but invalid tool call never aborts the stream. Enforce correctness separately with ValidateToolArguments before dispatching.
func RegisterBuiltins ¶ added in v0.2.0
func RegisterBuiltins(registry *Registry)
RegisterBuiltins registers the OpenAI-compatible and Anthropic adapters into registry, so a custom client keeps the built-in protocols alongside any added ones.
func Stream ¶
func Stream(ctx context.Context, model Model, input Context, options StreamOptions) (<-chan Event, error)
Stream uses the default client to start a streaming model request.
func ValidateToolArguments ¶
func ValidateToolArguments(tool ToolDefinition, toolCall ToolCall) (map[string]any, error)
ValidateToolArguments validates and coerces one tool call against tool.
func ValidateToolCall ¶
func ValidateToolCall(tools []ToolDefinition, toolCall ToolCall) (map[string]any, error)
ValidateToolCall validates and coerces a tool call against its definition.
Types ¶
type AnthropicMessagesCompatibility ¶
type AnthropicMessagesCompatibility = core.AnthropicMessagesCompatibility
Core conversation, model, and streaming types are aliases so callers only need this package.
type AnthropicStreamOptions ¶ added in v0.2.0
type AnthropicStreamOptions = core.AnthropicStreamOptions
Core conversation, model, and streaming types are aliases so callers only need this package.
type AnthropicToolChoice ¶ added in v0.2.0
type AnthropicToolChoice = core.AnthropicToolChoice
Core conversation, model, and streaming types are aliases so callers only need this package.
type AnthropicToolChoiceMode ¶ added in v0.2.0
type AnthropicToolChoiceMode = core.AnthropicToolChoiceMode
Core conversation, model, and streaming types are aliases so callers only need this package.
type AnthropicToolChoiceTool ¶ added in v0.2.0
type AnthropicToolChoiceTool = core.AnthropicToolChoiceTool
Core conversation, model, and streaming types are aliases so callers only need this package.
type ArgumentsMode ¶ added in v0.2.0
type ArgumentsMode = core.ArgumentsMode
Tool-related conversation types are aliased here so callers only need this package.
func ParseToolArgumentsMode ¶ added in v0.2.0
func ParseToolArgumentsMode(raw string) (map[string]any, ArgumentsMode)
ParseToolArgumentsMode is ParseToolArguments with the recovery mode it used, so a caller can decline to execute a tool whose arguments were not strictly parsed (ArgumentsPartial or ArgumentsInvalid).
type AssistantContent ¶
type AssistantContent = core.AssistantContent
Core conversation, model, and streaming types are aliases so callers only need this package.
type AssistantMessage ¶
type AssistantMessage = core.AssistantMessage
Core conversation, model, and streaming types are aliases so callers only need this package.
func Complete ¶
func Complete(ctx context.Context, model Model, input Context, options StreamOptions) (AssistantMessage, error)
Complete uses the default client and returns the final assistant message.
type Client ¶
Core conversation, model, and streaming types are aliases so callers only need this package.
func NewClient ¶
func NewClient() *Client
NewClient returns an isolated client with all built-in protocol adapters registered. Most callers can use the package-level Stream and Complete functions instead.
func NewClientWithRegistry ¶ added in v0.2.0
NewClientWithRegistry returns a client backed by the given registry. Combine it with NewRegistry, RegisterBuiltins, and Registry.Register to serve a custom ProtocolAdapter.
type Context ¶
Core conversation, model, and streaming types are aliases so callers only need this package.
type Diagnostic ¶ added in v0.2.0
type Diagnostic = core.Diagnostic
Core conversation, model, and streaming types are aliases so callers only need this package.
type Event ¶
Core conversation, model, and streaming types are aliases so callers only need this package.
type EventType ¶
Core conversation, model, and streaming types are aliases so callers only need this package.
type ImageContent ¶
type ImageContent = core.ImageContent
Core conversation, model, and streaming types are aliases so callers only need this package.
type Message ¶
Core conversation, model, and streaming types are aliases so callers only need this package.
type Model ¶
Core conversation, model, and streaming types are aliases so callers only need this package.
func LookupModel ¶
LookupModel returns a model from the built-in catalog.
type ModelCompatibility ¶
type ModelCompatibility = core.ModelCompatibility
Core conversation, model, and streaming types are aliases so callers only need this package.
type ModelCost ¶
Core conversation, model, and streaming types are aliases so callers only need this package.
type ModelInput ¶
type ModelInput = core.ModelInput
Core conversation, model, and streaming types are aliases so callers only need this package.
type ModelThinkingLevel ¶
type ModelThinkingLevel = core.ModelThinkingLevel
Core conversation, model, and streaming types are aliases so callers only need this package.
func ClampThinkingLevel ¶
func ClampThinkingLevel(model Model, level ModelThinkingLevel) ModelThinkingLevel
ClampThinkingLevel returns the nearest reasoning level accepted by model.
func SupportedThinkingLevels ¶
func SupportedThinkingLevels(model Model) []ModelThinkingLevel
SupportedThinkingLevels returns the reasoning levels accepted by model.
type OpenAICompletionsCompatibility ¶
type OpenAICompletionsCompatibility = core.OpenAICompletionsCompatibility
Core conversation, model, and streaming types are aliases so callers only need this package.
type OpenAICompletionsStreamOptions ¶ added in v0.2.0
type OpenAICompletionsStreamOptions = core.OpenAICompletionsStreamOptions
Core conversation, model, and streaming types are aliases so callers only need this package.
type OpenAIToolChoice ¶ added in v0.2.0
type OpenAIToolChoice = core.OpenAIToolChoice
Core conversation, model, and streaming types are aliases so callers only need this package.
type OpenAIToolChoiceFunction ¶ added in v0.2.0
type OpenAIToolChoiceFunction = core.OpenAIToolChoiceFunction
Core conversation, model, and streaming types are aliases so callers only need this package.
type OpenAIToolChoiceMode ¶ added in v0.2.0
type OpenAIToolChoiceMode = core.OpenAIToolChoiceMode
Core conversation, model, and streaming types are aliases so callers only need this package.
type Protocol ¶
Core conversation, model, and streaming types are aliases so callers only need this package.
type ProtocolAdapter ¶ added in v0.2.0
type ProtocolAdapter = core.ProtocolAdapter
Core conversation, model, and streaming types are aliases so callers only need this package.
type ProtocolStreamOptions ¶ added in v0.2.0
type ProtocolStreamOptions = core.ProtocolStreamOptions
Core conversation, model, and streaming types are aliases so callers only need this package.
type ProviderEnv ¶
type ProviderEnv = core.ProviderEnv
Core conversation, model, and streaming types are aliases so callers only need this package.
type Registry ¶ added in v0.2.0
Extension points for registering a custom protocol adapter.
func NewRegistry ¶ added in v0.2.0
func NewRegistry() *Registry
NewRegistry returns an empty protocol-adapter registry. Use it with RegisterBuiltins and Register to assemble a client that also serves a custom protocol. Most callers want NewClient instead.
type StopReason ¶
type StopReason = core.StopReason
Core conversation, model, and streaming types are aliases so callers only need this package.
type StreamOptions ¶
type StreamOptions = core.StreamOptions
Core conversation, model, and streaming types are aliases so callers only need this package.
type StreamWriter ¶ added in v0.2.0
type StreamWriter = core.StreamWriter
Core conversation, model, and streaming types are aliases so callers only need this package.
func NewStreamWriter ¶ added in v0.2.0
func NewStreamWriter(ctx context.Context, events chan<- Event, output *AssistantMessage) *StreamWriter
NewStreamWriter helps a custom ProtocolAdapter emit a well-formed event stream: it sends a single EventStart, attaches a Partial snapshot to each event, guarantees one terminal event, and turns context cancellation into an aborted terminal error. output is the assistant message the adapter builds.
type TextContent ¶
type TextContent = core.TextContent
Core conversation, model, and streaming types are aliases so callers only need this package.
type ThinkingContent ¶
type ThinkingContent = core.ThinkingContent
Core conversation, model, and streaming types are aliases so callers only need this package.
type ThinkingDisplay ¶ added in v0.2.0
type ThinkingDisplay = core.ThinkingDisplay
Core conversation, model, and streaming types are aliases so callers only need this package.
type ToolCall ¶
Tool-related conversation types are aliased here so callers only need this package.
func CloneToolCall ¶ added in v0.2.0
CloneToolCall returns a deep copy of a tool call for use in an event's ToolCall field while streaming.
type ToolDefinition ¶
type ToolDefinition = core.ToolDefinition
Tool-related conversation types are aliased here so callers only need this package.
func MustTool ¶
func MustTool[T any](name, description string) ToolDefinition
MustTool is NewTool for statically declared tools. It panics when the tool name or argument type cannot produce a valid definition.
func NewTool ¶
func NewTool[T any](name, description string) (ToolDefinition, error)
NewTool creates a tool definition whose parameters are generated from T. T must be a struct or pointer to a struct. Fields without json omitempty are required, and jsonschema tags can add descriptions, enums, and constraints.
type ToolResultContent ¶
type ToolResultContent = core.ToolResultContent
Tool-related conversation types are aliased here so callers only need this package.
type ToolResultMessage ¶
type ToolResultMessage = core.ToolResultMessage
Tool-related conversation types are aliased here so callers only need this package.
type Usage ¶
Core conversation, model, and streaming types are aliases so callers only need this package.
type UsageCost ¶
Core conversation, model, and streaming types are aliases so callers only need this package.
func CalculateCost ¶
CalculateCost calculates the model cost for usage.
type UserContent ¶
type UserContent = core.UserContent
Core conversation, model, and streaming types are aliases so callers only need this package.
type UserMessage ¶
type UserMessage = core.UserMessage
Core conversation, model, and streaming types are aliases so callers only need this package.