mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-20 22:02:19 +03:00
The live evidence makes this: four Grok Build logins at 32-93% weekly remaining, skipped as "model locked by resilience" because the one login at 1% answered 402 and `passthroughModels: true` made that read as a per-model billing miss. A shared weekly wallet is a connection-wide signal, not a model verdict — `isSharedWalletCredits402` puts the scope where the biller put it. --- Validated in one consolidated worktree cut from `release/v3.8.51`, boarded with the other 19 PRs of this batch. Two in-batch conflicts, both additive and resolved by keeping each side: the `ENVIRONMENT.md` table (#13035 + #13011) and the `chatHelpers.ts` import block (#12975 on the tip + #13017). - `typecheck:core` clean; `check:dashboard-typecheck` OK (206 pre-existing, within baseline); `check:changelog-integrity` OK; `check:docs-counts` migrations ✓ - complexity 2816 / baseline 3218 and cognitive-complexity 1271 / baseline 1437 — both under baseline - 531 of 532 focused assertions green across the batch's 46 test files - `check-file-size` rebaselined for the batch's real growth (annotation `_rebaseline_2026_09_11_mergebatch_v3851_houminxi`, landed on #13038), attributed per PR The single red is **not this batch**: `tests/unit/combo/quota-weighted-strategy.test.ts` → "A/B isolation: 7 hard-empty + 2 at 0.5% + 1 at 40%, floor=1" asserts an order between two connections of identical weight and flakes on the pure tip too — 2 failures in 4 runs at `origin/release/v3.8.51` with nothing from this batch applied. ⚠️ base-red inherited: #12732 — `Docs Gates`, `Merge integrity`, `No new ESLint warnings`, `Unit Tests fast-path` and `Fast Quality Gates` reproduce on the pure tip (provider count 356 vs the 358 the modules define, SKILL.md drift, and `open-sse/utils/stream.ts` at 3115 > frozen 3098, untouched here). Thanks @HouMinXi — the live evidence on these (X500 logs, `storage.sqlite` state, real `/v1/models` probes, the 36-minute outage write-up) is what let a 20-PR batch be reviewed as a unit.
40 lines
1.6 KiB
TypeScript
40 lines
1.6 KiB
TypeScript
/**
|
|
* Providers whose 402 is a shared account wallet, not a per-model billing miss.
|
|
*
|
|
* Grok Build (`grok-cli`), grok.com cookie sessions (`grok-web`), and xAI
|
|
* OAuth (`xai-oauth`) bill Chat/Imagine/Voice/Build/API against one weekly
|
|
* percent pool. `passthroughModels: true` still stands for catalog/404
|
|
* behaviour; it must not send this 402 through the #12242 model-only lockout,
|
|
* or a combo of five grok-4.6 steps parks the empty account and then skips the
|
|
* remaining live accounts as "model locked".
|
|
*
|
|
* `matchesSharedWalletCreditsBody` expects a pre-lowercased string.
|
|
*/
|
|
const SHARED_WALLET_402_PROVIDERS = new Set(["grok-cli", "grok-web", "xai-oauth"]);
|
|
|
|
export const GROK_BUILD_USAGE_BALANCE_SIGNAL = "usage balance exhausted";
|
|
|
|
export function matchesSharedWalletCreditsBody(loweredErrorText: string): boolean {
|
|
return loweredErrorText.includes(GROK_BUILD_USAGE_BALANCE_SIGNAL);
|
|
}
|
|
|
|
export function isSharedWalletCredits402(
|
|
provider: string | null | undefined,
|
|
status: number,
|
|
errorText?: string | null
|
|
): boolean {
|
|
if (status !== 402 || typeof provider !== "string" || !SHARED_WALLET_402_PROVIDERS.has(provider)) {
|
|
return false;
|
|
}
|
|
if (errorText == null || String(errorText).trim() === "") return true;
|
|
return matchesSharedWalletCreditsBody(String(errorText).toLowerCase());
|
|
}
|
|
|
|
export function isCreditsExhaustedWithSharedWallet(
|
|
errorText: string,
|
|
signals: readonly string[]
|
|
): boolean {
|
|
const lower = String(errorText || "").toLowerCase();
|
|
return signals.some((sig) => lower.includes(sig)) || matchesSharedWalletCreditsBody(lower);
|
|
}
|