Skip to main content

Aura-State

Aura-State

Prove your AI agent can't be prompt-injected — before you ship it.

A type-checker for LLM agents. Static analysis + formal proofs — Z3, CTL model checking, taint dataflow, conformal risk — over your agent's design. Catches injection paths, unsafe tool calls, hallucinated outputs, and leaked secrets. Runs locally, in CI, no API key.

PyPI CI License: MIT Python tests

Aura Studio: verify a design, import a real agent from its code, the lethal trifecta lights up with the exact path, then gate regressions
Verify a design → import a real agent from its code → the lethal trifecta lights up with the exact path → save a baseline and gate regressions.  ·  ▶ watch the full walkthrough

pip install aura-state          # or:  uv pip install aura-state  ·  uv add aura-state

Catch a prompt-injection in one command

Point it at your agent design. It fails the build if an untrusted input can reach a real tool call unsanitized:

$ aura-state check my_agent.json

  aura-state check · sql-agent (naive) · 3 nodes

  ✗ taint [Execute]: untrusted data from 'Ask' can reach sink 'Execute' with no sanitizer — injection path
  ✗ obligation [GenSQL]: 'read_only' not proven — the generated SQL may not be read-only

  ✗ NOT PROVEN — 2 blocking findings          # exit code 1 → CI fails

Zero install — run it straight from PyPI with uv:

uvx aura-state check agents/*.json          # no venv, no install — perfect for CI

Drop it into CI and every PR is checked:

# .github/workflows/aura.yml
- uses: your-org/aura-state@v0
  with: { paths: "agents/*.json" }

Catch the lethal trifecta — before an attacker does

The lethal trifecta is the scariest failure mode for a tool-using agent: the moment it can (1) read private data, (2) ingest untrusted content, and (3) communicate externally — all on one reachable path — a prompt injection hidden in that content can read your data and ship it out. Everyone warns about it. Aura proves your agent can't close it, statically, before you ship:

$ aura-state check dev_assistant.tools.json   # ← your MCP tools/list export

  ✗ trifecta [slack_post_message]: lethal trifecta closed — prompt injection at 'fetch'
    (untrusted) can reach external sink 'slack_post_message' unsanitized while 'read_file'
    brings private data into scope. Path: fetch → Agent → slack_post_message.
    Break it with a sanitizer between 'fetch' and 'slack_post_message'.

Point it straight at your MCP setup. Export your agent's tools/list (or hand it your client config) and Aura models the worst case — the LLM can call any tool in any order — then decides whether fetch + filesystem + slack together form an exfiltration channel. It never connects to or runs a server.

Or point it at your agent's code. Aura statically imports the tool surface from a LangGraph / CrewAI / LangChain source file or repo — no install, and it never runs your code:

aura-state check your_agent.py          # extracts @tool functions & framework tools
aura-state check ./my-agent-repo/       # a whole directory
✗ trifecta [post_to_slack]: prompt injection at 'fetch_url' (untrusted) can reach
  'post_to_slack' unsanitized while 'read_customer_file' brings private data into scope.

We audited real MCP-server compositions and agent frameworks (GitHub, filesystem, fetch, Slack, Postgres · CrewAI, AutoGPT) modeled from their published tool surfaces. 5 of 6 can close the lethal trifecta — including the exact shape of the Invariant Labs GitHub-MCP exploit. Full writeup + sources: docs/AUDIT.md. Reproduce it: python examples/audit/run.py.

(Also python examples/audit.py: 9 hand-built agent patterns, 5 with an unguarded injection path, 4 closing the trifecta — each fixable with one sanitizer via Aura's auto-repair.)

Gate regressions, not existing debt

Absolute checks are noisy on a legacy agent. Give check a baseline and it fails only on paths this change newly opened — the line that gets Aura into every agent repo's CI:

$ aura-state check agents/*.json --baseline main-baseline.json

  ✗ taint [send_email] [NEW]: untrusted data from 'read_web' can reach sink 'send_email'…
  ✗ REGRESSION — 1 new blocking finding this change      # exit 1 → PR fails
aura-state check agents/*.json --json > main-baseline.json   # on main
aura-state check agents/*.json --baseline main-baseline.json # on the PR

See it in 10 seconds (no API key)

Paste this after installing — Z3 rejects a hallucinated value and accepts a correct one, in the loop:

from aura_state import prove_extraction

print(prove_extraction({"area": 100, "rate": 3, "total": 999}, ["total == area * rate"]).verified)  # False
print(prove_extraction({"area": 100, "rate": 3, "total": 300}, ["total == area * rate"]).verified)  # True

For the full runnable proofs against the real solvers — each ~10s, no API key — clone the repo:

git clone https://github.com/munshi007/Aura-State && cd Aura-State
pip install -e .
Demo What it proves
aura-state check examples/agents/*.json statically audits 9 common agent designs — 5 have injection paths
python examples/audit.py the audit table you can drop in a launch post
python examples/verified_loop_demo.py Z3 rejects a hallucinated extraction in the loop, retries, accepts
python examples/taint_proof_demo.py untrusted input provably can't reach a dangerous tool
python examples/risk_abstention_demo.py acts only within a calibrated risk budget, else escalates to a human
python examples/emit_contract_demo.py a portable contract compiled faithfully from the design
python examples/replan_demo.py the verifier repairs the plan until it's proven-safe
python examples/pasc_demo.py pipeline-aware conformal calibrates the end-to-end answer, not just each step

Aura Studio — the whole platform, running locally (no cloud, no key)

Prefer a console to code? Launch a local web app that runs the real verifiers on your own machine. One command, nothing leaves your laptop:

pip install "aura-state[ui]" && aura-state ui     # opens http://127.0.0.1:8155
# or zero-install:  uvx --from "aura-state[ui]" aura-state ui

A full agent IDE — design an agent, prove it, run it, watch it execute, and hand it off to code — all in one local console. Not a sandbox you type into: every check is the actual framework verifier.

An agent is a typed graph of four node kinds — you name them anything:

  • Extract — an LLM step producing structured output (Z3 obligations + conformal calibration prove it)
  • Decision — a verified branching rule (compiled to a whitelisted evaluator, never eval)
  • Tool — a declared external call (db.write, http.get, payment.refund, …). Aura proves its preconditions; it does not execute it — you bind the real tool in your code / aura-runtime
  • Sanitizer — a taint boundary that makes a downstream tool safe

The LangGraph SQL agent modeled in Aura and verified: read-only + injection-safe
A real OSS agent — the LangGraph SQL agent — modeled in Aura and proven read-only + injection-safe.

Module What you do
Build drag a typed graph; configure each node (model · prompt · schema · Z3 obligations · tool + side-effect · retry · consensus); Verify runs Z3 + CTL + taint; Auto-repair fixes a taint violation in one click
Run feed input (text · URL fetch · file); Extract/Decision nodes run for real, Tool nodes show a proven boundary with a mock return; watch the path light up on the canvas with a step scrubber and a plain-English "why"
Runs · Evals every run persisted for replay; test-case suites with assertions
Prove · Dataset Z3 point-check any record; bulk-verify a dataset
Monitor live feed of your real agent's outputs (via the SDK), verified as they happen, with pass-rate charts
Calibrate · Memory conformal intervals + risk-controlled abstention; context-pruning preview
Audit a tamper-evident, hash-chained log of every action, exportable for compliance
Versions · Certify snapshot + diff designs; export a signed proof certificate (SHA-256) or the whole agent as runnable Python
SDK copy-paste snippets to use the library in code — the studio is optional

Bring any model. A local Ollama model needs no key. For OpenAI / Gemini / DeepSeek, paste your key in Settings → Providers — it's held in memory for the session (never written to disk) and works immediately, no restart. Keys set in your environment before launch are picked up too. Nothing leaves your laptop.

Connect your agent (any code · CrewAI · LangGraph)

You don't rebuild your agent in the studio — you verify it where it already runs, and stream the results in. A tiny SDK does both:

from aura_state.hooks import Monitor, verified

mon = Monitor()   # points at a local `aura-state ui`

# verify + stream any output:
mon.record({"refund_amount": 180, "order_total": 200},
           ["refund_amount <= order_total"], node="RefundAgent")

# or decorate your extraction / CrewAI task / LangGraph node (fail-closed):
@verified(["total == area * rate"], monitor=mon, strict=True)
def extract_quote(text) -> dict:
    ...        # your LLM call
    return {"area": 100, "rate": 3, "total": 300}

Verification runs in your code even if the studio is closed; when it's open, the Monitor shows every output proven or rejected, live.

Aura Studio Build — configure every part of a typed agent
Build — click a node, configure everything (prompt, model, schema, obligations, transitions)

Aura Studio Run — the full agent executes end-to-end with a live verified trace
Run — the real engine executes the whole agent; each step extracted, Z3-verified, and a contract emitted

Aura Studio Monitor — your real agent's outputs streamed in via the SDK and verified live
Monitor — your real agent (via the SDK hook) streams outputs in, proven or rejected live

What this is

Most LLM frameworks let you chain API calls and hope for the best. Aura-State takes a different approach: you define your workflow as a typed graph of nodes, and verification runs inside the loop — every extraction must satisfy its formal contract before the workflow moves on.

The key difference is what happens between nodes:

  • Extractions are checked against Z3 proof obligations, in the extract→verify→retry loop — a value that can't be proven is not accepted (fail-closed)
  • Math runs in a no-exec sandboxed interpreter, never hallucinated
  • Uncertainty uses split-conformal / jackknife+ calibration (with the honest worst-case coverage); repeated same-input runs are reported as dispersion, not a coverage guarantee
  • Workflows are model-checked (CTL) for reachability/completion/ordering before they run
  • Routing (when a node returns an ambiguous edge) is a Thompson-sampling bandit, not an LLM guess

Scope & honest limits

Aura-State is a design-time verifier, and worth being precise about:

  • It reasons over your agent's structure (a typed graph / tool surface), not its runtime behaviour — it does not execute your agent or tools.
  • The lethal-trifecta / taint checks are sound but heuristic: tool roles are inferred from names + declared side-effects, so the analysis over-flags rather than misses (fail-closed), and you can correct any call with a data_class / exfil override. It is not a semantic proof that a specific injection string succeeds.
  • The Z3 / CTL guarantees are exact for the obligations and properties you write; they don't invent the spec for you.
  • It's early (v0.x) — verified on real OSS agent shapes, but treat it as a strong linter you can trust to fail closed, not a certified security product.

Quick example

from aura_state import AuraEngine, Node, CompiledTransition
from pydantic import BaseModel, Field
from openai import OpenAI

# Define what you want to extract
class LeadData(BaseModel):
    name: str = Field(description="Full name")
    budget: int = Field(description="Budget in USD")
    timeline: str = Field(description="Buying timeline")

# Define a node that extracts it — with a Z3 obligation the value must satisfy
class ExtractLead(Node):
    system_prompt = "Extract lead info from a sales call transcript."
    extracts = LeadData
    obligations = ["budget > 0"]   # proven in the loop; unprovable -> not accepted

    def handle(self, user_text, extracted_data=None, memory=None):
        return "QualifyBudget", extracted_data.model_dump()

# Define a decision node that does deterministic math (no LLM). Its rule runs
# even though the node does no extraction — it reads prior state from memory.
class QualifyBudget(Node):
    system_prompt = "Score the lead."
    sandbox_rule = "result = budget > 100000"  # runs in the no-exec sandbox

    def handle(self, user_text, extracted_data=None, memory=None):
        return "END", memory

# Wire it up
engine = AuraEngine(llm_client=OpenAI())
engine.register(ExtractLead, QualifyBudget)
engine.connect([
    CompiledTransition(from_node=ExtractLead, to_node=QualifyBudget),
])

# Run
next_state, data = engine.process("ExtractLead", user_text="Hi, I'm Sarah. Budget is $450k.")

What happens under the hood

When you call engine.process(), it runs through these steps in order:

1. Few-shot injection      →  optional: inject similar past successes as examples.
2. Verification loop       →  extract → check (sandbox rule + Z3 obligations) → retry.
                              A value that fails its contract is not accepted (fail-closed).
3. Consensus dispersion    →  with consensus > 1, measure agreement across the runs
                              (dispersion, not a calibrated coverage guarantee).
4. Your handle() method    →  your routing / business logic runs here.
5. Bandit router           →  if handle() returns an invalid edge, Thompson-sample a feasible one.
6. State serialization     →  save state (JSON, tamper-evident) for time-travel debugging.

Graph-level properties (reachability, completion, ordering) are checked separately at design time with engine.verify([...]) — CTL model checking over the whole graph, which per-transition checks can't do. Everything above happens in the loop; engine.verification_reports() returns the proof results and intervals per step.

Formal verification (the interesting part)

This is what actually makes Aura-State different from other frameworks.

Verify your workflow graph before it runs

Your node graph gets compiled into a Kripke structure and checked against temporal logic properties:

from aura_state import verify_engine, reachability, mutual_exclusion, eventual_completion

results = verify_engine(engine, [
    {"description": "QualifyBudget is reachable", "formula": reachability("QualifyBudget")},
    {"description": "All paths terminate", "formula": eventual_completion("QualifyBudget")},
])
# Result: PROVEN or VIOLATED, with the exact states that satisfy/violate

This is the same technique used to verify hardware circuits and flight control systems (CTL model checking, Clarke et al. 1986).

Prove that extracted data is correct

After the LLM extracts values, Z3 (a theorem prover from Microsoft Research) can formally prove they satisfy your constraints:

from aura_state import prove_extraction

result = prove_extraction(
    {"budget": 450000, "cost_per_sqft": 3, "total": 1350000},
    obligations=["budget > 0", "total == budget * cost_per_sqft"],
)
# result.verified = True
# If False, Z3 gives you a counterexample showing exactly what broke

It also proves your obligations aren't self-contradictory. ["x > 5", "x < 3"] can never hold — Z3 catches that symbolically (variables ranging freely over the declared field bounds, not pinned to one value), and the design→contract compiler flags it per node before you ship.

Confidence intervals on extractions

Run the extraction multiple times and get distribution-free confidence intervals:

from aura_state import conformal_interval

budgets = [450000, 452000, 448000, 450000, 451000]
ci = conformal_interval(budgets, confidence=0.95)
# ci.lower = 447800, ci.upper = 452200

This uses conformal prediction (Vovk et al., 2005) — no distributional assumptions required.

Pipeline-aware (PASC): a 95% guarantee at each node is not 95% end-to-end — errors compound. PipelineConformal calibrates on the composed output so the guarantee holds for the final answer. In the demo, per-step conformal covers the end-to-end result only ~48%; PASC hits the nominal 90%. See python examples/pasc_demo.py.

Compile a runtime contract from the design

The obligations, CTL verdicts, and confidence a workflow was proven against compile into a single portable, versioned contract. Because it's derived from the same typed design the engine runs, the specification is faithful by construction — spec and implementation are one artifact and can't drift.

contract = engine.compile_contract(properties=[
    {"description": "RouteLead is reachable", "formula": reachability("RouteLead")},
])
contract.to_json()                        # portable, content-addressable
check_faithfulness(contract, "QualifyLead", extracted)   # contract agrees with the loop
diff_contracts(old, contract)             # design-time regression gate

Every other assurance system consumes a behavioral contract it can't author — and hand-written policy drifts from the code (and is only 24–35% faithful when translated from prose). Here the contract is emitted from the design that was proven. See python examples/emit_contract_demo.py.

Prove untrusted data can't reach a dangerous tool (injection-proof)

Label nodes with capability types and the compiler statically proves — over the typed graph — that no untrusted source can reach a dangerous sink without passing a sanitizer. It tracks provenance, not content, so it can't be fooled by the encodings that defeat runtime scanners. The verdict compiles into the contract, so a runtime can refuse to deploy a VIOLATED graph.

class Ingest(Node):    untrusted_source = True     # LLM / external tool output
class Review(Node):    sanitizer = True            # clears taint
class SendEmail(Node): dangerous_sink = True       # irreversible action

analyze_taint(engine)   # -> VIOLATED (Ingest -> SendEmail) unless Review is in the path

It's field-level: label individual fields, and a clean field passes a sink untouched while only a tainted field reaching it is a violation — with the exact field and its origin named. A field-specific sanitizer clears just its field.

class Ingest(Node): untrusted_fields = ["note"]   # free text is untrusted
class Send(Node):   sink_fields = ["account_id"]  # the action consumes account_id

analyze_field_taint(engine)   # PROVEN — the tainted `note` never reaches the sink arg

Everyone else sells injection detection (probabilistic). This is impossibility over the design. See python examples/taint_proof_demo.py.

Act only if calibrated risk ≤ ε, otherwise escalate

The "knows when it doesn't know" story made into an actual gate. Calibrate a controller on a labeled set and the agent auto-acts only when its false-action rate is provably within budget — everything below the threshold escalates to a human, never a silent guess.

ctrl = RiskController(epsilon=0.05).calibrate(scores, correct)   # false-action rate ≤ 5%

class Decide(Node):
    risk_controller = ctrl
    escalation_node = "HumanReview"
    def risk_score(self, extracted_data=None, conformal=None, memory=None):
        return confidence   # in [0,1]

Uses Conformal Risk Control (arXiv:2208.02814); Learn-Then-Test (arXiv:2110.01052) for tuning several thresholds. Abstention is a first-class engine outcome. See python examples/risk_abstention_demo.py.

Let the verifier repair the plan (counterexample-guided replanning)

Verification is usually a gate that says VIOLATED and stops. Here the counterexample — a tainted path, a CTL violating state, a Z3 assignment — is fed back to a replanner, which edits the plan and re-verifies, until it's proven or a budget is hit. The plan is provably correct because the verifier drove it there.

result = engine.repair()          # verify → counterexample → repair → re-verify
result.verified                   # True: driven to PROVEN (e.g. a sanitizer inserted)
result.unresolved                 # if it aborts: the explicit remaining violations

Never a silent pass — an unrepairable design aborts with the violation named. Refs: PAT-Agent (arXiv:2509.23675), VERIMAP (arXiv:2510.17109). See python examples/replan_demo.py.

Results — real data, reproducible, no API key

Every number below comes from running Aura-State on real, public data (or a real local model). Nothing here is simulated.

What Real subject Result Reproduce
Z3 verifies invariants at scale 1,000 real public sales records (3 arithmetic invariants each) 1,000/1,000 verified, 3,000 obligations, ~1,200 records/sec; rejects a corrupted record with the exact failing obligation python examples/real_data/verify_real_dataset.py
Conformal coverage on real data 442 real diabetes patient records (scikit-learn) requested 90% → 91.3% empirical coverage on held-out patients python examples/real_data/conformal_on_real_data.py
A real LangGraph agent, local model qwen2.5:0.5b via Ollama — no key, no cloud agent's extraction Z3-verified, tool graph proven injection-safe, audit contract emitted python examples/integrations/langgraph_verified.py
# real data through the verifier — no LLM, no key
python examples/real_data/verify_real_dataset.py
pip install scikit-learn && python examples/real_data/conformal_on_real_data.py

# a real LangGraph agent on a local model — no key, no cloud
ollama pull qwen2.5:0.5b && pip install langgraph
OLLAMA_MODEL=qwen2.5:0.5b python examples/integrations/langgraph_verified.py

# verification rejects a hallucination in the loop — no key
python examples/verified_loop_demo.py

See examples/real_data/ and examples/integrations/ for the full runs.

Project structure

aura_state/
├── core/
│   ├── engine.py              # Main engine — verified process() loop + bandit router
│   ├── adaptive_graph.py      # Node health metrics + per-edge Beta-Bernoulli posteriors
│   ├── verification_loop.py   # Extract → verify (sandbox + Z3) → retry loop
│   └── providers.py           # Multi-model routing + cost tracking
├── verification/             # ← the core: correct, adversarially-tested primitives
│   ├── proof_engine.py        # Z3 proofs (fail-closed AST→Z3 compiler, no eval)
│   ├── conformal.py           # jackknife+ prediction intervals (order statistic)
│   └── temporal_verifier.py   # Kripke + CTL model checking (init-state, structural deadlocks)
├── execution/
│   ├── sandbox.py             # No-exec allowlist AST evaluator (deny-by-default)
│   └── tracer.py              # State serialization, tamper-evident JSON (time-travel debug)
├── compiler/
│   ├── schema_compiler.py     # JSON Schema → Node classes
│   └── dspy_tuner.py          # KNN few-shot selection (real embedder required)
├── memory/
│   └── pruner.py              # Context window optimization
└── consensus/
    └── auto_vote.py           # Multi-run extraction with voting

Installation

pip install aura-state

Or the latest from source:

pip install git+https://github.com/munshi007/Aura-State.git

Python 3.10+ required. Dependencies: pydantic, instructor, openai, networkx, pyModelChecking, z3-solver, pyyaml.

Tests

python -m pytest tests/ -v
# 216 tests passing

Works with any LLM provider

Aura-State's verification is independent of the model — only extraction calls one, and nearly every provider speaks the OpenAI-compatible API. Point the client anywhere; the Z3/CTL/taint/conformal code is identical:

from openai import OpenAI
# Gemini, DeepSeek, Together, or a local model via Ollama/vLLM — just the base_url
engine = AuraEngine(llm_client=OpenAI(api_key=key, base_url="https://api.deepseek.com"))

See examples/cookbook/ for OpenAI / Gemini / DeepSeek / local recipes. Your API key is read from your environment — never hard-coded.

Docs

  • Cookbook — realistic agents, verified end to end; any provider
  • LangGraph integration — a real LangGraph agent on a local model (Ollama), verified by Aura-State — no API key
  • Real-data verification — Z3 verifies 1,000 real sales records (3,000 obligations, ~1,200/sec); conformal hits 91.3% coverage on real diabetes records — no LLM, no key
  • Comparison — Aura-State vs LangGraph / CrewAI / Guardrails (they orchestrate; we verify)
  • Usage Guide — code examples for every feature
  • Algorithm Reference — deep-dive into CTL, Z3, Thompson sampling, conformal prediction
  • Contributing — architecture overview and how to contribute
  • Pipeline walkthrough — an illustrative end-to-end pipeline (mocked LLM); for measured results see real-data

License

MIT

Metadata

Release files for aura-state 0.8.8

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for aura-state 0.8.8
File Size Uploaded
aura_state-0.8.8.tar.gz 6.1 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for aura-state 0.8.8
File Interpreter ABI Platform
aura_state-0.8.8-py3-none-any.whl Python 3 none any Details

Total release size: 6.4 MB

Release files / aura_state-0.8.8.tar.gz

Download URL aura_state-0.8.8.tar.gz
Size 6.1 MB
Tags Source
SHA-256 checksum
How to use checksums
3a4922a5321c8b7614e0011742597ef32cb299501ea389f740ec37887f7d640b
BLAKE2b-256 checksum
How to use checksums
341235512a7279d77e1578426c6a4a2bc1c3be3cd8155e8b96e069814e386bf9
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 Sep 21, 2026.

Transparency log

Release files / aura_state-0.8.8-py3-none-any.whl

Download URL aura_state-0.8.8-py3-none-any.whl
Size 253.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b6b6eb1e632317d89fba5fef9f5ade643ab6fe9825445f7b5e89b0f4bbe95135
BLAKE2b-256 checksum
How to use checksums
dc17a1f3de790d3170f9f2f6e1dcfe19f8f6f961cdd32c6f0da061f467dbc7fb
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 Sep 21, 2026.

Transparency log

Release history Release notifications | RSS feed

0.11.6

2 release files

0.11.5

2 release files

0.11.4

2 release files

0.11.3

2 release files

0.11.2

2 release files

0.11.1

2 release files

0.11.0

2 release files

0.10.0

2 release files

0.9.0

2 release files

0.8.13

2 release files

0.8.12

2 release files

0.8.11

2 release files

0.8.10

2 release files

0.8.9

2 release files

This release

0.8.8 This release

2 release files

0.8.7

2 release files

0.8.6

2 release files

0.8.5

2 release files

0.8.4

2 release files

0.8.3

2 release files

0.8.2

2 release files

0.8.1

2 release files

0.8.0

2 release files

0.7.2

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.1

2 release files

0.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page