Lazarus is a small coding agent built around one idea: an IPython interpreter can be both the agent's computer and its memory.
The model has two tools:
pythonruns a cell in a long-lived IPython process.start_new_loopruns a final handoff cell, discards earlier chat history, and continues with the same IPython process.
Both tools default to a 300-second timeout. The model can set timeout on any
call when a cell needs more or less time.
The model decides when to start a new loop. Lazarus also steers it toward a handoff when the current context reaches 150,000 tokens. The handoff cell is ordinary, free-form Python. It can preserve notes, functions, objects, relevant file slices, commands, and anything else the next loop needs. There is no checkpoint schema or helper API.
Lazarus requires Python 3.12+ and uv.
uv tool install git+https://github.com/ExpressGradient/lazarus
lazarusRun directly from a checkout:
uv run lazarusRun one request and exit:
lazarus --prompt "fix the failing tests"Set a different context-loop threshold, for example 250,000 tokens:
lazarus --loop-token-limit 250000Change the maximum tool output kept in context, for example to 64 KiB:
lazarus --tool-output-limit-kib 64Quit an interactive session with /quit.
Lazarus uses kosong and supports Kimi, OpenAI Responses, Codex subscription
usage, Anthropic, Google, and generic OpenAI-compatible Chat Completions APIs.
The named providers have default models; openai-legacy requires an explicit
model ID.
lazarus --provider kimi # kimi-k3
lazarus --provider codex # gpt-5.6-sol, uses `codex login`
lazarus --provider openai # gpt-5.6-sol
lazarus --provider anthropic # claude-opus-5
lazarus --provider google # gemini-3.7-flash
lazarus --provider openai-legacy --model your-modelSet the credentials expected by the chosen provider before running Lazarus.
For codex, run codex login; usage counts against that ChatGPT subscription.
For openai-legacy, set OPENAI_API_KEY. Set OPENAI_BASE_URL for a compatible
server; if omitted, it uses OpenAI's default endpoint. APIs that return thinking
in an extra message field can set OPENAI_REASONING_KEY, such as
reasoning_content.
IPython runs in a child process. Requests and results use a private JSON channel, so Python and subprocess output cannot corrupt the protocol. Standard input is detached from that channel, and names remain alive until Lazarus exits or the worker process dies. Concurrent tool requests are serialized, and each displayed call stays paired with its result.
Tool output is capped at 48 KiB by default across stdout and stderr. Truncation keeps the first third and final two thirds. Lazarus saves the complete output in a temporary file and gives the model its path for targeted reads. It keeps the latest 20 files across worker restarts and removes them when Lazarus exits.
When start_new_loop succeeds, Lazarus retains only:
- The original user task.
- The assistant's handoff tool call.
- The handoff tool result.
The system prompt and IPython process stay unchanged. The retained tool call makes the reset explicit, while restoring the original task prevents the goal from depending on the model's handoff. Lazarus adds no separate reset message.
After every model response, Lazarus prints a LAZARUS_TOKEN_USAGE JSON record
with cumulative input, cache-read, cache-creation, output, total, and successful
loop-reset counts. This makes long agent runs measurable without changing the
model conversation. Reset counts remain telemetry and are not added to the
system prompt.
Automatic steering uses the size of the latest context, not cumulative billing
usage. Cached and uncached input are counted once, along with the latest output.
At 150,000 tokens by default, Lazarus adds one user message asking the model to
compact its useful state into a handoff and call start_new_loop. Change the
threshold with --loop-token-limit. A successful reset clears that loop's
steering state while lifetime usage totals continue accumulating.
uv run python -m lazarus.cli --helpThe implementation is intentionally small:
src/lazarus/cli.py providers, tools, and agent loop
src/lazarus/python_worker.py persistent IPython worker
MIT