Skip to main content
No single model is best at everything. Fabro lets you assign the right model to each workflow step — cheap, fast models for boilerplate, frontier models for hard reasoning, and a different provider for cross-critique so the reviewer brings fresh eyes. When a provider goes down, Fabro can fail over automatically.
Ensemble workflow: fan out to Opus and Gemini Pro, merge, then synthesize

Model catalog

Fabro keeps five related concepts separate:
  • A provider serves requests, such as openai or openrouter.
  • A model slug is Fabro’s canonical, human-facing model ID, such as gpt-5.6-sol.
  • An alias is another user-facing selector, such as gpt-56-sol.
  • A family is display and matching metadata. It does not affect routing identity.
  • An API ID is the opaque model string sent on the provider wire. Workflows should never reference it.
One provider’s route to one model slug is an offering, identified by (provider, model slug). The same slug and alias may appear on several providers. Within one provider, however, every slug or alias must identify exactly one offering. For an unqualified selector, Fabro checks canonical slugs before aliases, filters the candidates to providers whose adapters are ready, and then chooses the highest provider priority. Equal priorities use canonical provider ID order. An explicit provider restricts selection to that provider and is a pin: if it is unavailable, Fabro reports the error instead of silently switching. For example, the shared gpt-56-sol alias can be portable across direct OpenAI and OpenRouter offerings: Fabro performs this selection once when creating a run and persists the chosen provider and canonical slug in the run settings and graph. Resuming that run does not reconsider provider priority when credentials change. Runtime model fallbacks are the separate mechanism for handling a later provider failure. Each provider requires its own API key. Server-backed workflows read provider credentials from the server vault (for example ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, DEEPSEEK_API_KEY, or POOLSIDE_API_KEY set with fabro secret set or fabro provider login). Standalone SDK/CLI flows can opt into env-backed credential sources explicitly. See the Quick Start for setup. Claude Fable 5 is available as an explicit model but is not the default Anthropic model. If Fable refuses a request, Fabro reports the refusal as a content-filter LLM error and applies the configured run.model.fallbacks chain when one is present.

Configuring providers and models

Fabro’s catalog is the lithos-llm built-in catalog. The [llm] table in settings is a second layer over it: a lithos catalog overlay that adds providers and models or changes existing entries. Later layers win. Tables merge key by key and every other value replaces. Models are nested under their provider, so two providers can expose the same model id without overwriting each other. Provider and model facts use lithos field names: adapter, codec, base_url, auth, enabled, limits, capabilities, pricing, small_default, probe, family, and the cutoffs. The coding harness a model expects lives under metadata.agent, a namespace lithos ships and other agents such as Pebble read too. See Settings Configuration for every key.
settings.toml
The gateway’s API key is PROXY_API_KEY: lithos derives the secret name from the provider id (upper case, - and . as _, then _API_KEY). Store it with fabro secret set PROXY_API_KEY .... For LiteLLM, Fabro ships a disabled provider entry. Enable it in settings and declare the models your proxy exposes:
settings.toml
api_model is the model name sent to that provider’s API. It defaults to the exact model id, so omit it when the two strings match. Fabro does not infer vendor prefixes or rewrite the value.
A provider/model selector such as openai/gpt-5.6-sol pins the provider and names the model by id, alias, or wire id. A bare selector with no provider pin picks the highest-priority ready offering; a separate provider = "openrouter" pin selects the OpenRouter offering. Providers with allow_passthrough = true also accept provider/model selectors for models the catalog does not list.
Model roles are separate: the provider’s default_model controls normal model selection for workflow execution, while small_default = true on a model row marks the provider’s small utility model for metadata tasks such as generated run titles. If a provider has no small default, Fabro falls back to that provider’s default model. Provider auth has two parts. The lithos auth scheme says how a credential is sent: { type = "bearer" }, { type = "header", name = "x-api-key" }, { type = "headers" } for providers that take several secret headers, { type = "none" }, or { type = "aws" }. lithos also says which secret names a provider reads: OPENAI_API_KEY for openai, GEMINI_API_KEY then GOOGLE_API_KEY for gemini, MODAL_TOKEN_ID and MODAL_TOKEN_SECRET for modal, and <PROVIDER>_API_KEY for a provider you define. Fabro looks each name up in the process environment first and the server vault second. Custom headers for any provider go in default_headers as literal text or {{ secrets.NAME }} tokens; put credentials in secrets and reference them with {{ secrets.NAME }} instead of a bare literal. Workflow runs also add x-session-id: <run-id> to every LLM request so compatible gateways can group requests from the same run. An explicitly configured x-session-id in provider default_headers takes precedence. Provider metadata.agent.profile defaults from adapter and controls profile-specific behavior such as which tools the agent registers, project-memory filenames, CLI/ACP command selection, and native session routing. Valid values are anthropic, claude-5, openai, gemini, kimi, gpt56, and gpt6; model-level values override provider-level values. Three profiles are selected per model rather than per provider, because they follow the model wherever it is served: claude-5 for Claude 5 models, kimi for Kimi models, and gpt56 for the GPT-5.6 models (Sol, Terra, Luna); gpt6 for GPT-6 Astra runs on the same harness as gpt56. The gpt56 profile uses Codex’s narrow core surface — shell_command, apply_patch, and update_plan, plus optional credential-backed web_search — instead of fabro’s dedicated file-read, discovery, and web_fetch tools. On OpenAI-compatible routes that cannot carry the freeform apply_patch grammar, it substitutes the JSON-schema edit_file tool. Session features may add their own question, skill, or subagent tools separately. Costs come from the lithos pricing table on each model row. Each token bucket (input, output, reasoning, cache read, cache write) prices at its own rate, with optional long-context and speed tiers. Providers that return an authoritative charge, such as OpenRouter, override the catalog estimate; the billing record says which source it came from.
Provider fields in configuration, APIs, and model routing are provider ID strings. Built-in names like anthropic, openai, and gemini still work, but custom IDs like proxy work anywhere a provider ID is accepted.

Venice

Fabro ships a built-in Venice provider with a curated catalog of Venice-hosted Kimi, Grok, GLM, DeepSeek, and Qwen models. Store its API key with fabro provider login --provider venice. Pin provider = "venice" when a shared model slug must use Venice instead of a higher-priority direct provider.

Poolside

Fabro ships a built-in Poolside provider for Laguna S 2.1 and Laguna XS 2.1 over Poolside’s OpenAI-compatible API. Store a direct API key with fabro provider login --provider poolside. The same model slugs are also available through the opt-in OpenRouter provider; its vendor-namespaced strings remain provider-only api_model values.

OpenRouter

Fabro ships an OpenRouter provider definition with a curated model catalog, disabled by default. Enable it in settings and store an API key with fabro provider login --provider openrouter:
settings.toml
Fabro ships a Modal provider definition for Kimi K3, disabled by default. Modal assigns the endpoint URL and authenticates requests with a two-part proxy token:
settings.toml
Store both token values in the Fabro server vault:

Amazon Bedrock

Fabro ships an Amazon Bedrock provider definition with a curated multi-vendor catalog over Bedrock’s Converse API, disabled by default. Enable it and authenticate with a Bedrock API key or AWS SigV4 credentials:
settings.toml

Ollama

Fabro ships an Ollama provider definition that is disabled by default. Enable it in settings when you want Fabro to route through a local Ollama server:
settings.toml
Enabling the provider alone does not expose any models — until #267 adds auto-discovery, add explicit [llm.providers.ollama.models."<model-id>"] blocks for each Ollama model you have pulled locally. Ollama’s OpenAI-compatible endpoint accepts any bearer token, so local users can set OLLAMA_API_KEY=ollama.

Default models

When no model or provider is specified, Fabro chooses the default offering on the highest-priority ready provider. If no provider adapter is ready, run creation reports that no eligible offering is available. Each provider has its own default model:

Using models in workflows

Assign models to workflow nodes using model stylesheets, which use a CSS-like syntax:
example.fabro
This routes the spec node to Haiku (the default), implementation to Sonnet, and review to Gemini Pro.

Overriding the default model

Model stylesheets set per-node models inside the workflow graph, but you can also override the default model for an entire run. This is useful for quick experimentation or when you want to swap models without editing the Graphviz file.

CLI flags

Pass --model and optionally --provider to fabro run:
These flags set the default model for all nodes that don’t have an explicit model assigned via a stylesheet. Without --provider, Fabro selects among ready offerings by priority. Add --provider to pin an exact provider, including for an uncatalogued provider model string.

Run config TOML

For repeatable runs, set the model in a run config file:
run.toml
Then launch with:
The [run.model.fallbacks] table is optional. Each key names the originally requested model. Its value is the ordered list to try after that model’s active provider fails. An entry may be a bare provider token (like "gemini"), a bare model ID or alias (like "gpt-terra"), or a qualified "provider:selector" reference. A qualified selector may be the provider’s canonical model ID, alias, or API ID, including API IDs with slashes such as "openrouter:moonshotai/kimi-k3". Fabro selects one chain from the original request. It does not switch to the chain configured for a fallback target. When the requested reasoning level is unavailable on a fallback target, Fabro uses the nearest supported level. Equal-distance choices round up.
The precedence order is: node-level stylesheet > run config TOML > CLI flags > server defaults. More specific settings always win.

CLI commands

List models

View all available models, or filter by provider:

Test models

Verify that your API keys are working by sending a test prompt to each configured provider:
This is useful for confirming connectivity after setup or when adding a new provider key.