providers

package
v0.5.0 Latest Latest
Warning

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

Go to latest
Published: Jun 14, 2026 License: AGPL-3.0 Imports: 7 Imported by: 0

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

View Source
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).

View Source
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.

View Source
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.

View Source
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).

View Source
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.

View Source
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.

View Source
const SchemaVersion = 1

SchemaVersion is the highest providers.json schema_version this binary understands. Files declaring a newer version are rejected at load.

Variables

View Source
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

func Configure(paths []string) error

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

func IsReasoningModel(model string) bool

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) AuthLogin

func (r *Registry) AuthLogin(id string) (AuthLogin, bool)

AuthLogin returns the auth login spec with the given id.

func (*Registry) AuthLogins

func (r *Registry) AuthLogins() []AuthLogin

AuthLogins returns every auth login spec in declaration order.

func (*Registry) ContextWindow

func (r *Registry) ContextWindow(spec string) int64

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

func (r *Registry) DisplayName(spec string) string

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) IDs

func (r *Registry) IDs() []string

IDs returns every provider id in declaration order.

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.

func (*Registry) Prefixes

func (r *Registry) Prefixes() []string

Prefixes returns every registered model-spec prefix (with trailing slash) in declaration order — used for ParseModel error hints.

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"
)

Jump to

Keyboard shortcuts

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