Providers and models
The unit that travels is the workflow, not the runtime. The same YAML can run a step on any of
three kinds of provider, all declared in registries.json and resolved by internal/catalog:
| Kind | What it is | Examples from the registry |
|---|---|---|
http |
An OpenAI-compatible chat endpoint. The credential is an env var name (apiKeyEnv), never a value. |
openrouter, anthropic, groq, ollama-http, lmstudio, vllm |
cli |
A local agent CLI driven one prompt at a time. | claude-cli, codex-cli, copilot-cli, opencode |
acp |
A local agent spoken to over the Agent Client Protocol. | devin, opencode-acp, codex-acp |
The provider registry page lists every entry, generated from the
file. A step picks one with provider: and optionally a model:.
Defaults
Section titled “Defaults”WFX_DEFAULT_PROVIDER: the provider for every step that names none.wfx doctorprints it on its first line and flags it when it is not ready.WFX_DEFAULT_CLASSIFIER: the classifier fordecide:steps that name none, and for proposal reviews.
Both are server configuration, and ScrubServerEnv removes them from the environment a run sees.
See Env store and secrets.
ACP adapters: devin, opencode, codex
Section titled “ACP adapters: devin, opencode, codex”agentadapter/ makes a local agent CLI usable as a model. There are four presets
(ACPPresets):
| Adapter | Command | Mode | Provider |
|---|---|---|---|
| devin | devin acp (model via --model) |
bypass | devin |
| opencode | opencode acp (model over the protocol) |
build | opencode-acp |
| claude | npx -y @agentclientprotocol/claude-agent-acp (uses claude’s own login) |
default | add an entry with "kind": "acp", "preset": "claude" |
| codex | npx -y @zed-industries/codex-acp |
full-access | codex-acp |
A fresh session every turn. Every ACP provider opens a new session for each turn, in the same
process. Each turn’s prompt is already the complete request, so a kept session only accumulates
copies of it and every turn pays for all the earlier ones again. A registry entry can opt out with
"keepSession": true; do that only for an agent you have measured to need it.
wfx adapters # each adapter, whether it is installed, and how to install itwfx models opencode-acp # the models the agent offers, asked livewfx models opencode-acp --free # only the free onesThe platform’s own loop executes the tools, because that is the only place a step’s tool allowlist and guardrails apply. The adapter therefore refuses the agent’s own native tools by default. When a turn ends empty after refusals, the adapter hands the platform the equivalent call instead (read, grep, glob, bash), but only for tools the step offers. An edit, a fetch or a sub-task has no safe equivalent and stays refused.
The opencode CLI
Section titled “The opencode CLI”The default opencode entry is a cli provider: one fresh opencode run --standalone -m <model>
process per turn, with the prompt on stdin. --standalone gives each turn a private opencode
server instead of opencode’s shared background service, which sits on one fixed port for the whole
machine; with it, two users or two steps on one box no longer collide.
Fallback providers
Section titled “Fallback providers”A provider that cannot be reached does not have to fail the step. A registry entry can name providers to try next, in order:
"openrouter": { "kind": "http", "apiKeyEnv": "OPENROUTER_API_KEY", "fallback": ["opencode"]}The server can also name a list that applies to every step, after the step’s provider and that
provider’s own fallback: model.fallback in config.yaml, or WFX_FALLBACK_PROVIDERS
(comma separated). That is the one place an operator fixes a broken provider for every workflow at
once.
A step falls back only when nothing was answered: its provider does not resolve (key unset, binary missing) or its first call fails before the model has said anything. A step that got any answer is never re-run elsewhere, because its working directory may already have changed.
Where keys live
Section titled “Where keys live”An http entry names its key by apiKeyEnv, never by value. The engine looks that name up in the
step’s environment, which includes the env store, and then in
the server process’s own environment. The env store is the recommended place:
wfx env set OPENROUTER_API_KEY # read without echoing, stored encryptedwfx doctor # says which providers are ready and which key is missingFree models
Section titled “Free models”--free does not guess. A model counts as free only if its id ends in -free (opencode Zen) or
:free (OpenRouter). The default opencode cli entry runs opencode/ling-3.1-flash-free; opencode-acp is no longer the default because opencode now refuses free models over ACP. opencode-acp used
opencode/space-bunny-free, which needs no key. Its registry description records why: it was the
fastest of the free models that scored 7 out of 7 on a commit-classification check on 2026-09-27.