Model selection
The models service starts a conversation with start({agent, cwd, ownership?}, context).
The agent field names /etc/sausage/roster/<name>.md.
Each file has YAML frontmatter and a role prompt as its body. The filename supplies the name.
Frontmatter supplies description, model, thinking, and optional tool or isolation settings.
Project definitions use <repo>/.sausage/roster/*.md.
An additive project overlay retains the base settings and appends its body.
A project definition with description and model replaces the base role prompt.
The service stores the selected name in models.profile.
discover(cwd) exposes the live definition resolver to subagents.
configure(tx, id, {agent, inheritedTools, excludeTools?, model?, thinking?}) configures a child within its creation transaction.
It retains inherited tools, explicit overrides, and exclusions at later run boundaries.
Each resolution reads the settings and Markdown files through host.fs.
Provider, roster, and prompt edits apply at the next run without a restart.
The global prompt precedes the role prompt.
The main agent follows main_agent_name in /etc/sausage/config.yaml.
To rename it, rename its Markdown file and set main_agent_name to the new filename without .md.
The main agent retains its conversation and adopts the new definition.
A conversation without a role uses the main agent's model.
The optional models.pin service supplies pin(tx, conversationId) for an external model override.
Providers and metadata
providers is a dictionary in /etc/sausage/config.yaml.
Each provider has type, base_url, api_key, and models.
Supported API types are anthropic-messages, openai-responses, and openai-chat-completions.
Model references use <provider>/<model>.
The optional catalog field selects a models.dev provider ID. It defaults to the configured provider's name.
Authentication and the base URL come from the config before each request.
Missing keys and unknown providers produce errors that name the config file.
Provider API keys in the config are intentionally visible to agents. Do not print or commit them.
The host refreshes https://models.dev/api.json at startup and caches it in host/models-dev.json.
A failed refresh uses the cache or the packaged snapshot.
Each model entry is a string ID or an object with id and metadata overrides.
Supported overrides are context_window, max_tokens, reasoning, and cost.
Cost fields are input, output, cache_read, and cache_write, in USD per million tokens.
An unknown model needs all metadata fields. Its error lists missing fields and the config path.
An override retains all catalog values that it does not replace.
Pi-ai computes call costs and stores them in assistant usage. These costs are estimates, not billing totals.
GET /harness/models lists configured models and resolved metadata without authentication data.
host/tests/it/provider_models.rs exercises all three real API adapters against a local fake server.
It also checks live provider edits and stored usage costs.
host/tests/it/core_ext.rs checks live Markdown edits and main agent renames through the snapshot loader.