feat: Limit auto-claude window usage based on budget #1907
feat: Limit auto-claude window usage based on budget #1907eyalk11 wants to merge 2 commits intoAndyMik90:developfrom
Conversation
- Add `budgetCapPercent` setting: a single unified slider that caps both
session and weekly thresholds, preventing usage beyond the configured
percentage of the plan (e.g. 80% budget cap).
- Add `noExtraUsage` toggle: marks an account unavailable once either
usage limit hits 100%, preventing Anthropic extra-usage (pay-per-use
overage) from being consumed.
- Apply both settings in profile-scorer (availability checks, fallback
scoring, unified account scoring, proactive switch logic) and in
usage-monitor threshold checks.
- Add UI controls (budget cap slider + toggle) in AccountSettings below
the weekly threshold slider, visible when proactive monitoring is on.
- Add i18n keys for both new controls in en/fr settings locales.
- Move budget cap and noExtraUsage controls into a dedicated "Usage Limits"
section visible regardless of account count (no longer gated by totalAccounts > 1).
- Budget cap and noExtraUsage now work independently of the auto-switch master
toggle, so single-account users can also enforce plan limits.
- When a budget limit is hit and no alternative account is available, emit
budget-exhausted from UsageMonitor → initializeUsageMonitorForwarding calls
agentManager.killAll() to stop all running agents immediately.
- Pass agentManager into initializeUsageMonitorForwarding in index.ts (both
the primary and fallback init paths).
|
|
📝 WalkthroughWalkthroughAdds an optional unified budget cap and a noExtraUsage hard-stop to Claude auto-switching: settings now include Changes
Sequence Diagram(s)sequenceDiagram
participant UsageMonitor as Usage Monitor
participant ProfileScorer as Profile Scorer
participant ProactiveSwap as Proactive Swap
participant AgentManager as Agent Manager
participant TerminalHandlers as Terminal Handlers
participant Renderer as Renderer
UsageMonitor->>ProfileScorer: compute effective thresholds<br/>(weekly, session, budgetCapPercent, noExtraUsage)
ProfileScorer-->>UsageMonitor: threshold evaluation & reason
alt Budget exceeded & no alternatives
UsageMonitor->>ProactiveSwap: performProactiveSwap(stopIfExhausted=true)
ProactiveSwap-->>UsageMonitor: no alternative found
UsageMonitor->>TerminalHandlers: emit budget-exhausted event (main)
TerminalHandlers->>AgentManager: agentManager.killAll()
AgentManager-->>TerminalHandlers: agents killed
TerminalHandlers->>Renderer: forward budget_exhausted payload
else Alternatives available
UsageMonitor->>ProactiveSwap: performProactiveSwap(stopIfExhausted=false)
ProactiveSwap-->>UsageMonitor: switched account
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Suggested labels
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
⚔️ Resolve merge conflicts
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request enhances the Claude profile management system by introducing robust usage limit controls. It allows users to define a budget cap for both session and weekly usage and to prevent extra usage beyond their plan limits. These new settings are deeply integrated into the system's logic for determining profile availability and proactive switching, and are exposed through a new, dedicated section in the user interface. The changes ensure that agents are stopped if budget limits are hit and no alternative accounts are available, providing better cost control and preventing unexpected overages. Highlights
Changelog
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
🎉 Thanks for your first PR!
A maintainer will review it soon. Please make sure:
- Your branch is synced with
develop - CI checks pass
- You've followed our contribution guide
Welcome to the Auto Claude community!
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
| const effectiveSession = settings.budgetCapPercent !== undefined | ||
| ? Math.min(baseSession, settings.budgetCapPercent) | ||
| : baseSession; | ||
| const effectiveWeekly = settings.budgetCapPercent !== undefined | ||
| ? Math.min(baseWeekly, settings.budgetCapPercent) | ||
| : baseWeekly; |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
There was a problem hiding this comment.
Code Review
This pull request introduces a budget cap feature to limit token usage by auto-claude. It adds budgetCapPercent and noExtraUsage settings, which are correctly implemented across the profile scoring, usage monitoring, and UI components. The logic to stop agents when the budget is exhausted and no alternative accounts are available is also well-implemented. My main feedback is to refactor some duplicated code for calculating effective thresholds into a shared helper function to improve maintainability.
| // Effective thresholds: budget cap (if set) acts as a ceiling on both thresholds | ||
| const effectiveWeeklyThreshold = settings.budgetCapPercent !== undefined | ||
| ? Math.min(settings.weeklyThreshold, settings.budgetCapPercent) | ||
| : settings.weeklyThreshold; | ||
| const effectiveSessionThreshold = settings.budgetCapPercent !== undefined | ||
| ? Math.min(settings.sessionThreshold, settings.budgetCapPercent) | ||
| : settings.sessionThreshold; |
There was a problem hiding this comment.
To improve maintainability and adhere to the DRY (Don't Repeat Yourself) principle, consider extracting the logic for calculating effective thresholds into a helper function. This logic is duplicated in several places in this file (calculateFallbackScore, scoreUnifiedAccount, shouldProactivelySwitch) and also in apps/frontend/src/main/claude-profile/usage-monitor.ts in the checkThresholdsExceeded function.
A shared utility function could look like this:
function getEffectiveThresholds(settings: ClaudeAutoSwitchSettings) {
const baseSession = settings.sessionThreshold ?? 95;
const baseWeekly = settings.weeklyThreshold ?? 99;
const effectiveSessionThreshold = settings.budgetCapPercent !== undefined
? Math.min(baseSession, settings.budgetCapPercent)
: baseSession;
const effectiveWeeklyThreshold = settings.budgetCapPercent !== undefined
? Math.min(baseWeekly, settings.budgetCapPercent)
: baseWeekly;
return { effectiveSessionThreshold, effectiveWeeklyThreshold };
}There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/frontend/src/main/claude-profile/usage-monitor.ts (1)
1927-1979:⚠️ Potential issue | 🔴 CriticalBudget exhaustion can be missed because alternatives aren’t policy-filtered.
At Line 1928-Line 1959, alternatives are collected by auth/availability only. If every alternative is already over budget/no-extra limits,
unifiedAccounts.lengthis still non-zero, so thebudget-exhaustedbranch at Line 1965 may never run.Suggested fix
private async performProactiveSwap( @@ ): Promise<void> { const profileManager = getClaudeProfileManager(); + const settings = profileManager.getAutoSwitchSettings(); const excludeIds = new Set([currentProfileId, ...additionalExclusions]); @@ for (const profile of oauthProfiles) { if (!excludeIds.has(profile.id)) { + if (stopIfExhausted && profile.usage) { + const session = profile.usage.sessionUsagePercent; + const weekly = profile.usage.weeklyUsagePercent; + const budgetCap = settings.budgetCapPercent; + const overBudgetCap = budgetCap !== undefined && (session >= budgetCap || weekly >= budgetCap); + const overNoExtra = !!settings.noExtraUsage && (session >= 100 || weekly >= 100); + if (overBudgetCap || overNoExtra) { + continue; + } + } const unifiedId = `oauth-${profile.id}`;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/frontend/src/main/claude-profile/usage-monitor.ts` around lines 1927 - 1979, After collecting oauth and api alternatives into unifiedAccounts (from profileManager.getProfilesSortedByAvailability and loadProfilesFile), filter unifiedAccounts by the same budget/policy check used for the current profile so accounts that are over-budget or have "no extra limits" are excluded; e.g. call the existing budget-check helper (create or reuse a helper like isAccountWithinBudget or isProfileAllowedByPolicy) for each unifiedAccount.unifiedId or id and only keep those that pass before checking unifiedAccounts.length, then if filtered list is empty follow the stopIfExhausted -> emit('budget-exhausted', ...) or emit('proactive-swap-failed', ...) branches accordingly (also reference excludeIds and additionalExclusions when emitting).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/frontend/src/main/claude-profile/usage-monitor.ts`:
- Around line 1105-1124: The function checkThresholdsExceeded currently seeds
baseSession/baseWeekly to 95/99 which causes noExtraUsage-only mode to trigger
before 100%; change the baseline when settings.noExtraUsage is true so
thresholds default to 100 instead of 95/99. Concretely, in
checkThresholdsExceeded adjust how baseSession and baseWeekly are computed (or
override effectiveSession/effectiveWeekly) to use 100 when settings.noExtraUsage
is true, then apply the budgetCapPercent ceiling (Math.min) only afterwards if
budgetCapPercent is provided; keep the rest of the
sessionExceeded/weeklyExceeded checks unchanged and reference the existing
symbols baseSession, baseWeekly, effectiveSession, effectiveWeekly, and
settings.noExtraUsage.
---
Outside diff comments:
In `@apps/frontend/src/main/claude-profile/usage-monitor.ts`:
- Around line 1927-1979: After collecting oauth and api alternatives into
unifiedAccounts (from profileManager.getProfilesSortedByAvailability and
loadProfilesFile), filter unifiedAccounts by the same budget/policy check used
for the current profile so accounts that are over-budget or have "no extra
limits" are excluded; e.g. call the existing budget-check helper (create or
reuse a helper like isAccountWithinBudget or isProfileAllowedByPolicy) for each
unifiedAccount.unifiedId or id and only keep those that pass before checking
unifiedAccounts.length, then if filtered list is empty follow the
stopIfExhausted -> emit('budget-exhausted', ...) or
emit('proactive-swap-failed', ...) branches accordingly (also reference
excludeIds and additionalExclusions when emitting).
ℹ️ Review info
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (9)
apps/frontend/src/main/claude-profile/profile-scorer.tsapps/frontend/src/main/claude-profile/profile-storage.tsapps/frontend/src/main/claude-profile/usage-monitor.tsapps/frontend/src/main/index.tsapps/frontend/src/main/ipc-handlers/terminal-handlers.tsapps/frontend/src/renderer/components/settings/AccountSettings.tsxapps/frontend/src/shared/i18n/locales/en/settings.jsonapps/frontend/src/shared/i18n/locales/fr/settings.jsonapps/frontend/src/shared/types/agent.ts
| private checkThresholdsExceeded( | ||
| usage: ClaudeUsageSnapshot, | ||
| settings: { sessionThreshold?: number; weeklyThreshold?: number } | ||
| settings: { sessionThreshold?: number; weeklyThreshold?: number; budgetCapPercent?: number; noExtraUsage?: boolean } | ||
| ): { sessionExceeded: boolean; weeklyExceeded: boolean; anyExceeded: boolean } { | ||
| const sessionExceeded = usage.sessionPercent >= (settings.sessionThreshold ?? 95); | ||
| const weeklyExceeded = usage.weeklyPercent >= (settings.weeklyThreshold ?? 99); | ||
| const baseSession = settings.sessionThreshold ?? 95; | ||
| const baseWeekly = settings.weeklyThreshold ?? 99; | ||
|
|
||
| // Budget cap acts as a ceiling on both thresholds | ||
| const effectiveSession = settings.budgetCapPercent !== undefined | ||
| ? Math.min(baseSession, settings.budgetCapPercent) | ||
| : baseSession; | ||
| const effectiveWeekly = settings.budgetCapPercent !== undefined | ||
| ? Math.min(baseWeekly, settings.budgetCapPercent) | ||
| : baseWeekly; | ||
|
|
||
| // noExtraUsage: also flag when hitting 100% | ||
| const sessionExceeded = usage.sessionPercent >= effectiveSession || | ||
| (!!settings.noExtraUsage && usage.sessionPercent >= 100); | ||
| const weeklyExceeded = usage.weeklyPercent >= effectiveWeekly || | ||
| (!!settings.noExtraUsage && usage.weeklyPercent >= 100); |
There was a problem hiding this comment.
Budget-only mode is still enforcing proactive thresholds.
Line 1109 and Line 1110 always seed 95/99 (or configured) thresholds, so noExtraUsage-only mode can trigger exhaustion flow before 100%. That contradicts the “stop at 100%” behavior.
Suggested fix
- private checkThresholdsExceeded(
+ private checkThresholdsExceeded(
usage: ClaudeUsageSnapshot,
- settings: { sessionThreshold?: number; weeklyThreshold?: number; budgetCapPercent?: number; noExtraUsage?: boolean }
+ settings: { sessionThreshold?: number; weeklyThreshold?: number; budgetCapPercent?: number; noExtraUsage?: boolean },
+ useProactiveThresholds: boolean
): { sessionExceeded: boolean; weeklyExceeded: boolean; anyExceeded: boolean } {
- const baseSession = settings.sessionThreshold ?? 95;
- const baseWeekly = settings.weeklyThreshold ?? 99;
+ const baseSession = useProactiveThresholds ? (settings.sessionThreshold ?? 95) : 100;
+ const baseWeekly = useProactiveThresholds ? (settings.weeklyThreshold ?? 99) : 100;- const thresholds = this.checkThresholdsExceeded(usage, settings);
+ const thresholds = this.checkThresholdsExceeded(usage, settings, isProactiveEnabled);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/frontend/src/main/claude-profile/usage-monitor.ts` around lines 1105 -
1124, The function checkThresholdsExceeded currently seeds
baseSession/baseWeekly to 95/99 which causes noExtraUsage-only mode to trigger
before 100%; change the baseline when settings.noExtraUsage is true so
thresholds default to 100 instead of 95/99. Concretely, in
checkThresholdsExceeded adjust how baseSession and baseWeekly are computed (or
override effectiveSession/effectiveWeekly) to use 100 when settings.noExtraUsage
is true, then apply the budgetCapPercent ceiling (Math.min) only afterwards if
budgetCapPercent is provided; keep the rest of the
sessionExceeded/weeklyExceeded checks unchanged and reference the existing
symbols baseSession, baseWeekly, effectiveSession, effectiveWeekly, and
settings.noExtraUsage.
Previously the budget check only ran on the periodic usage monitor poll, meaning an agent could wake up and start doing work before the next poll cycle detected the overage. Now startSpecCreation checks cached usage against the budget policy before spawning — if the limit is already exceeded it emits an error immediately and refuses to start. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
| try { | ||
| const activeProfile = profileManager.getActiveProfile(); | ||
| const budgetCheck = UsageMonitor.getInstance().isBudgetExceeded(activeProfile.id); | ||
| if (budgetCheck.exceeded) { | ||
| console.warn(`[AgentManager] Refusing to start task "${taskId}": budget limit already exceeded — ${budgetCheck.reason}`); | ||
| this.emit('error', taskId, `Budget limit reached: ${budgetCheck.reason}. Adjust the budget cap in Settings > Accounts to continue.`); | ||
| return; | ||
| } | ||
| } catch { | ||
| // getActiveProfile can throw if no profiles exist; auth check above already handles that case. | ||
| } |
There was a problem hiding this comment.
Bug: The startTaskExecution function lacks a pre-flight budget check, allowing tasks to start even when the user's budget is exceeded.
Severity: MEDIUM
Suggested Fix
Add a pre-flight budget check to the startTaskExecution function, similar to the one implemented in startSpecCreation. This will prevent tasks from starting if the user's budget is already exceeded, ensuring consistent budget enforcement and avoiding unnecessary resource consumption.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location: apps/frontend/src/main/agent/agent-manager.ts#L249-L261
Potential issue: The `startTaskExecution` function does not perform a pre-flight budget
check before initiating a task. This allows a user to run an existing task even if their
budget is already depleted. While the `startSpecCreation` function includes this check,
its absence in `startTaskExecution` means an agent can be spawned and begin consuming
resources, only to be terminated by the periodic budget monitor shortly after. This
bypasses the intended budget enforcement for pre-existing tasks.
Did we get this right? 👍 / 👎 to inform future reviews.
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
apps/frontend/src/main/claude-profile/usage-monitor.ts (1)
930-979:⚠️ Potential issue | 🟠 MajorSeparate proactive thresholds from hard budget exhaustion.
budgetCapPercent !== undefinedtreats100%as an active cap even though the UI says it disables the cap, andcheckThresholdsExceeded()always starts from 95/99. That means budget-only or no-extra-usage-only mode can block startup or emitbudget-exhaustedbefore 100%, especially becausestopIfExhaustedis passed ashasBudgetPolicyinstead of “hard budget limit actually exceeded.” The label also reportsnoExtraUsage (100%)when a lower budget cap caused the hit.Suggested direction
- const hasBudgetPolicy = settings.budgetCapPercent !== undefined || settings.noExtraUsage; + const hasBudgetCap = settings.budgetCapPercent !== undefined && settings.budgetCapPercent < 100; + const hasBudgetPolicy = hasBudgetCap || !!settings.noExtraUsage; const isProactiveEnabled = settings.enabled && settings.proactiveSwapEnabled;- const thresholds = this.checkThresholdsExceeded(usage, settings); + const budgetThresholds = this.checkThresholdsExceeded(usage, settings, false); + const proactiveThresholds = isProactiveEnabled + ? this.checkThresholdsExceeded(usage, settings, true) + : { sessionExceeded: false, weeklyExceeded: false, anyExceeded: false }; + const thresholds = budgetThresholds.anyExceeded ? budgetThresholds : proactiveThresholds;- hasBudgetPolicy + budgetThresholds.anyExceededprivate checkThresholdsExceeded( usage: ClaudeUsageSnapshot, - settings: { sessionThreshold?: number; weeklyThreshold?: number; budgetCapPercent?: number; noExtraUsage?: boolean } + settings: { sessionThreshold?: number; weeklyThreshold?: number; budgetCapPercent?: number; noExtraUsage?: boolean }, + useProactiveThresholds: boolean ): { sessionExceeded: boolean; weeklyExceeded: boolean; anyExceeded: boolean } { - const baseSession = settings.sessionThreshold ?? 95; - const baseWeekly = settings.weeklyThreshold ?? 99; + const hasBudgetCap = settings.budgetCapPercent !== undefined && settings.budgetCapPercent < 100; + const baseSession = useProactiveThresholds ? (settings.sessionThreshold ?? 95) : 100; + const baseWeekly = useProactiveThresholds ? (settings.weeklyThreshold ?? 99) : 100; // Budget cap acts as a ceiling on both thresholds - const effectiveSession = settings.budgetCapPercent !== undefined + const effectiveSession = hasBudgetCap ? Math.min(baseSession, settings.budgetCapPercent) : baseSession; - const effectiveWeekly = settings.budgetCapPercent !== undefined + const effectiveWeekly = hasBudgetCap ? Math.min(baseWeekly, settings.budgetCapPercent) : baseWeekly;- const hasBudgetPolicy = settings.budgetCapPercent !== undefined || settings.noExtraUsage; + const hasBudgetPolicy = (settings.budgetCapPercent !== undefined && settings.budgetCapPercent < 100) || !!settings.noExtraUsage;const thresholds = this.checkThresholdsExceeded( { sessionPercent, weeklyPercent } as ClaudeUsageSnapshot, - settings + settings, + false );Also applies to: 1105-1124, 1147-1175
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/frontend/src/main/claude-profile/usage-monitor.ts` around lines 930 - 979, The code treats any budget setting presence as a hard budget policy and passes hasBudgetPolicy into performProactiveSwap, and also shows misleading labels; update logic around hasBudgetPolicy/HardBudgetExceeded so budgetCapPercent === 100 is treated as "no cap", compute a boolean (e.g., hardBudgetExceeded) that is true only when the exceeded threshold is actually due to a hard cap (settings.noExtraUsage OR (settings.budgetCapPercent !== undefined && settings.budgetCapPercent < 100 && limitPercent >= settings.budgetCapPercent)), use that boolean for stopIfExhausted in performProactiveSwap, and build capLabel from the actual cap that caused the exceed (use 'noExtraUsage (100%)' only when noExtraUsage triggered it, or `budgetCap (${settings.budgetCapPercent}%)` only when budgetCapPercent < 100 triggered it); references: checkThresholdsExceeded, settings.budgetCapPercent, settings.noExtraUsage, hasBudgetPolicy, thresholds.anyExceeded, limitPercent, capLabel, and performProactiveSwap.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/frontend/src/main/agent/agent-manager.ts`:
- Around line 249-261: The budget pre-flight gate (emitBudgetExceededIfNeeded /
UsageMonitor.getInstance().isBudgetExceeded via profileManager) is only applied
when creating specs but not when starting existing tasks, allowing
startTaskExecution to call spawnProcess(...) and bypass budget checks; add a
call to the existing helper (emitBudgetExceededIfNeeded) immediately after the
auth/profile check inside startTaskExecution and return early if it signals
budget exceeded so startTaskExecution cannot proceed to spawnProcess when budget
is exceeded.
---
Duplicate comments:
In `@apps/frontend/src/main/claude-profile/usage-monitor.ts`:
- Around line 930-979: The code treats any budget setting presence as a hard
budget policy and passes hasBudgetPolicy into performProactiveSwap, and also
shows misleading labels; update logic around hasBudgetPolicy/HardBudgetExceeded
so budgetCapPercent === 100 is treated as "no cap", compute a boolean (e.g.,
hardBudgetExceeded) that is true only when the exceeded threshold is actually
due to a hard cap (settings.noExtraUsage OR (settings.budgetCapPercent !==
undefined && settings.budgetCapPercent < 100 && limitPercent >=
settings.budgetCapPercent)), use that boolean for stopIfExhausted in
performProactiveSwap, and build capLabel from the actual cap that caused the
exceed (use 'noExtraUsage (100%)' only when noExtraUsage triggered it, or
`budgetCap (${settings.budgetCapPercent}%)` only when budgetCapPercent < 100
triggered it); references: checkThresholdsExceeded, settings.budgetCapPercent,
settings.noExtraUsage, hasBudgetPolicy, thresholds.anyExceeded, limitPercent,
capLabel, and performProactiveSwap.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: edb410ff-9afd-4d5e-a05d-31e99c94999e
📒 Files selected for processing (2)
apps/frontend/src/main/agent/agent-manager.tsapps/frontend/src/main/claude-profile/usage-monitor.ts
| // Pre-flight budget check: Refuse to start if cached usage already exceeds configured budget cap. | ||
| // This prevents agents from waking up and doing work that the periodic monitor would immediately kill. | ||
| try { | ||
| const activeProfile = profileManager.getActiveProfile(); | ||
| const budgetCheck = UsageMonitor.getInstance().isBudgetExceeded(activeProfile.id); | ||
| if (budgetCheck.exceeded) { | ||
| console.warn(`[AgentManager] Refusing to start task "${taskId}": budget limit already exceeded — ${budgetCheck.reason}`); | ||
| this.emit('error', taskId, `Budget limit reached: ${budgetCheck.reason}. Adjust the budget cap in Settings > Accounts to continue.`); | ||
| return; | ||
| } | ||
| } catch { | ||
| // getActiveProfile can throw if no profiles exist; auth check above already handles that case. | ||
| } |
There was a problem hiding this comment.
Apply the budget pre-flight gate to startTaskExecution too.
This check only protects spec creation. Starting an existing task through startTaskExecution still reaches spawnProcess(...) without consulting cached budget usage, so budget/no-extra-usage can be bypassed until the next monitor poll.
Suggested refactor to reuse the gate in both start paths
+ private emitBudgetExceededIfNeeded(taskId: string, profileManager: ClaudeProfileManager): boolean {
+ try {
+ const activeProfile = profileManager.getActiveProfile();
+ const budgetCheck = UsageMonitor.getInstance().isBudgetExceeded(activeProfile.id);
+ if (!budgetCheck.exceeded) {
+ return false;
+ }
+
+ console.warn(`[AgentManager] Refusing to start task "${taskId}": budget limit already exceeded — ${budgetCheck.reason}`);
+ this.emit('error', taskId, `Budget limit reached: ${budgetCheck.reason}. Adjust the budget cap in Settings > Accounts to continue.`);
+ return true;
+ } catch {
+ return false;
+ }
+ }
+
async startSpecCreation(- try {
- const activeProfile = profileManager.getActiveProfile();
- const budgetCheck = UsageMonitor.getInstance().isBudgetExceeded(activeProfile.id);
- if (budgetCheck.exceeded) {
- console.warn(`[AgentManager] Refusing to start task "${taskId}": budget limit already exceeded — ${budgetCheck.reason}`);
- this.emit('error', taskId, `Budget limit reached: ${budgetCheck.reason}. Adjust the budget cap in Settings > Accounts to continue.`);
- return;
- }
- } catch {
- // getActiveProfile can throw if no profiles exist; auth check above already handles that case.
- }
+ if (this.emitBudgetExceededIfNeeded(taskId, profileManager)) {
+ return;
+ }Also call the helper after the auth check in startTaskExecution:
if (this.emitBudgetExceededIfNeeded(taskId, profileManager)) {
return;
}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/frontend/src/main/agent/agent-manager.ts` around lines 249 - 261, The
budget pre-flight gate (emitBudgetExceededIfNeeded /
UsageMonitor.getInstance().isBudgetExceeded via profileManager) is only applied
when creating specs but not when starting existing tasks, allowing
startTaskExecution to call spawnProcess(...) and bypass budget checks; add a
call to the existing helper (emitBudgetExceededIfNeeded) immediately after the
auth/profile check inside startTaskExecution and return early if it signals
budget exceeded so startTaskExecution cannot proceed to spawnProcess when budget
is exceeded.
|
If you plan to work on it, some new commits on docker branch related to auto resume budget-waiting tasks. which is also a needed feature.. |
budgetCapPercentsetting: a single unified slider that caps both session and weekly thresholds, preventing usage beyond the configured percentage of the plan (e.g. 80% budget cap).noExtraUsagetoggle: marks an account unavailable once either usage limit hits 100%, preventing Anthropic extra-usage (pay-per-use overage) from being consumed.Base Branch
developbranch (required for all feature/fix PRs)main(hotfix only - maintainers)Description
It makes auto-claude stop when reaches X% of allowed tokens in the 5-hours window . Also, make auto-claude not consume extra-usage even if available.
Looks like that :
Related Issue
Closes #
Type of Change
Area
Commit Message Format
Follow conventional commits:
<type>: <subject>Types: feat, fix, docs, style, refactor, test, chore
Example:
feat: add user authentication systemAI Disclosure
Tool(s) used:
Testing level:
Untested -- AI output not yet verified
[ X ] Lightly tested -- ran the app / spot-checked key paths . I checked that it works.
Fully tested -- all tests pass, manually verified behavior
[ X] I understand what this PR does ** but not how the underlying code works**
Checklist
developbranchPlatform Testing Checklist
CRITICAL: This project supports Windows, macOS, and Linux. Platform-specific bugs are a common source of breakage.
platform/module instead of directprocess.platformchecksfindExecutable()or platform abstractions)If you only have access to one OS: CI now tests on all platforms. Ensure all checks pass before submitting.
CI/Testing Requirements
Screenshots
Feature Toggle
use_feature_nameNew Features
Documentation
Summary by CodeRabbit
Release Notes
New Features
Localization