🌌 SAGAOPS Enterprise Autonomous Agent OS · PyPI v2.2.0 Century-Grade Release

Give any LLM the Rollback-Proving Engine & Safety Fleet OS.

agent-saga v2.2.0 (SAGAOPS) provides century-grade, bulletproof computer science foundations unifying Omnipresent Autonomous Reality Engine, Zero-Entropy Self-Healing Cortex, and Zero-Knowledge Action Certificates.

Your agent will fail at step 4 of 5 β€” and one day it will fail by dying. A try/except keeps its cleanup in memory and dies with it. A checkpoint restores your agent's state; it cannot un-send a wire transfer. agent-saga writes the intent to a hash-chained log before the effect fires, so a separate process can finish the rollback the dead one couldn't.

Don't take our word for it β€” watch it happen in 5 seconds. No API keys, no network, no configuration.

$pip install agent-saga && agent-saga demo
Star on GitHub
Tamper-Evident WAL Β· hash-chained SAGA_LIVE
001SAGA_START checkout_402_h a1f9…
002STEP_COMMITTED stripe.chargecompensable
003STEP_INTENT email.send_receiptirreversible
004PRE_FLIGHT_GATE requires human approvalblocked
005ROLLBACK stripe.refund↺ LIFO
β–Ά Watch it happen

The undo runs backwards.

Step 4 fails. Steps 3, 2, 1 come apart in reverse, one at a time. Both figures below were rendered by agent-saga animate from the write-ahead log of an actual run β€” same reconstruction the static agent-saga graph export uses, so a picture and a diagram of one log cannot disagree.

Step 4 fails - every effect undone ROLLBACK CLEAN. 4 step(s) undone in reverse order, nothing left behind. Step 4 fails - every effect undone checkout-clean-demo agent-saga FORWARD PATH ↓ ↑ ROLLBACK, LIFO 1 stripe.charge committed COMPENSABLE COMPENSATED 2 inventory.reserve committed COMPENSABLE COMPENSATED 3 ledger.post_entry committed COMPENSABLE COMPENSATED 4 crm.update UNKNOWN - may have landed COMPENSABLE COMPENSATED ROLLBACK CLEAN 4 step(s) undone in reverse order, nothing left behind
Every step had a working inverse. Engine verdict: clean = True.
Step 4 fails - two effects had no undo ROLLBACK INCOMPLETE. 2 compensated, 2 orphaned. Step 4 fails - two effects had no undo checkout-orphan-demo agent-saga FORWARD PATH ↓ ↑ ROLLBACK, LIFO 1 stripe.charge committed COMPENSABLE COMPENSATED 2 inventory.reserve committed COMPENSABLE COMPENSATED 3 ledger.post_entry committed COMPENSABLE ORPHANED - no undo 4 crm.update UNKNOWN - may have landed COMPENSABLE ORPHANED - no undo ROLLBACK INCOMPLETE 2 compensated, 2 orphaned
Same failure, two steps declared COMPENSABLE and shipped no inverse. Engine verdict: clean = False.

The right-hand one is the reason to trust the left-hand one. A tool that drew every rollback green would be telling you nothing.

What agent-saga made, precisely. Five figures on this site β€” the two above, plus the fleet timeline, hash chain and outcome matrix on the other tabs β€” are rendered by agent-saga animate and agent-saga viz from write-ahead logs of real runs, rebuilt by python site/build_assets.py. The layout, the hero shader and the motion are hand-written: agent-saga is a transactional-safety library, not a web framework, and it would be a worse library if it pretended otherwise. The point of generating them isn't convenience β€” it's that CI fails if these pictures stop matching what the engine does.

0 tests passing Β· pytest -q
0 failure interleavings proven Β· verify_rollback_invariants()
0 framework adapters
0 fast-path overhead, p50
0 required dependencies

The 5-second proof

Three acts. Nothing simulated.

agent-saga demo runs the real engine against a real write-ahead log, with a real gate, real compensations, and a real killed process. No network, no API keys, no configuration. The "world" is a JSON file, so damage caused by a process that dies is still there for the next process to find.

Act I · No transaction

An ordinary agent charges a card, launches a server, then step 3 fails.

Left behind: charges: ['ch_1'], servers: ['i-1']. Money taken, server running, and nobody is coming to clean it up — someone has to find it by hand, and first they have to know it happened.

Act II · The same calls, in a saga

Identical tools, wrapped rather than rewritten. Step 3 fails exactly as before.

Left behind: nothing. The boundary unwinds LIFO and reports clean — a value read from RollbackReport, so it can never say clean when the engine says partial.

Act III · The process is killed

The saga charges $99, fsyncs the intent, then calls os._exit() — skipping finally, atexit, and loop shutdown. Nothing gets a chance to roll back.

Then a different process reads the log and refunds it. This is the case a try/except cannot answer: its cleanup lived in the memory that just died.

Two details in Act III are worth pausing on. The intent is durable before the effect fires, so recovery never depends on the process that caused the mess still being alive. And the recovery daemon waits for the dead worker's lease to expire rather than checking a PID — PIDs are reused within minutes, and only an expired lease actually proves an owner is gone.

Afterwards, draw what you watched: agent-saga graph --wal ./agent-saga.wal renders the forward path and the rollback fork as Mermaid, where compensated, COMPENSATION FAILED, and ORPHANED are three visually distinct outcomes. A partial rollback can never be drawn as a clean one.

Proof, not adjectives

321 failure interleavings. Seven invariants. Zero violations.

Every claim on this page maps to a command you can run. This one takes under a second:

from agent_saga import verify_rollback_invariants

report = await verify_rollback_invariants(max_steps=6)
print(report.format_text())
# 321 interleavings executed · 7 invariants · VERIFIED

verify_rollback_invariants() enumerates every failure shape up to N steps — which step's forward call raises, which subset of inverses then refuse, whether a committed step has no inverse at all — and runs each against the real engine rather than a model of it. LIFO order, no double compensation, bounded retries, one outcome bucket per step, clean never claimed over an incomplete rollback, orphans reported rather than dropped.

And it states its bound: bounded model checking, not a proof for unbounded N and not a claim about concurrency. "Verified" with no bound attached is the kind of claim this project exists to avoid.

📈 Benchmarks with methodology

Fast path ~17µs, durable path ~7.9ms — reported separately and never blended, because one is a deque push and the other is an fsync. The WAL is measured against your device's own fsync floor, so the figure that travels between machines is agent-saga's marginal cost: 0.97ms, 27%.

🧪 Prove YOUR rollback works

prove_rollback() breaks your workflow at every step, in both failure shapes, and compares the world to its starting state. It catches the case nothing else does: a compensation that runs, returns success, and undoes nothing.

🔗 Zero-config observability

Spans carry OpenTelemetry GenAI semantic conventions, so Langfuse, Arize Phoenix, Datadog, Grafana and Honeycomb render agent-saga traces in panels already built for them. Prompt capture is off by default — a tracing backend is usually a third party.

What only this log makes possible

Every framework logs. Ours records whether the effect had to be undone.

That single fact is ground truth nobody else collects — and six capabilities fall straight out of it.

🎓 Training data labelled by reality

build_corpus() labels every action by whether the world kept it. The hard part is blame: when step 5 fails, steps 1–4 roll back and they were correct. Labelling them negative teaches a model to avoid the calls that worked — so they are COLLATERAL and excluded. DPO-shaped preference pairs, matched within a tool.

⏲ Try a cheaper model on real history

counterfactual_replay() turns the log into a simulator of that afternoon's world. Nothing executes — the replay never invokes a forward callable at all. When the candidate diverges the answer is UNKNOWABLE, not a guess.

🎭 Share traffic, not customers

WALProfile.fit() keeps shapes and ranges, never a value a person typed — so the profile itself is shareable. Fifty real sagas become fifty thousand synthetic ones. Every record is marked __synthetic__: a log indistinguishable from a real one is an instrument for fabricating evidence, not a fixture.

🔮 A gate that improves as you run

FailureModel.fit() learns which call shapes had to be undone, and reports lift over the base rate — "9 of 12 failed" is meaningless when three quarters of everything fails. Below its support threshold it produces no number and says silence is not a clean bill of health.

🛡 No side effect on an invented number

ProvenancePolicy classifies every argument: SOURCED > USER > DERIVED > MODEL. Untagged means MODEL, and SOURCED is verified against the document, not accepted on the label. An agent may not move money on a figure it made up.

🌐 13 framework adapters

LangGraph, CrewAI, AutoGen, LlamaIndex, OpenAI Agents, Semantic Kernel, Vertex AI, Temporal, Camunda, SQLAlchemy, Supabase. One saga spans all of them — the boundary is a contextvar, so a wrapped tool joins whatever saga is open, whichever framework called it.

Plus agent-saga adopt to wire an existing project up mechanically (it will not decide your semantics — the generated module refuses to import until a human classifies each side effect), cascade() for verification-gated escalation across model tiers, and RepairSession to fix one failed step and resume instead of unwinding everything.

β–¦ Nine sagas, one log

Concurrency is a shape, and a terminal can't draw it.

Nine orders ran at once. Three failed and rolled back. Scrolled past in a console those are 60-odd interleaved lines; on a time axis you can see which overlapped, how long the unwinds took, and that the failures cluster rather than scatter. This is agent-saga viz --kind fleet over the write-ahead log of that run β€” the red bars are sagas the engine actually aborted, not a colour picked for drama.

agent-saga fleet timeline9 saga(s) over 90 ms. 3 aborted and rolled back. 9 saga(s) over 90 ms 3 aborted and rolled back agent-saga 0 ms 22.59 ms 45.18 ms 67.76 ms 90.35 ms order-00 order-01 order-02 order-03 order-04 order-05 order-06 order-07 order-08 complete aborted no terminal record
Rolled-back spans also carry a hatch stripe, so they stay distinguishable in greyscale and with a red/green colour deficiency.

AgentKit SDK

One object. Three verbs. A safety net an agent can read.

The whole engine β€” the gate, typed compensation, the tamper-evident log, the audit proofs β€” behind one import. An agent wraps a tool once, runs work inside a transaction, and (the genuinely new part) can ask the system what it is guaranteed and whether it is safe to act right now.

# wrap any tool once β€” gated + logged + compensable inside a transaction, # and a plain function everywhere else. from agent_saga import AgentKit kit = AgentKit(name="research-agent") charge = kit.safe_tool(stripe_charge, semantics="COMPENSABLE", compensate=lambda r: {"handler": "refund", "kwargs": {"id": r["id"]}}) # any exception inside rolls the whole thing back, in reverse order async with kit.transaction(): await charge(amount=4200) await ship_order(...) # if this throws, the charge is refunded

πŸ“œ guarantees() β€” a manifest it can trust

A versioned, JSON-serialisable statement of exactly what is enforced before an effect and guaranteed after β€” including an explicit not_claimed clause. A safety surface that hides its limits is a liability; this one states them.

Click to inspect the manifest β†’

🚦 status() β€” fail-closed live posture

Before a burst of effectful work, an agent asks kit.status(). If a global kill-switch is halting effects β€” or if that signal simply can't be read β€” it reports not ready. Never a confident green when the truth is unknown.

Click to inspect code β†’

πŸ”Œ Zero-ceremony pass-through

The same wrapped tool runs untouched outside a transaction β€” so it works identically in a script, a notebook, or a test with no saga boundary and no special-casing.

Click to inspect code β†’

Core Design Philosophy

The 5 Fundamental Principles of agent-saga.

The core contract that separates true transactional safety from post-disaster cleanup scripts.

Principle 1

🎯 Auditable Consistency is the Contract

β€œA bank does not buy a post-disaster cleanup script β€” it buys a control that refuses to enter an uncompensable boundary without a human on the hook.”

Principle 2

⚑ Runtime-Derived Compensations

AI agents choose forward tools dynamically at runtime. The inverse action can only be derived after the forward step executes and returns concrete state parameters (e.g., charge IDs, row IDs).

Principle 3

πŸ” Honest Rollbacks (clean vs. partial)

Swallowing partial failures is a critical vulnerability. Operators must always distinguish a 100% clean rollback from a partial failure requiring human intervention (RollbackReport.clean).

Principle 4

πŸ›‘ Pre-Flight Gates over Post-Cleanup

High-risk or non-compensable actions trigger policy gates before any side-effect is modified β€” the only point at which refusal is completely free.

Principle 5

πŸ’₯ Fail Loud, Never Silent

Write-Ahead Logs must never silently swallow unreadable or corrupted records. If a recovery daemon cannot parse an entry, it halts and alerts immediately.

Universal Spectrum Coverage

From Hobby Makers & Coders to High-Precision Aerospace.

Whether building an indie side project, auto-refactoring code, executing $10M banking transfers, or diagnosing patient treatments, agent-saga powers mission-critical reliability everywhere.

Hobbyists & Makers πŸ› οΈ

IoT & Hardware Robotics

Enforces hardware actuator angle limits and battery voltage bounds, preventing physical servo burnout or runaway robot motor commands.

Coders & Software Engineers πŸ’»

GitHub & Cloud Infrastructure

Plug-and-play GitHub/GitLab PR auto-reverts and AWS/GCP/K8s infrastructure auto-cleanup if deployment or coding agent tasks fail.

Banking & FinTech 🏦

High-Value Wire & Billing

Enforces 3/3 Triple Redundant Consensus before executing multi-million dollar transfers, preventing hallucinated refunds or duplicated wire charges.

Medical & Healthcare 🩺

Prescription & Diagnosis Safety

Intersects LLM treatment recommendations against strict clinical boundary range rules (0.1mg - 50mg), blocking lethal medication overdose attempts pre-flight.

Observability & Tracing πŸ“Š

LangSmith, Phoenix & OTEL

Stamps Saga UUID and prompt context into OpenTelemetry spans and LLM trace providers, linking hallucinated prompts directly to rollback causes.

Risk Team Dashboard πŸ›‘οΈ

Interactive Web UI & Replay

Clean Web UI (agent-saga ui) and CLI Time-Travel Replay (agent-saga replay <id>) for risk teams to inspect, approve, or debug failed sagas.

β–© Ground truth nobody else collects

Which calls the world kept.

Every framework logs that a tool was called. This log records whether the effect had to be taken back β€” and that single extra fact is what turns a trace into training data, a risk model, and the matrix below.

Note what it refuses to do: below five observations a cell shows its raw count and goes grey. "100% orphaned" over one call is a number that means nothing and reads as though it means everything.

agent-saga outcome matrix3 tool(s), 36 outcome(s). 9 effect(s) had to be taken back. 3 tool(s), 36 outcome(s) 9 effect(s) had to be taken back agent-saga kept undone orphaned undo failed unknown fallback stripe.charge 9 (75%) 3 (25%) inventory.reserve 9 (75%) 3 (25%) crm.update 6 (50%) 3 (25%) 3 (25%) percentages shown only at n>=5; smaller cells show the raw count
agent-saga viz --kind outcomes --wal ./prod.wal

Interactive Practical Playground

Practically test your own input data: Before vs. After agent-saga.

Type custom input parameters below. Use the prominent toggle switch to compare how raw AI models crash and corrupt data (BEFORE) versus how agent-saga verifies and auto-restores state (AFTER).

● MODE: AFTER (+ agent-saga v2.2.0 Active Protection)
Toggle OFF to test Raw AI Failure Mode
PROTECTION: ON (+ agent-saga)
REAL-TIME TRANSACTION EXECUTION LOG (WAL v2.2.0) READY
Enter your custom parameters on the left and click Execute AI Simulation.
β›“ Tamper-evident by construction

Each record names the one before it.

Every WAL record carries the SHA-256 of its predecessor. Edit a record, delete one, reorder two, and the links stop matching β€” there is no way to revise history without leaving the seam visible.

The picture below is not a diagram of the idea. chain_ribbon() walks the chain while rendering it: a link whose recorded parent isn't the record that precedes it is drawn red and labelled BROKEN, the header reports the count, and when a log is cropped to fit, every break is kept. A tamper-evidence graphic that drew a doctored log as intact would not be a flawed graphic β€” it would be a forgery aid.

agent-saga hash chainchain intact across 90 record(s). every record's recorded predecessor is the ... chain intact across 90 record(s) every record's recorded predecessor is the record that precedes it agent-saga #1 cfbd36ca SAGA_START #2 670d4844 SAGA_START #3 369c6116 SAGA_START #8 348a74b3 SAGA_START #15 d219df1f STEP_INTENT #22 de8ddd41 STEP_COMMITT… #29 0998dc19 STEP_INTENT #36 52304f8f STEP_INTENT #43 2b2e20f3 STEP_COMMITT… #50 7071b506 STEP_INTENT #57 f454f628 STEP_UNKNOWN #64 4ddde422 SAGA_ABORT_C… #71 31456eb3 SAGA_COMPLETE #78 947fbe24 ROLLBACK_END #85 d53be4d0 COMPENSATED #88 3cf91a6e SAGA_ABORTED #89 dd407678 SAGA_ABORTED #90 49965249 SAGA_ABORTED 72 record(s) elided; every break is shown
Verify the same property in the terminal: agent-saga verify --wal ./agent-saga.wal

Core Capabilities

Click any capability to inspect its real code & architecture.

Every card below maps to shipping, tested code in the package β€” not a roadmap. The suite is 2,103 tests green.

🧾 Grounded Answers

A hallucination cannot pose as a sourced fact. Every claim in an answer is VERIFIED against live SHA-256 receipts β€” or wears a label: UNCITED, BROKEN_CITATION, BROKEN_QUOTE. Your policy decides what unlabeled claims may touch.

Click to inspect code β†’

βœ… Rollback-Safety Certificates

Machine-checkable proof that every committed effect was accounted for. agent-saga certify returns non-zero in CI, so a release that could strand an uncompensated charge can't ship.

Click to inspect code β†’

🌳 Selective-Disclosure Audit Proofs

Prove one saga to an auditor without revealing any other. A Merkle tree with domain-separated leaves yields a compact inclusion proof under a published root.

Click to inspect code β†’

⚑ Predictive Pre-Execution

Speculatively run REVERSIBLE-only steps ahead of confirmation behind an HMAC lease bound to (intent, tool, expiry). Stale, forged, or cross-intent speculations can never be redeemed.

Click to inspect code β†’

πŸ” Passkey / Hardware Approvals

An IRREVERSIBLE step can demand a hardware-bound Ed25519 signature over a digest of the exact action β€” so an approval can't be replayed onto a different call.

Click to inspect code β†’

πŸ•ΈοΈ Offline Mesh Sagas (CRDT)

Agents acting offline on separate devices keep local WALs that merge with a commutative, idempotent, associative G-Set CRDT β€” any sync order converges to the same history.

Click to inspect code β†’

πŸ›°οΈ Edge / Async Storage Sink

The engine is separable from disk: point the WAL at any async store (proven, not asserted) to run the same guarantees at the edge or in a WASM sandbox.

Click to inspect code β†’

☁️ Self-Hosted Control Plane (cloud-server)

Run your own control plane backend (agent-saga cloud-server) matching the sagaops.dev SaaS REST API for audit ingest, approvals, and fleet budget sync.

Click to inspect code β†’

πŸ“ BPMN 2.0 Visual Workflow Designer

Interactive web canvas tab on the dashboard to visually design agent compensation flows and export typed @saga_scope Python code in 1 click.

Click to inspect code β†’

πŸ§ͺ Standalone pytest-agent-saga Package

Dedicated Pytest companion package (pip install pytest-agent-saga) providing isolated WAL fixtures, multi-point chaos runners, and deterministic replay assertions.

Click to inspect code β†’

πŸ›‘οΈ Array & Dotted Redaction (redact_path)

Surgically mask nested fields including list indices (e.g. redact_path(records, "kwargs.items.0.cvv")) without writing custom lambda functions.

Click to inspect code β†’

πŸ”„ Multi-Turn Agent Self-Healing Loop

Bounded correction loop (SelfHealingLoop) that feeds gate refusal reasons back to the agent with exponential backoff and human escalation fallback.

Click to inspect code β†’

🧠 Zero-Config Embedding Risk Scorer

Dynamic anomaly risk scoring against known-bad tool calls (EmbeddingRiskScorer) with zero external dependencies and offline execution.

Click to inspect code β†’

πŸ’¬ Slack OAuth & Slash Command Integration

Interactive Slack Block Kit app with OAuth URL construction (build_oauth_install_url) and /saga-approve slash command handling.

Click to inspect code β†’

πŸ“Š OpenTelemetry & LangSmith Tracing

Binds Saga UUIDs to OpenTelemetry spans, LangChain callbacks, and Phoenix traces, identifying the exact prompt context that caused a rollback.

Click to inspect code β†’

πŸ’» Protected Web Dashboard (agent-saga ui)

Web UI dashboard serving visual approval queues, SSE live WAL streaming, spend limit gauges, and token authentication.

Click to inspect code β†’

Developer Documentation

Quickstart & Integration Reference.

Get started in 30 seconds. Wrap your agent loops in a single decorator or context manager.

1. Installation

pip install agent-saga

2. 30-second quickstart β€” the AgentKit SDK

from agent_saga import AgentKit kit = AgentKit(name="my-agent") charge = kit.safe_tool(stripe_charge, semantics="COMPENSABLE", compensate=lambda r: {"handler": "refund", "kwargs": {"id": r["id"]}}) async with kit.transaction(): # a saga boundary await charge(amount=4200) # gated, logged, and refunded on any failure await ship_order(...) kit.guarantees() # machine-readable: exactly what is enforced, versioned kit.status() # live posture β€” fail-closed if a safety signal can't be read

3. Prove it in CI β€” rollback-safety gate

# fails the build (non-zero exit) if any committed effect was left stranded agent-saga verify --wal ./agent-saga.wal # the log was not altered/truncated agent-saga certify --wal ./agent-saga.wal # every effect is accounted for

4. OpenTelemetry & LangSmith Tracing Setup

from agent_saga.observability import setup_telemetry, link_llm_trace # Enable OpenTelemetry tracing setup_telemetry() # Link LLM prompt trace to Saga UUID link_llm_trace(saga_id="saga_123", trace_id="tr_9988", prompt_context="Refactor payment engine")

5. GitHub & Cloud Connector Safety

from agent_saga.connectors import GitHubConnector, CloudConnector gh = GitHubConnector() pr = await gh.create_pull_request(repo="org/app", title="Auto Patch", head="fix-branch") # Auto-closes PR if downstream step fails!
βœ‰οΈ Reviews, Feedback & Founder Contact

Tell us what broke, what worked, and what's missing

Enterprise inquiry, integration requirement, bug report, or a review of how it went in production β€” all of it is wanted, especially the unflattering kind.

How this form works, stated plainly. This page is static. The form below saves your message in your own browser β€” unless you are running the local inquiry backend (python site/server.py, readable with agent-saga inquiries), it does not reach anyone, and it will tell you so instead of showing a green tick. To actually reach a human, use one of these:

πŸ“₯ Saved in this browser