Repository navigation
fix(sse): treat OpenCode free-tier 403 as request-scoped for combo routing - #14675
Merged
diegosouzapw merged 1 commit intoSep 24, 2026
Conversation
…uting A FreeTierError refusal is the same verdict on every account for the same request shape, so combo must not record model lockout or connection cooldown from it. Class FreeTierError (type/code) and the relayed body sentence as request-scoped in comboPredicates, pause the synthetic noauth path for a short TTL after such a refusal (opencodeFreeTierSkip), and disclose the OpenCode-only free-tier gate in catalog copy and FREE_TIERS.md. Refs diegosouzapw#14313
Owner
|
Verified the wiring end to end — |
gravonyxcloud
pushed a commit
to gravonyxcloud/OmniRoute
that referenced
this pull request
Sep 29, 2026
…uting (diegosouzapw#14675) Validated in the round-3 combined board (release/v3.8.51 @ e3b152badd + 59 PRs, gates on the 192.168.0.113 box): typecheck/open-sse/dashboard typecheck, complexity, cognitive, changelog integrity, route-validation, docs-counts, cycles, changed node:test files and vitest green except the inherited base-reds tracked in diegosouzapw#14496/diegosouzapw#14547 and file-size ratchet drift (rebaselined in a follow-up). Thanks @Laksopan23!
idoomblast
added a commit
to idoomblast/OmniRoute
that referenced
this pull request
Oct 4, 2026
A 403/451 FreeTierError refusal says nothing about the account or the model: every sibling account gets the same verdict for the same request, and the same account answers 200 once the request matches the contract. Handle it without poisoning account health (upstream diegosouzapw#14011, diegosouzapw#14675, diegosouzapw#14313): - errorClassifier.ts: classify the refusal as PROJECT_ROUTE_ERROR instead of FORBIDDEN (would ban the connection permanently) or GEO_BLOCKED (would park a healthy account for 24h). - auth.ts: zero-cooldown fallback for the refusal; per-model 402 credits keep the model-only lockout on passthrough providers (connection stays active); skip the synthetic noauth candidate while its short-TTL refusal skip is on. - comboPredicates.ts: request-scoped classification for combos, both by FreeTierError type and by the relayed sentence alone (the parser keeps error.type aside, so the body sentence is the reachable signal). - resilienceCandidateFilter.ts: exclude the skipped synthetic noauth node. - noauth.ts + FREE_TIERS.md: disclose the client-contract restriction so the dashboard does not promise keyless access upstream will refuse.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #14313 — OpenCode free-tier 403 (\FreeTierError) was not request-scoped for combo routing, so both lockout arms (first-failure + done-retrying) and provider cooldown could fire from a refusal that is the same verdict on every account for the same request shape.
Changes
oauth\ id and the body is a free-tier refusal; read by
esilienceCandidateFilter\ (auto-combo noauth candidates) and \maybeSyntheticNoAuthFallback\ (credential selection).
otice\ and \docs/reference/FREE_TIERS.md\ now document that the free tier can only be used from within OpenCode.
oauth-refresh-guard.test.ts\ — no production change needed; that test file gained a \clearOpencodeFreeTierSkips\ beforeEach so the new TTL does not leak across cases in the same process.
Tests (TDD)
Verification
pm run test:vitest: 482/482 pass
px eslint : 0 errors
pm run check:cycles: OK
pm run check:changelog-integrity: OK
pm run typecheck:core: only pre-existing base-red \cliproxyAccountHealth.ts:157\ TS2322
Notes
Refs #14313