agents, models, and providers
agents is the only required block, a model reference is provider/model or a name from models, and providers sets a reusable endpoint such as Docker Model Runner.
You open capture/fixtures/agents/files.yaml and find model: local on the agent, a local entry under models, and provider: dmr inside that entry. A second file, dmr.yaml, adds a providers block with a URL, and its run never reaches the recorder.
When you finish this section, you can follow an agent's model value to the endpoint it calls, and predict what auto picks.
The file and its schema
Agent file: a YAML or HCL document that matches agent-schema.json, the schema of Docker Agent v16. Its root allows 16 keys and requires one: agents, a map of agent configurations with at least one agent. A misspelled top-level key fails the load, because the parser rejects unknown top-level keys.
version is a string from "0" to "16" in the schema enum. The same docs page still gives 15 as the current version. The capture files declare "16" and load, so this manual follows the schema. When you load an older config, Docker Agent migrates it to the latest schema. The agent that share pull fetched from agentcatalog/pirate declares version: "2" and names openai/gpt-4.1 inline (16-share-pull-agent.yaml).
version: "16"
agents:
root:
model: local
description: Lists the files of a small repository and counts lines.
instruction: |
You answer questions about the files in the working directory.
Use the tools to look; never guess. Answer in one sentence that
names the files and gives the line count.
max_iterations: 8
toolsets:
- type: filesystem
- type: shell
models:
local:
provider: dmr
model: ai/qwen3:4b
temperature: 0Agent keys
Agent: one entry under agents, named by its key. The first agent of the team runs unless --agent names another. The schema AgentConfig lists the keys, and these are the ones the capture files use or rely on.
| Key | In the capture | Schema rule |
|---|---|---|
model | local, qwen, dmr/ai/qwen3, openai/gpt-4.1 | a model name or provider/model |
instruction | a block string in every file | the system prompt: a string, or a list joined with blank lines |
max_iterations | 8 in files.yaml, 3 for writer | an integer from 0 |
max_consecutive_tool_calls | not set | identical calls before the agent stops, and 0 means the default of 5 |
redact_secrets | not set | true by default: a builtin scrubs secrets on three hook events |
toolsets, sub_agents, handoffs, hooks | files.yaml, team.yaml, guarded.yaml | toolsets, delegation, permissions |
Model references
Model reference: the value of model on an agent. It takes five forms:
provider/modelinline, such asdmr/ai/qwen3ingreeter.yaml.- a name under
models, such aslocal, withprovider,model, and parameters such astemperature: 0. - a
first_availablelist: at load time, Docker Agent picks the first candidate that has its credentials configured. - an alloy: two references with a comma between them, which the runtime alternates in one conversation.
auto: the first cloud provider that has a configured credential, then a pulled Model Runner model.
run --model [agent=]provider/model replaces the reference for one run. On the recording Mac, doctor resolved auto to dmr/docker.io/ai/qwen3:4b with only the 4B tag pulled (25-doctor.txt). With no Model Runner, it named dmr/ai/qwen3:latest and reported no usable model (16-doctor.txt).
providers and the Model Runner endpoint
Provider definition: an entry under providers with an underlying provider (default openai), a base_url, a token_key, and defaults that its models inherit.
version: "16"
providers:
runner:
provider: dmr
base_url: http://localhost:12434/engines/llama.cpp/v1
models:
qwen:
provider: runner
model: ai/qwen3:4b
temperature: 0
…files.yaml names provider: dmr with no base_url, and then Docker Agent finds the DMR endpoint by itself. It runs docker model status --json, which 16-dry-run.txt prints inside its error when no Docker daemon answers. An eval container has no docker CLI, so the same discovery fails there, as eval shows.
With an explicit base_url, dmr.yaml answered Hello (the capture). That run is live in every capture, because an explicit base_url bypasses the --record proxy and leaves the cassette empty (kit notes). Set base_url when discovery cannot work, and leave it out when you want a cassette.
Provider ids changed too. doctor prints fireworks-ai, togetherai, and moonshotai, and the docs Models table lists fireworks, together, and moonshot. This manual prints the ids that doctor prints (conflict C58), and the providers table has the rest. A named patch under flavors changes any of these blocks at run time with --flavor, and the capture ran none.
files.yaml resolves local to the dmr provider and finds the endpoint itself, while dmr.yaml resolves qwen through providers.runner to a fixed URL. Read each column top down, from the agent to the endpoint. Violet blocks are agent entries and plum blocks are model and provider entries. The bottom row is the auto decision as doctor printed it.Docker Sandboxes (sbx) and Docker Agent (docker-agent) sbx 0.47.0, docker-agent 1.149.0 · bf4169c · 2026-10-07 · Edition 2026.10