llm

package module
v0.3.7 Latest Latest
Warning

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

Go to latest
Published: Oct 29, 2026 License: MIT Imports: 21 Imported by: 1

README

llm-go

llm-go is a provider-neutral Go library for model generation, streaming, tool use, multimodal messages, reasoning, and usage accounting. Provider SDK types stay behind a small common API, so applications can switch protocols without changing their conversation model.

Requires Go 1.27 or newer. The public API is still under active development.

Highlights

  • One request, response, tool, error, and model contract across providers
  • Synchronous generation and lifecycle-safe streaming with typed events
  • Multi-turn reasoning replay, prompt caching, and usage/cost accounting
  • JSON Schema coercion and validation, plus tolerant JSON repair helpers
  • Immutable model catalogs, provider profiles, and extensible protocol factories
  • Concurrency-safe credentials, OAuth refresh, retries, and token budgeting
  • Caller-owned HTTP clients, contexts, and returned data

Install

go get github.com/XiaoConstantine/llm-go

Protocols and providers

llm-go separates wire-protocol adapters from model and provider metadata. Every adapter supports generation, typed stream events, classified errors, and token usage. In the matrix below, ✓ means the adapter implements the feature and — means it does not. Model-scoped features must still be declared by the configured model; a ✓ does not imply that every model exposed by an endpoint supports it.

Package / protocol Streaming Background Tools JSON mode Image input Audio input Reasoning Cache tokens Authentication
openai/responses · OpenAI Responses ✓ ✓ ✓ ✓ ✓ — Summaries and encrypted replay Read/write API key
openai/azure · Azure OpenAI Responses ✓ — ✓ ✓ ✓ — Summaries and encrypted replay Read/write Azure API key
openai · OpenAI-compatible Chat Completions ✓ — ✓ ✓ ✓ WAV/MP3 input Controls and provider-state replay Read/write API key or custom headers
openai/codex · ChatGPT subscription Codex Responses ✓ — ✓ — ✓ WAV/MP3/M4A/WebM/Ogg input Summaries and encrypted replay Read/write Access token or credential resolver
anthropic · Anthropic-compatible Messages ✓ — ✓ — ✓ — Signed thinking replay Read/write, including 1h writes API key, OAuth token, or custom headers
gemini · Gemini Developer API ✓ — ✓ ✓ ✓ ✓ Controls and thought-signature replay Read API key
vertex · Google Vertex AI ✓ — ✓ ✓ ✓ ✓ Controls and thought-signature replay Read API key, ADC, or authenticated HTTP client
bedrock · Amazon Bedrock ConverseStream ✓ — ✓ — ✓ — Controls and signed replay Read/write AWS credentials, profile, bearer token, or unauthenticated gateway
mistral · Mistral Conversations ✓ — ✓ — ✓ — Thinking blocks and controls — API key

JSON mode refers to llm.ResponseFormatJSON, not tool argument schemas. Tool calls work in generation and streaming, including partial argument events where the protocol exposes them. Strict tools and reasoning replay are model- and protocol-dependent. Cache retention markers are emitted only where supported; unsupported cache keys and session-affinity mappings fail before provider I/O. OpenAI Responses also supports durable background jobs through llm.BackgroundGenerator.

Codex transport modes

openai/codex.Config.Transport supports these modes; the default remains SSE.

Mode Behavior
TransportSSE Original HTTP event stream
TransportWebSocket Transient socket with full context; never falls back to SSE
TransportWebSocketCached Session socket with verified incremental context; never falls back to SSE
TransportAuto Cached WebSocket when possible; SSE fallback only when connect or handshake fails before response.create

Cached sockets require Request.SessionID, are isolated by client, session, account, and credential. WebSocketMaxSessions defaults to 64; busy overflow and requests with per-attempt headers use transient sockets. Use WebSocketDialer for WebSocket-specific proxy, mTLS, or custom dialing. Client.Close is idempotent and closes all owned sockets and timers.

Portable orchestration helpers

These helpers are opt-in and do not change provider defaults.

API Purpose
llm.WithRetry Bounded retries; streams retry only before their first chunk; attempt hooks may add validated headers
llm.Collect Closes and assembles a stream, preserving partial results and validating completed calls against supplied schemas
llm.CollectStructural Collects with structure and strict-JSON checks, leaving argument-schema validation to the execution owner
llm.Tool.Strictness Requests prefer or require constrained tool arguments while retaining legacy Tool.Strict behavior
llm.TransformHistory Owns cross-model history, normalizes tool IDs, repairs missing/orphaned results, and reports every change
llm.BudgetRequest Uses a caller-supplied token estimator and model limits to clamp an owned request copy
llm.ValidateToolArguments Coerces model-generated arguments through JSON Schema, then validates and returns an owned value
llm.IsContextOverflow Detects classified, explicit, and silent context-window overflow
llm.RepairJSON / llm.ParseStreamingJSON Repairs malformed string escapes and reads partial streaming JSON

Tool inputs use JSON Schema 2020-12 by default, support declared drafts and local references offline, and use Go/RE2-compatible patterns.

Generate, Stream, background responses, and CollectStructural(stream) return complete, structurally valid tool calls with their original arguments. They do not enforce argument schemas. Execution owners must call ValidateToolCalls(tools, calls) before invoking tools and can return an error ToolResult on rejection so the model can correct its call. Tool declarations, strict JSON, provider protocol checks, and constrained-generation settings are unchanged. ValidateToolCallStream remains an explicit schema-validation wrapper for callers that deliberately want schema failures to terminate collection.

Migration: automatic response argument-schema validation has been removed. Collect(stream, tools) retains its published signature and schema-validation behavior, including rejection of undeclared calls when tools is nil. Agent loops that need corrective tool results can use CollectStructural(stream) and validate arguments explicitly at the execution boundary. No request flag or diagnostic metadata is needed; do not execute an unchecked call just because generation succeeded.

Custom protocols and dynamic catalogs

models.NewFactoryRegistry creates an immutable registry containing the nine built-in protocol factories plus caller registrations. ProviderConfig.API remains the default route when ModelInfo.API is empty; AdditionalAPIs explicitly enables mixed-protocol models for the same provider. Factories receive owned construction snapshots and an optional live credential resolver.

models.CatalogManager keeps Catalog immutable while atomically publishing a static baseline plus validated provider overlays. Refresh restores persisted state before conditional fetches, supports ETag/Last-Modified, force and provider-selective refresh, and NoNetwork restore-only operation. Available uses CredentialManager and optional secret-free provider filters. Refreshes run only when called; the manager owns no permanent goroutines and needs no Close. The modelsdev package provides a CatalogSource implementation to dynamically fetch models from models.dev.

Built-in provider profiles

models.BuiltinProvider supplies protocol and endpoint defaults for these services:

Provider ID Protocol Default endpoint
openrouter OpenAI Chat Completions https://openrouter.ai/api/v1
groq OpenAI Chat Completions https://api.groq.com/openai/v1
deepseek OpenAI Chat Completions https://api.deepseek.com
xai OpenAI Responses https://api.x.ai/v1
cerebras OpenAI Chat Completions https://api.cerebras.ai/v1
fireworks OpenAI Chat Completions https://api.fireworks.ai/inference/v1
mistral Mistral Conversations https://api.mistral.ai/v1
google-vertex Google Vertex AI SDK-derived regional endpoint
amazon-bedrock Bedrock ConverseStream https://bedrock-runtime.us-east-1.amazonaws.com
Local and compatible servers

Local servers that expose an OpenAI-compatible /v1/chat/completions endpoint use the openai adapter. They do not need a built-in profile, and the adapter permits an empty API key; authenticated servers can instead use an API key or custom headers.

Server Typical BaseURL Support
Ollama http://localhost:11434/v1 OpenAI-compatible endpoint; the native /api/chat API is not implemented
llama.cpp llama-server http://localhost:8080/v1 OpenAI-compatible endpoint

Choose a provider ID, configure models.OpenAIChatCompletions, and supply the local model through llm.ModelInfo. Streaming, tools, JSON mode, vision, and reasoning depend on what that server and model implement, so declare only the capabilities they actually support. The same configuration works for other compatible servers.

The built-in catalog covers OpenAI, Anthropic, Amazon Bedrock, Gemini, Vertex AI, Mistral, Codex, and the OpenAI-compatible profiled providers. Azure Responses uses caller-supplied model metadata. Custom BaseURL, headers, and HTTP clients support compatible gateways.

Quick start

The generated catalog can configure the protocol, capabilities, compatibility, and pricing for a model:

package main

import (
    "context"
    "log"
    "os"
    "time"

    llm "github.com/XiaoConstantine/llm-go"
    "github.com/XiaoConstantine/llm-go/models"
)

func main() {
    model, ok := models.BuiltinCatalog().Model("openai", "gpt-5-mini")
    if !ok {
        log.Fatal("model not found")
    }

    providers, err := models.New(models.ProviderConfig{
        ID:     "openai",
        API:    models.OpenAIResponses,
        APIKey: os.Getenv("OPENAI_API_KEY"),
    })
    if err != nil {
        log.Fatal(err)
    }

    generator, err := providers.GeneratorFor(model)
    if err != nil {
        log.Fatal(err)
    }

    ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
    defer cancel()

    response, err := generator.Generate(ctx, llm.Request{
        Messages: []llm.Message{{
            Role:    llm.RoleUser,
            Content: []llm.Part{{Text: "Say hello in one sentence."}},
        }},
    })
    if err != nil {
        log.Fatal(err)
    }
    log.Print(response.Text())
}

Concrete provider packages can also be constructed directly when protocol-level configuration is needed.

Streaming

Every successful stream must be closed, including after Recv returns an error. Close is idempotent, unblocks a pending Recv, and waits for transport cleanup. A cleanup error returned by Close does not replace the stream's sticky terminal state.

stream, err := generator.Stream(ctx, request)
if err != nil {
    return err
}

for {
    chunk, recvErr := stream.Recv()
    if errors.Is(recvErr, io.EOF) {
        break
    }
    if recvErr != nil {
        _ = stream.Close()
        return recvErr
    }
    for _, part := range chunk.Content {
        fmt.Print(part.Text)
    }
}
if err := stream.Close(); err != nil {
    return err
}

Chunk.Events exposes typed lifecycle events for text, reasoning, and partial or completed tool calls. Completed values remain available through the ordinary chunk fields for response assembly.

Errors and cancellation

Provider and protocol failures are classified as *llm.Error. Context cancellation, deadlines, custom cancellation causes, and underlying transport errors remain discoverable with errors.Is or errors.As. llm.IsContextOverflow handles both classified failures and providers that silently fill or truncate the context window.

The library does not impose a default request timeout. Supply an appropriate context deadline or configure the provided http.Client.

Model catalogs and credentials

models.BuiltinCatalog() returns an immutable generated catalog whose read methods return independently owned model metadata. models.Catalog and models.Collection are immutable and safe for concurrent use when caller-supplied HTTP clients and credential resolvers are also safe.

models.CredentialStore supports API-key and OAuth credentials. models.MemoryCredentialStore provides an in-memory implementation, while models.CredentialManager coalesces concurrent refreshes, supports live credential rotation for long-lived generators, and safely handles token rotation. models.AnthropicOAuth and models.CodexOAuth expose non-interactive PKCE exchange/refresh primitives. Their subscription endpoints and client IDs are provider-private, unofficial, unstable, and replaceable; applications remain responsible for browser, callback, prompt UI, and persistent storage.

models.FindEnvAPIKeys lists configured variables in precedence order, models.EnvAPIKey returns the preferred value, and models.HasAmbientCredentials reports selected Vertex ADC and Bedrock environment or file hints without exposing secrets.

Development

make fmt       # Format Go sources.
make fmt-check # Check formatting without changing files.
make lint      # Run the pinned golangci-lint version used by CI.
go test ./...
go test -race ./...
go vet ./...

The built-in catalog source is models/catalogsource/catalog.json. Regenerate and verify it with:

go generate ./models
git diff --exit-code -- models/catalog_generated.go

The Update model catalog GitHub Actions workflow checks models.dev every six hours and opens a tested pull request for Anthropic, direct OpenAI, and Google catalog updates. New entries must advertise tool support and text-only output; other model types and Codex subscription entries need separate maintenance. See the catalog maintenance guide for setup, manual runs, and reproducing an update from its saved snapshot.

Documentation

Overview

Package llm defines provider-neutral contracts for working with large language models in Go. It is independent of agent and prompt-programming frameworks. Provider implementations may use provider SDKs internally, but those SDK types are not part of this package's requests, responses, streams, errors, or interfaces.

Unless documented otherwise, an implementation borrows all storage reachable from a request, including slices, pointers, and JSON values, until an operation returns. For a successful streaming operation, the borrow ends when the stream is closed; if establishing the stream fails, it ends when Stream returns. Callers must not mutate borrowed storage concurrently. All storage reachable from values returned by an implementation belongs to the caller and is not mutated by the implementation after delivery.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AttemptHeaders

func AttemptHeaders(ctx context.Context) http.Header

AttemptHeaders returns an owned copy of headers supplied by the current WithRetry AttemptHook. It returns nil outside an attempt carrying headers. Custom Generator implementations may read these values for their validated transport request; mutating the result never changes retry or sibling state.

func BudgetRequest

func BudgetRequest(ctx context.Context, info ModelInfo, request Request, estimator TokenEstimator, reserve int) (Request, TokenBudget, error)

BudgetRequest returns an owned Request copy whose MaxOutputTokens fits the known context window, known model output limit, estimated input, and reserve. A zero requested output limit selects the largest computed limit. A zero model MaxOutputTokens means that limit is unknown, so only the context window bounds output. A zero ContextWindow is rejected because no safe model-aware budget can be computed. Low-level generators never call this helper implicitly.

func IsContextOverflow added in v0.3.0

func IsContextOverflow(response *Response, err error, contextWindow int) bool

IsContextOverflow reports whether a failed or successful generation indicates that its input exceeded the model context window. Built-in generators classify explicit provider failures as KindContextLimit. The message-pattern fallback supports custom generators that retain an unclassified provider error.

A positive contextWindow additionally detects providers that silently accept oversized input and providers that truncate input until no output tokens remain. response may be nil when err is non-nil.

func ParseJSONWithRepair added in v0.3.0

func ParseJSONWithRepair(value string, target any) error

ParseJSONWithRepair decodes a complete JSON value into target. It first uses strict encoding/json semantics, then retries after RepairJSON only when the input changed. target follows json.Unmarshal's pointer requirements.

func ParseStreamingJSON added in v0.3.0

func ParseStreamingJSON(value string) any

ParseStreamingJSON parses a complete or partial JSON value. It returns an empty object for empty, null, or unrecoverable input. Partial objects, arrays, strings, numbers, booleans, and null values are recovered as far as possible.

func RepairJSON added in v0.3.0

func RepairJSON(value string) string

RepairJSON repairs malformed JSON string literals by escaping raw control characters and preserving backslashes that precede invalid JSON escapes. Bytes outside string literals are unchanged.

func TransformHistory

func TransformHistory(source, target ModelInfo, history []Message) ([]Message, []TransformWarning, error)

TransformHistory creates a caller-owned history for target. ProviderData is preserved only for the exact same provider, protocol, and model because it may contain model-bound signatures or encrypted state. Unsupported image and audio parts are replaced with visible text placeholders and individually reported. OpenAI Chat tool-result images are preserved only when its explicit image fallback compatibility is enabled; tool-result audio is always converted. Tool history targeting a model without tool capability fails rather than being silently omitted. Unless source and target have the same complete identity, tool-call IDs are normalized to a target-compatible form; duplicate IDs are normalized in all cases. Missing tool results are inserted before the next non-tool turn and at the end of the transcript, orphan results are removed, and result names that conflict with their matched call are corrected. Every repair is reported. Input messages and nested storage are never modified.

func ValidateToolArguments added in v0.3.0

func ValidateToolArguments(tool Tool, call ToolCall) (any, error)

ValidateToolArguments coerces call arguments according to tool's JSON Schema, validates the converted value, and returns independently owned JSON-compatible storage. It does not modify tool, call, or nested input.

func ValidateToolCallArguments added in v0.3.0

func ValidateToolCallArguments(tools []Tool, call ToolCall) (any, error)

ValidateToolCallArguments finds call's declared tool, coerces its arguments according to the tool's JSON Schema, validates the converted value, and returns independently owned JSON-compatible storage.

func ValidateToolCallStructure added in v0.3.4

func ValidateToolCallStructure(calls []ToolCall) error

ValidateToolCallStructure checks names, identity fields, and strict JSON in completed calls without checking tool declarations or argument schemas. It does not mutate calls. Execution owners should use ValidateToolCalls to check declared names and schemas before invoking a tool.

func ValidateToolCalls

func ValidateToolCalls(tools []Tool, calls []ToolCall) error

ValidateToolCalls validates complete tool-call arguments against declared tool schemas. Partial streaming argument deltas must not be passed here. Schemas default to JSON Schema draft 2020-12 and may select draft 4, 6, 7, 2019-09, or 2020-12 with $schema. References must resolve within the supplied schema; filesystem and network loading are disabled. Pattern keywords use Go regexp syntax.

Types

type API

type API string

API identifies a provider wire protocol. Unknown nonempty values are valid so applications can describe protocols implemented outside this module.

const (
	APIAnthropicMessages     API = "anthropic-messages"
	APIOpenAIChatCompletions API = "openai-chat-completions"
	APIOpenAIResponses       API = "openai-responses"
	APIAzureOpenAIResponses  API = "azure-openai-responses"
	APIOpenAICodexResponses  API = "openai-codex-responses"
	APIGeminiGenerateContent API = "gemini-generate-content"
	APIMistralConversations  API = "mistral-conversations"
	APIGoogleVertex          API = "google-vertex"
	APIBedrockConverseStream API = "bedrock-converse-stream"
)

type AnthropicCompatibility

type AnthropicCompatibility struct {
	EagerToolInputStreaming CompatibilityToggle
	LongCacheRetention      CompatibilityToggle
	SessionAffinity         CompatibilityToggle
	CacheControlOnTools     CompatibilityToggle
	Temperature             CompatibilityToggle
	AdaptiveThinking        CompatibilityToggle
	EmptyThinkingSignature  CompatibilityToggle
	StrictTools             CompatibilityToggle
	// ToolReferences enables defer_loading definitions and tool_reference
	// result content.
	ToolReferences CompatibilityToggle
}

AnthropicCompatibility describes model-specific differences among Anthropic Messages-compatible APIs.

type Attempt

type Attempt struct {
	Operation   string
	Number      int
	MaxAttempts int
	Model       ModelInfo
}

Attempt describes one call made by a retrying Generator. Number is one-based. Model and its nested storage are a fresh copy owned by the hook and may be retained or mutated without affecting the generator.

type AttemptHook

type AttemptHook func(context.Context, Attempt) (http.Header, error)

AttemptHook is called after Request validation and immediately before each provider attempt. It may observe the attempt and return request headers, but cannot inspect, replace, or mutate the validated Request payload. Hooks may be called concurrently and therefore must be safe for concurrent use. A hook must honor ctx cancellation and return promptly so Stream.Close can unblock retry opening attempts. Returned headers are borrowed only until the hook returns and are cloned before use.

type BackgroundGenerator added in v0.2.0

type BackgroundGenerator interface {
	Generator
	StartBackground(context.Context, Request) (*BackgroundResult, error)
	FetchBackground(context.Context, BackgroundHandle) (*BackgroundResult, error)
	CancelBackground(context.Context, BackgroundHandle) (*BackgroundResult, error)
}

BackgroundGenerator starts, fetches, and cancels durable provider-side generations. A handle passed to FetchBackground or CancelBackground must match the provider, model, and API reported by Info. Implementations validate requests and handles before I/O and are safe for concurrent use. A failed provider generation returns a result with BackgroundFailed together with its provider error. Malformed output or cancellation that races with an observed provider response may also return its handle and status with an error; transport errors before a response is observed return a nil result.

type BackgroundHandle added in v0.2.0

type BackgroundHandle struct {
	Provider       string
	Model          string
	API            API
	ID             string
	Tools          []Tool
	ResponseFormat ResponseFormat
}

BackgroundHandle contains the durable identity and output-validation contract for a provider-side generation. Tools and their schemas are retained for caller-owned validation of fetched tool calls. Handles returned by implementations are caller-owned and may be persisted. Callers must not modify a handle concurrently with FetchBackground or CancelBackground.

func (BackgroundHandle) Validate added in v0.2.0

func (h BackgroundHandle) Validate() error

Validate reports whether h has complete identity and valid output-validation metadata.

type BackgroundResult added in v0.2.0

type BackgroundResult struct {
	Handle   BackgroundHandle
	Status   BackgroundStatus
	Response *Response
}

BackgroundResult is one observed state of a background generation. Response is non-nil only when Status is BackgroundCompleted or BackgroundIncomplete and output conversion succeeds. Handle and all nested response storage are caller-owned. Callers must retain a non-nil result even when the accompanying error is non-nil, because StartBackground may have created a durable job.

type BackgroundStatus added in v0.2.0

type BackgroundStatus string

BackgroundStatus describes the lifecycle of a durable provider-side generation. The zero value is invalid.

const (
	BackgroundQueued     BackgroundStatus = "queued"
	BackgroundInProgress BackgroundStatus = "in_progress"
	BackgroundCompleted  BackgroundStatus = "completed"
	BackgroundIncomplete BackgroundStatus = "incomplete"
	BackgroundCancelled  BackgroundStatus = "cancelled"
	BackgroundFailed     BackgroundStatus = "failed"
)

type CacheControlFormat

type CacheControlFormat string

CacheControlFormat identifies a prompt-cache marker convention. Empty means the protocol default. Metadata support does not by itself add cache markers to a request that contains none.

const (
	CacheControlDefault   CacheControlFormat = ""
	CacheControlAnthropic CacheControlFormat = "anthropic"
)

type CacheRetention

type CacheRetention string

CacheRetention controls provider prompt-cache policy. Default leaves the provider's policy unchanged; None explicitly disables request cache markers; Short and Long request the provider's short and longest portable retention.

const (
	CacheRetentionDefault CacheRetention = ""
	CacheRetentionNone    CacheRetention = "none"
	CacheRetentionShort   CacheRetention = "short"
	CacheRetentionLong    CacheRetention = "long"
)

type Capability

type Capability string

Capability identifies an operation supported by a model.

const (
	// CapabilityGeneration indicates text or multimodal generation support.
	CapabilityGeneration Capability = "generation"
	// CapabilityStreaming indicates incremental generation support.
	CapabilityStreaming Capability = "streaming"
	// CapabilityTools indicates tool-calling support.
	CapabilityTools Capability = "tools"
	// CapabilityJSON indicates structured JSON output support.
	CapabilityJSON Capability = "json"
	// CapabilityVision indicates image input support.
	CapabilityVision Capability = "vision"
	// CapabilityAudio indicates audio input support.
	CapabilityAudio Capability = "audio"
)

type Chunk

type Chunk struct {
	ID               string
	Model            string
	Content          []Part
	ToolCalls        []ToolCall
	ReasoningSummary string
	ProviderData     json.RawMessage
	FinishReason     FinishReason
	Usage            *Usage
	Events           []StreamEvent
}

Chunk contains new output from a generation stream. To assemble a Response, append Content, ToolCalls, and ReasoningSummary in chunk order, retain any nonempty ID, Model, and FinishReason, use the single nonempty ProviderData, and use the last non-nil Usage. Events describe the same output at a finer granularity and must not be appended to the response. The assembled message has RoleAssistant.

Text parts may be fragments; other parts and ToolCalls must be complete values. Events may expose incomplete tool argument fragments, but ToolCalls never do. Nonempty ID and Model values must not change between chunks. A nonzero FinishReason must not change between chunks. ProviderData must be a complete value and appear in at most one chunk. Usage, when present, is cumulative for the request.

type CompatibilityToggle

type CompatibilityToggle string

CompatibilityToggle is a tri-state model compatibility override. Default leaves protocol behavior unchanged; Enabled and Disabled explicitly opt in or out. The zero value is Default.

const (
	CompatibilityDefault  CompatibilityToggle = ""
	CompatibilityEnabled  CompatibilityToggle = "enabled"
	CompatibilityDisabled CompatibilityToggle = "disabled"
)

type Error

type Error struct {
	Kind       ErrorKind
	Op         string
	Provider   string
	HTTPStatus int
	RetryAfter time.Duration
	Retryable  *bool
	Err        error
}

Error describes a provider-neutral model error. Provider and Op identify its source when known. HTTPStatus is zero when unavailable; provider-native codes remain available through Err. RetryAfter is positive when a provider advised a delay. Err retains the underlying cause, including context cancellation and deadline errors. Retryable is nil when the provider supplied no explicit retry hint; non-nil true or false takes precedence over generic classification.

func (*Error) Error

func (e *Error) Error() string

Error returns a concise description of e.

func (*Error) Unwrap

func (e *Error) Unwrap() error

Unwrap returns the underlying cause.

type ErrorKind

type ErrorKind uint8

ErrorKind classifies an error independently of a provider's wire format. The constants below are the complete set of valid kinds. Implementations must use the most specific applicable kind. The zero value is KindUnknown.

const (
	// KindUnknown identifies an error that has no more specific classification.
	KindUnknown ErrorKind = iota
	// KindInvalidRequest identifies an invalid request without a more specific
	// classification, whether detected locally or rejected by a provider.
	KindInvalidRequest
	// KindAuthentication identifies missing or invalid credentials.
	KindAuthentication
	// KindPermission identifies a request forbidden for valid credentials.
	KindPermission
	// KindRateLimit identifies provider throttling.
	KindRateLimit
	// KindContextLimit identifies a request that does not fit within a model's
	// context limit.
	KindContextLimit
	// KindUnsupported identifies a capability the implementation cannot honor.
	KindUnsupported
	// KindTransport identifies a failure communicating with a provider.
	KindTransport
	// KindProvider identifies another provider-side failure.
	KindProvider
	// KindMalformedResponse identifies a response that cannot be decoded or
	// violates the provider protocol.
	KindMalformedResponse
)

func (ErrorKind) String

func (k ErrorKind) String() string

String returns a stable name for k.

type FinishReason

type FinishReason string

FinishReason describes why generation stopped.

const (
	// FinishReasonStop indicates a natural or requested stop sequence.
	FinishReasonStop FinishReason = "stop"
	// FinishReasonLength indicates that a token limit was reached.
	FinishReasonLength FinishReason = "length"
	// FinishReasonToolCall indicates that the model requested a tool call.
	FinishReasonToolCall FinishReason = "tool_call"
	// FinishReasonContentFilter indicates that content was withheld by a safety
	// system.
	FinishReasonContentFilter FinishReason = "content_filter"
)

type GeminiCompatibility added in v0.3.3

type GeminiCompatibility struct {
	// ThinkingLevelsOnly restricts explicit reasoning controls to low, medium,
	// and high effort. Token budgets, disabled reasoning, and other effort
	// levels are rejected before provider I/O.
	ThinkingLevelsOnly CompatibilityToggle
}

GeminiCompatibility describes model-specific differences among Gemini GenerateContent-compatible APIs.

type Generator

type Generator interface {
	Info() ModelInfo
	Generate(ctx context.Context, request Request) (*Response, error)
	Stream(ctx context.Context, request Request) (Stream, error)
}

Generator produces model responses. A Generator is configured for the model reported by Info and may be used concurrently by multiple goroutines. Implementations must first call Request.Validate and return its error unchanged or wrapped so errors.As preserves its Error fields. They must next return an error matching ctx.Err if the context is already done, then apply capability checks, then model-specific checks, all before provider I/O. Implementations must continue to honor cancellation until Generate returns or a stream commits its terminal state. They return a nil response when Generate returns an error and a nil Stream when Stream returns an error. Before returning a Stream error, an implementation must release all storage borrowed from the request. Info must include CapabilityGeneration. If it does not include CapabilityStreaming, Stream returns an error classified KindUnsupported. Callers should give operations a context deadline appropriate to their workload when an unbounded request is not acceptable.

Returned tool calls have valid structure and strict JSON, but their arguments may violate the declared schemas. Execution owners must use ValidateToolCalls before invoking tools; a schema mismatch is not a provider/stream failure.

func WithRetry

func WithRetry(generator Generator, policy RetryPolicy) (Generator, error)

WithRetry wraps generator with an explicit bounded retry policy. Providers remain single-attempt when this wrapper is not used.

type InstructionRole

type InstructionRole string

InstructionRole selects the Chat Completions role used for canonical system instructions. The zero value uses system.

const (
	InstructionRoleDefault   InstructionRole = ""
	InstructionRoleSystem    InstructionRole = "system"
	InstructionRoleDeveloper InstructionRole = "developer"
)

type MaxTokensField

type MaxTokensField string

MaxTokensField identifies the Chat Completions request field used for an output-token limit. The zero value uses the protocol default.

const (
	MaxTokensFieldDefault    MaxTokensField = ""
	MaxTokensFieldCompletion MaxTokensField = "max_completion_tokens"
	MaxTokensFieldLegacy     MaxTokensField = "max_tokens"
)

type Message

type Message struct {
	Role         Role
	Content      []Part
	ToolCalls    []ToolCall
	ToolResults  []ToolResult
	ProviderData json.RawMessage
}

Message is one turn in a model conversation. ToolCalls are valid only on an assistant message and may accompany Content. ToolResults are valid only on a tool message; its Content must be empty because each result carries its own content. Providers translate this canonical form to their wire format.

ProviderData is opaque state returned by a provider. Callers may pass it back unchanged on a later turn. A provider must ignore data it does not recognize.

func (Message) Text

func (m Message) Text() string

Text returns the concatenation of the message's text parts. For a tool message, it concatenates the text parts in each result in result order.

type Model

type Model struct {
	Provider        string
	ID              string
	Name            string
	API             API
	Capabilities    []Capability
	ContextWindow   int
	MaxOutputTokens int
	Reasoning       bool
	Cost            *ModelCost
	Compatibility   *ModelCompatibility
}

Model describes one catalog entry. Name is a human-readable display name and defaults conceptually to ID when empty. Reasoning reports whether the model supports explicit reasoning controls. ContextWindow and MaxOutputTokens are zero when unknown.

func (Model) Info

func (m Model) Info() ModelInfo

Info returns the provider-neutral configuration used to construct a Generator. The returned capability slice is owned by the caller.

type ModelCompatibility

type ModelCompatibility struct {
	OpenAIChat      *OpenAIChatCompatibility
	OpenAIResponses *OpenAIResponsesCompatibility
	Gemini          *GeminiCompatibility
	Anthropic       *AnthropicCompatibility
}

ModelCompatibility contains at most one protocol-specific compatibility block. Catalog validation requires that block to match the model API.

func (*ModelCompatibility) Validate

func (c *ModelCompatibility) Validate(api API) error

Validate reports whether compatibility is well formed for api.

type ModelCost

type ModelCost struct {
	Input      float64
	Output     float64
	CacheRead  float64
	CacheWrite float64
	Tiers      []ModelCostTier
}

ModelCost contains prices in US dollars per million tokens. Tiers apply the highest threshold exceeded by total input usage to the entire request.

func (ModelCost) Validate

func (c ModelCost) Validate() error

Validate reports whether the pricing table is finite, nonnegative, and has valid, unique tier thresholds.

type ModelCostTier

type ModelCostTier struct {
	InputTokensAbove int
	Input            float64
	Output           float64
	CacheRead        float64
	CacheWrite       float64
}

ModelCostTier overrides all rates when total input usage is greater than InputTokensAbove.

type ModelInfo

type ModelInfo struct {
	Provider        string
	Model           string
	API             API
	Capabilities    []Capability
	ContextWindow   int
	MaxOutputTokens int
	Reasoning       bool
	Cost            *ModelCost
	Compatibility   *ModelCompatibility
}

ModelInfo describes a configured model. API identifies its wire protocol. ContextWindow and MaxOutputTokens are zero when unknown. Reasoning reports support for explicit reasoning controls. Cost and Compatibility are nil when pricing or protocol compatibility metadata is unknown.

type OpenAIChatCompatibility

type OpenAIChatCompatibility struct {
	MaxTokensField           MaxTokensField
	InstructionRole          InstructionRole
	ThinkingFormat           ThinkingFormat
	ReasoningEffort          CompatibilityToggle
	StreamingUsage           CompatibilityToggle
	FinishReason             CompatibilityToggle
	ToolResultName           CompatibilityToggle
	ToolResultImageFallback  CompatibilityToggle
	AssistantAfterToolResult CompatibilityToggle
	ReasoningContentReplay   CompatibilityToggle
	StrictTools              CompatibilityToggle
	CacheControlFormat       CacheControlFormat
	LongCacheRetention       CompatibilityToggle
	// SessionAffinity enables SessionID headers for this compatible endpoint.
	SessionAffinity CompatibilityToggle
	// SessionAffinityFormat selects the header convention when enabled.
	SessionAffinityFormat SessionAffinityFormat
}

OpenAIChatCompatibility describes model-specific differences among OpenAI Chat Completions-compatible APIs.

type OpenAIResponsesCompatibility

type OpenAIResponsesCompatibility struct {
	DeveloperRole      CompatibilityToggle
	EncryptedReasoning CompatibilityToggle
	StrictTools        CompatibilityToggle
	// AdditionalTools enables replaying deferred tool definitions as
	// additional_tools input items.
	AdditionalTools CompatibilityToggle
	// ToolSearch enables client tool-search call/output replay when
	// AdditionalTools is not enabled.
	ToolSearch              CompatibilityToggle
	LongCacheRetention      CompatibilityToggle
	ExplicitPromptCacheMode CompatibilityToggle
	// SessionAffinityFormat selects the SessionID header convention. Its zero
	// value auto-detects native OpenAI or OpenRouter from provider routing.
	SessionAffinityFormat SessionAffinityFormat
}

OpenAIResponsesCompatibility describes model-specific differences among OpenAI Responses-compatible APIs.

type Part

type Part struct {
	Kind            PartKind
	Text            string
	Data            []byte
	MediaType       string
	CacheBreakpoint bool `json:",omitzero"`
}

Part is one piece of message content. Text parts use Text and leave Data and MediaType empty. Image and audio parts use Data and MediaType and leave Text empty. Other combinations are invalid. CacheBreakpoint marks the exact end of a reusable prompt prefix. It requires short or long cache retention and is rejected by adapters that do not support explicit breakpoint placement.

type PartKind

type PartKind uint8

PartKind identifies the representation of a message part. The zero value is PartText.

const (
	// PartText contains UTF-8 text in Part.Text.
	PartText PartKind = iota
	// PartImage contains encoded image bytes in Part.Data.
	PartImage
	// PartAudio contains encoded audio bytes in Part.Data.
	PartAudio
)

type ReasoningEffort

type ReasoningEffort string

ReasoningEffort controls how much internal reasoning a capable model uses. The zero value leaves the provider's default unchanged. Providers may map an effort to the nearest level supported by the configured model.

const (
	ReasoningEffortDefault ReasoningEffort = ""
	ReasoningEffortNone    ReasoningEffort = "none"
	ReasoningEffortMinimal ReasoningEffort = "minimal"
	ReasoningEffortLow     ReasoningEffort = "low"
	ReasoningEffortMedium  ReasoningEffort = "medium"
	ReasoningEffortHigh    ReasoningEffort = "high"
	ReasoningEffortXHigh   ReasoningEffort = "xhigh"
	ReasoningEffortMax     ReasoningEffort = "max"
)

type Request

type Request struct {
	Messages        []Message
	Tools           []Tool
	ToolChoice      ToolChoice
	ResponseFormat  ResponseFormat
	ReasoningEffort ReasoningEffort
	// ReasoningBudgetTokens requests an explicit provider reasoning-token
	// budget. Zero leaves budgeting to the provider or ReasoningEffort.
	ReasoningBudgetTokens int
	CacheRetention        CacheRetention
	// CacheKey partitions provider prompt-cache identity. It is not a session
	// affinity identifier and unsupported mappings are rejected.
	CacheKey string
	// SessionID supplies provider session-affinity identity independently of
	// CacheRetention. When caching is enabled, it may also be used as the fallback
	// prompt-cache key if CacheKey is empty.
	SessionID        string
	MaxOutputTokens  int
	Temperature      *float64
	TopP             *float64
	PresencePenalty  *float64
	FrequencyPenalty *float64
	Stop             []string
}

Request describes one generation operation. Messages must not be empty. MaxOutputTokens set to zero and nil sampling or penalty fields ask the provider to use its default. An empty Tools or Stop list means none. Implementations must treat Request as read-only.

func (Request) HasCacheBreakpoints added in v0.3.3

func (r Request) HasCacheBreakpoints() bool

HasCacheBreakpoints reports whether any message or tool-result content marks an explicit cache breakpoint.

func (Request) Validate

func (r Request) Validate() error

Validate reports whether r satisfies the provider-neutral Request contract. JSON values must conform to RFC 7493, including valid UTF-8 and unique object names. Provider implementations may apply additional model-specific constraints. On failure, Validate returns an *Error with KindInvalidRequest and Op set to "validate".

type Response

type Response struct {
	ID      string
	Model   string
	Message Message
	// ReasoningSummary is provider-generated explanatory text about the model's
	// reasoning. It is empty when the provider omits a summary and is separate
	// from the assistant message returned by Text.
	ReasoningSummary string
	FinishReason     FinishReason
	Usage            *Usage
}

Response is the result of a generation operation.

func Collect

func Collect(stream Stream, tools []Tool) (*Response, error)

Collect receives and assembles all chunks from stream according to the Chunk contract. It always closes stream before returning. The returned Response is non-nil once collection begins and contains every valid chunk committed before a failure. A non-EOF receive, invariant, schema-validation, cancellation, or close failure is returned with that partial response. A close failure is joined after an earlier failure and never replaces it.

tools declares schemas for completed tool calls. Passing nil is valid only when the stream emits no tool calls. Use CollectStructural when argument-schema validation belongs to the execution owner instead.

func CollectStructural added in v0.3.4

func CollectStructural(stream Stream) (*Response, error)

CollectStructural assembles and closes stream with the same partial-response, invariant, cancellation, and cleanup behavior as Collect. Completed calls are checked for structure and strict JSON, not declared names or argument schemas. Execution owners must use ValidateToolCalls before invoking tools.

func (Response) Text

func (r Response) Text() string

Text returns the concatenation of the response message's text parts.

type ResponseFormat

type ResponseFormat uint8

ResponseFormat identifies the requested response representation. The zero value is ResponseFormatText.

const (
	// ResponseFormatText requests ordinary model output.
	ResponseFormatText ResponseFormat = iota
	// ResponseFormatJSON requests a valid JSON value.
	ResponseFormatJSON
)

type RetryPolicy

type RetryPolicy struct {
	MaxAttempts    int
	InitialBackoff time.Duration
	MaxBackoff     time.Duration
	Multiplier     float64
	Jitter         float64
	ShouldRetry    func(error) bool
	Hook           AttemptHook
}

RetryPolicy configures an opt-in retrying Generator. MaxAttempts includes the first attempt and must be positive. Zero backoff fields use conservative defaults. MaxBackoff also bounds an acceptable provider RetryAfter; a larger requested minimum stops retrying instead of sleeping less than requested. Ambiguous transport failures are not retried by default because a POST may already have been accepted; use an explicit provider Retryable hint or ShouldRetry when the caller can accept that risk. Jitter is a fractional range from zero through one. ShouldRetry, if non-nil, replaces the default retry classification and must be concurrency-safe.

type Role

type Role string

Role identifies a message participant. The constants below are the complete set of valid roles; the zero value is invalid.

const (
	// RoleSystem carries instructions that apply to the conversation.
	RoleSystem Role = "system"
	// RoleUser carries input from the end user.
	RoleUser Role = "user"
	// RoleAssistant carries model output.
	RoleAssistant Role = "assistant"
	// RoleTool carries results produced by tools.
	RoleTool Role = "tool"
)

type SessionAffinityFormat

type SessionAffinityFormat string

SessionAffinityFormat identifies provider session-affinity header conventions. The zero value is resolved from the configured provider endpoint.

const (
	SessionAffinityDefault         SessionAffinityFormat = ""
	SessionAffinityOpenAI          SessionAffinityFormat = "openai"
	SessionAffinityOpenAINoSession SessionAffinityFormat = "openai-nosession"
	SessionAffinityOpenRouter      SessionAffinityFormat = "openrouter"
)

type Stream

type Stream interface {
	// Recv returns the next chunk. It returns io.EOF on clean completion. When
	// it returns an error, the chunk is zero and later calls return the same
	// error. Context cancellation and deadline errors remain discoverable with
	// errors.Is.
	Recv() (Chunk, error)

	// Close stops the stream and releases its resources. It is idempotent and
	// must unblock a pending Recv. It commits io.EOF unless another terminal
	// state won first or the context was already done. Close does not return
	// until the implementation has released all storage borrowed from the
	// request. Repeated calls return the same error; a Close error does not
	// replace the stream's terminal state.
	Close() error
}

Stream is a sequence of generation chunks. Callers must close every Stream, including after Recv returns an error. Only one goroutine may call Recv at a time. Close is safe to call concurrently with any Stream method.

A stream commits an ordered sequence of chunks followed by exactly one terminal state: io.EOF or a non-EOF error. Recv delivers every committed chunk exactly once, in order, before the terminal state; Close does not discard committed chunks. Natural completion and Close commit io.EOF, while provider and context failures commit their error. The first terminal transition wins. However, if the context passed to Generator.Stream is already done when Close is called, its error precedes Close. If cancellation and Close occur concurrently, either may win.

func ValidateToolCallStream

func ValidateToolCallStream(stream Stream, tools []Tool, provider string) (Stream, error)

ValidateToolCallStream wraps stream so every completed ToolCall in a Chunk or ToolCallEnd event is validated before the chunk is delivered. Partial argument delta events are never validated. The caller retains the normal obligation to close the returned stream. If setup fails, stream is closed before returning. This is an explicit schema-validation wrapper, not installed by providers.

func ValidateToolCallStructureStream added in v0.3.4

func ValidateToolCallStructureStream(stream Stream, provider string) (Stream, error)

ValidateToolCallStructureStream checks completed calls using ValidateToolCallStructure before delivering each chunk. Partial argument deltas are not checked. Schema mismatches and undeclared names are delivered unchanged for the execution owner to reject. The caller must close the stream.

type StreamEvent

type StreamEvent struct {
	Kind         StreamEventKind
	Index        int
	Subindex     int
	Delta        string
	Content      string
	ToolCallID   string
	ToolName     string
	ToolCall     *ToolCall
	FinishReason FinishReason
}

StreamEvent describes a semantic transition represented by a Chunk. Index identifies a provider output item and Subindex identifies a part within it; both are stable for events belonging to that item. Providers without nested output parts leave Subindex zero. Delta is newly received text, reasoning text, or raw tool argument fragment; a tool argument delta need not be valid JSON by itself. Content is the completed text for an end event when the provider makes it available. ToolCallID and ToolName contain the identity known at a tool-call start or delta. ToolCall is set on a successfully completed ToolCallEnd and contains complete strict-JSON arguments, which may violate the tool schema; execution owners must use ValidateToolCalls before invoking tools. It is nil when an incomplete response interrupts a started call. FinishReason is set only for Done.

Streams report failures through Recv rather than as events. Event storage is owned by the caller after Recv returns.

type StreamEventKind

type StreamEventKind string

StreamEventKind identifies one semantic event in a generation stream.

const (
	StreamEventStart          StreamEventKind = "start"
	StreamEventTextStart      StreamEventKind = "text_start"
	StreamEventTextDelta      StreamEventKind = "text_delta"
	StreamEventTextEnd        StreamEventKind = "text_end"
	StreamEventReasoningStart StreamEventKind = "reasoning_start"
	StreamEventReasoningDelta StreamEventKind = "reasoning_delta"
	StreamEventReasoningEnd   StreamEventKind = "reasoning_end"
	StreamEventToolCallStart  StreamEventKind = "tool_call_start"
	StreamEventToolCallDelta  StreamEventKind = "tool_call_delta"
	StreamEventToolCallEnd    StreamEventKind = "tool_call_end"
	StreamEventDone           StreamEventKind = "done"
)

type ThinkingFormat

type ThinkingFormat string

ThinkingFormat identifies an OpenAI-compatible reasoning request convention. The zero value uses reasoning_effort.

const (
	ThinkingFormatDefault    ThinkingFormat = ""
	ThinkingFormatOpenAI     ThinkingFormat = "openai"
	ThinkingFormatOpenRouter ThinkingFormat = "openrouter"
	ThinkingFormatDeepSeek   ThinkingFormat = "deepseek"
	ThinkingFormatTogether   ThinkingFormat = "together"
	ThinkingFormatZAI        ThinkingFormat = "zai"
	ThinkingFormatQwen       ThinkingFormat = "qwen"
	ThinkingFormatString     ThinkingFormat = "string-thinking"
)

type TokenBudget

type TokenBudget struct {
	EstimatedInputTokens  int
	ReserveTokens         int
	AvailableOutputTokens int
	MaxOutputTokens       int
	Clamped               bool
}

TokenBudget reports how BudgetRequest derived the output limit.

type TokenEstimator

type TokenEstimator interface {
	EstimateInputTokens(context.Context, Request) (int, error)
}

TokenEstimator estimates input tokens for a request. Implementations must treat Request as read-only, be safe for the caller's intended concurrency, and honor ctx. Estimates are explicitly approximate unless the implementation uses the target model's exact tokenizer.

type TokenEstimatorFunc

type TokenEstimatorFunc func(context.Context, Request) (int, error)

TokenEstimatorFunc adapts a function to TokenEstimator.

func (TokenEstimatorFunc) EstimateInputTokens

func (f TokenEstimatorFunc) EstimateInputTokens(ctx context.Context, request Request) (int, error)

type Tool

type Tool struct {
	Name        string
	Description string
	InputSchema json.RawMessage
	Strict      bool
	Strictness  ToolStrictness
}

Tool describes a function that a model may call. InputSchema is a JSON Schema describing the function arguments. Providers check completed calls for structure and strict JSON, not argument-schema conformance. Execution owners must use ValidateToolCalls before invoking tools. Schemas default to draft 2020-12, may declare any supported standard draft, and may use only references resolved within that schema. Strict is the legacy require-strict flag. Strictness provides an explicit prefer/require policy; setting both Strict and Strictness is invalid.

func (Tool) RequiresStrict

func (t Tool) RequiresStrict() bool

RequiresStrict reports whether unsupported provider-side strict generation must fail before I/O.

func (Tool) StrictEnabled

func (t Tool) StrictEnabled(supported bool) bool

StrictEnabled reports whether strictness should be sent to a provider with the supplied capability.

type ToolCall

type ToolCall struct {
	ID        string
	Name      string
	Arguments json.RawMessage
}

ToolCall is a tool invocation requested by a model. Arguments contains one JSON value, normally an object. ID may be empty when a provider supplies only a function name. The order of ID-less calls is significant. Arguments are returned unchanged, not schema-validated; use ValidateToolCalls before execution.

type ToolChoice

type ToolChoice struct {
	Mode ToolChoiceMode
	Name string
}

ToolChoice is a closed provider-neutral tool selection. Name is required only for ToolChoiceNamed and must identify a declared tool.

type ToolChoiceMode

type ToolChoiceMode string

ToolChoiceMode controls whether and which tools the model may call. The zero value is automatic selection.

const (
	ToolChoiceAuto     ToolChoiceMode = ""
	ToolChoiceNone     ToolChoiceMode = "none"
	ToolChoiceRequired ToolChoiceMode = "required"
	ToolChoiceNamed    ToolChoiceMode = "named"
)

type ToolResult

type ToolResult struct {
	CallID         string
	Name           string
	Content        []Part
	IsError        bool
	AddedToolNames []string
}

ToolResult is the output of one tool invocation. CallID must match the call when its ID is available. Otherwise, Name must match the call and results are paired with preceding unmatched ID-less calls of that name in order. When both CallID and Name are set, both must identify the same call. AddedToolNames records tool definitions introduced after this result while replaying a transcript. Names absent from the current Request.Tools are ignored. Providers that support deferred tool loading may serialize available definitions at this position; other providers ignore the marker and send all request tools normally.

type ToolStrictness

type ToolStrictness string

ToolStrictness controls provider-side JSON Schema constrained generation. The zero value preserves legacy Tool.Strict behavior. Prefer enables provider strictness when supported, while Require fails before I/O when unsupported.

const (
	ToolStrictDefault ToolStrictness = ""
	ToolStrictPrefer  ToolStrictness = "prefer"
	ToolStrictRequire ToolStrictness = "require"
)

type TransformWarning

type TransformWarning struct {
	Code    TransformWarningCode
	Path    string
	Message string
}

TransformWarning describes one transformed or repaired history item.

type TransformWarningCode

type TransformWarningCode string

TransformWarningCode identifies one explicit history transformation or repair.

const (
	TransformRemovedProviderData     TransformWarningCode = "removed_provider_data"
	TransformReplacedImage           TransformWarningCode = "replaced_image"
	TransformReplacedAudio           TransformWarningCode = "replaced_audio"
	TransformNormalizedToolCallID    TransformWarningCode = "normalized_tool_call_id"
	TransformAddedMissingToolResult  TransformWarningCode = "added_missing_tool_result"
	TransformRemovedOrphanToolResult TransformWarningCode = "removed_orphan_tool_result"
	TransformCorrectedToolResultName TransformWarningCode = "corrected_tool_result_name"
)

type Usage

type Usage struct {
	InputTokens        int
	OutputTokens       int
	CacheReadTokens    int
	CacheWriteTokens   int
	CacheWrite1hTokens int
	ReasoningTokens    int
	TotalTokens        int
	Cost               *UsageCost
}

Usage reports token counts when a provider supplies them. InputTokens excludes cache reads and writes; TotalTokens is the sum of input, output, cache-read, and cache-write tokens. ReasoningTokens is a subset of OutputTokens. CacheWrite1hTokens is a subset of CacheWriteTokens. Cost is nil when no pricing metadata was configured.

type UsageCost

type UsageCost struct {
	Input      float64
	Output     float64
	CacheRead  float64
	CacheWrite float64
	Total      float64
}

UsageCost reports cost in US dollars for each token category.

func CalculateCost

func CalculateCost(cost ModelCost, usage Usage) (UsageCost, error)

CalculateCost calculates request cost in US dollars. CacheWrite1hTokens are charged at twice the selected input rate, matching Anthropic's one-hour cache retention pricing; remaining cache writes use the selected cache-write rate.

Directories

Path Synopsis
Package anthropic implements Anthropic's Messages API using llm's neutral request, response, tool, and stream contracts.
Package anthropic implements Anthropic's Messages API using llm's neutral request, response, tool, and stream contracts.
Package bedrock implements Amazon Bedrock's ConverseStream API.
Package bedrock implements Amazon Bedrock's ConverseStream API.
Package gemini implements llm.Generator with Google's official Gemini SDK.
Package gemini implements llm.Generator with Google's official Gemini SDK.
internal
deferredtools
Package deferredtools derives provider wire placements from portable tool introduction markers in a validated request.
Package deferredtools derives provider wire placements from portable tool introduction markers in a validated request.
stream
Package stream implements the internal producer side of llm.Stream.
Package stream implements the internal producer side of llm.Stream.
Package mistral implements Mistral's Conversations-compatible streaming chat API with llm-go's neutral model contracts.
Package mistral implements Mistral's Conversations-compatible streaming chat API with llm-go's neutral model contracts.
Package models constructs provider-neutral model generators from a reusable collection of provider configurations.
Package models constructs provider-neutral model generators from a reusable collection of provider configurations.
cmd/cataloggen command
modelsdev
Package modelsdev provides integration with the models.dev open model directory and API, allowing dynamic catalog loading and synchronization for llm-go.
Package modelsdev provides integration with the models.dev open model directory and API, allowing dynamic catalog loading and synchronization for llm-go.
Package openai implements OpenAI-compatible Chat Completions using llm's neutral contracts.
Package openai implements OpenAI-compatible Chat Completions using llm's neutral contracts.
azure
Package azure implements Azure OpenAI's Responses API with llm-go's neutral model contracts.
Package azure implements Azure OpenAI's Responses API with llm-go's neutral model contracts.
codex
Package codex adapts OpenAI's ChatGPT subscription Codex Responses protocol to llm's provider-neutral generation interfaces.
Package codex adapts OpenAI's ChatGPT subscription Codex Responses protocol to llm's provider-neutral generation interfaces.
responses
Package responses implements OpenAI's Responses API with llm-go's neutral model contracts.
Package responses implements OpenAI's Responses API with llm-go's neutral model contracts.
Package vertex implements Google Vertex AI GenerateContent using llm-go's neutral model contracts.
Package vertex implements Google Vertex AI GenerateContent using llm-go's neutral model contracts.

Jump to

Keyboard shortcuts

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