Tools
Auto Resume
Resume long OpenClaw agent tasks after a provider rate limit — same session, same model, from a checkpoint, never replaying side effects or crossing an approval gate.
Install
openclaw plugins install .
README
# OpenClaw Auto-Resume
[](https://github.com/MetehanQF/openclaw-auto-resume/actions/workflows/ci.yml)
[](LICENSE)
Resume long [OpenClaw](https://github.com/openclaw/openclaw) agent tasks after a
provider rate limit — in the same session, with the same model, without
replaying work that already happened.
A long task (a multi-step refactor, a release, a migration) that hits
"usage limit", "429" or "model is at capacity" normally just stops, and someone
has to notice, wait for the reset and type "continue". Auto-Resume records the
task's progress as it goes, notices the limit, waits until the provider says the
limit resets, and sends one continuation turn that starts from the recorded
checkpoint. Everything else — a cancellation, a changed session, an unknown
error, an approval gate — stops and waits for a human.
> Built and run against **OpenClaw 2026.9.8**. The observer uses public plugin
> hooks; the ingress check and failure-text lookup read the agent's SQLite
> database **read-only**, whose schema is internal and may change between
> releases. Run the tests and the verification below after every upgrade.
## How it works
```
owner turn ─► observer plugin ──admit──► registry (SQLite) ◄──checkpoint── the agent itself
(before_prompt_build, │
agent_end) │ every 5 min, no model
▼
watchdog ──► openclaw agent --session-key … (continuation)
│
└──► alerts script ──► chat.inject (UI note)
```
| Part | Role |
|---|---|
| `resume.py` | Task registry (SQLite, `0600`, in a `0700` directory), CLI and the watchdog. Standard library only. |
| `plugin/` | `auto-resume-observer` Gateway plugin. Admits owner turns, records how each run ended. |
| `examples/alerts.js` | Model-free script automation that surfaces terminal stops in a Control UI chat. |
**Admission.** On `before_prompt_build` the observer pre-filters a turn (user
trigger, not an automation job, provenance absent or `external_user`, a direct
`agent:<id>:dashboard:` session) and adds a short context note telling the agent
its task id and the checkpoint command. It never blocks the turn: in the
background, `resume.py admit` waits (up to 45 s) for that exact user message to be
persisted and admits it only if the Gateway marked it as sent by the owner, from
the owner's profile, over WebChat, in a direct and non-spawned session. Watchdog
continuations, automation turns and inter-session messages carry none of that
metadata and are refused, so the mechanism cannot enrol its own output.
**Checkpoints.** The agent records verified steps:
```bash
python3 resume.py checkpoint TASK --completed '["…"]' --pending '["…"]' --note '…'
```
A checkpoint on a stopped task fails loudly instead of being silently recorded.
**Settling.** On `agent_end` the observer reports the run's outcome. A short turn
that ended cleanly leaves nothing behind; a checkpointed one is marked
`COMPLETED`; a model limit pauses the task. Only a sanitized hint (a
`Retry-After` value or an ISO reset time) is passed on — never the error text,
the prompt or credentials.
**Watchdog.** A model-free command automation runs `resume.py watchdog` every five
minutes. For each task it re-reads the live session and stops the task if the
session id, key or model changed, if the run was aborted or the session archived,
or if a later turn finished (the human continued by hand). The last failure is
classified from the stored run error:
| Class | Outcome |
|---|---|
| Rate limit, quota, usage window, capacity | Paused until the reset, then one continuation |
| Authentication (expired OAuth, 401, logged out) | `FAILED/AUTH_FAILED`, never retried |
| Owner verification | `FAILED/OWNER_VERIFICATION`, never retried |
| Anything else | `FAILED/UNCLASSIFIED`, waits for a human |
Reset times are parsed from what providers actually print
(`resets 8am (Europe/Istanbul)`, `Oct 19 at 8:39 AM GMT+3`, `reset in 4 hours`,
`Retry-After`, ISO timestamps) plus a two-minute margin; without one, the delay
backs off from 30 minutes up to a day.
**Continuations** are started detached (`openclaw agent --session-key … --model …`)
with their own 12 h turn budget, logged to `~/.openclaw/state/auto-resume/runs/`.
The prompt tells the agent to inspect real files and its checkpoint first, not to
repeat completed side effects, and to keep every approval gate.
## Safety rules
- **At most three automatic continuations per task**, whatever caused them. The
attempt is charged in the same transaction that takes the retry lease, before
anything is launched, so a crash or a second watchdog can never get a free
retry. After three, the next limit stops the task as `RATE_LIMIT_STOPPED`.
- **An uncertain attempt is terminal.** If a retry lease expires without an
outcome the task stops as `INTERRUPTED_UNKNOWN` rather than replaying a side
effect that may already have happened.
- **Approval gates are never crossed.** `BLOCKED_APPROVAL` is never resumed. A
later owner turn closes it *without* approving it; nothing of the blocked work
is carried into the new task.
- **One active task per session and per project.** `bind-project` reserves a
canonical working tree; a second session can take it only after an explicit
`release-project`.
- **A running session is never duplicated**, and the model is never changed to
get around a limit.
- The objective stored for a task should be a short, secret-free summary, not the
raw prompt.
## Install
Requirements: OpenClaw ≥ 2026.9.8, Python ≥ 3.10, Node (for the plugin, provided
by OpenClaw), `zstd` on `PATH` (compressed transcript events).
```bash
git clone https://github.com/MetehanQF/openclaw-auto-resume.git
cd openclaw-auto-resume
# 1. Observer plugin. Non-bundled agent_end / before_prompt_build hooks need
# explicit conversation access.
openclaw plugins install . --link
openclaw config set plugins.entries.auto-resume-observer.hooks.allowConversationAccess true
# 2. Watchdog: a command automation, no model involved.
openclaw automations create --every 5m --name "Auto-Resume watchdog" \
--command-argv "[\"python3\",\"$PWD/resume.py\",\"watchdog\"]" \
--timeout-seconds 1800 --no-deliver
# 3. Optional: terminal-stop alerts in a Control UI chat (edit the constants first).
openclaw automations create --every 5m --name "Auto-Resume alerts" \
--script examples/alerts.js --no-deliver
```
Check that the Gateway loaded the plugin (`openclaw plugins list`) and whether it
reports that a restart is required before relying on it.
Disable in reverse: disable both automations, then
`openclaw plugins disable auto-resume-observer`. Task records are kept.
## Operator commands
```bash
python3 resume.py list # all tasks, newest first
python3 resume.py alerts # terminal stops that need review
python3 resume.py register --task-id T --agent-id main --session-key agent:main:… \
--session-id SID --model provider/model --cwd /abs/project --objective 'Secret-free summary'
python3 resume.py bind-project T --cwd /abs/worktree
python3 resume.py release-project T
python3 resume.py complete T | block T | stop T
python3 resume.py recover T --session-id LIVE_SID # after reviewing a recoverable stop
```
`register` is for sessions that are not auto-admitted (other channels, an
already-running task). It and `recover` check the live Gateway first and refuse a
mismatched session id or model. **The session id is not the UUID inside the
session key** — read both from `openclaw sessions --all-agents --json`.
`recover` accepts `SESSION_CHANGED`, `SESSION_ACTIVITY`, `UNCLASSIFIED`,
`RATE_LIMIT_EXHAUSTED`, `RATE_LIMIT_STOPPED`, `CONTINUATION_STOPPED`,
`AUTH_FAILED` (after logging in again) and `INTERRUPTED_UNKNOWN`, and starts a
new continuation budget. A manual `stop` is permanent.
A new approved request in a session whose task is `BLOCKED_APPROVAL` is new work:
`complete` the blocked task, then `register` the new one.
## Limits
- Only owner turns in direct Control UI (`dashboard`) sessions are enrolled
automatically. Nothing is enrolled retroactively.
- Agent CLIs run directly in a terminal (`codex`, `claude`) do not pass through the
Gateway and are neither admitted nor resumable.
- A tool call that stays silent longer than the agent harness's no-output timeout
is killed by the harness, not by this tool; keep single commands short.
- No generic mechanism can guarantee exactly-once external side effects. The
checkpoint and the approval gate are what make a continuation safe.
## Development
```bash
python3 -m unittest discover -p 'test_*.py' -v # 67 tests
node --test plugin/test.mjs # 7 tests
```
Tests use temporary registries and stubbed Gateway calls; none needs OpenClaw.
## License
[MIT](LICENSE). Not affiliated with the OpenClaw project.
tools
Comments
Sign in to leave a comment