Help us shape the future of Go! Take the 2026 Go Developer Survey

providers

package
v2.0.0 Latest Latest
Warning

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

Go to latest
Published: Oct 9, 2026 License: MIT Imports: 21 Imported by: 0

Documentation

Overview

Package providers handles LLM provider model listing and management.

Package providers handles LLM provider capabilities and model management.

Index

Constants

This section is empty.

Variables

View Source
var DeprecatedModels = map[string]string{
	"grok-4-1-fast":               "grok-4.20-0309-non-reasoning",
	"grok-4-1-fast-reasoning":     "grok-4.20-0309-non-reasoning",
	"grok-4-1-fast-non-reasoning": "grok-4.20-0309-non-reasoning",
	"grok-4-1-reasoning":          "grok-4.20-0309-non-reasoning",
	"grok-4-1":                    "grok-4.20-0309-non-reasoning",
}

DeprecatedModels maps Grok models that xAI silently ROUTES to the cost-prohibitive grok-4.3 (the grok-4-1-* family) to a safe replacement (#51). config's reconcileModel migrates them; ResolveModel never picks one.

View Source
var Registry = map[string]ProviderCapabilities{

	"openai": {
		Name:                    "OpenAI",
		BaseURL:                 "https://api.openai.com/v1",
		SupportsFunctionCalling: true,
		SupportsModelListing:    true,
		SupportsTokenTracking:   true,
		DefaultModel:            "gpt-4.1-nano",
		PreferredToolModel:      "gpt-4.1-nano",
		RequiresAPIKey:          true,
		IsOpenAICompatible:      true,
		SupportsResponses:       true,
		Notes:                   "Native function calling support. Gold standard implementation.",
	},

	"grok": {
		Name:                    "xAI Grok",
		BaseURL:                 "https://api.x.ai/v1",
		SupportsFunctionCalling: true,
		SupportsModelListing:    true,
		SupportsTokenTracking:   true,
		DefaultModel:            "grok-4.20-0309-non-reasoning",
		PreferredToolModel:      "grok-4.20-0309-non-reasoning",
		RequiresAPIKey:          true,
		IsOpenAICompatible:      true,
		Notes:                   "Default grok-4.20-0309-non-reasoning: reliable tool calling, no reasoning-token burn, never routes to the cost-prohibitive grok-4.3. Avoid grok-4-1-* (they route to grok-4.3).",
	},

	"venice": {
		Name:                    "Venice.ai",
		BaseURL:                 "https://api.venice.ai/api/v1",
		SupportsFunctionCalling: false,
		SupportsModelListing:    true,
		SupportsTokenTracking:   true,

		DefaultModel:       "venice-uncensored-1-2",
		PreferredToolModel: "",
		RequiresAPIKey:     true,
		IsOpenAICompatible: true,
		ToolsPerModel:      true,
		Notes:              "NSFW mode uses Venice. No function calling in uncensored mode. Image generation available.",
	},

	"anthropic": {
		Name:                    "Anthropic Claude",
		BaseURL:                 "https://api.anthropic.com",
		SupportsFunctionCalling: true,
		SupportsModelListing:    true,
		SupportsTokenTracking:   true,
		DefaultModel:            "claude-sonnet-4-5-20250929",
		PreferredToolModel:      "claude-sonnet-4-5-20250929",
		RequiresAPIKey:          true,
		IsOpenAICompatible:      false,
		Notes:                   "Advanced tool use features. OpenAI SDK compatibility is for testing only. Native API recommended.",
	},

	"gemini": {
		Name:                    "Google Gemini AI (AI Studio)",
		BaseURL:                 "https://generativelanguage.googleapis.com/v1beta",
		SupportsFunctionCalling: true,
		SupportsModelListing:    false,
		SupportsTokenTracking:   true,

		DefaultModel:       "gemini-flash-latest",
		PreferredToolModel: "gemini-flash-latest",
		RequiresAPIKey:     true,
		IsOpenAICompatible: false,
		Notes:              "RECOMMENDED: Native Google GenAI SDK with automatic authentication. Simple API keys (AIza...), free tier available. Full function calling support with streaming. Get key: https://aistudio.google.com/apikey",
	},

	"vertex": {
		Name:                    "Google Vertex AI (Cloud)",
		BaseURL:                 "https://aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION",
		SupportsFunctionCalling: true,
		SupportsModelListing:    false,
		SupportsTokenTracking:   true,

		DefaultModel:           "gemini-2.0-flash",
		PreferredToolModel:     "gemini-2.0-flash",
		DefaultModelUnverified: true,
		RequiresAPIKey:         false,
		IsOpenAICompatible:     false,
		Notes:                  "ENTERPRISE: Native Google GenAI SDK with automatic authentication. No manual token refresh! Use: (1) gcloud auth application-default login OR (2) Service account JSON. Tokens auto-refresh indefinitely. Requires GCP project + billing.",
	},

	"local": {
		Name:                    "Local (OpenAI-compatible)",
		BaseURL:                 "",
		SupportsFunctionCalling: true,

		SupportsModelListing:  false,
		SupportsTokenTracking: true,
		DefaultModel:          "",
		PreferredToolModel:    "",
		RequiresAPIKey:        false,
		IsOpenAICompatible:    true,
		ExampleBaseURL:        "http://127.0.0.1:8080/v1",
		Notes:                 "Any OpenAI-compatible server on this machine or the LAN: loopback, private IPs, single-label names, .local/.lan/.internal/.home.arpa (mlx-vlm, Ollama, LM Studio, llama.cpp). Set the model to whatever the server expects — mlx-vlm wants the full filesystem path. No API key required.",
	},

	"openrouter": {
		Name:                    "OpenRouter",
		BaseURL:                 "https://openrouter.ai/api/v1",
		SupportsFunctionCalling: true,
		SupportsModelListing:    true,
		SupportsTokenTracking:   true,
		DefaultModel:            "openai/gpt-4.1-nano",
		PreferredToolModel:      "openai/gpt-4.1-nano",
		RequiresAPIKey:          true,
		IsOpenAICompatible:      true,
		Notes:                   "Aggregator for multiple providers. Full OpenAI compatibility. Parallel function calling supported.",
	},

	"sakana": {
		Name:                    "Sakana AI",
		BaseURL:                 "https://api.sakana.ai/v1",
		SupportsFunctionCalling: true,
		SupportsModelListing:    true,
		SupportsTokenTracking:   true,
		DefaultModel:            "fugu",
		PreferredToolModel:      "fugu",
		RequiresAPIKey:          true,
		IsOpenAICompatible:      true,

		Notes: "Fugu / Fugu Ultra (1M context, deep reasoning). Fugu Ultra routes 1-3 expert agents. OpenAI-compatible chat completions. Install: curl -fsSL https://sakana.ai/fugu/install | bash",
	},

	"digitalocean": {
		Name:                    "DigitalOcean Gradient",
		BaseURL:                 "",
		ExampleBaseURL:          "https://your-agent.ondigitalocean.app/api/v1",
		SupportsFunctionCalling: false,
		SupportsModelListing:    false,
		SupportsTokenTracking:   true,
		DefaultModel:            "gpt-4.1-nano",
		PreferredToolModel:      "",
		RequiresAPIKey:          true,
		IsOpenAICompatible:      true,
		Notes:                   "Agent API with RAG capabilities. Token tracking supported via stream_options. Function calling requires cloud-hosted functions.",
	},

	"elevenlabs": {
		Name:                    "ElevenLabs",
		BaseURL:                 "https://api.elevenlabs.io/v1",
		SupportsFunctionCalling: false,
		SupportsModelListing:    false,
		SupportsTokenTracking:   false,
		DefaultModel:            "",
		PreferredToolModel:      "",
		RequiresAPIKey:          true,
		IsOpenAICompatible:      false,
		Notes:                   "Voice AI provider. Function calling support unknown.",
	},
}

Registry holds all supported provider configurations. Ordered by priority: Popular/Tested → OpenAI-Compatible → Untested

Functions

func CatalogToolSupport

func CatalogToolSupport(provider, modelID string) (supported, known bool)

CatalogToolSupport reports what the provider's own catalog says about a model's tool calling. known is false when no catalog is loaded, the model isn't listed, or the listing doesn't say. An OpenRouter ":variant" suffix falls back to the base id.

func CleanBaseURL

func CleanBaseURL(baseURL string) string

CleanBaseURL is a base URL safe to log: no userinfo, query or fragment.

func DetectProvider

func DetectProvider(baseURL string) string

DetectProvider attempts to detect provider from base URL.

func EndpointID

func EndpointID(provider, baseURL, apiKey string) string

EndpointID names one endpoint's catalog (provider, base URL, key hash) without the key, so callers can tell whether two lookups share one.

func ForgetCatalogsForTest

func ForgetCatalogsForTest()

ForgetCatalogsForTest is for tests only: it drops every catalog loaded in this process, so a test that fetched one doesn't leak it into the next.

func GetPerModelToolProviders

func GetPerModelToolProviders() []string

GetPerModelToolProviders returns the providers with no default tool support whose tool support is decided per model (ToolsPerModel), sorted.

func GetToolCallingProviders

func GetToolCallingProviders() []string

GetToolCallingProviders returns only providers that support function calling.

func HasCatalog

func HasCatalog(provider string) bool

HasCatalog reports whether celeste can list the models a provider serves. Gemini, Vertex, DigitalOcean, local servers and ElevenLabs have none.

func HasModelEndpoint

func HasModelEndpoint(provider string) bool

HasModelEndpoint reports whether the provider answers GET /models/{id}.

func IsAnthropicURL

func IsAnthropicURL(baseURL string) bool

IsAnthropicURL reports whether baseURL points at Anthropic: its host is anthropic.com or a subdomain of it, in any case, with or without a trailing dot or port. It is the one rule both DetectProvider (the header, capabilities, context windows) and the llm backend choice use (#372). A URL without a scheme is read as https.

func IsGeminiURL

func IsGeminiURL(baseURL string) bool

IsGeminiURL reports whether baseURL's host is Google AI Studio's generativelanguage.googleapis.com.

func IsGoogleURL

func IsGoogleURL(baseURL string) bool

IsGoogleURL reports whether baseURL is Gemini (AI Studio) or Vertex AI: the endpoints the native Google backend serves.

func IsLocalEndpoint

func IsLocalEndpoint(baseURL string) bool

IsLocalEndpoint reports whether baseURL is a server on this machine or the local network. It is IsLocalHost: one rule for the timeouts, the window probe and fallback, and the "local" provider (#377).

func IsLocalHost

func IsLocalHost(baseURL string) bool

IsLocalHost reports whether baseURL's parsed host is this machine or the local network: localhost, a loopback, private, link-local or unspecified IP, a single-label host, or a .local, .lan, .internal or .home.arpa name. A hosted URL that merely contains "localhost" in its path is not local. Such a server runs the model on the user's own hardware, which can take minutes before the first byte.

func IsVertexURL

func IsVertexURL(baseURL string) bool

IsVertexURL reports whether baseURL's host is Vertex AI's aiplatform.googleapis.com, global or regional (REGION-aiplatform...).

func IsXAIURL

func IsXAIURL(baseURL string) bool

IsXAIURL reports whether baseURL's host is x.ai or a subdomain of it. It is the one rule DetectProvider ("grok") and the llm backend choice use.

func ListProviders

func ListProviders() []string

ListProviders returns all provider names.

func OrchestratesServerSide

func OrchestratesServerSide(provider, modelID string) bool

OrchestratesServerSide reports whether the model does its own task decomposition, delegation and verification server-side, which makes celeste-cli's local planning phase redundant. Fugu is a trained conductor: it either answers directly or coordinates several frontier models and synthesises the result. Running our planner on top of it means two planners that cannot see each other.

This is deliberately a rule rather than a lookup against the static model list. Sakana ships version-bumped fugu IDs faster than that list is updated, and an unrecognised ID must not silently re-enable local planning against a conductor. The provider is checked too: Sakana serves an OpenAI-compatible API and could host a plain model, which still needs local planning.

func PrepareModels

func PrepareModels(ctx context.Context, provider, baseURL, apiKey string, models ...string)

PrepareModels loads an endpoint's catalog (the cache, or one fetch bounded by the timeout; a fetch that failed in the last five minutes is not retried) and, for providers that answer GET /models/{id}, checks each given model the catalog doesn't list. The answers stay in memory for ResolveFromMemory. It may block on the network: never call it from a Bubble Tea Update.

func ResolveFromMemory

func ResolveFromMemory(provider, baseURL, apiKey, configured string) (model, note string, pending bool)

ResolveFromMemory resolves configured against what this process knows the endpoint serves, with no I/O. A model is replaced only when celeste is sure it's gone: the catalog doesn't list it and, where the provider can say, GET /models/{id} answered 404. pending is true when PrepareModels would know more (no catalog loaded yet, a stale one, or an unchecked miss); until then the configured model is kept. A miss in a list older than the TTL is not proof either.

func ResolveModel

func ResolveModel(provider, configured string, cat []CatalogModel, ok bool) (model, note string)

ResolveModel picks the model a session uses from what the provider serves now, so a retired model is never sent. Pure; ok is false when there is no catalog (offline, no key, a provider without one).

  1. No catalog: the configured model, unchanged (the registry default when nothing is configured).
  2. The configured model is served: keep it.
  3. Otherwise, in order: the provider-flagged default; the newest served version of the configured model (its ID plus "-", "." or ":" and more); the registry default or preferred tool model, if served; the first tool-capable served model; the first served model.

Among ties (several flagged defaults or versions) a tool-capable model wins. The note says what happened; it is empty when nothing was replaced.

func SetCatalogFetchForTest

func SetCatalogFetchForTest(fetch func(ctx context.Context, provider, baseURL, apiKey string) ([]CatalogModel, error)) (restore func())

SetCatalogFetchForTest is for tests only: it replaces the /models fetch, so tests in other packages can see what a fetch was asked (its context, endpoint) without the network. Call the returned func to restore.

func SetCatalogForTest

func SetCatalogForTest(provider string, models []CatalogModel) (restore func())

SetCatalogForTest is for tests only. It makes provider's catalog the given models in every lookup (CachedCatalog, CatalogFor, LoadCatalog, RefreshCatalog), so no test reaches the network or the disk cache. A nil or empty list means "no catalog". Call the returned func to restore. It lives outside a _test.go file because tests in other packages (tui, main) need it.

func ToolsEnabledForModel

func ToolsEnabledForModel(provider, modelID string) bool

ToolsEnabledForModel reports whether celeste should offer tool calling for this provider/model pair. Most providers decide at the provider level (SupportsFunctionCalling); a ToolsPerModel provider (Venice) decides per model instead, since most of its models have no tool support but some do (#151). The chat's skillsEnabled gate calls this instead of reading SupportsFunctionCalling directly, so Venice stops being "no tools" for every model.

Types

type CatalogModel

type CatalogModel struct {
	ID string `json:"id"`
	// Tools is the provider's own word on tool calling; nil when the listing
	// doesn't say (most OpenAI-compatible APIs).
	Tools *bool `json:"tools,omitempty"`
	// Default marks the model the provider itself flags as its default
	// (Venice's "default" trait).
	Default bool `json:"default,omitempty"`
}

CatalogModel is one model a provider serves now, from its /models listing.

func CachedCatalog

func CachedCatalog(provider, baseURL, apiKey string) (models []CatalogModel, stale, ok bool)

CachedCatalog returns the cached catalog for an endpoint, from memory or the disk cache, without touching the network. stale is true when it is older than the TTL; the caller decides whether to refresh it.

func CatalogFor

func CatalogFor(provider string) ([]CatalogModel, bool)

CatalogFor returns the catalog most recently loaded in this process for a provider, whatever its endpoint. It never reads disk or the network: the tool gate calls it from the TUI's Update.

func FindServed

func FindServed(cat []CatalogModel, modelID string) (CatalogModel, bool)

FindServed looks a model up in a catalog the way resolution does (case ignored, OpenRouter :variant rules).

func LoadCatalog

func LoadCatalog(ctx context.Context, provider, baseURL, apiKey string) ([]CatalogModel, bool)

LoadCatalog returns the endpoint's catalog: the cached one when there is one (a stale cache is refreshed in the background), else a synchronous fetch bounded by catalogFetchTimeout. A fetch that failed less than five minutes ago is not retried. ok is false when there is no catalog. Never call it from a Bubble Tea Update.

func MemoryCatalog

func MemoryCatalog(provider, baseURL, apiKey string) (models []CatalogModel, stale, ok bool)

MemoryCatalog is CachedCatalog without the disk: it only sees catalogs already loaded in this process, so the TUI's Update can call it.

func RefreshCatalog

func RefreshCatalog(ctx context.Context, provider, baseURL, apiKey string) ([]CatalogModel, error)

RefreshCatalog fetches the endpoint's catalog and caches it. A failed fetch leaves the existing cache alone and is remembered for the negative window.

type ModelDetection

type ModelDetection struct {
	// contains filtered or unexported fields
}

ModelDetection provides heuristics for detecting model capabilities.

func NewModelDetection

func NewModelDetection(provider string) *ModelDetection

NewModelDetection creates a model detection helper.

func (*ModelDetection) SupportsTools

func (d *ModelDetection) SupportsTools(modelID string) bool

SupportsTools determines if a model supports function calling.

type ModelInfo

type ModelInfo struct {
	ID            string
	Name          string
	SupportsTools bool
	ContextWindow int
	Description   string
	Provider      string
	// OrchestratesServerSide mirrors OrchestratesServerSide(Provider, ID) so
	// display surfaces (/config, the model picker) can show it without
	// recomputing. The function stays the single source of truth.
	OrchestratesServerSide bool
}

ModelInfo represents metadata about a model.

func ModelInfosFromCatalog

func ModelInfosFromCatalog(provider string, cat []CatalogModel) []ModelInfo

ModelInfosFromCatalog turns a catalog into display rows, tool-capable models first. Tool support comes from the catalog when it says, else from the name heuristic.

func StaticModels

func StaticModels(provider string) []ModelInfo

StaticModels is the offline model list for a provider, used when no catalog is loaded.

type ModelService

type ModelService struct {
	// contains filtered or unexported fields
}

ModelService handles model listing and metadata.

func NewModelService

func NewModelService(apiKey, baseURL, provider string) *ModelService

NewModelService creates a new model service for a provider.

type ProviderCapabilities

type ProviderCapabilities struct {
	Name                    string
	BaseURL                 string
	SupportsFunctionCalling bool
	SupportsModelListing    bool
	SupportsTokenTracking   bool // Returns usage data with stream_options
	DefaultModel            string
	PreferredToolModel      string // Best model for function calling
	RequiresAPIKey          bool
	IsOpenAICompatible      bool
	Notes                   string
	// ToolsPerModel marks a provider with no tool support by default whose
	// catalogue has some tool-capable models (checked live per model, see
	// ModelDetection.SupportsTools). SupportsFunctionCalling stays false: it
	// drives the TUI's skill gate for the provider's default model.
	ToolsPerModel bool
	// DefaultModelUnverified marks a shipped default model nobody has
	// checked against the live service.
	DefaultModelUnverified bool
	// ExampleBaseURL is shown by `providers info` when BaseURL is empty
	// because the endpoint is the user's own (a local server, a DO agent).
	ExampleBaseURL string
	// SupportsResponses marks an OpenAI-compatible provider whose endpoint
	// serves the OpenAI Responses API; celeste then talks to it through
	// /v1/responses instead of Chat Completions (2.0 W8).
	SupportsResponses bool
}

ProviderCapabilities defines what a provider supports.

func GetProvider

func GetProvider(name string) (ProviderCapabilities, bool)

GetProvider returns provider capabilities by name.

Jump to

Keyboard shortcuts

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