Skip to content

cascadr

CI Crates.io Downloads License

Executor: routing · Stable — feature-complete; maintenance only. The scope is finished, not abandoned. See the component map for how this fits the rest.

Why this exists

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.

What it does

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 · …

Install

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   # container

Use

echo "Explain the borrow checker in one sentence." | cascadr --model sonnet
cascadr --prompt "2 + 2 = ?"    # or pass inline

The 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.

As a library

[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.

License

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.

About

Cost-ordered, fail-open LLM provider cascade — cheapest-capable first, never proxies the subscription hop

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages