feat(loop-context): track daily token spend across runs, add --on-exceed hook#273
Open
KhaiTrang1995 wants to merge 1 commit into
Open
feat(loop-context): track daily token spend across runs, add --on-exceed hook#273KhaiTrang1995 wants to merge 1 commit into
KhaiTrang1995 wants to merge 1 commit into
Conversation
…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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 thatnothing 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'stokensUsedinto a per-pattern state file(
.loop-context/daily-spend.<pattern>.json, rolling over at UTC midnight)and escalates with a new trigger
daily-budgetonce the running totalreaches 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 filelives.
--on-exceed <script>: on any escalate, pipes theBreakerDecisionasJSON to the script's stdin -- a scriptable replacement for
loop-budget.md's manual checklist. Fire-and-forget: the script's exitcode doesn't change
--check's own.--budget-level/--budget-cadence/--budget-conservativeflags for the daily lookup rather than addingparallel ones.
loop-guardskill template andloop-context's README withthe new flags and an example wiring both the per-run and daily budgets
together.
Why this shape
context-manager.ts'scheckCircuitBreakerstays pure and dependency-free-- the daily check and state file live in a new
daily-spend.tsmodule andthe CLI layer, mirroring how
budget-resolver.tswas kept separate fromit in the previous PR.
daily-budgetis an additive member of the existingBreakerTriggerunion,so no existing consumer of
BreakerDecisionbreaks.--on-exceedis intentionally dumb (JSON on stdin, no retry/backoff) toavoid 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 (wipednode_modules/dist, reinstalled, rebuilt).tools/loop-cost(thedependency 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 onerun, 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-exceedreceives the decision JSON on escalate, and isnot invoked when the run continues). All pre-existing tests pass unmodified.
Version 1.1.0 -> 1.2.0.