model

package
v0.0.2 Latest Latest
Warning

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

Go to latest
Published: Sep 9, 2026 License: Apache-2.0 Imports: 8 Imported by: 0

Documentation

Overview

Package model defines a neutral model registry + per-turn model-selection seam.

It is policy-free: oss ships a Registry (the available models + a default) and a Selector interface whose default impl (CapabilityDefault) only enforces capability matching. A distribution (e.g. sahara) plugs in a Selector that applies cost/complexity routing — that policy lives there, NOT in oss core.

Index

Constants

View Source
const MetaActiveModel = "active_model"

MetaActiveModel is the assistant-message metadata key carrying the worker's authoritative model selection for the addressed workspace/thread. Remote UI clients use it to mirror the worker state without parsing command text or assuming their local model registry has the same default.

Variables

View Source
var ErrInvalidRegistryFile = errors.New("model: invalid registry file")

ErrInvalidRegistryFile is the sentinel wrapping every malformed-models.yaml error, so a distribution can errors.Is against it (and wrap it in its own config error) rather than string-matching.

Functions

func ActiveModelFromMessage added in v0.0.2

func ActiveModelFromMessage(message protocol.ChatMessage) string

ActiveModelFromMessage returns the authoritative model stamped by the worker. Malformed or absent metadata is treated as unknown.

func KnownReasoningEfforts added in v0.0.2

func KnownReasoningEfforts() []string

KnownReasoningEfforts returns the provider-neutral effort vocabulary in display order. A model allowlist can narrow this set.

func NormalizeReasoningEffort added in v0.0.2

func NormalizeReasoningEffort(value string) (string, error)

NormalizeReasoningEffort canonicalizes a user/config value. "med" is a convenience alias; the provider wire value remains "medium".

func StampActiveModel added in v0.0.2

func StampActiveModel(message *protocol.ChatMessage, name string)

StampActiveModel records name on message when it is non-empty. Existing metadata is preserved.

Types

type Attempt

type Attempt struct {
	Model  string
	Reason string
}

Attempt records a model that failed within the current turn. Reason is the provider failure classification as a string (kept a string so this package stays free of a provider dependency); empty when unknown.

type Capabilities

type Capabilities struct {
	Vision bool `json:"vision" yaml:"vision"`
	Tools  bool `json:"tools" yaml:"tools"`
	Audio  bool `json:"audio" yaml:"audio"`
}

Capabilities describes what a model supports. Extensible; v1 gates on Vision (the modality that actually varies across frontier models) and Tools (the harness cannot function without tool-calling).

func (Capabilities) Satisfies

func (c Capabilities) Satisfies(req Capabilities) bool

Satisfies reports whether c covers every capability required by req.

type CapabilityDefault

type CapabilityDefault struct{}

CapabilityDefault is oss's neutral Selector: it keeps the configured default when that model satisfies the turn's required capabilities, otherwise it falls back to the first capable model in the registry, otherwise to the default (best-effort — selection never fails the turn). No cost/complexity policy.

func (CapabilityDefault) SelectModel

func (CapabilityDefault) SelectModel(_ context.Context, in SelectInput) (string, error)

type Model

type Model struct {
	Name         string       `json:"name" yaml:"name"`
	Capabilities Capabilities `json:"capabilities" yaml:"capabilities"`
	Tier         string       `json:"tier,omitempty" yaml:"tier,omitempty"`
	Provider     string       `json:"provider,omitempty" yaml:"provider,omitempty"`
	// Reasoning declares the operator default and optional allowlist for
	// request-scoped reasoning effort. It does not change the upstream model ID.
	Reasoning ReasoningConfig `json:"reasoning,omitzero" yaml:"reasoning,omitempty"`
	// Context is the model's total context window in tokens (0 = unknown). Used to
	// budget compaction to the model actually being called — critical when a turn
	// escalates from a large-context orchestrator to a smaller-context vision model,
	// so history is trimmed to fit the target instead of overflowing it.
	Context int `json:"context,omitempty" yaml:"context,omitempty"`
}

Model is a registry entry: a logical name (what the provider/sidecar routes to a real upstream) plus capabilities and an open Tier label for distribution-side routing policies (e.g. a sahara cost router's "light"/"primary"). Provider is the optional NAME of a ProviderConfig (in the registry's provider set) this model routes to; empty means "use the runner's single configured provider".

type ProviderConfig

type ProviderConfig struct {
	Name        string `json:"name" yaml:"name"`
	Kind        string `json:"kind,omitempty" yaml:"kind,omitempty"`
	BaseURL     string `json:"base_url,omitempty" yaml:"base_url,omitempty"`
	APIKey      string `json:"api_key,omitempty" yaml:"api_key,omitempty"`
	APIKeyEnv   string `json:"api_key_env,omitempty" yaml:"api_key_env,omitempty"`
	AuthProfile string `json:"auth_profile,omitempty" yaml:"auth_profile,omitempty"`
	Format      string `json:"format,omitempty" yaml:"format,omitempty"`
}

ProviderConfig is a named upstream a model can be routed to: a base URL, an inline API key (APIKey) or the env var holding it (APIKeyEnv), and a wire Format ("openai"/"responses"/"native"). It is pure data — construction of an actual provider client from it lives in the turn package (which imports provider), keeping this package free of a provider dependency. Missing fields are filled from the runner's env default by the resolver, not here.

type ReasoningConfig added in v0.0.2

type ReasoningConfig struct {
	DefaultEffort  string   `json:"default_effort,omitempty" yaml:"default_effort,omitempty"`
	AllowedEfforts []string `json:"allowed_efforts,omitempty" yaml:"allowed_efforts,omitempty"`
}

ReasoningConfig controls request-scoped reasoning effort for one model. AllowedEfforts is optional: an empty list means the registry imposes no model-specific restriction beyond the neutral known-value validation.

func (ReasoningConfig) Allows added in v0.0.2

func (c ReasoningConfig) Allows(effort string) bool

Allows reports whether an already-normalized effort is admitted by the model-specific allowlist. An empty allowlist is intentionally unrestricted.

type Registry

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

Registry is the set of available models + the default. Built from config (sahara) or left nil (oss falls back to the runner's single configured model).

func LoadRegistry

func LoadRegistry(path string) (*Registry, error)

LoadRegistry reads a models.yaml at path into a *Registry. A missing file returns (nil, nil): no registry means the consumer keeps its single configured model + provider. A present file that is malformed, or lists no models, is an error (wrapping ErrInvalidRegistryFile). Env vars are NOT resolved and defaults are NOT filled here — the file is parsed verbatim; resolution happens later in the per-model provider resolver.

func NewRegistry

func NewRegistry(models []Model, defaultName string) *Registry

NewRegistry builds a registry from models + a default name. Duplicate names keep the first occurrence. defaultName need not be present (Default() reports absence); callers decide how to handle a missing default.

func NewRegistryWithProviders

func NewRegistryWithProviders(models []Model, defaultName string, providers []ProviderConfig) *Registry

NewRegistryWithProviders is NewRegistry plus a set of named provider configs a model can reference (Model.Provider). Duplicate provider names keep the first occurrence. Providers with an empty Name are skipped.

func (*Registry) Capable

func (r *Registry) Capable(req Capabilities) []Model

Capable returns the models (declaration order) that satisfy req.

func (*Registry) Default

func (r *Registry) Default() (Model, bool)

Default returns the registry's default model.

func (*Registry) DefaultName

func (r *Registry) DefaultName() string

DefaultName returns the configured default model name (may be empty).

func (*Registry) Get

func (r *Registry) Get(name string) (Model, bool)

Get returns the model with the given name.

func (*Registry) List

func (r *Registry) List() []Model

List returns all models in declaration order.

func (*Registry) ProviderFor

func (r *Registry) ProviderFor(modelName string) (ProviderConfig, bool)

ProviderFor returns the ProviderConfig the named model references. It reports (_, false) when the registry is nil, the model is unknown, the model declares no provider, or the referenced provider name is not configured — in every one of those cases the caller should fall back to the default provider.

type SelectInput

type SelectInput struct {
	Addr     protocol.MessageAddress
	User     protocol.ChatMessage
	Required Capabilities
	Registry *Registry
	Default  string
	// Attempts are the models that already failed this turn, in order (empty on
	// the initial pick). The runner re-consults the Selector after a *retryable*
	// provider failure that same-model recovery (backoff, context trim) could not
	// resolve, so a Selector can avoid a model that just failed and escalate
	// (e.g. to a larger-context or higher tier). Returning "" declines further
	// fallback and surfaces the error. oss's CapabilityDefault always declines on
	// retry — cross-model fallback is opt-in via a distribution Selector.
	Attempts []Attempt
}

SelectInput is the per-turn context handed to a Selector. Required is the capability set this turn needs (e.g. Vision when the message carries images); Default is the runner's configured default model name.

type Selector

type Selector interface {
	SelectModel(ctx context.Context, in SelectInput) (string, error)
}

Selector picks the model name for a turn. oss calls it for the auto path only (an explicit /model or spawn(model=) override bypasses it). The default impl is CapabilityDefault; a distribution plugs in a cost/complexity router.

Jump to

Keyboard shortcuts

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