Skip to content

feat(cli): add docker agent doctor for model and credential diagnosis#3489

Merged
Sayt-0 merged 1 commit into
mainfrom
feat/3442-doctor-command
Jul 6, 2026
Merged

feat(cli): add docker agent doctor for model and credential diagnosis#3489
Sayt-0 merged 1 commit into
mainfrom
feat/3442-doctor-command

Conversation

@Sayt-0

@Sayt-0 Sayt-0 commented Jul 6, 2026

Copy link
Copy Markdown
Member

Phase 2 of #3442: a diagnosis command that answers "is this machine ready to run an agent, and if not, why?". Complements Phase 1 (#3452), which made run-time failures actionable.

What it does

docker agent doctor [agent-file] [--json] [--env-from-file <file>] [--models-gateway <url>]
Section Content
Model provider credentials provider, status, credential env var, source (environment, env-file, run-secrets, credential-helper, docker-desktop, pass, keychain)
Docker Model Runner reachable + pulled models, not installed, or unreachable + error
Model auto-selection the model auto would pick, whether it is usable, notes (configured default model, gateway, "not pulled yet")
Agent requirements (optional arg) env vars required by the given file (model credentials + tool secrets), each with status and source
Issues actionable problems, each naming the exact command or docs URL; non-zero exit code when present

Secret values are never printed, only the source that supplies them. --json emits the full report for scripting; the non-zero exit code makes it usable as a CI preflight.

Issue expectations vs implementation

Phase 2 expectation Status
provider / credential found / source (env, env-file, helper, Desktop, pass, keychain) yes
DMR installed/reachable + pulled models yes, via dmr.ListModels (queried once, result reused for auto-selection)
the model auto would select yes, via config.AutoModelConfig on the same source chain
optional doctor agent.yaml: models + toolset env (e.g. GITHUB_PERSONAL_ACCESS_TOKEN) yes; resolves first_available, honours the models gateway like the run-time preflight
values always redacted; --json for scripting yes, asserted by tests

Sample output

$ docker agent doctor golang_developer.yaml

Model provider credentials
  PROVIDER    STATUS    CREDENTIAL                 SOURCE
  anthropic   found     ANTHROPIC_API_KEY          environment
  openai      not set   OPENAI_API_KEY             -
  google      not set   GOOGLE_API_KEY (+2 more)   -
  ...

Docker Model Runner
  Status: reachable, 1 model(s) pulled:
    - ai/qwen3:latest

Model auto-selection
  auto -> anthropic/claude-sonnet-4-6

Agent requirements: golang_developer.yaml
  ENV VAR             REQUIRED BY   STATUS    SOURCE
  ANTHROPIC_API_KEY   models        found     environment
  OPENAI_API_KEY      models        not set   -

Issues
  - golang_developer.yaml requires environment variables that are not set: OPENAI_API_KEY (see https://docs.docker.com/ai/docker-agent/guides/secrets/)
Error: 1 issue(s) found

$ echo $?
1

Implementation notes

  • cmd/root/doctor.go: the command (telemetry, agent-ref completion, cli.StatusError{StatusCode: 1} when issues exist)
  • pkg/environment/default.go: DefaultSources() exposes the labeled secret-source chain and NewDefaultProvider() now consumes it, so the doctor and the runtime can never diverge; no behavior change
  • pkg/config/auto.go: CloudProviderEnvVars() exposes the auto-selection provider table without duplicating it
  • pkg/config/gather.go: RequiredModelEnvVars() mirrors the gateway-aware model-credential preflight used by the run path
  • Checks beyond the issue text: Docker AI Gateway configured but no Docker Desktop sign-in, configured default model whose provider has no credential
  • Every lookup (provider table, auto-selection, agent-file checks) goes through the same labeled source chain, so the report sections cannot disagree

Validation

Check Result
go build ./... ok
go test ./cmd/... ./pkg/environment ./pkg/config ok (TestURLSource_Read_RejectsLocalAddresses already fails on main in sandboxed networks, unrelated)
golangci-lint run on touched packages 0 issues
go run ./lint . no offenses

Open question

The issue leaves command naming open (doctor vs debug env vs models --verbose); doctor matches the flow in the issue's proposed behavior. If debug env seems more appropriate, it can always be changed.

Phase 2 of #3442:

- New `docker agent doctor [agent-file]` reports, without printing
  secret values: per-provider credential state with its source
  (environment, env-file, run-secrets, credential-helper,
  docker-desktop, pass, keychain), Docker Model Runner reachability
  and pulled models, and the model `auto` selection would pick
- With an agent file, lists the environment variables it requires
  (model credentials and tool secrets), whether each is set and from
  which source; resolves first_available selectors and honours the
  models gateway like the run-time preflight
- Issues are actionable (exact command or docs URL) and make the
  command exit non-zero for scripting; `--json` emits the full report
- environment.DefaultSources exposes the labeled secret-source chain
  consumed by NewDefaultProvider so doctor and runtime never diverge
- config.CloudProviderEnvVars exposes the auto-selection provider
  table; config.RequiredModelEnvVars mirrors the gateway-aware
  model-credential preflight
@Sayt-0 Sayt-0 requested a review from a team as a code owner July 6, 2026 17:53
@Sayt-0 Sayt-0 added area/config For configuration parsing, YAML, environment variables area/cli CLI commands, flags, output formatting area/providers/docker-model-runner Docker Model Runner (DMR) local inference kind/feat PR adds a new feature (maps to feat:). Use on PRs only. labels Jul 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/cli CLI commands, flags, output formatting area/config For configuration parsing, YAML, environment variables area/providers/docker-model-runner Docker Model Runner (DMR) local inference kind/feat PR adds a new feature (maps to feat:). Use on PRs only.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants