fix(quota): honor explicit per-connection preflight opt-out (#2831) (#2844)

Integrated into release/v3.8.6.
This commit is contained in:
Diego Rodrigues de Sa e Souza
2026-05-29 00:58:58 -03:00
committed by GitHub
parent 5f886dc73a
commit 01041967de
3 changed files with 62 additions and 0 deletions

View File

@@ -14,6 +14,7 @@
### 🔧 Bug Fixes
- **fix(quota):** honor explicit per-connection `quotaPreflightEnabled: false` even when the provider has global window defaults — adds early-return guard before the AND-of-negations gate in auth.ts ([#2831])
- **api:** include noAuth providers (opencode, etc.) in `/v1/models` active aliases so their models surface without a DB connection row (#2798)
- **opencode-go:** route Qwen3.x via Claude messages format and repair `fixMissingToolResponses` helper for Claude-shape upstreams (#2791 — thanks @jeferssonlemes)
- **validation:** register missing validation helper checks for web-cookie providers (`claude-web`, `gemini-web`, `copilot-web`, `t3-web`) (#2793 — thanks @oyi77)

View File

@@ -1494,6 +1494,15 @@ export async function getProviderCredentialsWithQuotaPreflight(
// Otherwise the resolver would return the factory default for every
// window, and a near-exhausted account would still be caught by the
// normal 429 → cooldown path.
// Explicit per-connection opt-out always wins over global/provider defaults.
// isQuotaPreflightEnabled is strict-=== true (back-compat), so it returns
// false for both "not set" and "explicit false" — we need an explicit check
// here to distinguish them.
const legacyForceDisable =
(credentials as { providerSpecificData?: Record<string, unknown> })
.providerSpecificData?.quotaPreflightEnabled === false;
if (legacyForceDisable) return credentials;
const hasConnectionOverrides = Object.keys(perConnectionWindowOverrides).length > 0;
const legacyForceEnable = isQuotaPreflightEnabled(credentials);
if (

View File

@@ -364,6 +364,58 @@ test("getProviderCredentialsWithQuotaPreflight invokes the fetcher when an overr
assert.equal(fetcherCalls, 1, "fetcher should have been invoked exactly once");
});
test("getProviderCredentialsWithQuotaPreflight: explicit quotaPreflightEnabled:false bypasses preflight even when provider has global window defaults (#2831)", async () => {
// Regression: when a provider has providerWindowDefaults set AND a connection
// carries quotaWindowThresholds, the AND-of-negations gate in auth.ts would
// proceed to preflight even if the connection explicitly opted out with
// providerSpecificData.quotaPreflightEnabled === false.
const conn = await seedConnection("github", {
name: "github-explicit-opt-out",
apiKey: "ghp-opt-out-test",
providerSpecificData: { quotaPreflightEnabled: false },
});
// Give the connection per-window overrides (simulates a user-configured
// threshold) — this is the field that previously caused the gate to keep going.
await (await import("../../src/lib/db/providers.ts")).updateProviderConnection(conn.id, {
quotaWindowThresholds: { primary: 50 },
});
// Seed provider-level window defaults so providerHasDefaults === true.
await settingsDb.updateSettings({
resilienceSettings: {
quotaPreflight: {
defaultThresholdPercent: 2,
warnThresholdPercent: 20,
providerWindowDefaults: { github: { primary: 10 } },
},
},
});
const quotaPreflight = await import("../../open-sse/services/quotaPreflight.ts");
let fetcherCalls = 0;
quotaPreflight.registerQuotaFetcher("github", async () => {
fetcherCalls++;
// Return a quota that would block if preflight actually ran.
return { used: 98, total: 100, percentUsed: 0.98 };
});
const selected = await auth.getProviderCredentialsWithQuotaPreflight("github");
assert.equal(
fetcherCalls,
0,
"fetcher must NOT run when connection explicitly opts out with quotaPreflightEnabled: false"
);
assert.equal(
(selected as any).connectionId,
conn.id,
"opted-out connection must be returned directly without being blocked by preflight"
);
// Cleanup: reset settings so subsequent tests see factory defaults.
await settingsDb.updateSettings({ resilienceSettings: {} });
});
test("getProviderCredentials keeps separate codex affinity per session", async () => {
await settingsDb.updateSettings({
fallbackStrategy: "round-robin",