Avadhika
Avadhika is a contract-bound execution runtime. It keeps LLM retries and fallbacks inside one deadline, one admission budget and one attempt policy.
Avadhika (Sanskrit, from avadhi, "limit") means "to the limit; time-bound, of a fixed period".
Status: Level A complete; first public release (0.1.0). The architecture is frozen (docs/spec.md) and the Level A evidence is complete (docs/evidence/LEVEL_A.md). No claim is made beyond the evidence linked below.
The problem
Applications that call several LLM providers wrap each call in retries and fallbacks. Under failure, those layers interact badly:
- Retries stack. A fallback restarts its own retry loop.
- Waits outlive the caller. Backoff sleeps past the caller's deadline.
- Health gets misattributed. A caller's own timeout puts a healthy provider into cooldown.
- Fallbacks go unchecked. A request falls back to a model that cannot take it, with the wrong context window or no tool support.
Afterwards, nobody can say exactly why an attempt was made.
What Avadhika guarantees
A request enters with one monotonic deadline, one hard admission budget and one attempt policy. Every attempt, wait, backoff, provider switch and fallback must fit inside that one contract.
- No attempt the contract can't afford. The runtime never authorizes an attempt whose worst-case cost (all billable dimensions, at a pinned price) or time could break the contract, just because an earlier attempt failed.
- One decision site. Retries and fallbacks are a single
PLANdecision against eleven legality predicates. They are not nested loops. - Failures are attributed. Caller deadlines, transport failures, attempt timeouts and unknown errors never count against a provider's health. Unknown errors stop: no retry, no fallback.
- Retry storms are bounded. A global extra-attempt budget, per-endpoint retry budgets and half-open probe slots are all acquired atomically.
- Streaming commits once. It commits at the first caller-visible delta. After that, output is never spliced from another model.
- Decisions can be replayed. Every decision is recorded with the inputs it consumed, and
avadhika replayreproduces it byte for byte. Provider output and network timing are never claimed to be reproducible.
Claim boundary. The budget is a hard admission budget: a limit on what the runtime authorizes. A provider can still bill beyond it, for example for unmodelled dimensions, generation after cancellation, or ignored caps. Those cases are detected and annotated (BILLING_BOUND_VIOLATION), never hidden. See spec section 5.3.
What it is not
- It is not a gateway or proxy.
- It does not pick "the best model". The caller or a policy supplies the candidate order.
- It does no learned routing, load balancing or hedging.
It is a small library with a single runtime dependency: httpx.
Quick start
python -m venv .venv && .venv/bin/pip install -e '.[dev]'
.venv/bin/avadhika plan --catalog examples/catalog.json --contract examples/contract.json
.venv/bin/avadhika run --catalog examples/catalog.json --contract examples/contract.json --prompt hi --record rec.json
.venv/bin/avadhika replay rec.json
.venv/bin/avadhika explain rec.json
.venv/bin/avadhika simulate --catalog examples/catalog.json --contract examples/contract.json --scenario examples/scenario-outage.json
The examples use the built-in fake provider and send nothing over the network.
Architecture
| Layer | Description |
|---|---|
Pure core (src/avadhika/core) |
A sans-I/O state machine, step(state, event) -> (state, commands, decision). It never reads a clock, socket, random source or shared state. Tests enforce this with a forbidden-import rule and byte-identical decision replay. |
Async shell (src/avadhika/shell) |
Real monotonic timers, cancellation, and teardown before an attempt's end is reported. A transactional HealthRegistry handles leases, breakers, probe slots and budgets. Observers run off the event loop. |
Adapters (src/avadhika/adapters) |
OpenAI-compatible Chat Completions, Anthropic Messages, and a scriptable fake. Keys are read from the environment at send time only. |
Simulator (src/avadhika/sim) |
A deterministic virtual clock driving the same core and registry, with seeded interleaving, a transport spy and an invariant checker. |
Design decisions that interpret the spec are recorded in docs/decisions/. docs/design-overview.md is a reader-oriented edition of the specification; where they differ, docs/spec.md governs.
Evidence
The full Level A evidence report is docs/evidence/LEVEL_A.md.
| Evidence | Status |
|---|---|
| Spec v0 frozen | docs/spec.md, sha256 in docs/spec.sha256, pinned by a test |
| Invariants I1–I19 | Tested: unit, golden records, simulator checker, property suite, real-async shell |
| Named scenarios S1–S24 | All present and passing |
| Policy coverage (spec 11.5) | Every policy field shown to affect decisions, admission or the digest |
| Mutation testing | core/ and the registry: every survivor has a written verdict, 0 unexplained (report) |
| Python 3.11–3.14 | tools/matrix.sh: see the final run in docs/evidence/LEVEL_A.md |
| Fresh install from wheel | tools/fresh_install.sh: OK |
| Benchmarks | docs/evidence/benchmarks.md, single runs, no provider claims |
| Offline adapter conformance (A1, A2, A4, A7) | Pass against documented-shape fixtures |
| Live conformance (A3, A5) | Opt-in harness (python -m avadhika.conformance.live); not yet run |
| Complete billing coverage (A6) | Not claimed |
| Pre-publication review pass | Done: 2 MAJOR / 11 MINOR / 8 NIT, each reproduced or adjudicated (adjudication, ADR-0007) |
Using it
- Pass an
httpx.AsyncClient. Avadhika's own deadline and attempt timers govern every attempt, and any httpx transport error, timeouts included, is treated as a transport failure. A client-level timeout is redundant, sotimeout=Noneis a reasonable choice. - Cancel a request with the
cancelevent or by cancelling its task, for example withasyncio.wait_for. Either way, the attempt is torn down and its lease released before the cancellation propagates. - Credentialed adapters require an
https://base URL. Local hosts are exempt, andallow_insecure_http=Trueoverrides the check.
Limitations
- Health state, leases and budgets are process-local.
- Admission is conservative. Without a caller-supplied input-token bound, the real adapters fail closed in hard-budget mode.
- A connection-refusing or stalling endpoint never trips its breaker, by design. Its fallbacks draw on the extra-attempt budget, which can run out (scenario S24 measures this).
- If teardown cannot be confirmed, the request is reported as
TEARDOWN_UNCONFIRMEDwith an incomplete decision record, and the endpoint is degraded until teardown is confirmed. - A failure after a request may have been sent is charged at its full reservation, which can exclude a later fallback under a tight budget. Connect-phase failures are charged nothing.
required.toolsandrequired.structured_outputfilter candidates only. The v1 adapters do not send tool or response-format payloads.
License
Apache-2.0
Metadata
Release files for avadhika 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| avadhika-0.1.0.tar.gz | 262.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| avadhika-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 350.4 kB
Release files / avadhika-0.1.0.tar.gz
| Download URL | avadhika-0.1.0.tar.gz |
|---|---|
| Size | 262.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
aa9ed8ddc7acaf05432dba903e95022e800e464eec3416f0faba84c0b16c9374
|
|
BLAKE2b-256 checksum How to use checksums |
9aeca856f4a23a39073c1bb90337f7c32cab858afa9e90d5b795608923f9bd81
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.
Transparency logRelease files / avadhika-0.1.0-py3-none-any.whl
| Download URL | avadhika-0.1.0-py3-none-any.whl |
|---|---|
| Size | 88.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c48847976c49bd85678748d5f88bd6691848731cb6df86512d6eb9473ad684f8
|
|
BLAKE2b-256 checksum How to use checksums |
bd2c1e7786a26b38783ddc349bca80d22ee775a85a49eaaf995ac1ccdb570379
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.
Transparency log