Skip to main content

Self-healing runner for Python projects: catches crashes, remembers them, and patches them on the fly with a headless Claude agent.

Project description

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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

lazarus_agent-0.1.0.tar.gz (151.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

lazarus_agent-0.1.0-py3-none-any.whl (38.4 kB view details)

Uploaded Python 3

File details

Details for the file lazarus_agent-0.1.0.tar.gz.

File metadata

  • Download URL: lazarus_agent-0.1.0.tar.gz
  • Upload date:
  • Size: 151.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for lazarus_agent-0.1.0.tar.gz
Algorithm Hash digest
SHA256 a129db4052ae01841e44717b5d385de390fe72fa5face0ff6a8a2e52e0f90e3a
MD5 527b166dc40b8495cee20e83806516c2
BLAKE2b-256 bed5045267d6df92261c6268be65b48d175254b02df46c18828562cfe27df380

See more details on using hashes here.

File details

Details for the file lazarus_agent-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: lazarus_agent-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 38.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for lazarus_agent-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8442b26428aeca64146624104586bffa4b143aa877c6b48ae7d9594e97b2805c
MD5 f3ade87f336c17f2ca0746d416eb85ed
BLAKE2b-256 ab8caaa575bbbebe3f2367fc14c45e43ebcb2b31e772dabc57617fab4e46d709

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page