Skip to content

feat(loop-context): track daily token spend across runs, add --on-exceed hook#273

Open
KhaiTrang1995 wants to merge 1 commit into
cobusgreyling:mainfrom
KhaiTrang1995:feat/loop-context-daily-budget
Open

feat(loop-context): track daily token spend across runs, add --on-exceed hook#273
KhaiTrang1995 wants to merge 1 commit into
cobusgreyling:mainfrom
KhaiTrang1995:feat/loop-context-daily-budget

Conversation

@KhaiTrang1995

Copy link
Copy Markdown
Contributor

Summary

--budget-from-pattern (previous PR) only guards a single run's ledger.
loop-budget.md's daily table ("Max tokens/day") is a cross-run cap that
nothing enforced, and its "On budget exceed" section is still a manual
3-step checklist (pause schedulers, log the event, open an issue).

What

  • --daily-budget-from-pattern <id>: accumulates the newest ledger attempt's
    tokensUsed into a per-pattern state file
    (.loop-context/daily-spend.<pattern>.json, rolling over at UTC midnight)
    and escalates with a new trigger daily-budget once the running total
    reaches loop-cost's suggestedDailyCap -- but only if no per-run trigger
    (stagnation, no-progress, token-budget, max-iterations) already fired;
    those always take priority.
  • --daily-state-dir <dir> (default .loop-context): where that state file
    lives.
  • --on-exceed <script>: on any escalate, pipes the BreakerDecision as
    JSON to the script's stdin -- a scriptable replacement for
    loop-budget.md's manual checklist. Fire-and-forget: the script's exit
    code doesn't change --check's own.
  • Reused the existing --budget-level/--budget-cadence/
    --budget-conservative flags for the daily lookup rather than adding
    parallel ones.
  • Updated the loop-guard skill template and loop-context's README with
    the new flags and an example wiring both the per-run and daily budgets
    together.

Why this shape

  • context-manager.ts's checkCircuitBreaker stays pure and dependency-free
    -- the daily check and state file live in a new daily-spend.ts module and
    the CLI layer, mirroring how budget-resolver.ts was kept separate from
    it in the previous PR.
  • daily-budget is an additive member of the existing BreakerTrigger union,
    so no existing consumer of BreakerDecision breaks.
  • --on-exceed is intentionally dumb (JSON on stdin, no retry/backoff) to
    avoid growing into a job-runner -- operators write the actual pause/log/
    notify logic.

Tested

tools/loop-context: 43/43 passing after a fully clean rebuild (wiped
node_modules/dist, reinstalled, rebuilt). tools/loop-cost (the
dependency this shells out to): 12/12 passing after the same clean rebuild.
12 new tests: daily-spend state module (fresh start, accumulation,
per-pattern isolation, stale-date rollover, persistence),
resolveDailyBudgetFromPattern (returns the daily cap, at least covers one
run, surfaces loop-cost's unknown-pattern error), and CLI integration
(escalates once the daily cap is reached, does not override an existing
per-run trigger, --on-exceed receives the decision JSON on escalate, and is
not invoked when the run continues). All pre-existing tests pass unmodified.
Version 1.1.0 -> 1.2.0.

…eed hook

Wire loop-cost's suggestedDailyCap into loop-context so the cross-run daily
cap in loop-budget.md is enforced, not just eyeballed, and give operators a
scriptable hook instead of a manual 3-step checklist on escalate.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant