Files
sausage/extensions/models

Model selection

The models service starts a conversation with start({agent, cwd, ownership?}, context). The agent field names a roster entry in /etc/sausage/config.yaml. The service stores that name in models.profile. discover(cwd) exposes the same live definition resolver to subagents. configure(tx, id, {agent, inheritedTools, excludeTools?, model?, thinking?}) configures an existing child in its creation transaction. It retains the parent's tool scope, explicit overrides, and exclusions for subsequent run boundaries. It applies the definition during creation and before each new run. Each roster entry names its model and thinking level directly. There are no model families or project overlays.

Each resolution reads /etc/sausage/config.yaml through host.fs. A file edit applies at the next run boundary without a restart. The global prompt precedes the role-specific prompt in every agent's system prompt. A standing conversation follows the current standing roster member, even after a rename.

The optional models.pin service supplies pin(tx, conversationId) for an external model override. Without that provider, the roster entry selects the model. A conversation without a role uses the standing roster member's model. No login fallback runs.

Existing registered models retain their transport. New model references reuse a template from their own registered provider and retain its proxy auth resolver. They never inherit another provider's transport. Unknown providers fail instead of silently using OpenAI. Models absent from the catalog receive zero prices, not the template's prices. The extension never reads a credential or registers a direct provider SDK.

Host proxy transports and prices

host/js/proxy-models.ts reads the authenticated /v1/models catalog once at host startup. OpenAI models use pi-ai's Responses transport. Anthropic models use its Messages transport. The catalog endpoint determines each model's base URL. For Anthropic, effort capabilities select adaptive thinking and its advertised effort levels. Both providers read the proxy key and base URL from /etc/sausage/config.yaml before each request. The usage tag remains unchanged. No provider login or direct endpoint fallback runs. Empty proxy settings do not prevent startup. A model request names the config file if either setting is empty.

If the catalog fails or exceeds five seconds, a small table supplies these defaults:

Provider/model API Proxy path
openai/gpt-6.1-sol Responses /v1/responses
anthropic/claude-opus-5-5 Messages, adaptive thinking /apis/anthropic/v1/messages

Catalog prices use USD per million tokens, with conversion from unit_tokens when necessary. The host uses the first advertised route's quote, including cache reads and cache writes. These costs are estimates, not billing totals. Another proxy route can charge different prices. Unavailable prices remain zero. Catalog changes apply after a host restart. Roster edits still apply at the next run boundary without a restart. host/tests/it/proxy_models.rs tests the real transports against a local fake proxy.

host/tests/it/core_ext.rs tests these services through the snapshot loader.