usage-limit-resume (omp extension)
Auto-resumes an omp session after a Codex/ChatGPT usage-limit window resets, for the case where every logged-in account is exhausted and omp's own native round-robin has nothing left to fail over to.
Source of truth: omp usage --json. No guessing at error-message
wording, no scraping the human-readable table — this reads the exact
per-account 5h/7d window status and resetsAt epoch timestamps that
omp usage --json reports directly.
Install
# As a plain extension (Pi-compatible, always works):
mkdir -p ~/.omp/agent/extensions
cp usage-limit-resume.ts ~/.omp/agent/extensions/
# Or via OMP plugin if your install uses plugin discovery:
omp plugin link . --scope user
Then, inside a running omp session:
/reload-plugins
(or just restart omp). You should see:
[usage-limit-resume] Extension loaded (source of truth: `omp usage --json`).
How it decides "blocked"
For each logged-in openai-codex account, it looks at that account's 5h
and 7d limit entries (ignoring tier-scoped limits like base-model-inference):
- If either is
"exhausted", that account is unusable until the later of its active blockers clears. - If a blocker is
exhaustedbutresetsAtis missing, that account is still considered blocked — the wake time is unknown, so the extension rechecks inOMP_RESUME_RECHECK_MSrather than guessing. - If every account is currently unusable, the session is genuinely stuck — the earliest moment any account becomes usable again is when it schedules the resume.
- If even one account still has headroom, it does nothing — that's exactly the case omp's own native rotation already handles.
This also means a weekly (7d) exhaustion is handled correctly: if the
earliest usable time is days away rather than hours, it'll exceed
OMP_RESUME_MAX_WAIT_MS (6h by default) and the extension will back off
and tell you to check manually, rather than silently blocking for days.
It also surfaces (but never auto-applies) any banked reset credits
(resetCredits.availableCount) it sees — including per-account email and
expiresAt — those can clear a 5h limit instantly, but they're a limited
resource, so that stays a manual choice.
First run — sanity check
DEBUG=1 omp
Deliberately trigger (or wait for) a usage-limit stop. You should see:
[usage-limit-resume:debug] usage analysis: { accountCount: 2, blocked: true, earliestUsableAt: ..., resetCreditsAvailable: ... }
If blocked doesn't flip to true when you know both accounts are out,
run omp usage --json by hand and compare against what the debug log
printed — the parsing only depends on the reports[].limits[] shape, so a
mismatch would mean that shape changed on your installed version.
Status bar
When loaded in a TUI session it writes to the status bar via ui.setStatus("usage-limit-resume", …) (hook status, refreshed every 60s):
⏳ Codex resume in 3h 12m @ 11:19 PM • 2 credit(s)— blocked, shows live countdown + wall time + banked credits⏳ recheck in 15m @ 02:30— blocked butresetsAtmissing, rechecking✓ Codex ready— at least one account has headroom (clears after 10s)⚠️ weekly cap 6.3h — manual— would exceedOMP_RESUME_MAX_WAIT_MS
Requires statusLine.showHookStatus: true (default true in ~/.omp/agent/config.yml). If you customized statusLine segments and hid hook status, set showHookStatus: true or add a segment that renders hook statuses.
Config (optional env vars)
| Variable | Default | Meaning |
|---|---|---|
OMP_BIN | omp | Binary invoked for the usage check |
OMP_RESUME_MESSAGE | Continue exactly where you left off. | Text re-injected to resume the session |
OMP_RESUME_BUFFER_MS | 60000 (1 min) | Grace period added after the reported reset time |
OMP_RESUME_MAX_ATTEMPTS | 12 | Safety cap on check/resume cycles per session |
OMP_RESUME_RECHECK_MS | 900000 (15 min) | Wait before re-checking if accounts look exhausted but no resetsAt was found |
OMP_RESUME_MAX_WAIT_MS | 21600000 (6 h) | Hard cap on total wait — protects against silently blocking for a multi-day weekly reset |
OMP_RESUME_MIN_CHECK_MS | 30000 (30 s) | Minimum time between omp usage --json calls |
OMP_RESUME_USAGE_TIMEOUT_MS | 20000 | Timeout for the omp usage child process |
DEBUG | unset | Set to 1 to log raw usage JSON + parsed analysis |
What it does and doesn't do
- Only schedules a resume when every Codex account is confirmed
exhausted via
omp usage --json— never on ordinary turn completions. - Persists the pending wake time to disk under
~/.omp/usage-limit-resume/, namespaced by session + cwd hash so concurrent projects don't collide, and pruned after 24h. If the omp process itself restarts mid-wait, the timer re-arms on the next session start. - Requires the omp process to keep running for the wait to fire — leave
the terminal/session open (or run it under
tmux/screen/a process supervisor). - Hard caps (
OMP_RESUME_MAX_ATTEMPTS,OMP_RESUME_MAX_WAIT_MS) stop it from looping forever if something other than a usage limit is actually wrong (billing, a revoked credential, etc.) — those show up as"ok"never turning up inomp usage --json, so it'll back off rather than spin. - Guards against multi-day
setTimeoutfor weekly caps: ifearliestUsableAt - now > OMP_RESUME_MAX_WAIT_MS, it refuses to schedule and tells you to handle it manually.
Relationship to omp's built-in behavior
This is deliberately a thin layer on top of what omp already does natively: round-robin credential rotation with per-credential backoff already handles one account running out mid-task. This extension only covers the remaining gap — every account out at once — which omp's own retry layer treats as a hard stop rather than something to sleep through.