TOML Schema¶
The native deployment file defines the LLM clients, targets, and routes a
Switchyard server serves. It is read by switchyard-server --config and by
switchyard launch --config.
Validate a file without starting the server:
Minimal Example¶
schema_version = 1
[llm_clients.openrouter]
format = "openai_chat"
base_url = "https://openrouter.ai/api/v1"
api_key_env = "OPENROUTER_API_KEY"
[targets.strong]
id = "anthropic/claude-sonnet-4.5"
llm_client = "openrouter"
[routes.default]
id = "switchyard"
type = "passthrough"
target = "strong"
schema_version must be 1. Table names under llm_clients, targets, and
routes are local references; clients send the route's id as the model name.
[llm_clients.<name>]¶
| Key | Required | Default | Meaning |
|---|---|---|---|
format |
Yes | — | openai_chat, openai_responses, or anthropic_messages. |
base_url |
Yes | — | Upstream base URL. |
api_key_env |
No | unset | Name of the environment variable holding the key. Omit to send no authentication. |
extra_headers |
No | {} |
Extra HTTP headers sent upstream. |
max_retries |
No | 2 |
Retry budget, 0–10. |
The TOML never contains the secret itself. api_key_env names a variable that
must exist and be non-empty when the server loads.
[targets.<name>]¶
| Key | Required | Default | Meaning |
|---|---|---|---|
id |
Yes | — | Exact model ID sent upstream. |
llm_client |
Yes | — | Key under [llm_clients]. |
extra_body |
No | {} |
Values merged into the upstream request when the request does not already set that key. |
[routes.<name>]¶
Every route takes id and type, plus the keys for that type.
noop¶
Returns a buffered assistant response containing OK without calling an
upstream model. Use it for local smoke tests.
passthrough¶
Sends every request to one target.
| Key | Required | Meaning |
|---|---|---|
target |
Yes | Target every request is sent to. |
random¶
Splits traffic across targets. See Random Routing.
| Key | Required | Default | Meaning |
|---|---|---|---|
targets |
Yes | — | Target names to choose from. |
weights |
No | equal | Finite, non-negative relative weights in targets order, with at least one positive value. Invalid weights are rejected at load time. |
seed |
No | unset | Reproduces the selection sequence. |
llm_classifier¶
Classifies each task, then routes to the weak or strong target. See LLM Classifier Routing for tuning.
| Key | Required | Default | Meaning |
|---|---|---|---|
classifier_target |
Yes | — | Target the judge is called through. Not a routing destination. |
strong_target |
Yes | — | Capable tier. |
weak_target |
Yes | — | Efficient tier. |
base_threshold |
Yes | — | Lowest solve probability that routes to the weak target. In [0, 1]. |
min_confidence |
No | 0.0 |
Lowest judge confidence that permits weak routing. |
capability_elevated_floor |
No | unset | Higher floor for uncertain tasks. Must exceed base_threshold. |
session_affinity |
No | false |
Reuses a session's first decision on later turns. |
message_hash_fallback |
No | false |
Keys affinity on the first user message. Requires session_affinity. |
recent_turn_window |
No | unset | Trailing turns the judge sees. |
escalation |
No | unset | Switches the route to escalation judging. |
Add an escalation table to judge each completed turn instead of classifying up
front. See
Escalation-Router Routing.
| Key | Required | Default | Meaning |
|---|---|---|---|
confirmations |
No | 2 |
Consecutive escalate verdicts required to latch. Above 1 needs a session ID. |
recent_turn_window |
No | 28 |
Trailing messages shown to the judge. |
window_message_chars |
No | 500 |
Per-message cap inside that window. |
base_threshold stays required, but escalation ignores it and the other
classifier keys.
stage_router¶
Scores tool signals to pick a tier per turn. See
Stage-Router Routing for the
optional handoff_notes and classifier tables and for tuning.
| Key | Required | Default | Meaning |
|---|---|---|---|
capable_target |
Yes | — | Capable tier. |
efficient_target |
Yes | — | Efficient tier. |
picker |
Yes | — | capable_first or efficient_first. Tier used when the signals are not confident. |
confidence_threshold |
Yes | — | Corroboration a decisive pick needs. In [0, 1]. |
recent_turn_window |
No | 3 |
Trailing tool results the signals are computed over. |
capable_system_prompt |
No | unset | System prompt handed to the capable tier. |
efficient_system_prompt |
No | unset | System prompt handed to the efficient tier. |
Validation Errors¶
--dry-run prefixes configuration failures with
invalid server config <path>:. Within that wrapper, TOML deserialization
errors start with failed to parse TOML:, while errors from validating the
built configuration retain their inner message unchanged.