From 1e726435953d5cfff88466b7fa58cb95befe5243 Mon Sep 17 00:00:00 2001 From: Diego Rodrigues de Sa e Souza <8016841+diegosouzapw@users.noreply.github.com> Date: Sat, 20 Jun 2026 21:54:16 -0300 Subject: [PATCH] fix(providers): generic web-cookie validator must not shadow per-provider validators (#4467) #4023 added validateWebCookieProvider (generic /models session ping -> AUTH_007 SESSION_EXPIRED on 401/403) and dispatched ALL web-cookie providers to it at the TOP of validateProviderApiKey, BEFORE the SPECIALTY_VALIDATORS table. That shadowed the rich per-provider validators (validateGrokWebProvider with #3474 IP-reputation/ Cloudflare guidance, validateChatGptWebProvider cf-mitigated, claude/gemini/copilot/ qwen/t3-web), which became dead code and broke all 41 web-cookie assertions in provider-validation-specialty.test.ts (latent on release/v3.8.32; surfaced by a __RUN_ALL__ unit run). Move the generic dispatch to AFTER SPECIALTY_VALIDATORS so it is a FALLBACK only for web-cookie providers without a dedicated validator. Rich validators run first (provider-validation-specialty 112/112 restored); the generic + its AUTH_007 capability are preserved (web-cookie-auth007 stays 5/5, it calls the function directly). Rebaselines validation.ts file-size 4518->4522 (+4, justified). Note: the sibling pricing half of this restore-green already landed via #4447; this PR carries only the stranded web-cookie validator fix. --- config/quality/file-size-baseline.json | 5 +++-- src/lib/providers/validation.ts | 22 +++++++++++++--------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/config/quality/file-size-baseline.json b/config/quality/file-size-baseline.json index 25353a857e..30ecc119f3 100644 --- a/config/quality/file-size-baseline.json +++ b/config/quality/file-size-baseline.json @@ -176,7 +176,7 @@ "src/lib/evals/evalRunner.ts": 961, "src/lib/memory/retrieval.ts": 1171, "src/lib/modelsDevSync.ts": 934, - "src/lib/providers/validation.ts": 4518, + "src/lib/providers/validation.ts": 4522, "src/lib/tailscaleTunnel.ts": 1202, "src/lib/usage/callLogs.ts": 975, "src/lib/usage/providerLimits.ts": 949, @@ -273,5 +273,6 @@ "_rebaseline_2026_06_17_4116_combo_hedge_listener": "combo.ts: +9 lines from #4116 (detach per-target listener from shared hedge abort signal to fix a listener leak). Behavior-preserving cleanup; 5289 -> 5298.", "_rebaseline_2026_06_20_4355_gpt5x_pro_pricing": "PR #4355 own growth: pricing.ts 1581->1592 (+11 = pure-data pricing rows for openai gpt-5.5-pro + gpt-5.4-pro, closing the $0 gap that tripped the catalog pricing gate after the #4324 sweep added them to the registry; -pro mirrors its base family tier). provider-models-route.test.ts 1616->1618 (+2 = test-only alignment to the intentional opencode-go discovery behavior: owned_by stamp + T39 two-endpoint fail-path fetchCalls). Both are data/test-only; not extractable.", "_rebaseline_2026_06_19_4293_codex_spark_scope": "PR #4293 (isolate Codex Spark quota scope) own growth, MEASURED on the actual merged tree (release/v3.8.30 + #4293). Production: auth.ts 2219->2279 (+60) threads requestedModel into Codex quota-policy/headroom/preflight/P2C scoring so normal Codex and GPT-5.3-Codex-Spark windows are evaluated independently; chatCore.ts 5116->5125 (+9) passes the failing model scope into Codex 429 failover (markCodexScopeRateLimited) instead of a connection-wide rateLimitedUntil write; accountFallback.ts 1727->1731 (+4) scopes Codex model-lock keys to codex vs spark. Heavy parsing/display logic lives in new leaf helpers under the cap (codexQuotaScopes.ts, codexUsageQuotas.ts, codexFailover.ts). Tests: account-fallback-service 1544->1569, executor-codex 1336->1339, sse-auth 1527->1553, usage-service-hardening 1612->1633 (added Spark-scope regression coverage). Cohesive wiring at existing selection/failover lockout boundaries; not extractable.", - "_rebaseline_2026_06_20_4447_openai_gpt41mini_o_mini_pricing": "PR #4447 own growth: pricing.ts 1592->1620 (+28 = pure-data pricing rows closing the null/$0 gap for registry-exposed OpenAI ids gpt-4.1-mini, gpt-4.1-nano, o3-mini, o4-mini that tripped the catalog pricing gate; getPricingForModel does an exact lookup, so a missing key resolves to null. Official OpenAI per-1M prices + the table's derived-field convention (reasoning=output*1.5, cache_creation=input, cached=official). Restore-green for a pre-existing release/v3.8.32 red surfaced by #4432's __RUN_ALL__ run. Cohesive data; not extractable." + "_rebaseline_2026_06_20_4447_openai_gpt41mini_o_mini_pricing": "PR #4447 own growth: pricing.ts 1592->1620 (+28 = pure-data pricing rows closing the null/$0 gap for registry-exposed OpenAI ids gpt-4.1-mini, gpt-4.1-nano, o3-mini, o4-mini that tripped the catalog pricing gate; getPricingForModel does an exact lookup, so a missing key resolves to null. Official OpenAI per-1M prices + the table's derived-field convention (reasoning=output*1.5, cache_creation=input, cached=official). Restore-green for a pre-existing release/v3.8.32 red surfaced by #4432's __RUN_ALL__ run. Cohesive data; not extractable.", + "_rebaseline_2026_06_20_web_cookie_validator_shadow_fix": "validation.ts 4518->4522 (+4 = move the generic web-cookie validateWebCookieProvider dispatch from the TOP of validateProviderApiKey to a FALLBACK after SPECIALTY_VALIDATORS, plus a comment, so #4023's generic AUTH_007 ping no longer shadows the rich per-provider validators (grok-web #3474 IP-reputation/Cloudflare, chatgpt-web cf-mitigated, claude/gemini/copilot/qwen/t3-web). Restores provider-validation-specialty.test.ts (112/112) while keeping web-cookie-auth007 (5/5). Behavior fix at an existing dispatch boundary; not extractable." } diff --git a/src/lib/providers/validation.ts b/src/lib/providers/validation.ts index c6904d715c..2578bc911e 100644 --- a/src/lib/providers/validation.ts +++ b/src/lib/providers/validation.ts @@ -4000,15 +4000,6 @@ export async function validateProviderApiKey({ provider, apiKey, providerSpecifi return { valid: false, error: "Provider and API key required", unsupported: false }; } - // Web-cookie providers (session-based authentication) - if (WEB_COOKIE_PROVIDERS[provider]) { - try { - return await validateWebCookieProvider({ provider, apiKey, providerSpecificData }); - } catch (error: any) { - return toValidationErrorResult(error); - } - } - if (isOpenAICompatibleProvider(provider)) { try { return await validateOpenAICompatibleProvider({ apiKey, providerSpecificData }); @@ -4417,6 +4408,19 @@ export async function validateProviderApiKey({ provider, apiKey, providerSpecifi } } + // Web-cookie providers WITHOUT a dedicated specialty validator above fall back to the generic + // session-ping check (AUTH_007 SESSION_EXPIRED on 401/403). Providers that DO have a rich + // per-provider validator (grok-web, chatgpt-web, claude-web, …) are handled by + // SPECIALTY_VALIDATORS first and must not be shadowed by this generic probe (issue: the + // #4023 dispatch was placed too early and intercepted every web-cookie provider). + if (WEB_COOKIE_PROVIDERS[provider]) { + try { + return await validateWebCookieProvider({ provider, apiKey, providerSpecificData }); + } catch (error: any) { + return toValidationErrorResult(error); + } + } + const entry = getRegistryEntry(provider); if (!entry) { if (isSelfHostedChatProvider(provider)) {