providers

package
v1.11.0 Latest Latest
Warning

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

Go to latest
Published: Sep 7, 2026 License: MIT Imports: 28 Imported by: 0

Documentation

Index

Constants

View Source
const (
	ClaudeCodeProviderID   = "claude-code"
	ClaudeCodeDefaultModel = "default"
	ClaudeCodeCheapModel   = "haiku"

	ClaudeCodeFieldBinary = "binary"
	ClaudeCodeEnvBinary   = "ASK_CLAUDE_BIN"
	ClaudeCodeDefaultBin  = "claude"

	ClaudeCodeContextWindow  = 200_000
	ClaudeCodeMaxOutputToken = 64_000
)
View Source
const (
	ModelsDevDefaultURL = "https://models.dev/api.json"
	ModelsDevCacheTTL   = 24 * time.Hour
)
View Source
const (
	OpenRouterProviderID     = "openrouter"
	OpenRouterDefaultModel   = "anthropic/claude-3.7-sonnet"
	OpenRouterDefaultBaseURL = "https://openrouter.ai/api/v1"
	OpenRouterEnvAPIKey      = "OPENROUTER_API_KEY"

	OpenRouterFieldAPIKey  = "apiKey"
	OpenRouterFieldBaseURL = "baseURL"
)
View Source
const (
	VertexProviderID              = "vertex"
	VertexDefaultModel            = "gemini-3.7-flash"
	VertexDefaultLocation         = "global"
	VertexContextWindow           = 1_048_576
	VertexFallbackMaxOutputTokens = 65_536

	VertexEnvApplicationCredentials = "GOOGLE_APPLICATION_CREDENTIALS"
	VertexEnvCloudProject           = "GOOGLE_CLOUD_PROJECT"

	VertexFieldProject           = "project"
	VertexFieldLocation          = "location"
	VertexFieldServiceAccountKey = "serviceAccountKey"
)
View Source
const MaxOutputTokensGemini int64 = 65_536

MaxOutputTokensGemini is the maximum output token limit for Gemini 3.7 Flash and Gemini models.

Variables

View Source
var (
	ModelsDevURL        = ModelsDevDefaultURL
	ModelsDevHTTPClient = http.DefaultClient
	ModelsDevCachePath  = func() (string, error) {
		home, err := os.UserHomeDir()
		if err != nil {
			return "", err
		}
		return filepath.Join(home, ".config", "ask", "cache", "models-dev.json"), nil
	}
)
View Source
var ClaudeCodeEffortOptions = []string{"low", "medium", "high", "xhigh", "max"}

ClaudeCodeEffortOptions are the CLI's effort levels; ask's global picker offers the first three.

View Source
var ClaudeCodeModelOptions = CatalogModelIDs(ClaudeCodeProviderID)

ClaudeCodeModelOptions are the catalog ids the picker shows for Claude Code.

View Source
var GlobalEffortOptions = []string{"low", "medium", "high"}

GlobalEffortOptions are the standard reasoning effort levels.

View Source
var ListOpenRouterModels = func(ctx context.Context, pc config.ProviderConfig) ([]string, error) {
	metas, err := fetchOpenRouterModels(ctx, ResolveOpenRouterBaseURL(pc))
	if err != nil {
		return nil, err
	}
	cacheOpenRouterMeta(metas)
	ids := make([]string, 0, len(metas))
	for _, m := range metas {
		ids = append(ids, m.ID)
	}
	return ids, nil
}
View Source
var ListVertexModels = func(ctx context.Context, pc config.ProviderConfig) ([]string, error) {
	client, err := VertexNewClient(ctx, pc)
	if err != nil {
		return nil, err
	}
	var models []string
	page, err := client.Models.List(ctx, nil)
	if err != nil {
		return nil, err
	}
	for _, m := range page.Items {
		name := m.Name
		name = strings.TrimPrefix(name, "publishers/google/models/")
		name = strings.TrimPrefix(name, "models/")
		if strings.Contains(strings.ToLower(name), "claude") || strings.Contains(strings.ToLower(name), "anthropic") {
			continue
		}
		if name != "" {
			models = append(models, name)
		}
	}
	return models, nil
}

ListVertexModels queries the Vertex AI / Gemini API dynamically for available models.

View Source
var ModelMetaLookup = ModelMetaFor

ModelMetaLookup is the seam StepCostUSD reads through; tests swap it to stand in for the models.dev / live-listing layers.

View Source
var OpenRouterEffortOptions = GlobalEffortOptions
View Source
var OpenRouterModelBuilder = func(ctx context.Context, pc config.ProviderConfig, modelID string) (model.LLM, error) {
	apiKey := ResolveOpenRouterAPIKey(pc)
	if apiKey == "" {
		return nil, MissingAPIKeyError(OpenRouterEnvAPIKey)
	}
	baseURL := ResolveOpenRouterBaseURL(pc)
	return NewOpenAICompatModel(OpenAICompatConfig{
		ModelID:         modelID,
		APIKey:          apiKey,
		BaseURL:         baseURL,
		Headers:         openRouterHeaders(),
		EncodeReasoning: openRouterReasoningEncoder(baseURL),
	}), nil
}
View Source
var OpenRouterModelOptions = CatalogModelIDs(OpenRouterProviderID)
View Source
var VertexCredentialsLoader = func(path string) (*auth.Credentials, error) {
	return credentials.NewCredentialsFromFile(credentials.ServiceAccount, path, &credentials.DetectOptions{
		Scopes: []string{"https://www.googleapis.com/auth/cloud-platform"},
	})
}

VertexCredentialsLoader is the swappable loader for service account *auth.Credentials.

View Source
var VertexEffortOptions = GlobalEffortOptions
View Source
var VertexModel = func(ctx context.Context, pc config.ProviderConfig, modelID string) (model.LLM, error) {
	cfg, err := vertexClientConfig(pc)
	if err != nil {
		return nil, err
	}
	return gemini.NewModel(ctx, modelID, cfg)
}

VertexModel constructs a model.LLM backed by Vertex AI via ADK's gemini package. Swappable in tests.

View Source
var VertexNewClient = func(ctx context.Context, pc config.ProviderConfig) (*genai.Client, error) {
	cfg, err := vertexClientConfig(pc)
	if err != nil {
		return nil, err
	}
	return genai.NewClient(ctx, cfg)
}

VertexNewClient constructs a genai.Client configured for Vertex AI — the model listing needs the raw client. Swappable in tests.

View Source
var VertexPrepareCredentials = func(pc config.ProviderConfig) (*auth.Credentials, error) {
	saKeyPath := VertexResolveServiceAccountKey(pc)
	if saKeyPath == "" {
		return nil, nil
	}
	if _, err := os.Stat(saKeyPath); err != nil {
		return nil, fmt.Errorf("vertex: read service account key %s: %w", saKeyPath, err)
	}
	return VertexCredentialsLoader(saKeyPath)
}

VertexPrepareCredentials resolves the SA key path, validates it is readable, and loads *auth.Credentials; nil credentials mean ADC.

Functions

func CanonicalClaudeCodeModelID

func CanonicalClaudeCodeModelID(modelID string, fallback ...string) string

CanonicalClaudeCodeModelID passes through a known alias or full model name; only an empty id falls back. The CLI accepts aliases ("opus") and full names ("claude-opus-5") alike, so ask does not second-guess an unrecognized id.

func CanonicalOpenRouterModelID

func CanonicalOpenRouterModelID(modelID string, fallback ...string) string

CanonicalOpenRouterModelID normalizes the model ID and falls back to fallback if the model ID is empty.

func CanonicalVertexModelID

func CanonicalVertexModelID(modelID string, fallback ...string) string

CanonicalVertexModelID normalizes the model ID and falls back to fallback (or VertexDefaultModel) if the model ID is empty or represents a legacy/unrecognized model from another provider.

func CatalogClampEffort

func CatalogClampEffort(provider string, modelID, effort string) string

CatalogClampEffort clamps a picked effort onto what the model actually offers.

func CatalogContextWindow

func CatalogContextWindow(provider string, modelID string, fallback int64) int64

CatalogContextWindow returns the model's context window, or fallback.

func CatalogDefaultMaxTokens

func CatalogDefaultMaxTokens(provider string, modelID string, fallback int64) int64

CatalogDefaultMaxTokens returns the model's published default max-output-tokens budget, or fallback.

func CatalogModelIDs

func CatalogModelIDs(provider string) []string

CatalogModelIDs returns the provider's model ids in catalog order.

func CatalogResolveEffort

func CatalogResolveEffort(providerID string, modelID, effort string) string

CatalogResolveEffort maps global abstract effort levels onto concrete ReasoningLevels.

func CatalogSupportsImages

func CatalogSupportsImages(provider string, modelID string, fallback ...bool) bool

CatalogSupportsImages reports image-attachment capability, defaulting to fallback.

func CheapestModel

func CheapestModel(providerID string) string

CheapestModel picks the provider's cheapest model: the one it names through CheapModeler, else the lowest list price (input plus output USD per 1M) among its catalog options, skipping deprecated ones; with no known price it falls back to the provider's default model.

func ClaudeCodeResolveBinary

func ClaudeCodeResolveBinary(pc config.ProviderConfig) string

ClaudeCodeResolveBinary: config value wins, then ASK_CLAUDE_BIN, then the default "claude".

func DefaultProviderID

func DefaultProviderID() string

DefaultProviderID is the id of the first registered provider — what an empty config resolves to.

func FilterVertexModelOptions

func FilterVertexModelOptions(all []string) []string

FilterVertexModelOptions strips Claude / Anthropic ids from the Vertex model list.

func LoadModelsDev

func LoadModelsDev(ctx context.Context) error

LoadModelsDev makes models.dev data available to ModelsDevMeta: memory first, then a disk cache younger than ModelsDevCacheTTL, then the network (refreshing the disk cache). A failed fetch falls back to a stale disk cache rather than returning nothing.

func MissingAPIKeyError

func MissingAPIKeyError(envKey string, hint ...string) error

MissingAPIKeyError returns a descriptive error when an API key is missing.

func ModelsDevLoaded

func ModelsDevLoaded() bool

func NewOpenAICompatModel

func NewOpenAICompatModel(cfg OpenAICompatConfig) model.LLM

NewOpenAICompatModel builds an ADK model.LLM backed by the official OpenAI Go SDK, pointed at cfg.BaseURL. The SDK owns the wire protocol (streaming aggregation, tool-call IDs, usage, vision); this type only translates between genai and OpenAI types.

func NormalizeModelID

func NormalizeModelID(modelID string) string

NormalizeModelID trims provider prefixes ("vertex/", "publishers/google/models/", "models/") to ensure model identifiers match registered catalog IDs.

func OpenRouterProviderOptions

func OpenRouterProviderOptions(modelID, effort string) (*genai.GenerateContentConfig, *float64)

OpenRouterProviderOptions carries ask's effort intent through genai's ThinkingConfig and sets the output-token budget. The effort is passed verbatim; the per-model capability gate and clamp live in the reasoning encoder, which has OpenRouter's live model metadata.

func ProviderConfigured

func ProviderConfigured(cfg config.Config, id string) bool

ProviderConfigured reports whether provider id can run with cfg — false for an unknown id or one missing its credentials.

func Register

func Register(p Provider)

Register adds p to the registry, replacing an earlier registration with the same id in place. A malformed provider — empty id, or a setting whose key is empty, duplicated, or reserved — panics: that is a programming error, not a runtime condition.

func ResolveModelID

func ResolveModelID(p Provider, explicit string, cfg config.Config) string

ResolveModelID picks the model a session on p should run: the explicit id when one was given, else the configured one, else the provider default — canonicalized either way.

func ResolveOpenRouterAPIKey

func ResolveOpenRouterAPIKey(pc config.ProviderConfig) string

ResolveOpenRouterAPIKey: config value wins, then OPENROUTER_API_KEY.

func ResolveOpenRouterBaseURL

func ResolveOpenRouterBaseURL(pc config.ProviderConfig) string

ResolveOpenRouterBaseURL: config value wins, then the default endpoint.

func SaveSettings

func SaveSettings(cfg *config.Config, id string, s ProviderSettings)

SaveSettings writes s into cfg under provider id, keeping the provider's declared fields untouched.

func SettingValue

func SettingValue(pc config.ProviderConfig, f SettingField) string

SettingValue resolves f against pc: the stored value, else the env fallback, else the default.

func SteeringPrompt

func SteeringPrompt(opts SteeringOptions) string

func StepCostUSD

func StepCostUSD(providerID, modelID string, inputTokens, outputTokens, cacheWriteTokens, cacheReadTokens int) (float64, bool)

StepCostUSD prices one call's token usage against the model's per-1M rates: cache reads at the cached-input rate, cache writes at the cache-write rate (crush's formula). ok=false when no price is known.

func ValidateVertexLocation

func ValidateVertexLocation(s string) error

ValidateVertexLocation accepts the literal "global" or a region id in the canonical GCP shape ("us-central1", "europe-west4").

func ValidateVertexProject

func ValidateVertexProject(s string) error

ValidateVertexProject screens a project id draft. Empty is invalid: the session would fail at start with "project is required", so the field visibly requires a value instead.

func ValidateVertexServiceAccountKey

func ValidateVertexServiceAccountKey(s string) error

ValidateVertexServiceAccountKey accepts an empty string (ADC) or the path of a readable file, tilde-expanded.

func VertexProviderOptions

func VertexProviderOptions(modelID, effort string) (*genai.GenerateContentConfig, *float64)

VertexProviderOptions translates ask's effort picker onto Gemini's thinking controls and configures max tokens.

func VertexResolveLocation

func VertexResolveLocation(pc config.ProviderConfig) string

VertexResolveLocation: config value wins, then the default location.

func VertexResolveProject

func VertexResolveProject(pc config.ProviderConfig) string

VertexResolveProject: config value wins, then GOOGLE_CLOUD_PROJECT.

func VertexResolveServiceAccountKey

func VertexResolveServiceAccountKey(pc config.ProviderConfig) string

VertexResolveServiceAccountKey: config value wins, then GOOGLE_APPLICATION_CREDENTIALS; "" means ADC. The path is tilde-expanded so a saved "~/keys/vertex.json" works.

func WithObservedToolSink

func WithObservedToolSink(ctx context.Context, sink ObservedToolSink) context.Context

WithObservedToolSink attaches a sink for natively-executed tool activity.

func WithWebSearchAvailable

func WithWebSearchAvailable(ctx context.Context, available bool) context.Context

WithWebSearchAvailable records whether ask's own web_search tool can run (i.e. a Brave API key is configured). ModelBuilder sets this from config so a provider's BuildModel can decide whether to enable a native fallback.

Types

type CheapModeler

type CheapModeler interface {
	CheapModel() string
}

CheapModeler is the optional capability of naming the provider's cheapest model outright. CheapestModel consults it before list prices, so a subscription provider whose catalog carries no USD rates (Claude Code) still routes background calls like memory extraction to its smallest model instead of its default.

type ClaudeCode

type ClaudeCode struct{}

ClaudeCode is the provider that forks the `claude` CLI in headless stream-json mode and drives it with ask's own tools, prompt, and modals. Claude Code never runs a tool itself: `--tools ""` strips every built-in and ask registers as an in-process (sdk-type) MCP server over the child's stdio, so the ADK loop executes every tool exactly as it does for Vertex or OpenRouter. Auth is whatever the `claude` binary is logged in as (Claude subscription or ANTHROPIC_API_KEY in the environment); ask never stores a credential.

func (ClaudeCode) BuildModel

func (ClaudeCode) BuildModel(ctx context.Context, pc config.ProviderConfig, modelID string) (model.LLM, error)

BuildModel returns the lock-step adapter. It does not spawn the child — the process starts on the first GenerateContent — but it fails fast if the binary cannot be found, so a misconfigured session errors at session start.

func (ClaudeCode) CallOptions

func (ClaudeCode) CallOptions(modelID, effort string) (*genai.GenerateContentConfig, *float64)

CallOptions rides ask's effort onto a ThinkingConfig; the adapter reads the resulting ThinkingLevel back into a --effort flag when it spawns the child.

func (ClaudeCode) CanonicalModelID

func (ClaudeCode) CanonicalModelID(modelID, fallback string) string

func (ClaudeCode) CheapModel

func (ClaudeCode) CheapModel() string

CheapModel is the smallest alias the CLI accepts. The plan bills by quota, not USD, so the catalog has no prices for CheapestModel to rank.

func (ClaudeCode) Configured

func (ClaudeCode) Configured(pc config.ProviderConfig) bool

Configured reports whether the claude binary resolves. Auth lives in the binary, so there is no credential to check.

func (ClaudeCode) ContextWindow

func (ClaudeCode) ContextWindow(modelID string) int64

func (ClaudeCode) DefaultModel

func (ClaudeCode) DefaultModel() string

func (ClaudeCode) DisplayName

func (ClaudeCode) DisplayName() string

func (ClaudeCode) EffortOptions

func (ClaudeCode) EffortOptions() []string

func (ClaudeCode) HasNativeWebSearch

func (ClaudeCode) HasNativeWebSearch() bool

HasNativeWebSearch reports that Claude Code can run web search in its own runtime. ask uses this as the fallback when no Brave key is configured; see NativeWebSearchProvider.

func (ClaudeCode) ID

func (ClaudeCode) ID() string

func (ClaudeCode) ListModels

func (ClaudeCode) ListModels(ctx context.Context, pc config.ProviderConfig) ([]string, error)

ListModels returns the account's live model list by spawning a short-lived child, reading the initialize control response's `models` array, and killing it — the same handshake a session does, without a turn. Falls back to the static catalog if the probe fails so the picker is never empty.

func (ClaudeCode) MaxOutputTokens

func (ClaudeCode) MaxOutputTokens(modelID string) int64

func (ClaudeCode) ModelOptions

func (ClaudeCode) ModelOptions() []string

func (ClaudeCode) Settings

func (ClaudeCode) Settings() []SettingField

func (ClaudeCode) SupportsImages

func (ClaudeCode) SupportsImages(modelID string) bool

type ClaudeExtraUsage

type ClaudeExtraUsage struct {
	IsEnabled    bool
	MonthlyLimit float64
	UsedCredits  float64
	HasLimit     bool // MonthlyLimit was present (non-null) in the response
}

ClaudeExtraUsage is the pay-as-you-go dollar budget attached to a paid plan ("extra usage"). When enabled with a monthly limit it is the account's dollar ceiling — the answer to "budget controlled by dollars".

type ClaudeUsage

type ClaudeUsage struct {
	FiveHour       *ClaudeUsageWindow
	SevenDay       *ClaudeUsageWindow
	SevenDayOpus   *ClaudeUsageWindow
	SevenDaySonnet *ClaudeUsageWindow
	Extra          ClaudeExtraUsage
	FetchedAt      time.Time
}

ClaudeUsage is the parsed /api/oauth/usage response. Each window pointer is nil when the endpoint returned null for that bucket (e.g. seven_day_opus for a plan without Opus weekly tracking).

func CachedClaudeUsage

func CachedClaudeUsage() (ClaudeUsage, bool)

CachedClaudeUsage returns the last fetched snapshot without touching the network. ok is false until a fetch has succeeded at least once. This is the render-path accessor: the TUI reads it every frame while a background refresh keeps it current.

func ClaudeCodeUsage

func ClaudeCodeUsage(ctx context.Context) (ClaudeUsage, error)

ClaudeCodeUsage returns the current usage snapshot, refreshing from the network when the cached one is stale. Concurrent callers serialize on the cache mutex, so a burst of tabs refreshing at once produces one network call. On any failure the last good snapshot is returned alongside the error (the caller keeps showing it); with no snapshot yet, a zero value + error.

type ClaudeUsageWindow

type ClaudeUsageWindow struct {
	Utilization float64
	ResetsAt    time.Time // zero when the endpoint omitted resets_at

	// Dollar view of the window; HasDollars is set only when the endpoint
	// populated limit_dollars (i.e. the account is billed by dollars).
	HasDollars       bool
	UsedDollars      float64
	LimitDollars     float64
	RemainingDollars float64
}

ClaudeUsageWindow is one rate-limit bucket: how much of it is used and when it resets. Utilization is a percentage in [0, 100]. On dollar-budgeted accounts (enterprise / pay-as-you-go) the same window also carries a dollar view — used/limit/remaining — which is nil on plain subscription accounts.

type ModelInfo

type ModelInfo struct {
	ID               string
	Name             string
	ContextWindow    int64
	DefaultMaxTokens int64
	SupportsImages   bool
	ReasoningLevels  []string
	// Pricing is the published list price (USD per 1M tokens) so the cost
	// meter and the picker work offline; nil when unknown.
	Pricing *ModelPricing
}

ModelInfo describes model metadata without external catalog dependencies.

func CatalogModel

func CatalogModel(provider string, modelID string) (ModelInfo, bool)

CatalogModel looks up one model's metadata. Only providers with a static catalog resolve; any other provider id misses rather than borrowing Vertex's.

type ModelLister

type ModelLister interface {
	ListModels(ctx context.Context, pc config.ProviderConfig) ([]string, error)
}

ModelLister is the optional capability of enumerating the models a provider currently serves. A provider without it is listed from the static catalog only.

type ModelMeta

type ModelMeta struct {
	ID              string
	Name            string
	Description     string
	ContextWindow   int64
	MaxOutputTokens int64
	// Pricing is USD per 1M tokens; nil means no price is known.
	Pricing         *ModelPricing
	InputModalities []string
	Reasoning       bool
	ReasoningLevels []string
	KnowledgeCutoff string
	ReleaseDate     string
	// Status is "" (current), "beta", or "deprecated".
	Status string
}

ModelMeta is the merged, display-ready description of one model: the static catalog seeds it, models.dev fills what the provider's own API does not publish, and a provider's live listing (OpenRouter) wins over both.

func ModelMetaFor

func ModelMetaFor(providerID, modelID string) (ModelMeta, bool)

ModelMetaFor layers every known source for providerID/modelID. It never touches the network — callers load models.dev and the provider listings ahead of time — so a miss on every layer reports ok=false.

Precedence, for every provider:

  • Description: models.dev first; the provider's own text is only the fallback when models.dev has none (OpenRouter truncates its text server-side, Vertex publishes none at all).
  • Everything else (limits, pricing, modalities, effort levels, dates): the provider's live listing wins over models.dev, which wins over the static catalog — the provider is authoritative for what it serves and bills.

A new provider's native layer goes through mergeProviderNative so it inherits both rules.

func ModelsDevMeta

func ModelsDevMeta(providerID, modelID string) (ModelMeta, bool)

ModelsDevMeta is an in-memory lookup; it reports ok=false until LoadModelsDev has succeeded, for unmapped providers, and for unknown ids.

type ModelPricing

type ModelPricing struct {
	InputPer1M       float64
	OutputPer1M      float64
	CachedInputPer1M float64
	CacheWritePer1M  float64
}

type NativeWebSearchProvider

type NativeWebSearchProvider interface {
	HasNativeWebSearch() bool
}

NativeWebSearchProvider is the optional capability of running web search in the provider's own runtime, used as a fallback when ask's Brave-backed web_search tool is unavailable (no API key). When HasNativeWebSearch reports true and no Brave key is configured, the session omits ask's web_search tool and the provider enables its native one (gated by the WebSearchAvailable context flag ModelBuilder sets, read in BuildModel). Claude Code implements this; Vertex and OpenRouter do not.

type ObservedToolSink

type ObservedToolSink interface {
	// ObservedToolCall reports a native tool call as it begins.
	ObservedToolCall(id, name string, input map[string]any)
	// ObservedToolResult reports the native call's result. id matches the
	// call's id; name is the tool name captured at the call.
	ObservedToolResult(id, name, output string, isError bool)
}

ObservedToolSink receives tool activity that the provider ran natively (not via ask's MCP bridge). ask injects one at model-build time through the build context; a nil sink (any non-interactive build) simply drops the events.

type OpenAICompatConfig

type OpenAICompatConfig struct {
	ModelID string
	APIKey  string
	BaseURL string
	Headers map[string]string
	// EncodeReasoning injects a requested effort ("low"/"medium"/"high") into
	// the request for the given model. Providers differ in wire shape and in
	// which models support reasoning, so the provider supplies it; nil means the
	// endpoint gets no reasoning controls.
	EncodeReasoning func(params *openai.ChatCompletionNewParams, modelID, effort string)
}

OpenAICompatConfig configures a shared OpenAI-compatible model.LLM. Any provider that speaks the OpenAI Chat Completions protocol (OpenRouter today, a native OpenAI / DeepSeek / Kimi endpoint tomorrow) is a thin wrapper over this: a base URL, a key, optional headers, and how it encodes reasoning.

type OpenRouter

type OpenRouter struct{}

OpenRouter is the OpenRouter provider: any model behind the OpenAI Chat Completions protocol at openrouter.ai, keyed by an API key.

func (OpenRouter) BuildModel

func (OpenRouter) BuildModel(ctx context.Context, pc config.ProviderConfig, modelID string) (model.LLM, error)

func (OpenRouter) CallOptions

func (OpenRouter) CallOptions(modelID, effort string) (*genai.GenerateContentConfig, *float64)

func (OpenRouter) CanonicalModelID

func (OpenRouter) CanonicalModelID(modelID, fallback string) string

func (OpenRouter) Configured

func (OpenRouter) Configured(pc config.ProviderConfig) bool

func (OpenRouter) ContextWindow

func (OpenRouter) ContextWindow(modelID string) int64

func (OpenRouter) DefaultModel

func (OpenRouter) DefaultModel() string

func (OpenRouter) DisplayName

func (OpenRouter) DisplayName() string

func (OpenRouter) EffortOptions

func (OpenRouter) EffortOptions() []string

func (OpenRouter) ID

func (OpenRouter) ID() string

func (OpenRouter) ListModels

func (OpenRouter) ListModels(ctx context.Context, pc config.ProviderConfig) ([]string, error)

func (OpenRouter) MaxOutputTokens

func (OpenRouter) MaxOutputTokens(modelID string) int64

func (OpenRouter) ModelOptions

func (OpenRouter) ModelOptions() []string

func (OpenRouter) Settings

func (OpenRouter) Settings() []SettingField

func (OpenRouter) SupportsImages

func (OpenRouter) SupportsImages(modelID string) bool

type Provider

type Provider interface {
	// ID is the short stable identifier stored in config ("vertex").
	ID() string
	// DisplayName is the human-readable name used in UI copy and errors.
	DisplayName() string
	// DefaultModel is the model used when the user has not picked one.
	DefaultModel() string
	// ModelOptions are the static catalog ids the picker shows before a
	// live listing lands.
	ModelOptions() []string
	// EffortOptions are the /effort choices; empty hides /effort.
	EffortOptions() []string
	// Settings declares the provider's configuration fields. The /config
	// screen renders them, the model picker's key prompt asks for the
	// Secret one, and Configured is judged against them.
	Settings() []SettingField
	// Configured reports whether pc (with the fields' env fallbacks)
	// carries the credentials the provider needs. Never touches the
	// network.
	Configured(pc config.ProviderConfig) bool
	// BuildModel constructs the ADK LLM for modelID from pc.
	BuildModel(ctx context.Context, pc config.ProviderConfig, modelID string) (model.LLM, error)
	// CanonicalModelID normalizes a user- or config-supplied model id. An
	// empty or foreign id resolves to fallback; an empty fallback means
	// DefaultModel.
	CanonicalModelID(modelID, fallback string) string
	// CallOptions maps ask's effort onto the wire request for modelID.
	CallOptions(modelID, effort string) (*genai.GenerateContentConfig, *float64)
	// SupportsImages reports whether modelID accepts image attachments.
	SupportsImages(modelID string) bool
	// ContextWindow is modelID's input window in tokens.
	ContextWindow(modelID string) int64
	// MaxOutputTokens is modelID's output budget in tokens.
	MaxOutputTokens(modelID string) int64
}

Provider is the contract every in-process LLM provider satisfies. The TUI, the headless engine, the /config screen, and the model picker are written against this interface and the registry below, so adding a provider is implementing it and adding it to builtin. Every method is required; optional capabilities are separate interfaces (ModelLister) that call sites discover by type assertion.

func All

func All() []Provider

All returns the registered providers in registration order.

func Get

func Get(id string) (Provider, bool)

Get returns the registered provider with the given id.

type ProviderSettings

type ProviderSettings struct {
	Model         string                      `json:"model"`
	Effort        string                      `json:"effort"`
	SlashCommands []config.ProviderSlashEntry `json:"slashCommands,omitempty"`
}

ProviderSettings is the per-provider slice of configuration the TUI reads and writes: the picked model, the reasoning effort (global — every provider shares Config.Effort), and the discovered slash commands.

func LoadSettings

func LoadSettings(cfg config.Config, id string) ProviderSettings

LoadSettings reads provider id's settings out of cfg.

type SettingField

type SettingField struct {
	// Key is the field's key in config.ProviderConfig.Fields.
	Key string
	// Title is the row label.
	Title string
	// Hint is shown while editing the field.
	Hint string
	// Secret masks the value in the UI and marks the field as the
	// credential the model picker prompts for.
	Secret bool
	// EnvKey is the environment variable consulted when the field is
	// unset.
	EnvKey string
	// Default is the value used when neither config nor env sets one.
	Default string
	// Validate rejects a draft before it is saved; nil accepts anything.
	Validate func(string) error
}

SettingField is one configuration field a provider declares. The /config → <provider> screen is rendered from these, one row per field.

func FieldByKey

func FieldByKey(p Provider, key string) (SettingField, bool)

FieldByKey returns p's setting with the given key.

func SecretField

func SecretField(p Provider) (SettingField, bool)

SecretField returns p's credential field, if it declares one.

type SteeringOptions

type SteeringOptions struct {
	InWorkflow bool
	Cwd        string
}

type Vertex

type Vertex struct{}

Vertex is the Vertex AI provider: Gemini through ADK's gemini model, authenticated with Google Cloud ADC or an explicit service-account key.

func (Vertex) BuildModel

func (Vertex) BuildModel(ctx context.Context, pc config.ProviderConfig, modelID string) (model.LLM, error)

func (Vertex) CallOptions

func (Vertex) CallOptions(modelID, effort string) (*genai.GenerateContentConfig, *float64)

func (Vertex) CanonicalModelID

func (Vertex) CanonicalModelID(modelID, fallback string) string

func (Vertex) Configured

func (Vertex) Configured(pc config.ProviderConfig) bool

func (Vertex) ContextWindow

func (Vertex) ContextWindow(modelID string) int64

func (Vertex) DefaultModel

func (Vertex) DefaultModel() string

func (Vertex) DisplayName

func (Vertex) DisplayName() string

func (Vertex) EffortOptions

func (Vertex) EffortOptions() []string

func (Vertex) ID

func (Vertex) ID() string

func (Vertex) ListModels

func (Vertex) ListModels(ctx context.Context, pc config.ProviderConfig) ([]string, error)

func (Vertex) MaxOutputTokens

func (Vertex) MaxOutputTokens(modelID string) int64

func (Vertex) ModelOptions

func (Vertex) ModelOptions() []string

func (Vertex) Settings

func (Vertex) Settings() []SettingField

func (Vertex) SupportsImages

func (Vertex) SupportsImages(modelID string) bool

Jump to

Keyboard shortcuts

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