Skip to content

Providers and lanes

A provider is an endpoint mini-ork can call. A lane is a name a workflow uses to ask for a model (model_lane: reviewer), bound to a provider entry in agents.yaml. Two files, two jobs:

File Answers
config/providers.yaml How do I reach this endpoint, and which env var holds its key?
config/agents.yaml Which provider does each role use?
flowchart LR
    W["workflow.yaml<br/>model_lane: reviewer"] --> A["agents.yaml<br/>reviewer: opus"]
    A --> P["providers.yaml<br/>opus: {kind, model}"]
    P --> K["credential<br/>${ANTHROPIC_API_KEY}"]
    P --> E["endpoint<br/>base_url"]

Resolution order

providers.yaml is resolved first hit wins:

  1. $MINI_ORK_PROVIDERS — explicit override.
  2. $MINI_ORK_HOME/config/providers.yaml — per-project, gitignored.
  3. <repo>/config/providers.yaml — the committed registry.

The project copy replaces the committed registry; it is not merged. Copy the entries you need into it rather than writing a partial file, or point MINI_ORK_PROVIDERS at a full document.

Provider kinds

kind Transport Required fields Use when
anthropic-native claude CLI, raw key or ambient login — (model optional) Anthropic directly, or a Claude Code login
anthropic-compat claude CLI → Anthropic-compatible gateway base_url, api_key_env Z.ai GLM, Kimi, MiniMax, DeepSeek, an internal gateway
openai-compat codex CLI → OpenAI-compatible /v1 base_url, api_key_env OpenAI, or a codex-routed gateway
openai-chat Direct HTTP /chat/completions base_url, api_key_env OpenRouter, Groq, vLLM, any OpenAI-compatible HTTP endpoint
uhp Direct HTTP /v1/responses base_url, api_key_env A UHP harness server that owns model routing
codex-native ambient Codex CLI login — No key to manage
opencode-native ambient opencode login — No key to manage
executable your script script A model behind custom CLI logic

Entry fields

Field Required Meaning
kind yes One of the kinds above
family no Coarse family recorded in llm_calls telemetry (anthropic, gateway, openai, opencode, uhp, local)
model usually Model id pin. Omit for anthropic-native to let the CLI pick
base_url for gateway kinds Endpoint root
api_key_env for keyed kinds Name of the env var holding the key — never the key
script for executable Absolute or repo-relative path
gateway no true only for an anthropic-compat endpoint that cannot stream; otherwise the CLI streams stream-json
extra_env no Map of extra env vars exported at dispatch

Secrets never go in providers.yaml

api_key_env names a variable; it does not contain a value. Put the value in the environment or in the owner-only secrets.local.sh, and see Vault and secrets.

A minimal registry

providers:
  openrouter:
    kind: openai-chat
    family: openrouter
    model: anthropic/claude-sonnet-4.6
    base_url: https://openrouter.ai/api/v1
    api_key_env: OPENROUTER_API_KEY

  my_gateway:
    kind: anthropic-compat
    family: my-gateway
    model: some-model-id
    base_url: https://gateway.example.com/anthropic
    api_key_env: MY_GATEWAY_API_KEY

  my_local_llm:
    kind: executable
    family: local
    script: scripts/my_llm_wrapper.sh

An executable provider must honour the dispatcher contract on argv:

<script> --print --output-format text "<prompt>"

Binding lanes

agents.yaml maps a lane name to a provider name:

lanes:
  planner: sonnet
  implementer: my_gateway
  reviewer: openrouter

A workflow node names the lane it wants:

- name: reviewer
  type: reviewer
  model_lane: reviewer

Resolution runs left to right: node model_lane → lanes map in agents.yaml → providers.yaml entry. A model_lane may also name a provider directly when no alias is defined.

Overlay precedence

The committed config/agents.yaml is the default. A per-project overlay at $MINI_ORK_HOME/config/agents.local.yaml (or $MINI_ORK_AGENTS) is merged over it and wins on conflict, so a machine can point one role at a local model without editing the committed lane map.

Fallback chains

If a lane fails, dispatch walks a role-aware chain:

Variable Default Applies to
MO_FALLBACK_CODING minimax,glm,deepseek_flash Coding roles
MO_FALLBACK_REVIEW opus,glm,sonnet Review roles

The tail lane must exist in providers.yaml. An unknown tail is dropped — and that is how a last-resort rung silently disappears, so keep the tail lane defined.

The chain is also what the pre-run lane-health gate probes. A dead lane aborts before any work starts; an unverifiable lane is recorded and, by default, does not block. See Feature flags for MO_LANE_HEALTH_GATE and MO_LANE_REQUIRE_VERIFICATION.

Routing

By default the executor uses the lane each node declares. Learning-governed routing is on (MO_LANE_ROUTER=1) and selects among lanes using recorded outcomes. A registered policy can replace the default selection:

MO_ROUTING_POLICY=<policy-name> mini-ork run code-fix ./kickoff.md

Policies are registered with mini_ork.dispatch.routing.register_policy.

Operating the registry

mini-ork providers status                     # configured lanes and readiness
mini-ork providers configure <lane>           # prompt securely for one lane's key
mini-ork providers configure --workflow <file> # discover and prompt for every key a workflow needs

configure writes secrets.local.sh atomically with 0600 permissions and never prints a value.

Legacy wrapper scripts

Older material describes lib/providers/cl_<name>.sh wrappers taking precedence over registry entries. The native dispatcher consumes providers.yaml directly — the header of that file is authoritative for current mini-ork.