Documentation
¶
Overview ¶
Package llm is a multi-provider Go SDK for LLM inference endpoints: OpenAI, Google Gemini, DeepSeek, Z.ai, Kimi (Moonshot) and Anthropic, plus any custom OpenAI-compatible gateway.
Design highlights:
- Multiple authenticated endpoints simultaneously, discovered from the environment via <PROVIDER>_API_KEY (aliases supported).
- Dynamic model discovery (ListModels) — no static model profile tables.
- One canonical request/response shape (OpenAI-compatible); Anthropic and Gemini formats are translated by per-format serializers.
- Zero external dependencies: stdlib only.
- Streaming with idle watchdog, hard wall-clock deadline, abort-with- partial-result, and retries that never duplicate partial output.
Index ¶
- Constants
- Variables
- func SetStreamIdleTimeout(d time.Duration)
- func StreamIdleTimeout() time.Duration
- type APIError
- type ChatClient
- func (c *ChatClient) Call(ctx context.Context, req *ChatRequest) (*ChatResult, error)
- func (c *ChatClient) CallStream(ctx context.Context, req *ChatRequest, onDelta func(Delta) error) (*ChatResult, error)
- func (c *ChatClient) Model() string
- func (c *ChatClient) ProviderID() string
- func (c *ChatClient) RequestTimeout() time.Duration
- func (c *ChatClient) SetRequestTimeout(d time.Duration)
- type ChatRequest
- type ChatResult
- type ConfigError
- type Delta
- type DeltaKind
- type Format
- type ListOption
- type Message
- type Model
- type Option
- type Provider
- type ProviderConfig
- type ProviderOption
- type Quirks
- type RateLimitError
- type Role
- type SDK
- type StreamAbortedError
- type SystemBlock
- type ToolCall
- type ToolDef
- type Usage
Constants ¶
const ( FinishStop = "stop" FinishLength = "length" FinishToolCalls = "tool_calls" FinishContentFilter = "content_filter" )
Canonical finish reasons.
const (
DefaultTimeout = 120 * time.Second
)
Transport tuning defaults, shared by every provider client an SDK builds.
Variables ¶
var ErrIdleTimeout = errors.New("llm: stream idle timeout")
ErrIdleTimeout is returned (with the partial result) when a stream goes silent longer than the idle watchdog after the first delta has been emitted. Before the first delta, idle timeouts are retried instead.
Functions ¶
func SetStreamIdleTimeout ¶ added in v0.2.1
SetStreamIdleTimeout overrides the SSE idle watchdog. Call at startup, before the first request; non-positive values are ignored.
func StreamIdleTimeout ¶ added in v0.2.1
StreamIdleTimeout reports the active idle watchdog (introspection/tests).
Types ¶
type APIError ¶
APIError is a non-2xx provider response. Status 0 with a non-nil underlying error form is not used; network failures surface as plain wrapped errors. Message is the provider's own error text when parseable. API keys are never included in any error text.
type ChatClient ¶
type ChatClient struct {
// contains filtered or unexported fields
}
ChatClient runs chat completions against one provider+model pair. Each client carries its own learn-once fallbacks and request timeout; it is safe for concurrent use but SetRequestTimeout must be called before the first request.
func (*ChatClient) Call ¶
func (c *ChatClient) Call(ctx context.Context, req *ChatRequest) (*ChatResult, error)
Call runs a buffered chat completion.
func (*ChatClient) CallStream ¶
func (c *ChatClient) CallStream(ctx context.Context, req *ChatRequest, onDelta func(Delta) error) (*ChatResult, error)
CallStream runs a streaming chat completion. onDelta receives canonical fragments; returning an error from it aborts generation — CallStream then returns the partial result alongside *StreamAbortedError.
func (*ChatClient) ProviderID ¶
func (c *ChatClient) ProviderID() string
ProviderID returns the bound provider's id.
func (*ChatClient) RequestTimeout ¶
func (c *ChatClient) RequestTimeout() time.Duration
RequestTimeout reports the per-request timeout (streaming wall-clock deadline).
func (*ChatClient) SetRequestTimeout ¶
func (c *ChatClient) SetRequestTimeout(d time.Duration)
SetRequestTimeout adjusts the per-request timeout. Call before the first request.
type ChatRequest ¶
type ChatRequest struct {
Model string
Messages []Message
System []SystemBlock
Tools []ToolDef
Thinking string
ThinkingBudget int
MaxTokens int
Temperature float64
}
ChatRequest is the canonical request. Model is filled from the ChatClient when empty. Thinking accepts "", "enabled", "disabled", "low", "medium", "high", "max" and is translated per provider format. Temperature: 0 means use the provider default (field omitted); use a negative value to explicitly send 0.
type ChatResult ¶
type ChatResult struct {
Content string
ReasoningContent string
// ThinkingSignature authenticates ReasoningContent (Anthropic extended
// thinking). Consumers must carry it back on the next assistant Message
// for tool loops to stay valid.
ThinkingSignature string
ToolCalls []ToolCall
FinishReason string
Usage Usage
}
ChatResult is the canonical response for both buffered and streaming calls.
type ConfigError ¶
type ConfigError struct{ Msg string }
ConfigError reports SDK misuse: unknown provider id, provider without an API key, or malformed options. Never retryable.
func (*ConfigError) Error ¶
func (e *ConfigError) Error() string
type Delta ¶
Delta is one streamed fragment. Text is the fragment for this event, not accumulated output.
type DeltaKind ¶
type DeltaKind int
DeltaKind discriminates streamed fragments.
const ( // DeltaReasoning is a thinking/reasoning fragment, usually before content. DeltaReasoning DeltaKind = iota // DeltaContent is an assistant text fragment. DeltaContent // DeltaToolArgs is a tool-call argument fragment (partial JSON). ToolIndex // and, on the first fragment of a call, ToolID/ToolName identify the call. DeltaToolArgs )
type Format ¶
type Format string
Format identifies a wire protocol family. The SDK translates the single canonical request shape into exactly one of these.
const ( // FormatOpenAI is the OpenAI chat-completions protocol — also spoken by // DeepSeek, Z.ai (GLM), Kimi/Moonshot and most self-hosted gateways. FormatOpenAI Format = "openai" // FormatAnthropic is the Anthropic Messages API. FormatAnthropic Format = "anthropic" // FormatGemini is the Google Gemini generateContent API. FormatGemini Format = "gemini" )
type ListOption ¶
type ListOption func(*listOpts)
ListOption tweaks ListModels.
func ForceRefresh ¶
func ForceRefresh() ListOption
ForceRefresh bypasses the model cache for this call and refreshes it.
type Message ¶
type Message struct {
Role Role
Content string
ReasoningContent string
// ThinkingSignature authenticates ReasoningContent for providers that
// require thinking to be replayed verbatim (Anthropic signature).
ThinkingSignature string
ToolCalls []ToolCall
ToolCallID string
ToolName string
// Cache marks this user message for Anthropic prompt caching
// (cache_control ephemeral on the text block). Ignored on other
// formats and on non-user roles.
Cache bool
}
Message is one canonical chat message. For RoleTool messages, ToolCallID and ToolName identify the call being answered and Content carries the tool result. ReasoningContent is provider-reported thinking text (deepseek-reasoner, anthropic thinking, gemini thoughts). The SDK replays it where a provider requires conversation continuity: OpenAI-format assistant messages echo it as reasoning_content (DeepSeek/GLM tool loops), and Anthropic re-serializes a signed thinking block as the first content block when ThinkingSignature is also set.
type Model ¶
type Model struct {
ID string
DisplayName string
CreatedAt time.Time
ContextWindow int // input token limit, 0 = unknown
MaxOutputTokens int // 0 = unknown
Capabilities []string
}
Model is one accessible model, as reported by a provider's models endpoint. Fields the provider does not report stay zero — the SDK never guesses.
type Option ¶
type Option func(*SDK)
Option configures an SDK at construction time.
func FromEnv ¶
func FromEnv() Option
FromEnv resolves <PROVIDER>_API_KEY (aliases included, primary first) and optional <PROVIDER>_BASE_URL overrides via os.LookupEnv. Providers without a key stay registered but unauthenticated.
func WithEnv ¶
WithEnv resolves API keys and base-URL overrides from the environment using lookup — the testable twin of FromEnv.
func WithModelCacheTTL ¶
WithModelCacheTTL sets the ListModels cache TTL. Zero disables caching — every call hits the provider's models endpoint.
func WithProvider ¶
func WithProvider(id string, popts ...ProviderOption) Option
WithProvider configures one provider — a built-in id (override) or a new custom provider (requires WithFormat and WithBaseURL, plus auth).
func WithRequestTimeout ¶
WithRequestTimeout sets the default per-request timeout for all chat clients (default 120s). Streaming calls use it as the hard wall-clock deadline.
func WithTransport ¶
func WithTransport(rt http.RoundTripper) Option
WithTransport replaces the SDK's pooled HTTP transport (tests, proxies).
type Provider ¶
type Provider struct {
// contains filtered or unexported fields
}
Provider is one configured endpoint with dynamic model discovery.
func (*Provider) Authenticated ¶
Authenticated reports whether an API key resolved.
func (*Provider) Config ¶
func (p *Provider) Config() ProviderConfig
Config returns the provider configuration. The copy carries the API key: treat it as a secret; it is never logged by the SDK itself.
func (*Provider) ListModels ¶
ListModels discovers the models accessible to this provider's account, on the fly — no static tables. Results are cached per SDK instance for the cache TTL (default 5 min; WithModelCacheTTL(0) disables). Fields the provider does not report stay zero.
type ProviderConfig ¶
type ProviderConfig struct {
ID string
Format Format
BaseURL string
APIKey string
// EnvKeys lists environment variable names to consult, primary first
// (aliases after). Resolution stops at the first non-empty value.
EnvKeys []string
Quirks Quirks
}
ProviderConfig fully describes one inference endpoint. APIKey is resolved from EnvKeys (primary first) or set explicitly; it is never included in error text, logs, or String() output.
func (ProviderConfig) String ¶
func (c ProviderConfig) String() string
type ProviderOption ¶
type ProviderOption func(*ProviderConfig)
ProviderOption configures one provider entry.
func WithAPIKey ¶
func WithAPIKey(key string) ProviderOption
WithAPIKey sets an explicit API key (overrides env).
func WithBaseURL ¶
func WithBaseURL(url string) ProviderOption
WithBaseURL overrides the provider's default base URL.
func WithEnvKeys ¶
func WithEnvKeys(keys ...string) ProviderOption
WithEnvKeys sets env var names consulted for this provider's key, primary first.
func WithFormat ¶
func WithFormat(f Format) ProviderOption
WithFormat sets the wire format (custom providers).
func WithQuirks ¶
func WithQuirks(q Quirks) ProviderOption
WithQuirks overrides protocol quirk flags.
type Quirks ¶
type Quirks struct {
// ThinkingObject: provider accepts the Anthropic-style top-level
// "thinking" object (Anthropic, DeepSeek, Z.ai GLM).
ThinkingObject bool
// ReasoningEffort: provider accepts reasoning_effort (OpenAI, GLM-5.3+).
ReasoningEffort bool
// ForceThinking lists model-name prefixes that reject
// thinking.type=disabled outright (GLM-5.3 always reasons; the
// documented migration is {type: enabled} + reasoning_effort "low").
ForceThinking []string
// AnthropicVersion is the anthropic-version header value required by
// FormatAnthropic providers ("2023-06-01").
AnthropicVersion string
}
Quirks carries per-provider protocol deviations, resolved at registration time. This replaces odek's URL-sniffing: a custom base URL gets its format's default quirks unless the caller overrides them explicitly.
type RateLimitError ¶
RateLimitError is the final failure after persistent 429 responses. RetryAfter carries the last observed Retry-After hint (0 if none).
func (*RateLimitError) Error ¶
func (e *RateLimitError) Error() string
func (*RateLimitError) Unwrap ¶
func (e *RateLimitError) Unwrap() error
Unwrap exposes the embedded APIError so errors.As(err, *APIError) reaches Status/Retryable without a type switch.
type SDK ¶
type SDK struct {
// contains filtered or unexported fields
}
SDK is a configured set of LLM endpoints. Build one with New and options:
sdk := llm.New(llm.FromEnv())
Providers are authenticated when an API key resolves from the environment or is set explicitly; every authenticated provider is usable concurrently through the SDK's shared connection pool.
func New ¶
New builds an SDK with the built-in provider registry and the given options. Options apply in order; later WithProvider calls for the same id override earlier ones.
func (*SDK) Chat ¶
func (s *SDK) Chat(providerID, model string) (*ChatClient, error)
Chat returns a chat client bound to a provider and model.
type StreamAbortedError ¶
type StreamAbortedError struct{ Reason error }
StreamAbortedError is returned by CallStream when the delta handler aborted generation. CallStream also returns the partial ChatResult assembled so far alongside this error.
func (*StreamAbortedError) Error ¶
func (e *StreamAbortedError) Error() string
func (*StreamAbortedError) Unwrap ¶
func (e *StreamAbortedError) Unwrap() error
type SystemBlock ¶
SystemBlock is one system-prompt segment. On Anthropic each block maps to a system text block (Cache marks it for prompt caching); on OpenAI-format providers blocks concatenate into a leading system message; on Gemini they become systemInstruction parts.
type ToolDef ¶
type ToolDef struct {
Name string
Description string
Parameters json.RawMessage
}
ToolDef declares a callable tool. Parameters is a JSON Schema object (json.RawMessage so callers can pass through marshaled schemas verbatim).
type Usage ¶
type Usage struct {
PromptTokens int
CompletionTokens int
ReasoningTokens int
CacheReadTokens int
CacheCreationTokens int
CachedTokens int
CacheReported bool
}
Usage reports token accounting. Fields the provider does not report stay 0. PromptTokens is exclusive (uncached-only) after provider-specific normalization: OpenAI cached_tokens and DeepSeek hit/miss are subsets of prompt_tokens and are subtracted; Anthropic reports cache volumes exclusively and is left alone. Cache volumes live in the cache fields so budget enforcement can sum without double-counting.