Agent configuration (agents.yaml)
A workflow’s delegate: states say what kind of thinking a step needs — coding, reasoning, prose — without naming a model. agents.yaml is where you bind those labels to actual models, once, and share them across every workflow you run. Without it you’d be hard-coding claude-opus-4-7 into each workflow and editing fifty files when a better model ships; with it you change one line and the swap propagates.
The shape is deliberately small: one mandatory default: list, plus sparse overrides keyed by affinity, tier, or both. (The file, its resolver, and the validation below are all part of the open-source platform — you author the bindings here regardless of which runtime ends up driving them.)
The minimum viable file
Section titled “The minimum viable file”version: 1default: - provider: { name: anthropic } model: claude-sonnet-4-6That’s enough. Every delegate: state in every workflow you run will resolve to Claude Sonnet 4.6. Add overrides as you need them.
Closed enums
Section titled “Closed enums”The keys you can use in overrides: are fixed. This is deliberate — agents.yaml is a contract between operators (who pick models) and workflow authors (who pick affinities). A closed enum keeps that contract testable.
Affinity (5):
coding— code generation / refactoringreasoning— multi-step planning, debugging, mathprose— natural-language writingweb-search— model that benefits from a search-augmented endpoint (e.g., Perplexity)recon— local summarization and codebase navigation
Tier (3):
frontier— the most capable model in the provider’s catalogstandard— the default workhorse modelcommoditized— small/cheap/fast
Provider (5 + escape hatch): anthropic | openai | google | ollama | lmstudio | custom. custom requires an endpoint: field.
Enum additions in future flowgate releases are minor-version compatible; removals are major. Workflow authors get a stable contract.
Sparse overrides
Section titled “Sparse overrides”You don’t need to define every affinity × tier combination. The resolver walks from most-specific to least:
<affinity>-<tier>(exact match)<affinity>alone<tier>alonedefault
Affinity wins the tiebreaker. If a workflow asks for coding-frontier and you’ve defined both coding and frontier (but not coding-frontier), the resolver picks coding.
version: 1default: - provider: { name: anthropic } model: claude-sonnet-4-6overrides: coding-frontier: - provider: { name: anthropic } model: claude-opus-4-7 features: extended_thinking: true thinking_budget_tokens: 16000 prose: - provider: { name: anthropic } model: claude-haiku-4-5-20251001Chain of Responsibility (per list)
Section titled “Chain of Responsibility (per list)”Each override is a list of bindings. The resolver tries them in order, falling through to the next on infrastructure failures (401, 403, 429, 404, network timeouts). It surfaces content failures (other 4xx, schema, safety) to the caller.
overrides: coding-frontier: - provider: { name: anthropic } model: claude-opus-4-7 - provider: { name: openai } model: gpt-5If your Anthropic key is rate-limited, the resolver tries OpenAI. If Anthropic returns 400 because of a malformed request, the error surfaces — that’s not the kind of failure a fallback can fix.
Eager auth preflight
Section titled “Eager auth preflight”When a runtime starts a workflow, it probes every distinct primary binding (the first entry in each list, plus the default’s first entry) once. If a provider’s API key env var is missing or the credentials are rejected, startup fails with the offending binding named.
This means you find out about an expired Anthropic key at startup — not three states in, after the workflow has already done work.
Bypass with FLOWGATE_SKIP_PREFLIGHT=1 (useful for CI / disconnected dev).
Provider credentials come from the environment — set ANTHROPIC_API_KEY and friends in your shell rc or CI secrets. See Provider API keys.
Strict mode
Section titled “Strict mode”If you want the specificity walk to be EXACT only — no fall-through from coding-frontier to coding — set:
version: 1strict_specificity: truedefault: - provider: { name: anthropic } model: claude-sonnet-4-6overrides: coding-frontier: - provider: { name: anthropic } model: claude-opus-4-7In strict mode, a workflow asking for coding-frontier matches the exact key or errors at load. A workflow asking for reasoning-frontier (no exact match defined) walks to default as normal.
File locations + precedence
Section titled “File locations + precedence”--agents-config <PATH>(or$FLOWGATE_AGENTS_CONFIG)..flowgate/agents.yamlin the current working directory (project).~/.config/flowgate/agents.yaml(user —dirs::config_dir()).--agent name=provider/modelCLI flags (deprecated v0.2 path).
When both project and user files exist, project wins whole-file — not slot-level merge. Doctor reports the shadowed user file so the surprise is visible.
If you mix --agent flags and an on-disk agents.yaml, startup fails with AmbiguousAgentSource. Choose one source.
Migrating to agents.yaml
Section titled “Migrating to agents.yaml”The v0.2 --agent planning=anthropic/claude-sonnet-4 flag form still works in runtimes that accept it, but the on-disk file is the supported path. To migrate, write the equivalent file:
version: 1default: - provider: { name: anthropic } model: claude-sonnet-4-6You don’t need to name affinities in default: — the default catches everything. Adding affinity-specific overrides is purely incremental.
Feature toggles
Section titled “Feature toggles”Per-provider feature structs use #[serde(deny_unknown_fields)], so typos fail at load with the offending key named. extended_thinking on an OpenAI binding fails; reasoning_effort on an Anthropic binding fails.
Anthropic: extended_thinking: bool, thinking_budget_tokens: u32.
OpenAI: reasoning_effort: "low" | "medium" | "high" | "xhigh".
Google: thinking_budget_tokens: u32.
Each provider exposes “think harder” differently — Anthropic takes a thinking-token budget, OpenAI takes an effort level. At spawn time flowgate translates your toggle to one internal effort level and then back out to whatever shape the target provider’s API wants, so you express the intent once and it lands correctly on each provider. Mapping:
- Anthropic —
extended_thinking: truewith no explicit budget defaults to high effort. Athinking_budget_tokensvalue snaps to the nearest effort level (≤2048 → low, ≤6144 → medium, ≤16384 → high, larger → xhigh), and when set, the explicit budget wins over the boolean. - OpenAI —
low|medium|high|xhighpass straight through. Any other value is dropped with a warning so the typo is visible. - Google — same budget-to-effort mapping as Anthropic.
Validating an agents.yaml
Section titled “Validating an agents.yaml”The same loader that resolves agents.yaml at workflow start (AgentsFile::from_path) runs at config load, so mcp-flowgate check surfaces a malformed bindings file before anything tries to use it. The stable error_kind contract — MISSING_DEFAULT, EMPTY_DEFAULT, MISSING_PROVIDER_MODEL, UNKNOWN_OVERRIDE_KEY, UNKNOWN_FEATURE_KEY, PROVIDER_ENDPOINT_REQUIRED, VERSION_MISMATCH, YAML_SYNTAX, IO — is what cap.implement.write-agents-config switches on for its round-trip step, and what your own pre-commit hooks and editor integrations can rely on.
mcp-flowgate check --config gateway.yamlA bad override key fails the check with the offending key named, e.g. `vision-frontier` is not a valid <affinity> | <tier> | <affinity>-<tier>.
Guided setup with flow.configure-models
Section titled “Guided setup with flow.configure-models”Hand-authoring agents.yaml is fine for two-line files, but as soon as you want per-affinity overrides + CoR fallbacks across multiple providers, the flowgate-meta repo ships an orchestrator that walks you through it. Loaded into your gateway config and driven through an MCP host (or the open agentic runtime), meta/flow.configure-models runs five stages:
-
cap.research.model-inventory— probes each provider you name (anthropic,openai,google,ollama,lmstudio) for its model catalog. Failures are classified per the sameFailureClassenum the resolver uses (Auth401,RateLimit429,NetworkTimeout, etc.) so a missing API key surfaces explicitly, not silently. -
cap.plan.suggest-bindings— an agent composes one opinionated plan: adefault:list, sparse overrides keyed to the affinity-tier pairs your workflows actually reference, plus rationale + assumptions for each non-obvious choice. -
cap.gate.human-approve-plan— HITL gate. Two modes:review_plan(default) — surfaces the plan + rationale + assumptions for your approval. You can hand back an edited plan instead of approving the original.auto— skips the gate. Useful for CI / scripted setup.
-
cap.implement.write-agents-config— atomic write (temp file in the target dir →mcp-flowgate checkround-trip →rename). A failed round-trip rolls back the temp file rather than replacing a workingagents.yamlwith a broken one. -
cap.verify.auth-only-smoke-test— 1-token completion per binding in the just-written file. This proves auth, not capability. Output names the limitation explicitly:Auth verified for the bindings reported above. CAPABILITY NOT TESTED — a model that authenticates may still fail to code, reason, or follow safety constraints in your actual workflows.
The v0.4 roadmap replaces this with a capability harness that exercises bindings against real workflow tasks. Until then, the smoke test is honest about what it does and doesn’t cover.
Inputs (passed when the orchestrator is started via flowgate.command):
{ "providers": "anthropic,openai,google", "delegates": ["coding-frontier", "reasoning-frontier", "prose-standard"], "mode": "review_plan", "target_path": ".flowgate/agents.yaml"}If the round-trip fails or you reject the plan, the orchestrator terminates in failed rather than done — and your existing agents.yaml (if any) is untouched.
What’s next
Section titled “What’s next”- The full validation rules cover every schema check the loader enforces.
- v0.3.1 wires per-list runtime CoR over actual provider failures + per-provider feature-toggle translation. The classifier, structured
AgentResolutionExhausted, and typed feature structs are already in place. - v0.4 ships periodic re-probing of model availability + the capability harness that replaces the auth-only smoke test.