Skip to main content

Lazarus

Self-healing runner for Python. Run your app under it; when the app crashes, Lazarus captures the full incident (traceback, locals, source context), stores it in a per-project SQLite memory, hands it to a headless Claude agent that reads the code — and past related incidents — patches the root cause, and then restarts (or hot-reloads) to verify the fix held.

Zero runtime dependencies (stdlib only). Needs Python ≥ 3.11 and the claude CLI for healing.

Built by AJTheDev — a North London developer. If Lazarus saves you a 2am debugging session, say hi.

Install

pip install lazarus-agent

Or from source:

git clone https://github.com/AlexJamesDean/lazarus
pip install -e lazarus

(Stdlib-only, so it installs into any venv.)

Per project

cd my-new-project
lazarus init            # writes lazarus.toml, creates .lazarus/, gitignores it
lazarus run app.py      # or: lazarus run -m mypackage.server

That's it. The loop:

  1. Run — your program runs as a child process with a crash-reporting hook, breadcrumb capture (last output lines + log records), and — for batch jobs — an optional dead-man timer (max_runtime) that catches hangs and deadlocks by dumping every thread's stack.
  2. Capture — an unhandled exception writes a structured report: frames, code lines, local variables, breadcrumbs, fingerprint. When the failing call's arguments are serializable, the crash is frozen into a permanent regression test in .lazarus/repro/ (crash-to-test).
  3. Remember — the incident lands in .lazarus/lazarus.db. Recurrences of the same fingerprint bump a counter instead of duplicating. Related past incidents are recalled by fuzzy token similarity (not just exact type/file match), and verified fixes from your other projects are pulled from the hive (~/.lazarus/hive.db).
  4. Heal — a headless claude -p agent (Read/Edit/Grep/Glob, plus WebSearch for library errors) patches the root cause with the smallest safe change. A per-attempt model ladder (models = ["haiku", "sonnet", "opus"]) starts cheap and escalates. Implicated files are backed up to .lazarus/backups/ first, and the resulting diff is stored with the attempt. With heal_clones = true the agent also greps for the same bug pattern elsewhere and patches the siblings.
  5. Gate — before a patch counts, the canary runs: your test_command plus every captured repro test. A patch that breaks the tests is marked failed immediately and the next attempt is escalated.
  6. Verify — Lazarus restarts the program. Clean exit, a long healthy run (verify_seconds), or even a different crash => the fix is verified, recorded in the hive, and written up in the patchlog (.lazarus/PATCHLOG.md) — root cause, fix summary, and diff. The same crash => the attempt is marked failed and the next heal is escalated with the failed diff ("this was tried; it didn't work"). After max_attempts failures on one error it gives up and tells you.

Transient-looking exceptions (ConnectionError, TimeoutError, ...) get one free backoff-retry before any healing — no code patches for a flaky network.

Healing without a restart

For long-running services where a restart is unacceptable, guard the hot path:

from lazarus import guard

@guard                      # or @guard(retries=2)
def handle_request(payload):
    ...

When the function raises, Lazarus heals in-process, importlib.reloads the patched module, and retries the call with the same arguments. (Functions defined in __main__ can't be reloaded — the patch still lands on disk, and lazarus run covers those via restart instead.)

Inspecting the memory

lazarus errors        # every incident: status, hit count, location
lazarus show 3        # full traceback + every fix attempt with its diff
lazarus hive          # verified fixes shared across ALL your projects

Config (lazarus.toml)

key default meaning
model sonnet model for healing (haiku for cheap, opus for hard)
models [] per-attempt escalation ladder; overrides model
max_attempts 3 fix attempts per distinct error before giving up
max_turns 25 agent turn cap per heal (cost control)
verify_seconds 30 survival time that counts as "fix verified"
restart auto never = patch once, don't relaunch
allow_web_search true let the healer search the web for library errors
allow_bash false let the healer run shell commands
heal_timeout 600 seconds before a heal is aborted
catch_threads true uncaught thread exceptions count as crashes
breadcrumbs true capture recent output + log records for the healer
test_command "" canary command a patch must pass (e.g. pytest)
test_timeout 120 seconds before the canary command is killed
repro_tests true freeze crashes into regression tests
repro_dir .lazarus/repro where generated repro tests live
transient [Connection…, Timeout…] exception types that get a free retry
transient_backoff 5 seconds to wait before the free retry
max_runtime 0 dead-man timer for batch jobs; 0 = off (servers)
hive true share verified fixes across projects
heal_clones false also patch the same bug pattern elsewhere
patchlog .lazarus/PATCHLOG.md postmortem journal of verified fixes
protected [] files the healer must never edit
healer claude or any shell command (see examples/fake_healer.py)
claude_path — explicit path if claude isn't on PATH

Safety rails

  • Per-error attempt cap — no infinite patch/crash loops.
  • Pre-heal backups of implicated files in .lazarus/backups/incidentN-attemptM/.
  • Every attempt's diff is stored; lazarus show makes the agent auditable.
  • The healer gets no Bash by default and is told never to touch .lazarus/, lazarus.toml, or anything in protected.
  • Non-Python deaths (segfault, OOM kill) are reported, never "healed".

Browser bridge (Lazarus Bridge extension)

Instead of (or alongside) the healer's own WebSearch, Lazarus can research through your browser. Load extension/ as an unpacked extension (chrome://extensions → Developer mode → Load unpacked). While lazarus run or lazarus bridge is up, the extension long-polls 127.0.0.1:8377 and:

  • researches crashes — searches the web and opens the top results in background tabs (your active tab, and your video, are never touched), extracts each page to markdown with a bundled defuddle build (fallback extractor included), saves it under .lazarus/research/incidentN/, cites it to the healer, then closes its tabs.
  • lets you clip pages — the popup's "Clip this page for Lazarus" button saves whatever you're reading into .lazarus/research/clips/, and clipped pages ride along into the next heal prompt. See a relevant GitHub issue? One click and the healer has it.
  • gives Lazarus a voice — with personality = "roast", Lazarus checks what you're watching when the crash lands, roasts you for it via chrome.tts ("Do not pause Never Gonna Give You Up on my account. One of us has a stack trace to read."), announces fixes out loud, and sends a desktop notification with the fix summary. The Claude healer is asked for a bespoke ROAST: line; canned lines cover token-free backends. deadpan keeps the spoken status updates and drops the jokes; the popup has a mute toggle.

The bridge binds localhost only. No extension connected simply means research and speech are skipped. examples/fake_browser.py speaks the same protocol for token-free testing and doubles as protocol documentation.

Troubleshooting

  • heal failed: ... 401 Invalid authentication credentials — the claude CLI's own login is stale (it authenticates separately from the desktop app). Run claude login once in a terminal.
  • Lazarus can itself be launched from inside a Claude Code session: it strips the session-scoped auth environment before spawning the healer, so the nested CLI authenticates like a normal terminal launch.

Try the demo

cd examples
lazarus run buggy.py      # crashes with KeyError, heals itself, reruns clean
lazarus errors

Metadata

Release files for lazarus-agent 0.1.0

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

Source distribution (sdist)

Source distribution for lazarus-agent 0.1.0
File Size Uploaded
lazarus_agent-0.1.0.tar.gz 151.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for lazarus-agent 0.1.0
File Interpreter ABI Platform
lazarus_agent-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 189.9 kB

Release files / lazarus_agent-0.1.0.tar.gz

Download URL lazarus_agent-0.1.0.tar.gz
Size 151.4 kB
Tags Source
SHA-256 checksum
How to use checksums
a129db4052ae01841e44717b5d385de390fe72fa5face0ff6a8a2e52e0f90e3a
BLAKE2b-256 checksum
How to use checksums
bed5045267d6df92261c6268be65b48d175254b02df46c18828562cfe27df380
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.4

Release files / lazarus_agent-0.1.0-py3-none-any.whl

Download URL lazarus_agent-0.1.0-py3-none-any.whl
Size 38.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8442b26428aeca64146624104586bffa4b143aa877c6b48ae7d9594e97b2805c
BLAKE2b-256 checksum
How to use checksums
ab8caaa575bbbebe3f2367fc14c45e43ebcb2b31e772dabc57617fab4e46d709
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.4

Release history Release notifications | RSS feed

This release

0.1.0 This release

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