Documentation
¶
Overview ¶
Package llm: provider_chain assembles the runtime Provider decorator stack.
NewProviderChain wraps a primary provider, innermost to outermost, with cache, fallback, retry, throttle, per-call timeout and budget layers. The throttle layer is process-wide when a throttle key is set (see WithThrottleKey): every chain built for the same provider name shares one semaphore so LLM_THROTTLE_CONCURRENCY bounds concurrent calls across all runs, not per chain.
Index ¶
- Variables
- func PromptBytes(messages []Message) int
- func ValidatePromptBytes(messages []Message, maxBytes int) error
- func WithCacheStatsCollector(ctx context.Context, collector *CacheStatsCollector) context.Context
- type AnthropicProviderConfig
- type Budget
- type BudgetGuardProvider
- type BudgetMetrics
- type BudgetStats
- type CacheMetrics
- type CacheProvider
- type CacheStats
- type CacheStatsCollector
- type CachedProvider
- type ChainOption
- func WithBudget(b *Budget) ChainOption
- func WithCache(cache ResponseCache) ChainOption
- func WithCallTimeout(d time.Duration) ChainOption
- func WithChainBudgetMetrics(m BudgetMetrics) ChainOption
- func WithChainCacheMetrics(m CacheMetrics) ChainOption
- func WithChainFallbackMetrics(m FallbackMetrics) ChainOption
- func WithChainRetryMetrics(m RetryMetrics) ChainOption
- func WithFallback(p Provider) ChainOption
- func WithRetry(maxAttempts int) ChainOption
- func WithRetryBaseDelay(d time.Duration) ChainOption
- func WithThrottle(n int) ChainOption
- func WithThrottleKey(key string) ChainOption
- type CompletionRequest
- type CompletionResponse
- type CompletionUsage
- type Composer
- func (c Composer) BuildProvider(cfg config.LLMConfig, appMetrics any, logger *slog.Logger, budget *Budget) Provider
- func (c Composer) BuildProviderForSelection(cfg config.LLMConfig, providerName, model string, logger *slog.Logger) (Provider, error)
- func (c Composer) WrapProviderChain(primary Provider, cfg config.LLMConfig, appMetrics any, logger *slog.Logger, ...) Provider
- type FallbackMetrics
- type FallbackProvider
- type GoogleProviderConfig
- type MemoryResponseCache
- type Message
- type ModelTier
- type OllamaProviderConfig
- type OpenAIProviderConfig
- type OpenCodeProviderConfig
- type PromptTooLargeError
- type Provider
- type ProviderFunc
- type ProviderRegistration
- type Registry
- type ResponseCache
- type ResponseFormat
- type ResponseFormatType
- type RetryMetrics
- type RetryOption
- type RetryProvider
- type RuntimeProviderFactories
- type ThrottledProvider
Constants ¶
This section is empty.
Variables ¶
var ( // ErrProviderNotFound indicates that no provider has been registered for a name. ErrProviderNotFound = errors.New("llm provider not found") // ErrModelTierNotConfigured indicates that a provider was found but has no model for the requested tier. ErrModelTierNotConfigured = errors.New("llm model tier not configured") )
var ErrBudgetExhausted = errors.New("llm: daily budget exhausted")
ErrBudgetExhausted is returned when daily request or token budget is spent. RetryProvider treats this as non-retryable (unknown error type, no statusCoder).
Functions ¶
func PromptBytes ¶
PromptBytes returns the UTF-8 byte size of all message contents.
func ValidatePromptBytes ¶
ValidatePromptBytes rejects prompts that exceed maxBytes.
func WithCacheStatsCollector ¶
func WithCacheStatsCollector(ctx context.Context, collector *CacheStatsCollector) context.Context
WithCacheStatsCollector attaches collector to ctx.
Types ¶
type AnthropicProviderConfig ¶
AnthropicProviderConfig is the config shape required by an Anthropic factory.
type Budget ¶
type Budget struct {
// contains filtered or unexported fields
}
Budget tracks daily request and token usage with thread-safe counters. Zero limits mean unlimited. Call Reset() to clear counters (e.g. at UTC midnight).
func BuildLLMBudget ¶
BuildLLMBudget converts config budget fields into an LLM budget guard.
func NewBudget ¶
NewBudget creates a Budget with the given daily limits. Zero values for either limit mean that dimension is unlimited.
func (*Budget) Allow ¶
Allow returns true if a new request is within budget. It auto-resets counters when UTC midnight has passed.
func (*Budget) Reset ¶
func (b *Budget) Reset()
Reset clears all counters and sets the next reset time.
func (*Budget) Stats ¶
func (b *Budget) Stats() BudgetStats
Stats returns current budget usage (for observability).
type BudgetGuardProvider ¶
type BudgetGuardProvider struct {
// contains filtered or unexported fields
}
BudgetGuardProvider wraps a Provider, rejecting calls when budget is exhausted. On success it records token usage back to the budget.
func NewBudgetGuardProvider ¶
func NewBudgetGuardProvider(inner Provider, budget *Budget) *BudgetGuardProvider
NewBudgetGuardProvider wraps inner with budget enforcement.
func (*BudgetGuardProvider) Complete ¶
func (b *BudgetGuardProvider) Complete(ctx context.Context, req CompletionRequest) (*CompletionResponse, error)
Complete checks budget before delegating. Records usage after success.
func (*BudgetGuardProvider) WithBudgetMetrics ¶
func (b *BudgetGuardProvider) WithBudgetMetrics(m BudgetMetrics) *BudgetGuardProvider
WithBudgetMetrics attaches optional budget metrics.
type BudgetMetrics ¶
type BudgetMetrics interface {
RecordLLMBudgetExhausted()
}
BudgetMetrics captures budget exhaustion events for observability.
type BudgetStats ¶
type BudgetStats struct {
Requests int
MaxRequestsPerDay int
PromptTokens int
CompletionTokens int
TotalTokens int
MaxTokensPerDay int
ResetAt time.Time
}
BudgetStats holds a snapshot of budget usage.
type CacheMetrics ¶
type CacheMetrics interface {
RecordLLMCacheHit()
RecordLLMCacheMiss()
}
CacheMetrics records aggregate cache hits and misses.
type CacheProvider ¶
type CacheProvider struct {
// contains filtered or unexported fields
}
CacheProvider wraps a Provider with response caching.
func NewCacheProvider ¶
func NewCacheProvider(provider Provider, cache ResponseCache, version string) (*CacheProvider, error)
NewCacheProvider wraps provider with a response cache. An empty version uses the default cache version.
func (*CacheProvider) Complete ¶
func (c *CacheProvider) Complete(ctx context.Context, request CompletionRequest) (*CompletionResponse, error)
Complete returns a cached response when available, otherwise it delegates to the wrapped provider and stores the result.
func (*CacheProvider) WithCacheMetrics ¶
func (c *CacheProvider) WithCacheMetrics(m CacheMetrics) *CacheProvider
WithCacheMetrics attaches optional cache metrics.
type CacheStats ¶
type CacheStats struct {
Hits int `json:"hits"`
Misses int `json:"misses"`
Requests int `json:"requests"`
HitRate float64 `json:"hit_rate"`
MissRate float64 `json:"miss_rate"`
}
CacheStats summarizes cache behavior for a single run.
type CacheStatsCollector ¶
type CacheStatsCollector struct {
// contains filtered or unexported fields
}
CacheStatsCollector records per-context cache hits and misses.
func CacheStatsCollectorFromContext ¶
func CacheStatsCollectorFromContext(ctx context.Context) *CacheStatsCollector
CacheStatsCollectorFromContext returns the collector stored on ctx, if any.
func NewCacheStatsCollector ¶
func NewCacheStatsCollector() *CacheStatsCollector
NewCacheStatsCollector returns an empty stats collector.
func (*CacheStatsCollector) Snapshot ¶
func (c *CacheStatsCollector) Snapshot() CacheStats
Snapshot returns the current hit/miss totals and rates.
type CachedProvider ¶
type CachedProvider = CacheProvider
CachedProvider is a compatibility alias for CacheProvider.
func NewCachedProvider ¶
func NewCachedProvider(provider Provider, cache ResponseCache) *CachedProvider
NewCachedProvider wraps provider with a response cache using the default cache version. It returns nil when provider or cache is invalid.
type ChainOption ¶
type ChainOption func(*chainConfig)
ChainOption configures the provider chain built by NewProviderChain.
func WithBudget ¶
func WithBudget(b *Budget) ChainOption
WithBudget attaches a budget guard that rejects calls when daily limits are hit.
func WithCache ¶
func WithCache(cache ResponseCache) ChainOption
WithCache enables response caching using the given cache store.
func WithCallTimeout ¶
func WithCallTimeout(d time.Duration) ChainOption
WithCallTimeout wraps each Complete call with a per-call context timeout. Zero or negative values disable per-call timeout.
func WithChainBudgetMetrics ¶
func WithChainBudgetMetrics(m BudgetMetrics) ChainOption
WithChainBudgetMetrics attaches metrics to the budget guard layer.
func WithChainCacheMetrics ¶
func WithChainCacheMetrics(m CacheMetrics) ChainOption
WithChainCacheMetrics attaches metrics to the cache layer.
func WithChainFallbackMetrics ¶
func WithChainFallbackMetrics(m FallbackMetrics) ChainOption
WithChainFallbackMetrics attaches metrics to the fallback layer.
func WithChainRetryMetrics ¶
func WithChainRetryMetrics(m RetryMetrics) ChainOption
WithChainRetryMetrics attaches metrics to the retry layer.
func WithFallback ¶
func WithFallback(p Provider) ChainOption
WithFallback adds a secondary provider tried when primary fails.
func WithRetry ¶
func WithRetry(maxAttempts int) ChainOption
WithRetry sets the max retry attempts (including initial call). Values < 1 are ignored.
func WithRetryBaseDelay ¶
func WithRetryBaseDelay(d time.Duration) ChainOption
WithRetryBaseDelay sets the base delay for exponential backoff.
func WithThrottle ¶
func WithThrottle(n int) ChainOption
WithThrottle sets the max concurrent calls. Values < 1 are clamped to 1.
func WithThrottleKey ¶
func WithThrottleKey(key string) ChainOption
WithThrottleKey makes the throttle layer share the process-wide semaphore registered under key (typically the provider name). Chains built without a key use a private semaphore.
type CompletionRequest ¶
type CompletionRequest struct {
Model string `json:"model,omitempty"`
Messages []Message `json:"messages"`
Temperature float64 `json:"temperature,omitempty"`
MaxTokens int `json:"max_tokens,omitempty"`
ResponseFormat *ResponseFormat `json:"response_format,omitempty"`
}
CompletionRequest captures the provider-agnostic input required for a chat completion.
type CompletionResponse ¶
type CompletionResponse struct {
Content string `json:"content"`
Usage CompletionUsage `json:"usage"`
Model string `json:"model,omitempty"`
LatencyMS int `json:"latency_ms,omitempty"`
CostUSD float64 `json:"cost_usd,omitempty"`
UsedFallback bool `json:"used_fallback,omitempty"`
TimedOut bool `json:"timed_out,omitempty"`
}
CompletionResponse captures the provider-agnostic result of a chat completion.
type CompletionUsage ¶
type CompletionUsage struct {
PromptTokens int `json:"prompt_tokens"`
CompletionTokens int `json:"completion_tokens"`
}
CompletionUsage tracks token counts returned by the provider.
type Composer ¶
type Composer struct {
// contains filtered or unexported fields
}
Composer owns runtime LLM provider assembly.
func NewComposer ¶
func NewComposer(factories RuntimeProviderFactories) Composer
NewComposer constructs a runtime composer from provider factories.
func (Composer) BuildProvider ¶
func (c Composer) BuildProvider(cfg config.LLMConfig, appMetrics any, logger *slog.Logger, budget *Budget) Provider
BuildProvider builds the configured primary provider and wraps it with the runtime chain.
type FallbackMetrics ¶
type FallbackMetrics interface {
RecordLLMFallback(reason string)
}
FallbackMetrics captures fallback events for observability.
type FallbackProvider ¶
type FallbackProvider struct {
// contains filtered or unexported fields
}
FallbackProvider wraps a primary and secondary Provider. If the primary provider fails, the request is retried against the secondary provider. Fallback events are logged for observability.
Context cancellation errors are returned immediately. DeadlineExceeded errors are retried against the secondary provider using a fresh context.
func NewFallbackProvider ¶
func NewFallbackProvider(primary, secondary Provider, logger *slog.Logger) (*FallbackProvider, error)
NewFallbackProvider constructs a FallbackProvider that tries primary first and falls back to secondary on non-context errors. If logger is nil, slog.Default() is used.
func (*FallbackProvider) Complete ¶
func (f *FallbackProvider) Complete(ctx context.Context, request CompletionRequest) (*CompletionResponse, error)
Complete tries the primary provider first. On failure it logs the event and attempts the secondary provider. Context.Canceled is returned immediately without fallback. Context.DeadlineExceeded is retried against the secondary provider with a fresh context. If both providers fail the secondary error is returned.
func (*FallbackProvider) WithMetrics ¶
func (f *FallbackProvider) WithMetrics(metrics FallbackMetrics) *FallbackProvider
WithMetrics wires an optional metrics recorder into the provider.
type GoogleProviderConfig ¶
GoogleProviderConfig is the config shape required by a Google factory.
type MemoryResponseCache ¶
type MemoryResponseCache struct {
// contains filtered or unexported fields
}
MemoryResponseCache is a capacity-bounded in-memory ResponseCache implementation. When the cache is full an arbitrary entry is evicted before inserting the new one, bounding memory consumption to at most maxItems entries.
func NewMemoryResponseCache ¶
func NewMemoryResponseCache() *MemoryResponseCache
NewMemoryResponseCache returns an empty in-memory response cache bounded to defaultMemoryCacheMaxItems entries.
func NewMemoryResponseCacheWithLimit ¶
func NewMemoryResponseCacheWithLimit(maxItems int) *MemoryResponseCache
NewMemoryResponseCacheWithLimit returns an empty in-memory response cache bounded to maxItems entries. If maxItems is <= 0 the default limit is used.
func (*MemoryResponseCache) Get ¶
func (c *MemoryResponseCache) Get(key string) (*CompletionResponse, bool)
Get returns a cloned cached response for the given key.
func (*MemoryResponseCache) Set ¶
func (c *MemoryResponseCache) Set(key string, response *CompletionResponse)
Set stores a cloned response for the given key. If the cache is at capacity an arbitrary entry is evicted first to keep the total entry count bounded.
type ModelTier ¶
type ModelTier string
ModelTier identifies the level of reasoning required for a request.
type OllamaProviderConfig ¶
OllamaProviderConfig is the config shape required by an Ollama factory.
type OpenAIProviderConfig ¶
OpenAIProviderConfig is the config shape required by an OpenAI-compatible factory.
type OpenCodeProviderConfig ¶
type OpenCodeProviderConfig struct {
BaseURL string
Username string
Password string
Model string
UseRequestModel bool
}
OpenCodeProviderConfig is the config shape required by an OpenCode factory.
type PromptTooLargeError ¶
PromptTooLargeError reports a prompt body that exceeds a byte ceiling.
func (*PromptTooLargeError) Error ¶
func (e *PromptTooLargeError) Error() string
type Provider ¶
type Provider interface {
Complete(ctx context.Context, request CompletionRequest) (*CompletionResponse, error)
}
Provider defines the minimal interface required to execute an LLM completion.
func NewProviderChain ¶
func NewProviderChain(primary Provider, logger *slog.Logger, opts ...ChainOption) Provider
NewProviderChain composes a resilient provider from existing primitives.
Chain order (outermost → innermost):
budget guard → timeout → throttle → retry → fallback → cache → raw provider
Each layer is optional; only layers whose options are provided are added. The resulting Provider delegates to the composed chain.
type ProviderFunc ¶
type ProviderFunc func(ctx context.Context, request CompletionRequest) (*CompletionResponse, error)
ProviderFunc adapts a plain function to the Provider interface.
func (ProviderFunc) Complete ¶
func (f ProviderFunc) Complete(ctx context.Context, request CompletionRequest) (*CompletionResponse, error)
Complete delegates to the wrapped function.
type ProviderRegistration ¶
ProviderRegistration stores a provider along with the models assigned to each tier.
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry stores providers by name and their tier-specific model mappings.
func (*Registry) Get ¶
func (r *Registry) Get(name string) (ProviderRegistration, bool)
Get returns the registered provider entry for a name.
type ResponseCache ¶
type ResponseCache interface {
Get(key string) (*CompletionResponse, bool)
Set(key string, response *CompletionResponse)
}
ResponseCache stores completion responses by cache key.
type ResponseFormat ¶
type ResponseFormat struct {
Type ResponseFormatType `json:"type"`
Schema json.RawMessage `json:"schema,omitempty"`
}
ResponseFormat describes the expected response shape.
Schema is optional and allows future providers to pass through a JSON schema for structured output modes supported by OpenAI, Anthropic, or Google APIs.
type ResponseFormatType ¶
type ResponseFormatType string
ResponseFormatType identifies the requested output format for a completion.
const ( // ResponseFormatText requests plain text output. ResponseFormatText ResponseFormatType = "text" // ResponseFormatJSONObject requests structured JSON object output. ResponseFormatJSONObject ResponseFormatType = "json_object" )
type RetryMetrics ¶
type RetryMetrics interface {
RecordLLMRetry()
}
RetryMetrics captures retry events for observability.
type RetryOption ¶
type RetryOption func(*RetryProvider)
RetryOption configures a RetryProvider.
func WithBaseDelay ¶
func WithBaseDelay(d time.Duration) RetryOption
WithBaseDelay sets the base delay for exponential backoff.
func WithMaxAttempts ¶
func WithMaxAttempts(n int) RetryOption
WithMaxAttempts sets the maximum number of attempts (including the first).
type RetryProvider ¶
type RetryProvider struct {
// contains filtered or unexported fields
}
RetryProvider wraps a Provider with exponential-backoff retry logic. It retries on transient errors (rate limits, server errors, timeouts) and does not retry on client errors (bad request, auth failures).
func NewRetryProvider ¶
func NewRetryProvider(provider Provider, logger *slog.Logger, opts ...RetryOption) *RetryProvider
NewRetryProvider wraps provider with retry logic using exponential backoff. If logger is nil, slog.Default() is used.
func (*RetryProvider) Complete ¶
func (r *RetryProvider) Complete(ctx context.Context, request CompletionRequest) (*CompletionResponse, error)
Complete executes the completion request with retry logic. Token usage is aggregated across all attempts (including failed ones that return partial usage).
func (*RetryProvider) SetTimerFn ¶
SetTimerFn overrides the function used to create backoff timers between retries. This is intended for testing only. The function should return a channel that fires after the duration and a stop function to release resources.
func (*RetryProvider) WithRetryMetrics ¶
func (r *RetryProvider) WithRetryMetrics(m RetryMetrics) *RetryProvider
WithRetryMetrics attaches optional retry metrics.
type RuntimeProviderFactories ¶
type RuntimeProviderFactories struct {
OpenAI func(OpenAIProviderConfig) (Provider, error)
Anthropic func(AnthropicProviderConfig) (Provider, error)
Google func(GoogleProviderConfig) (Provider, error)
OpenRouter func(OpenAIProviderConfig) (Provider, error)
XAI func(OpenAIProviderConfig) (Provider, error)
Ollama func(OllamaProviderConfig) (Provider, error)
OpenCode func(OpenCodeProviderConfig) (Provider, error)
}
RuntimeProviderFactories provides provider constructors used by the runtime composer.
type ThrottledProvider ¶
type ThrottledProvider struct {
// contains filtered or unexported fields
}
ThrottledProvider wraps a Provider with a concurrency limiter. All callers share the same semaphore, preventing Ollama (or any serial LLM backend) from being overwhelmed by concurrent requests.
func NewThrottledProvider ¶
func NewThrottledProvider(inner Provider, maxConcurrent int) *ThrottledProvider
NewThrottledProvider creates a provider that allows at most maxConcurrent simultaneous LLM calls. Additional calls block until a slot is available.
func NewThrottledProviderWithSemaphore ¶
func NewThrottledProviderWithSemaphore(inner Provider, sem chan struct{}) *ThrottledProvider
NewThrottledProviderWithSemaphore creates a provider that acquires a slot from the supplied semaphore for each call. Several providers may share one semaphore; tests can pass their own channel to observe capacity.
func (*ThrottledProvider) Capacity ¶
func (t *ThrottledProvider) Capacity() int
Capacity reports the semaphore size.
func (*ThrottledProvider) Complete ¶
func (t *ThrottledProvider) Complete(ctx context.Context, request CompletionRequest) (*CompletionResponse, error)
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package embedding provides a Provider interface and implementations for generating vector embeddings from text.
|
Package embedding provides a Provider interface and implementations for generating vector embeddings from text. |
|
Package opencode implements an LLM provider backed by a private OpenCode server.
|
Package opencode implements an LLM provider backed by a private OpenCode server. |