diff --git a/packages/shared/src/usageLimits.test.ts b/packages/shared/src/usageLimits.test.ts index 9d2bf395a9d72..6d2604e9c6dd1 100644 --- a/packages/shared/src/usageLimits.test.ts +++ b/packages/shared/src/usageLimits.test.ts @@ -180,6 +180,16 @@ describe("new thread model fallback", () => { ["opencode", "console-custom"], ], ["opencode", ["budget_all"], "opencode/model", false, undefined, []], + ["claudeAgent", ["seven_day_fable"], "claude-opus-5-5", false, undefined, undefined], + ["claudeAgent", ["seven_day_fable"], "claude-fable-5-1", true, undefined, undefined], + [ + "claudeAgent", + ["seven_day", "seven_day_fable"], + "claude-opus-5-5", + true, + undefined, + undefined, + ], ] as const)( "matches %s pools %s to %s", (driver, ids, model, usesFallback, modelIds, providerIds) => { diff --git a/packages/shared/src/usageLimits.ts b/packages/shared/src/usageLimits.ts index b7902f11d6733..ad28aa1e3c7f2 100644 --- a/packages/shared/src/usageLimits.ts +++ b/packages/shared/src/usageLimits.ts @@ -70,6 +70,14 @@ export function exhaustedUsageWindow( return exhausted.find( (window) => !window.id.startsWith("go_") || model.startsWith("opencode-go/"), ); + case "claudeAgent": { + // Model-scoped weekly buckets (`seven_day_`, e.g. Fable) only cap that model. + const slug = model.toLowerCase().replace(/[^a-z0-9]+/g, "_"); + return exhausted.find((window) => { + const scope = window.id.match(/^seven_day_(.+)$/)?.[1]; + return scope === undefined || slug.includes(scope); + }); + } default: return exhausted[0]; }