Documentation
¶
Overview ¶
Package providers is the single, data-driven source of truth for vix's LLM providers and models. Everything that differs between providers that is pure data — model prefixes, base URLs, auth header styles, request headers/query params, credential env vars, OAuth endpoints, and the curated model catalogue — lives in an embedded providers.json (optionally overlaid by ~/.vix and ./.vix copies). Behavior (SSE parsing, request shaping, OAuth mechanics) stays compiled and is selected from JSON via closed enums: wire_format, the credential kinds, the auth flow, and the chat effort_style.
The package has no dependencies on other internal packages so it can be imported by the inference layer (internal/daemon/llm), credential resolution (internal/config), the OAuth subsystem (internal/auth), and the TUI catalogue (internal/ui) without import cycles.
Index ¶
- Constants
- Variables
- func Configure(paths []string) error
- func IsReasoningModel(model string) bool
- type AuthLogin
- type CredentialMethod
- type DeviceSpec
- type File
- type InferenceSpec
- type ModelSpec
- type ProviderSpec
- type Registry
- func (r *Registry) All() []ProviderSpec
- func (r *Registry) AuthLogin(id string) (AuthLogin, bool)
- func (r *Registry) AuthLogins() []AuthLogin
- func (r *Registry) ContextWindow(spec string) int64
- func (r *Registry) DisplayName(spec string) string
- func (r *Registry) IDs() []string
- func (r *Registry) Lookup(id string) (ProviderSpec, bool)
- func (r *Registry) ParseModel(spec string) (ProviderSpec, string, error)
- func (r *Registry) Prefixes() []string
- type WireFormat
Constants ¶
const ( // EffortAdaptive always defaults to "adaptive" (Anthropic, MiniMax). EffortAdaptive = "adaptive" // EffortOpenAIReasoning defaults to "medium" for reasoning-capable models // and "" otherwise (OpenAI, OpenRouter, MiMo). EffortOpenAIReasoning = "openai_reasoning" )
Effort policy names (default reasoning effort for a model spec).
const ( // EffortStyleReasoningEffort sends the standard OpenAI reasoning_effort knob // (level), gated on reasoning-capable models (OpenRouter, MiMo). EffortStyleReasoningEffort = "reasoning_effort" // EffortStyleReasoningSplit sends reasoning_split=true whenever effort is // non-empty (MiniMax M2 — no level knob). EffortStyleReasoningSplit = "reasoning_split" // EffortStyleNone sends no reasoning field. EffortStyleNone = "" )
Chat-only effort styles: how a non-empty effort maps onto a Chat Completions request body. The set is closed.
const ( // AuthSchemeBearer sends Authorization: Bearer <value> (OpenAI-family). AuthSchemeBearer = "bearer" // AuthSchemeXAPIKey sends x-api-key: <value> (Anthropic SDK default). AuthSchemeXAPIKey = "x-api-key" )
Auth scheme names: how a resolved credential value authenticates a request.
const ( // CredAPIKey is a static API key from env / keychain / .env. CredAPIKey = "api_key" // CredOAuthMintKey is an OAuth login that mints a normal (non-refreshing) API key. CredOAuthMintKey = "oauth_mint_key" // CredOAuthToken is an OAuth login yielding a refreshable access token. CredOAuthToken = "oauth_token" // CredNone marks a provider that needs no credential (local servers such as // Ollama or llama.cpp). Resolution yields a fixed placeholder value. CredNone = "none" )
Credential method kinds (mirror config.AuthKind without importing config).
const ( // FlowOAuthPKCEToken is PKCE auth-code → direct bearer access token (Anthropic). FlowOAuthPKCEToken = "oauth_pkce_token" // FlowOAuthCodex is the ChatGPT/Codex browser + device-code flow. FlowOAuthCodex = "oauth_codex" // FlowOAuthPKCEMint is PKCE → minted user API key (OpenRouter). FlowOAuthPKCEMint = "oauth_pkce_mint" )
OAuth flow names: select the compiled auth.Provider implementation.
const ( // ProducerAnthropicOAuth adds the anthropic-beta header an OAuth bearer needs. ProducerAnthropicOAuth = "anthropic_oauth" // ProducerCodexOAuth adds the Codex backend headers (chatgpt-account-id, beta). ProducerCodexOAuth = "codex_oauth" )
ExtraHeaders producer names: compiled functions that derive extra request headers from a resolved credential value. The set is closed.
const SchemaVersion = 1
SchemaVersion is the highest providers.json schema_version this binary understands. Files declaring a newer version are rejected at load.
Variables ¶
var URLDenied func(string) bool
URLDenied, when non-nil, reports whether a provider/auth URL is blocked by the user's deny_list. It is injected by internal/config at startup so the providers package stays free of internal imports (avoiding an import cycle). Validation rejects any spec URL for which URLDenied returns true.
Functions ¶
func Configure ¶
Configure loads the embedded defaults, overlays each existing path in order (later wins, merged by id), validates, and installs the result as the process-wide registry. Missing paths are skipped. On any error the previous registry is left intact and the error is returned.
func IsReasoningModel ¶
IsReasoningModel reports whether a bare model name belongs to a reasoning-capable family that accepts the OpenAI reasoning_effort knob. Used for the openai_reasoning default-effort policy.
Types ¶
type AuthLogin ¶
type AuthLogin struct {
ID string `json:"id"`
Flow string `json:"flow"`
ClientID string `json:"client_id"`
ClientIDB64 string `json:"client_id_b64"`
AuthorizeURL string `json:"authorize_url"`
TokenURL string `json:"token_url"`
KeysURL string `json:"keys_url"` // mint flow
CallbackPort int `json:"callback_port"`
CallbackPath string `json:"callback_path"`
RedirectURI string `json:"redirect_uri"`
Scope string `json:"scope"`
Originator string `json:"originator"`
ExtraAuthorizeParams map[string]string `json:"extra_authorize_params"`
Device *DeviceSpec `json:"device"`
}
AuthLogin describes one OAuth login flow, keyed by a login id that may differ from a transport provider id (e.g. "openai-codex"). A credential method references it by LoginID.
type CredentialMethod ¶
type CredentialMethod struct {
Kind string `json:"kind"` // api_key | oauth_mint_key | oauth_token | none
EnvVar string `json:"env_var"`
Keyring string `json:"keyring"`
LoginID string `json:"login_id"` // oauth_*: internal/auth login id
BaseURL string `json:"base_url"` // endpoint override implied by this method
HeaderStyle string `json:"header_style"` // "" | "bearer"
ExtraHeadersProducer string `json:"extra_headers_producer"` // "" | anthropic_oauth | codex_oauth
// Label is a human-readable name for this method, shown in the credential
// panel and used as the method's stable identity for the default-method
// marker when a provider exposes more than one method of the same kind
// (e.g. MiMo's pay-as-you-go key vs. its Token Plan key).
Label string `json:"label"`
// RequiresBaseURL marks a method whose endpoint is supplied by the user at
// credential-entry time (e.g. MiMo Token Plan's region-specific base URL),
// rather than baked into the provider spec. The UI prompts for it and it is
// stored alongside the key.
RequiresBaseURL bool `json:"requires_base_url"`
// BaseURLEnv, when set, is an environment variable that overrides the stored
// user-supplied base URL for a RequiresBaseURL method.
BaseURLEnv string `json:"base_url_env"`
}
CredentialMethod is one ordered way to obtain a credential for a provider.
type DeviceSpec ¶
type DeviceSpec struct {
UserCodeURL string `json:"user_code_url"`
TokenURL string `json:"token_url"`
VerificationURI string `json:"verification_uri"`
RedirectURI string `json:"redirect_uri"`
TimeoutSeconds int `json:"timeout_seconds"`
}
DeviceSpec holds the RFC 8628 device-code endpoints for a flow that supports a headless path (Codex).
type File ¶
type File struct {
SchemaVersion int `json:"schema_version"`
Providers []ProviderSpec `json:"providers"`
AuthLogins []AuthLogin `json:"auth_logins"`
}
File is the top-level providers.json document.
type InferenceSpec ¶
type InferenceSpec struct {
BaseURL string `json:"base_url"`
AuthScheme string `json:"auth_scheme"` // bearer | x-api-key
AuthHeader string `json:"auth_header"` // for non-standard raw schemes; usually empty
Headers map[string]string `json:"headers"` // static request headers
QueryParams map[string]string `json:"query_params"` // appended to every request
JSONSet map[string]any `json:"json_set"` // injected into every request body
EffortStyle string `json:"effort_style"` // chat_completions only
}
InferenceSpec holds the data needed to build a wire client. String values may contain ${env:VAR} / ${env:VAR:-default} interpolation, resolved when the inference layer constructs a client (see Resolve).
func (InferenceSpec) Resolve ¶
func (in InferenceSpec) Resolve() InferenceSpec
ResolveInference returns a copy of in with every string field expanded via interpolate and empty query-param values dropped. The inference layer calls this when constructing a client so env-driven overrides (base URLs, region, attribution headers, group id) take effect without per-provider Go code.
type ModelSpec ¶
type ModelSpec struct {
Spec string `json:"spec"` // full prefixed identifier, e.g. "anthropic/claude-opus-4-8"
DisplayName string `json:"display_name"`
// ContextWindow is the input context window in tokens. 0 (omitted) means
// unknown: callers render it as "—" and disable auto-compaction.
ContextWindow int64 `json:"context_window,omitempty"`
}
ModelSpec is one catalogue entry shown in the model picker.
type ProviderSpec ¶
type ProviderSpec struct {
ID string `json:"id"`
DisplayName string `json:"display_name"`
ModelPrefix string `json:"model_prefix"` // without trailing slash, e.g. "anthropic"
WireFormat WireFormat `json:"wire_format"`
EffortPolicy string `json:"effort_policy"`
Inference InferenceSpec `json:"inference"`
Credential []CredentialMethod `json:"credential_methods"`
Models []ModelSpec `json:"models"`
// Local marks a provider backed by a user-run local server (Ollama,
// llama.cpp). Local providers may use a loopback http:// base URL, are
// grouped separately in the TUI, and their model list is discovered live
// from the server rather than from the static catalogue.
Local bool `json:"local,omitempty"`
}
ProviderSpec is one transport provider: how vix reaches it, how it authenticates, and which models it exposes in the picker.
func (ProviderSpec) DefaultEffort ¶
func (p ProviderSpec) DefaultEffort(model string) string
DefaultEffort returns the default reasoning effort for a bare model name under the provider's effort policy.
func (ProviderSpec) Prefix ¶
func (p ProviderSpec) Prefix() string
Prefix returns the model-spec prefix including the trailing slash.
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry is an immutable, validated set of provider specs and auth logins, indexed for lookup by id and by model-spec prefix.
func Default ¶
func Default() *Registry
Default returns the process-wide provider registry. On first use it loads the embedded providers.json only; call Configure first to overlay on-disk layers.
func (*Registry) All ¶
func (r *Registry) All() []ProviderSpec
All returns every provider spec in declaration order.
func (*Registry) AuthLogins ¶
AuthLogins returns every auth login spec in declaration order.
func (*Registry) ContextWindow ¶
ContextWindow returns the input context window in tokens for a full model spec (e.g. "anthropic/claude-opus-4-8"), or 0 when the model isn't catalogued or has no window recorded. Callers treat 0 as "unknown".
func (*Registry) DisplayName ¶ added in v0.4.1
DisplayName returns the catalogued display name for the model identified by spec (e.g. "anthropic/claude-opus-4-8"). Falls back to the raw spec when the model isn't catalogued, so callers never render a blank name.
func (*Registry) Lookup ¶
func (r *Registry) Lookup(id string) (ProviderSpec, bool)
Lookup returns the provider spec with the given id.
func (*Registry) ParseModel ¶
func (r *Registry) ParseModel(spec string) (ProviderSpec, string, error)
ParseModel maps a vix-style model spec (with mandatory provider prefix) to its provider spec and bare model name — the first matching prefix wins. Bare unprefixed names error explicitly rather than routing to the wrong provider.
type WireFormat ¶
type WireFormat string
WireFormat selects the compiled inference adapter for a provider. The set is closed; an unknown value is a load-time validation error.
const ( // WireMessages is the Anthropic Messages API (internal/daemon/llm/anthropic.go). WireMessages WireFormat = "messages" // WireResponses is the OpenAI Responses API (internal/daemon/llm/openai.go), // shared by OpenAI and the ChatGPT/Codex backend. WireResponses WireFormat = "responses" // WireChatCompletions is the OpenAI-compatible Chat Completions API // (internal/daemon/llm/chat_completions.go), shared by OpenRouter, MiniMax, // MiMo, and any other OpenAI-compatible vendor. WireChatCompletions WireFormat = "chat_completions" )