Repository navigation
Description
Summary
A harness provider needs an external coding-agent to be present at runtime (a CLI binary and/or a Python/JS SDK wrapper, plus auth). Today there is no first-class way to (a) install the providers you intend to use, or (b) verify they are actually installed and usable before you run a real workflow. Failures surface late, mid-run, as a subprocess error inside app.harness(...). This is especially painful in containers/CI where you want the image build to fail fast if a required harness is missing.
We want a clean, bloat-free DX for declaring and verifying harness provider availability, consistent across the Python, TypeScript, and Go SDKs.
Why "just add pip/npm extras" is not enough
The real dependency is usually a binary, not a pip/npm library:
| Provider | Python install | TS/JS install | Underlying binary |
|---|---|---|---|
| claude-code | claude-agent-sdk (PyPI) |
@anthropic-ai/claude-agent-sdk (npm) |
bundles the Claude Code CLI |
| codex | openai-codex (PyPI) or raw CLI |
@openai/codex-sdk (npm) |
codex (Rust binary, npm/brew) |
| gemini | none (CLI only) | none official (CLI only) | gemini (npm @google/gemini-cli) |
| opencode | opencode-ai (PyPI, alpha) or raw CLI |
@opencode-ai/sdk (npm) |
opencode (curl/npm) |
So pip/npm extras can pin the Python/JS glue where an SDK exists, but they cannot install the actual agent binary (gemini, opencode, codex, the bundled claude node binary). An extra that installs nothing real (e.g. gemini) would be misleading. We need extras and a runtime preflight that checks ground truth (binary on PATH + version + auth).
Context: gemini-cli is being retired for consumer tiers on 2026-06-18 (superseded by Antigravity). Factor this into how aggressively we invest in a gemini extra.
Proposed DX (three layers)
1. Optional extras for the pip/npm-installable wrappers
- Python:
agentfield[harness-claude],[harness-codex],[harness-opencode], and[harness-all]. (Today onlyharness/harness-claudeexist and both just pullclaude-agent-sdk.) - TS: optional
peerDependenciesfor@openai/codex-sdkand@opencode-ai/sdk(we already mark@anthropic-ai/claude-agent-sdkoptional). - These pin versions and make
importwork; they do not claim to install binaries.
2. A harness doctor preflight (the real fix for "is it installed?")
A single command/function that, per provider, checks: binary on PATH (shutil.which), version (and min-version compatibility), and auth (required env vars present). Returns a structured report and a non-zero exit when a requested provider is unusable.
- CLI:
af harness doctor [--provider opencode,codex] [--json] - Library:
await app.harness_doctor(providers=[...]) -> list[ProviderHealth] - This is the thing you run in a Dockerfile / CI step / container entrypoint to guarantee the harness is present before any real (paid) run. Same pattern as
flutter doctor,gh auth status.
3. Standardized, actionable missing-dependency errors (fail fast, not mid-run)
- Every provider does a
shutil.which-style preflight before spawning the subprocess, and raises a typedHarnessProviderUnavailablenaming the exact install command and the missing auth env var. - The CLI providers already do part of this on
FileNotFoundError; make it proactive, typed, and uniform across all four providers and all three SDKs.
Acceptance criteria
- Python extras:
harness-claude,harness-codex,harness-opencode,harness-all. - TS optional peer deps for codex + opencode SDKs.
-
af harness doctorCLI +app.harness_doctor()library API returning structured per-provider health (installed / version / auth / usable), non-zero exit on any requested provider being unusable. - Typed
HarnessProviderUnavailableraised before subprocess spawn, with exact install command + missing auth env var, uniform across providers. - Docs: per-provider install matrix + a "verify in your container" snippet.
- Mirror the design in Python first, then port to TS and Go (Go is subprocess-only, so doctor + errors matter most there).
Open question
Should doctor optionally attempt a zero-cost liveness probe (e.g. --version / a no-op invocation) per provider, or only static PATH/env checks? Static is faster and offline-safe; a probe catches broken installs. Lean static by default, probe behind a --probe flag.
Spun out of the harness UX/DX review done alongside #684 (project_dir/cwd output placement fix).
Activity
AbirAbbas commentedon Jun 24, 2026
Triage
Classification: feature ✓
Suggested labels: enhancement
Likely affected files:
Triage by github-buddy
hiSandog commentedon Jun 27, 2026
The distinction between library extras and real provider availability is important here. A useful
harness doctorcontract would probably check three layers separately: package/import availability, required CLI binary on PATH with version, and auth/config readiness. Returning standardized missing-provider errors with a suggested install/auth command would make CI failures much easier to understand than a late subprocess error inside a workflow.fix(harness): align claude-code doctor spec with Python SDK, trim doc…
feat(harness): add Python provider preflight (Agent-Field#756)
feat(go-sdk): add harness doctor preflight and provider availability …