Executor: routing · Stable — feature-complete; maintenance only. The scope is finished, not abandoned. See the component map for how this fits the rest.
A subscription cockpit's hop cannot be routed through a proxy without breaking prompt-cache integrity. The cache is keyed on the request as the vendor's own client sends it; put a proxy in front and you are no longer sending that request. The cache misses, you pay full input cost on every turn, and nothing in the stack tells you — the failure is a silent bill, not an error.
So that rung has to be a direct child-process call to claude -p. Not a design preference: a
constraint on what any router covering that hop is allowed to do.
This is the whole reason cascadr is not simply LiteLLM. LiteLLM, OpenRouter and Portkey are proxies,
and a proxy is exactly the thing the constraint forbids in that slot. They drop in perfectly behind
the same Provider trait as the paid rung — cascadr does not replace them and does not try to. It
covers the one hop they structurally cannot.
If you are not routing through a subscription cockpit, you do not need cascadr. Use LiteLLM.
Honest limit: the invariant is currently held by wiring discipline, not by the type system.
Router accepts any Vec<Box<dyn Provider>> and cannot tell a direct hop from a proxying one, so a
misconfigured provider in that slot breaks the guarantee with no signal —
#9. Until that lands, the paragraph above
describes an invariant the code relies on rather than one it enforces.
cascadr dispatches a prompt down an ordered list of providers, stopping at the first that
returns a completion and failing open past any rung that is unavailable (down, rate-limited,
errored). This crate implements the claude -p (anthropic-cli) and paid OpenAI-compatible
rungs of that cascade; a local-fleet rung can be layered in by a wider cascade, not here.
Part of the Barnett Studios agentic-harness toolkit → cxpak · commitward · abproof · cascadr · …
brew tap Barnett-Studios/tap && brew install cascadr # macOS/Linux
cargo install cascadr # any platform
docker run --rm -i ghcr.io/barnett-studios/cascadr --model sonnet # containerecho "Explain the borrow checker in one sentence." | cascadr --model sonnet
cascadr --prompt "2 + 2 = ?" # or pass inlineThe cascade is built from the environment: the claude -p rung first (needs claude on PATH),
then an OpenAI-compatible rung if LLM_OPENAI_COMPAT_URL is set. Exit 0 on a completion,
1 if every rung was unavailable, 64 on a usage error.
[dependencies]
cascadr = "0.1"use cascadr::{ClaudeCliDispatch, OpenAiCompat, Provider, Router};
// `new` keeps the child's permission checks ON. Opt out only under your own sandbox:
// ClaudeCliDispatch { skip_permissions: true, ..ClaudeCliDispatch::new(..) }
let anthropic = ClaudeCliDispatch::new(model, timeout, work_dir);
let mut providers: Vec<Box<dyn Provider>> = vec![Box::new(anthropic)];
if let Some(rung) = OpenAiCompat::from_env(timeout) { providers.push(Box::new(rung)); }
let completion = Router::new(providers).dispatch(prompt).await?;Implement Provider to add a rung; order them cheapest-first. classify_http_status /
classify_anthropic_cli map an upstream failure to "unavailable" so the Router walks to the
next rung instead of surfacing a fake completion.
See CONTRACT.md.
Licensed under either of MIT or Apache-2.0 at your option. Unless you explicitly state otherwise, any contribution you intentionally submit for inclusion in the work shall be dual-licensed as above, without any additional terms.
Built by Barnett Studios — part of the agentic-harness toolkit: cxpak · commitward · cascadr · abproof · cordon · slicr.