Provider-portable agent runtimes
If your product depends on a single coding-agent CLI you have a vendor problem. Here's the shape of the abstraction I settled on after wiring the same orchestrator to two providers.
Janus drives a coding agent in headless mode every night across a handful of projects. Locking the orchestrator to one CLI was the obvious move — and the wrong one. CLIs change shape between minor versions. Subscriptions get rate-limited at the worst possible time. A second provider as fallback is the cheapest insurance you can buy.
One interface, many runners
The contract fits on a screen: each runner declares what it supports and how to run a prompt. Adapters sit behind it; the orchestrator resolves a runner from config and never knows which CLI it’s calling. Swapping providers is a one-line config change. A fallback wrapper retries on the secondary runner when the primary throws a retriable error — overload, rate-limit, network — and lets unrecoverable ones (auth missing, invalid input) bubble up. The classification of which error is which lives in the adapter, not the orchestrator.
A few things that turned out to matter
Capability flags, not lowest common denominator. Each adapter declares what it supports — effort control, session resume, cost tracking, JSON streaming. Call sites read the flags and degrade gracefully. The alternative — only exposing what every runner supports — leaves the entire upside of the better runner on the table.
Prompt over STDIN, always. Argv has size limits (~128KB on most Unixes). A long system prompt plus context breaks at the OS layer before the CLI ever sees it, with an error message that points nowhere useful. STDIN is universal and doesn’t care about size.
Don’t fake cost numbers. If the provider doesn’t expose per-call
cost, the cost field stays null. Estimating from token counts and the
published price list looks reasonable until plan-tier discounts, free
quota, and rate-limit penalties pull the estimate away from reality.
Null is honest; a made-up number is a footgun.
The bigger point
The runner is not the product. The orchestration is. Whichever coding-agent CLI wins next quarter, the rest of the system shouldn’t have to know.