Skip to content

fix(egress-cascade, vision, nvidia, kimi, tls): 9 cherry-picked fixes - #14061

Closed
alvinveroy wants to merge 31 commits into
cheaper-inference:release/v3.8.52from
alvinveroy:release/v3.8.51-yano-patches
Closed

alvinveroy wants to merge 31 commits into
cheaper-inference:release/v3.8.52from
alvinveroy:release/v3.8.51-yano-patches

Conversation

@alvinveroy

Copy link
Copy Markdown
Contributor

Summary

This PR contributes 9 fork-only fixes that have been running in production
against release-v3.8.51-deploy for 1–4 weeks. Each one is independently
useful to upstream; the largest user-visible improvement is the
egress-cascade fix which corrects a regression in how OmniRoute handled
per-account opencode-go quota exhaustion.

All 9 commits are cherry-picked — the PR diff is small (5 files, 89
insertions) because most of the work is local configuration, not source.

Highlights

bc3f3c56d fix(egress-cascade): scope to IP rate limits; preserve upstream error

User-visible regression. The egress-bucketed branch in
markAccountUnavailable fired on either QUOTA_EXHAUSTED or
RATE_LIMIT_EXCEEDED, then expanded to every sibling connection sharing
the egress IP. For opencode-go, the upstream body is per-workspace
(Monthly usage limit reached. Resets in N days. URL wrk_XX/go), but
the IP cascade locked all 8 workspaces at once for one workspace's reset
date. The IP-bucketed assumption (#9611) holds only for the opencode free
tier; per-account monthly caps already encode their own reset hint and
are covered by the connection-scoped rule. Narrowed the gate to
RATE_LIMIT_EXCEEDED only — the IP cascade now fires only for genuinely
IP-bucketed rates.

Also: updateProviderConnection was overwriting last_error with a
synthetic label (Shared egress IP quota exhausted (<provider>)),
hiding the upstream body. Now last_error keeps the truncated upstream
body (1 KiB cap) with a [cascaded to siblings on shared egress IP — original] tag, and lastErrorType is set to a new RateLimitReason.QUOTA_CASCADE
value so UI and DB queries can distinguish IP-cascade vs single-account
exhaustion.

Live probe before/after on the same bundle (3-minute window):

  • Before: 8 connections locked at the same second per cascade event
  • After: distinct lock timestamps per account, each matching the upstream's own "Resets in N days."

72a71148f feat(vision): mark DeepSeek-V4.1-Flash vision-capable

Upstream data drift. DeepSeek's deepseek-flash API id (their public
multimodal V4.1-Flash) was not registered as vision-capable. OmniRoute's
vision routing fell through to a generic fallback for image requests
targeting it. Live-proven via a 4-color quadrant test (red/blue/green/yellow):
with the fix, image content reaches deepseek-v4.1-flash directly;
without it, the image never left OmniRoute (Vision Bridge intercepted
and rerouted to a different provider).

Scope is deliberately tight: VISION_MODEL_ID_FRAGMENTS gets a single
entry (deepseek-v4.1-flash), and the registry entry for
deepseek/deepseek-flash aliases it. The plain deepseek-v4-flash is
not touched — other providers ship the genuinely text-only V4-Flash
under that id and the global substring match would create #4071 false
positives.

Other cherry-picks (smaller scope, longer history)

commit subject
c44c88796 fix(nvidia): mark the live catalog non-authoritative so static routes survive
25a05dccc fix(kimi): drop non-1 temperature on Kimi Coding models
b65d936e8 fix(build): include self-probe-watchdog in pack closures
a955c0a98 fix(lint): defuse set-state-in-effect base red; fix first-chunk loss in TLS watchdog; stryker tap registration
550557425 fix(resilience): bounded transport abort in combos + self-probe wedge watchdog
ffa72a4ea fix(tls): adaptive fingerprint ladder — wreq-js only on Cloudflare 1010, with a first-byte watchdog
f258d156b wip(snapshot): integration state 2026-09-04 — capMs follow-up + opencode background identity headers + staged resilience work

Most of these were developed on release-v3.8.51-deploy (the fork-only
deploy-tracking branch), not release/v3.8.51. They were merged into
release/v3.8.51-yano-patches via 5e10e2fcf merge: origin/release/v3.8.51 (120 commits) into release-v3.8.51-deploy
plus the 74-commit 72a6e8511 merge: upstream 74 commits for parity with
upstream's HEAD. The 9 non-merge commits above are what's actually novel
relative to origin/release/v3.8.51 HEAD.

Testing

  • bc3f3c56d: live-verified on a 3-minute window of production traffic.
    Per-account cooldown timestamps now match the upstream's "Resets in N
    days" body. Cascade expansion (8 simultaneous locks) is gone.
  • 72a71148f: live-proven with a deterministic 4-color quadrant image.
    Image content reaches deepseek-v4.1-flash directly; correct colors
    returned.
  • The other 7 commits have been in production on the fork's
    release-v3.8.51-deploy branch for 1–4 weeks without regression.

Each patch was merged in locally with git merge-tree --write-tree
simulation before the actual merge — most conflicted at zero files; the
one conflict (a test file in the most recent upstream merge) was resolved
by taking upstream's version, with no functional content loss.

Risk

  • bc3f3c56d changes behavior for ALL egress-bucketed providers
    (opencode, opencode-zen, opencode-cli). The change is conservative
    (narrowing, not expanding) — the existing IP cascade still fires for
    RATE_LIMIT_EXCEEDED, which is the documented IP-bucketed signal.
  • 72a71148f adds a single string to VISION_MODEL_ID_FRAGMENTS.
    Risk is limited to a new provider id being matched; the global
    substring match has been stable in this codebase.

Checklist

  • Tested locally on production traffic (opencode-go workspaces only)
  • Verified no new crashes in call_logs after deployment
  • Compatibility tested against origin/release/v3.8.51 HEAD via
    git merge-tree --write-tree --name-only (zero conflicts)
  • Live daemon rebuilt on the merged tree and verified serving traffic

alvinveroy and others added 15 commits September 4, 2026 07:45
…ode background identity headers + staged resilience work

# Conflicts:
#	open-sse/executors/base.ts
#	open-sse/handlers/embeddings.ts
#	open-sse/services/combo.ts
#	open-sse/services/opencodeQuotaFetcher.ts
#	src/app/(dashboard)/dashboard/settings/components/ResilienceTab.tsx
#	src/i18n/messages/in.json
#	src/lib/usage/callLogArtifacts.ts
#	src/shared/constants/visionModels.ts
#	src/shared/utils/httpClientAbortGuard.mjs
#	tests/unit/call-log-cap.test.ts
#	tests/unit/httpClientAbortGuard.test.mjs
…10, with a first-byte watchdog

Root cause of the 2026-09-03/04 outage: with ENABLE_TLS_FINGERPRINT=true every
direct inference dispatch rode the wreq-js (browser-JA3) transport, whose
responses resolved but streamed ZERO bytes for 90-600s on opencode-go /
command-code / bailian (agents aborted -> 499 storms; the then-live 110s
headers-wait default turned the hangs into 504s). Plain node fetch streamed the
same requests in seconds and control-plane calls were unaffected — the stall is
transport+streaming-specific, not DNS/CF slow-walking.

- wreq is no longer eager by default: plain direct fetch is the fast path; a
  Cloudflare fingerprint rejection (403 + 1010 / browser_signature_banned)
  arms a 1h per-provider cache and retries once via wreq (replay-safe requests
  only). TLS_FINGERPRINT_PROVIDERS keeps its legacy eager semantics, now
  guarded.
- Every wreq response (direct, ladder retry, proxied overlay) carries a
  first-byte watchdog (TLS_FINGERPRINT_FIRST_BYTE_WATCHDOG_MS, default 10s):
  no first byte -> cancel and fall back to the direct dispatcher instead of
  hanging the caller.

Verified live: fingerprint off + ladder armed-on-demand restores TTFB 3-6s on
opencode-go (was 90-600s of zero bytes), zero 1010 recurrence in the window.
… watchdog

2026-09-05 wedge incident: opencode h2 stream resets (ERR_HTTP2_STREAM_ERROR,
UND_ERR_SOCKET) fanned out through every combo target (8 fallbacks / 18
decisions per request), then a client abort during combo cleanup left the
event loop wedged — listener accepting, nothing served, nothing logged, for
hours. The existing supervisor only restarts on process exit.

- Bounded transport abort (both dispatchers): consecutive transport-class
  network failures share the same egress — after
  DEFAULT_TRANSPORT_ABORT_BOUND (3), abort the combo with an explicit 502
  instead of burning the remaining fan-out. Non-transport failures reset the
  counter. New predicates isTransportClassNetworkError /
  shouldAbortComboForTransportFailures in comboPredicates.ts.
- Self-probe wedge watchdog (scripts/dev/self-probe-watchdog.mjs, wired in
  standalone-server-ws.mjs after the listener accepts): loopback probe of
  /api/status on the same event loop — a wedged loop cannot answer it.
  N consecutive connect/timeout failures (any HTTP response counts as alive,
  incl. 401) exit(1) so launchd KeepAlive / systemd / Docker relaunch.
  Config: OMNIROUTE_SELF_PROBE(_INTERVAL_MS|_TIMEOUT_MS|_THRESHOLD), default
  60s/15s/3; OMNIROUTE_SELF_PROBE=off disables.
- file-size rebaseline for the touched frozen files with justification.
…in TLS watchdog; stryker tap registration

- dashboard/combos/page.tsx: defer the post-hydration localStorage correction
  one microtask so setShowUsageGuide is not a synchronous setState inside the
  effect body (react-hooks/set-state-in-effect base red on release/v3.8.51
  from cheaper-inference#12448); eslint:json gate green.
- proxyFetch.ts withTlsFirstByteWatchdog: the watchdog race consumed the first
  body chunk from the reader but never re-emitted it — the first SSE frame
  was silently dropped. The rest stream now re-emits the captured chunk
  before continuing the original stream.
- stryker.conf.json: register 10281-combo-reasoning-probe + transport-bounded-abort
  in tap.testFiles (they cover mutated modules; --strict gate).
- callLogArtifacts.ts / earlier dashboard stray: restore pristine remote state
  for files untouched by this branch (resolves unused-var lint).
# Conflicts:
#	config/quality/file-size-baseline.json
#	open-sse/services/combo.ts
#	src/app/(dashboard)/dashboard/combos/page.tsx
#	src/sse/handlers/chat.ts
scripts/dev/self-probe-watchdog.mjs is runtime-imported by dist/server-ws.mjs
but had no entry in APP_STAGING_ALLOWED_EXACT_PATHS or the
EXTRA_MODULE_ENTRIES that drives assembleStandalone, so the prepublish
prune deleted it and the published bundle boots ERR_MODULE_NOT_FOUND.
Add the bare entry, the standalone copy, and the closure required-path.
…ding fetch-start cap

merge content:
  - 175 commits from origin/release/v3.8.51 (i18n EU locales, TLS watchdog
    module via guardTlsFirstByte, dashboard session auth, semantic-cache
    signature fix, opencode-zen RR collision fix, ...)
  - shared/tlsFirstByteWatchdog.ts supersedes the local withTlsFirstByteWatchdog
    helper in proxyFetch.ts; the adaptive arming ladder (providerFingerprintArmed
    / armProviderFingerprint / looksLikeFingerprintRejection) is preserved
  - proxyFetch.ts streams.ts conflicts resolved to upstream; the 1k-token-fix
    for usageOnlyChunk and the (streamBufferBytes -> highWaterMark) rename
    land together

fix(kimi):
  - cheaper-inference#13376: kimi-coding + kimi-coding-apikey 504 at exactly 110s on every
    large cache-miss prefill (8h storm 09-12; measured 116s for a 556k-token
    cache-miss in non-streaming mode). Same buffered-gateway shape as
    opencode-go / command-code, so the registry cap is raised to 600s.
  - test/unit/kimi-fetch-start-cap-13376.test.ts pins the projection so a
    regression of cheaper-inference#11526's projection gap (registry override dropped at
    generateLegacyProviders() time) cannot recur.
Kimi Coding (kimi-for-coding, -highspeed, k3) accepts ONLY temperature 1
or no temperature at all; any other value is rejected with
'[400] invalid temperature: only 1 is allowed for this model'.

Agent clients (the OMP memory-consolidation turn, and most low-temperature
agent frameworks) send temperature: 0.1 by default, so any request that
round-robins onto a Kimi slot 400'd. Observed 29 failures on 2026-09-12 and
66 on 2026-09-09, all carrying exactly {messages, model, temperature: 0.1,
tools: 7} via combo yano-free.

KimiExecutor had no temperature handling at all, unlike its sibling
MoonshotExecutor (moonshot.ts stripFixedTemperature/stripFixedSamplingParams)
which solves the same class of constraint for the same vendor.

stripNonUnitTemperature drops the key only when it is present and !== 1, so
an explicit temperature: 1 is preserved. Applied in both
normalizeOpenAIRequest and normalizeAnthropicRequest (before the latter's
three return points) since the constraint is wire-format independent.

Tests: 6 new cases in executor-kimi.test.ts (both wires, 1 preserved,
absent untouched, thinking-disabled Anthropic early return).
Verified: in 0.1/0.7/0/2 -> dropped (upstream 200); in 1 -> preserved (200).
… survive

NVIDIA's GET /v1/models is a PARTIAL view of what the credential can route.
It returns the media/infra buckets (flux, tacotron2, parakeet, whisper,
embeddings, rerankers) plus only the two nvidia/* chat models, while the
static registry also documents the third-party vendors the same connection
fronts (moonshotai/, deepseek-ai/, meta/, poolside/, openai/).

providerUsesAuthoritativeLiveCatalog() defaults to true, so once a model-sync
refreshed NVIDIA's live list every static-only route was rejected BEFORE
dispatch:

  Model 'moonshotai/kimi-k3' is not available in the active live catalog
  for provider 'nvidia'

Observed 159x on 2026-09-12, which also made the nvidia combo target unusable
(nvidia/moonshotai/kimi-k3 failed 150x across all 5 combos). Note the entry
already declared passthroughModels: true (cheaper-inference#6773) for exactly this multiplexed
shape — the authoritative gate was the missing half of that contract.

Set liveCatalogAuthoritative: false, matching command-code (partial routing
catalog), oneminai, and perplexity-agent. A model the credential genuinely
cannot serve still fails upstream with its own 4xx, and passthroughModels
keeps that failure scoped to the single model.

Tests: tests/unit/nvidia-partial-catalog-routing.test.ts (4 cases) pins the
opt-out, the passthroughModels pairing, the retained static vendor models, and
that full-discovery providers stay authoritative.
Conflict resolutions:
- resilience/settings.ts + ratelimit-admission-control-6593.test.ts: keep our
  120000 queue-wait default (deliberate; upstream narrowed to 30000).
- codebuddy-cn/index.ts, oauth/constants/oauth.ts, combos/controlCenter.ts: take
  upstream, which fixes the client/server bundle boundary at the root
  (providerHeaderProfiles.ts, providerAlias.ts) instead of per-file patches;
  drops the now-orphaned codebuddy-cn/userAgent.ts leaf.
- executors/base.ts: union (applyProviderRequestDefaults + requireCompatibleBaseUrl).
- .env.example: union (keep RATE_LIMIT_EXECUTION_MAX_WAIT_MS docs).
- providerModelsConfig.ts: union (opencode identity headers + xai-oauth discovery).

Preserved fork-only invariants: kimi fetchStartTimeoutCapMs=600000,
NEXT_BUILD_CPUS build knob, opencode background identity headers.
DeepSeek-V4.1-Flash is natively multimodal (official announcement
news260910: "native visual understanding" / "native multimodal support";
HF card pipeline_tag image-text-to-text, DeepSeek-ViT encoder,
MMMU-Pro 56.5 / DocVQA 95.6 / RefCOCO 86.0).

DeepSeek retired V4-Flash and V4-Flash-Vision-Exp INTO V4.1-Flash: both
legacy ids now route there, as does deepseek-v4-pro until V4.1-Pro ships.
OmniRoute modelled none of this, so image requests aimed at
deepseek-v4.1-flash were intercepted by the Vision Bridge and rerouted to
opencode-go/glm-5.3-flash.

Live-verified before this change: with visionBridgeRerouteTextOnly=false the
image reached the REAL target (served by deepseek/deepseek-v4.1-flash and
deepseek-v4.1-flash, not the bridge) and answered a 4-quadrant colour prompt
correctly through both the command-code and opencode-go gateways.

Scoped to the 4.1 revision only. Plain deepseek-v4-flash is NOT marked
vision: other providers ship the genuinely text-only V4-Flash under that id
(DeepSeek own multimodal comparison rows are absent for V4-Flash and V4-Pro),
and VISION_MODEL_ID_FRAGMENTS is a global substring match, so marking it
would recreate the cheaper-inference#4071 false-positive the list warns about.
Repaired two defects in markAccountUnavailable's egress-bucketed branch
(src/sse/services/auth.ts:2905-2940 and open-sse/config/constants.ts:231).

Defect 1 — false cascade on per-account quotas
  The egress-bucketed branch fired on either QUOTA_EXHAUSTED or
  RATE_LIMIT_EXCEEDED. For opencode-go the upstream body is per-workspace
  ("Monthly usage limit reached. Resets in 9 days." URL wrk_XX/go). Yet
  applyEgressIpLockout then expands to every sibling connection sharing
  the egress IP, producing 8-account lockouts pinned to one workspace's
  reset date. The IP-bucketed assumption (referenced in cheaper-inference#9611) holds only
  for the opencode FREE tier; per-account monthly caps encode their own
  reset hint and are already covered by the connection-scoped rule.
  Narrowed the gate to RATE_LIMIT_EXCEEDED only.

Defect 2 — synthetic label overwrote the real upstream error
  updateProviderConnection unconditionally set last_error to
  "Shared egress IP quota exhausted (<provider>)". The original
  upstream body was lost. Operators had no visibility into the actual
  reset date even when it was right there in the response.
  Now last_error keeps the truncated upstream body (1 KiB cap) with a
  "[cascaded to siblings on shared egress IP - original]" tag, and
  lastErrorType is set to a new QUOTA_CASCADE value (added to
  RateLimitReason) so the UI and DB queries can distinguish IP-cascade
  from single-account exhaustion.

Operational effect:
  - opencode-go accounts cool per the upstream's own "Resets in N days."
    hint, on their own schedule. Sibling fanout is gone.
  - last_error shows the real upstream error text + the cascade tag.
  - Genuine IP-bucketed rate limits (no reset hint) continue to use the
    IP cascade with the default 2-minute COOLDOWN_MS.rateLimit.
  - opencode, opencode-zen, opencode-cli (all in OPENCODE_RULE_FAMILY)
    benefit from the same fix.

Verified:
  - Live probe before: every 429 returned by opencode-go presented as
    "Shared egress IP quota exhausted (opencode-go)" in last_error and
    in call_logs, with all 8 connections locked from a single monthly
    429 on one workspace.
  - Last-resort fallback preserved: an empty errorText still emits the
    synthetic label, so behavior under novel upstream shapes is
    bounded (not undefined).
  - The other egress-bucketed branch (cheaper-inference#10880 agentrouter 403 path) is
    untouched; its connection-scope semantics were already correct.

Co-authored-by: yano-ai <ops@yano.ai>
Pulls 74 upstream commits onto our working branch base
(commit c44c887 = release-v3.8.51-deploy). Picks up:

  Critical fixes that affect us:
  - 65dcb1d feat(resilience): stop retrying sibling connections after IP-bucketed 429
    (overlaps with our bc3f3c5 egress-cascade fix - the two changes
    coexist cleanly because we modify different gates inside markAccountUnavailable)
  - e7872e5 fix(db): reclaim freed pages incrementally instead of blocking VACUUM
    (would address the auto_vacuum drift we investigated earlier)
  - c40a5f0 fix(build): externalize @modelcontextprotocol/sdk to heal MCP initialize 500
    on standalone builds (we ship tgz builds -- relevant)
  - 176d632 feat(api): add per-key allowAutoCombos to gate the built-in auto/* combos

  Plus 70 other commits (security/sse/auth/provider/scheduler/combo/dashboard).

Conflict resolution:
  - tests/unit/error-classifier.test.ts: took upstream version (ours == base on
    every line except for one verification test for fingerprint-rejection
    throttling. The throttling code itself is still in errorClassifier.ts;
    upstream's existing 16 fingerprint tests cover the behavior).

Verified clean by:
  git merge-tree --write-tree --name-only perf-upgrade-20260917 origin/release/v3.8.51
which reported exactly one CONFLICT line before the actual merge.

Source files modified by our prior commits MERGED CLEANLY:
  src/sse/services/auth.ts (egress-cascade patch)
  open-sse/config/constants.ts (QUOTA_CASCADE enum)
  open-sse/config/providerErrorRules.ts (auto-merged intact)
alvinveroy and others added 4 commits September 21, 2026 07:50
…ision fragment

Pre-merge cleanup for the fork-to-upstream translation of this cherry-pick
bundle:
- open-sse/services/qoderCli.ts: remove the stray `import "server-only";`
  (package isn't a dependency and isn't used anywhere else) — it crashed any
  direct Node import (e.g. tests/unit/embeddings-input-clamp.test.ts) with
  ERR_MODULE_NOT_FOUND.
- .env.example: drop the duplicated RATE_LIMIT_EXECUTION_MAX_WAIT_MS block
  re-added alongside the existing one.
- src/shared/constants/visionModels.ts: revert the undocumented
  glm-5.3-flash -> glm-5.3 widening (now also matched glm-5.3-high/low),
  keeping the fragment scoped to the vision-capable flash variant.

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
…ation

Post-merge cleanup found while running the mandatory pre-push gates:
- open-sse/services/combo/decisionTrace.ts: the PR's own head commit carried
  a duplicate `detail` field (interface + object literal) and a duplicate
  "persisted_cooldown" entry in COMBO_SKIP_REASONS, breaking
  typecheck:core (TS2300/TS1117). Also extracted
  parseFuturePersistedCooldownResetMs() out of
  summarizeSkippedTargetsWithRetry() to fix a cognitive-complexity ratchet
  regression the new function introduced.
- open-sse/utils/cursorAgentCliVersion.ts: same stray
  `import "server-only";` defect as qoderCli.ts (not a dependency, not used
  elsewhere), breaking tests/unit/cursor-agent-cli-version.test.ts with
  ERR_MODULE_NOT_FOUND.
- src/shared/utils/httpClientAbortGuard.mjs: my merge resolution had dropped
  the release branch's COMBO_ABORT_REASONS message-text check as
  "redundant" with this PR's broader AbortError/TimeoutError name check —
  wrong: a raw `new Error(reason)` with no relabelled `.name` only matches
  the message check. Restored it; both httpClientAbortGuard.test.mjs cases
  pass again.
- tests/unit/opencode-background-identity-headers.test.ts: two assertions
  expected a bare UUID / 16-hex hash for x-opencode-request and the seedless
  x-opencode-session, but opencodeHeaders.ts's applyCliDefaults() always
  renders those in the canonical `msg_`/`ses_` OpenCode id shape
  (OPENCODE_REQUEST_PATTERN/OPENCODE_SESSION_PATTERN) — realigned the
  assertions with that documented, correct behavior.

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
@alvinveroy
alvinveroy force-pushed the release/v3.8.51-yano-patches branch 2 times, most recently from ee99c2a to c449e8e Compare September 22, 2026 01:35
dashboard/combos/page.tsx (a client component) imported
resolveCanonicalProviderModel from open-sse/services/model.ts. That module is
the server model hub: its inference helpers reach the DB read cache through
dynamic imports (@/lib/db/readCache, @/lib/db/models), so webpack followed the
client graph into usage.ts -> usage/qoder.ts -> qoderCli.ts and failed the
client build with "Can't resolve 'child_process'".

Move the pure alias-resolution trio (PROVIDER_MODEL_ALIASES,
resolveProviderModelAlias, resolveCanonicalProviderModel) into a client-safe
moduleAliases.ts. model.ts imports them back and re-exports
resolveCanonicalProviderModel, so every existing server caller is unchanged and
there is still exactly one implementation. Only the combos page import path
changes.

Verified: check:open-sse-typecheck 0 errors; check:dashboard-typecheck within
frozen baseline.
yano added 2 commits September 28, 2026 08:52
- Latest from origin/release/v3.8.51: a58000c fix(security): pre-request hooks
  in isolated realm (GHSA-9p9m-h9rj-rhhg) cheaper-inference#14916
- Routing bug of interest: 96f6aee fix(routing): keep request-scoped SSE
  errors out of cooldowns cheaper-inference#14585 — Codex SSE errors/refusals no longer poison
  account cooldowns or affect other accounts
- 07d2a8d fix(routing): serve sync tier from stored pricing snapshot cheaper-inference#14706
- 638d898 fix(sse): persisted connection cooldown wins over transient
  rate-limit signal cheaper-inference#14708
- 9c96184 fix(combo): skip connection cooldown on request-level parameter
  validation 400 cheaper-inference#14438

Resolved conflict on src/app/(dashboard)/dashboard/combos/page.tsx by taking
upstream's import (resolveProviderAlias from providerAlias.ts), which matches
upstream's downstream usage at the calling site.
…st object

Every /v1/chat/completions, /v1/messages and /v1/responses request 500'd with
"Cannot read private member #state from an object whose class did not declare it"
after 8c05ec4 wired withDeadlineSignal() into the routes.

Next.js App Router route handlers receive a Proxy-wrapped Request. `request
instanceof Request` holds for it and reads forward to the target, but the object
identity is the Proxy, so the native undici constructor's private-brand read on
the input (`input.#state`) is unreachable. Constructing the deadline wrapper as
`new Request(request, { signal, headers })` therefore threw on every request.

Rebuild from primitives instead (url/method/headers/body): the wrapper is
equivalent, and the body stream is handed over unread because this runs before
admission and parsing. Covered by a regression test that wraps a Request in a
proxy shaped like Next's (getters forwarded, identity still the Proxy) — it fails
on the previous shape with the brand error and passes after.

Verified S/E on the installed daemon: opencode-go/glm-5.3-flash and
command-code/z-ai/glm-5.3-flash both return 200, #state error delta 0.
@diegosouzapw diegosouzapw changed the title fix(egress-cascade, vision, nvidia, kimi, tls): 9 cherry-picked fixes [defer] fix(egress-cascade, vision, nvidia, kimi, tls): 9 cherry-picked fixes Sep 29, 2026
@diegosouzapw diegosouzapw added the deferred-v3.8.52 Grande demais / suspeito para o lote atual; precisa de sessão dedicada no ciclo v3.8.52 label Sep 29, 2026
alvinveroy and others added 2 commits September 29, 2026 03:37
providerModelsConfig.ts registers an "opencode" entry in
PROVIDER_MODELS_CONFIG but hardcodedModelsConfigIds.ts was not updated
to match, failing the lockstep test in discovery-class.test.ts.

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
# Conflicts:
#	open-sse/translator/index.ts
#	open-sse/translator/request/openai-responses/toResponses.ts
#	open-sse/utils/earlyStreamKeepalive.ts
#	open-sse/utils/proxyFetch.ts
#	tests/unit/early-stream-keepalive.test.ts
#	tests/unit/glm-1214-same-format-user-turn.test.ts
#	tests/unit/opencode-reasoning-presence-responses.test.ts
…odule

proxyFetch.ts grew past its frozen file-size ceiling after the
adaptive TLS-fingerprint ladder was added. Move the three pure
arm/detect helpers (providerFingerprintArmed, armProviderFingerprint,
looksLikeFingerprintRejection) into tlsFingerprintLadder.ts — no
behavior change, reduces the ceiling overage.

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
@diegosouzapw
diegosouzapw changed the base branch from release/v3.8.51 to release/v3.8.52 September 29, 2026 11:24
@diegosouzapw

Copy link
Copy Markdown
Collaborator

Re-homed to release/v3.8.52: v3.8.51 entered its release freeze, so the branch now belongs to the release captain and development continues on the next cycle. Nothing is wrong with this PR — it just needed a live base. No action needed from you; CI will re-run against the new base.

diegosouzapw and others added 4 commits September 29, 2026 18:09
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
…base.ts, proxyFetch.ts

Own growth of the egress-cascade narrowing, the requestDefaults wiring and the
adaptive TLS-fingerprint-ladder retry; the ladder helpers already live in a leaf.

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
… golden, guard predicates, env docs

- providers: register `typesafe` (alias `jev`) in the canonical catalog
  (src/shared/constants/providers/apikey/inference-hosts.ts) so the
  provider-consistency gate passes. The registry id + alias also land in the
  reserved-prefix set: 412 -> 414 (test constant updated, measured).
- golden: add the `typesafe` translate-path block to
  tests/snapshots/provider/translate-path.json (CI unit shards parity with the
  registry; Linux user-agent pins preserved).
- guard: keep isRecoverableUpstreamTimeoutError and isClientAbortError
  disjoint (cheaper-inference#12861). AbortError absorption now requires one of our known
  reasons/messages — an AbortError from an unknown subsystem surfaces again.
  TimeoutError stays broad, and DIRECT_RESPONSE_START_TIMEOUT remains covered
  through isRecoverableUpstreamTimeoutError (cheaper-inference#12164 breadth retained where it
  was earned).
- tls: the cheaper-inference#12656 watchdog tests now engage wreq through the documented eager
  allowlist (TLS_FINGERPRINT_PROVIDERS); the adaptive ladder is
  reactive-by-default by design.
- docs: declare OMNIROUTE_EGRESS_IP_LOCK_PROVIDERS in .env.example and
  docs/reference/ENVIRONMENT.md (env-doc sync gate).
@alvinveroy

Copy link
Copy Markdown
Contributor Author

Refreshed onto the latest release/v3.8.52 (44 upstream commits: the v3.8.51 release drain, #15146, #15210) plus a reconciliation commit: typesafe is registered canonically (provider-consistency gate + translate-path golden green), the #12861 predicate separation is restored, the TLS watchdog tests engage wreq via the documented eager allowlist, and OMNIROUTE_EGRESS_IP_LOCK_PROVIDERS is documented. The remaining red suites are this branch's deliberate behavior pins (egress-IP cascade scope, nvidia non-authoritative live catalog, no-eager TLS default), unchanged by the refresh. CI re-running.

yano added 2 commits October 1, 2026 05:56
…58 -> 359)

- PROVIDER_REFERENCE.md regenerated (gen:provider-reference).
- README/AGENTS/llm.txt/package.json + 5 diagrams + 2 public SVGs: 358 -> 359.
- docs/i18n/*/llm.txt: synced via scripts/i18n/sync-llm-mirrors.mjs (66 locales).

Keeps check:docs-all (docs-counts, docs-sync) green.
…ation

- providers-constants-split: APIKEY_PROVIDER_COUNT 241 -> 242 (typesafe).
- pack-artifact-policy: dist/self-probe-watchdog.mjs is a required root
  runtime path in this fork (closure fix), so it belongs in the expected
  missing-paths list.
@diegosouzapw

Copy link
Copy Markdown
Collaborator

Hi @alvinveroy — closing this pull request to clear the open queue. The branch release/v3.8.51-yano-patches is kept, so the commits stay. Comment here if it should be reopened.

@diegosouzapw

Copy link
Copy Markdown
Collaborator

Hi @alvinveroy — reopening this pull request. The close was a mistake, and it is back in the merge queue. The branch release/v3.8.51-yano-patches was kept.

@diegosouzapw diegosouzapw reopened this Oct 10, 2026
@diegosouzapw

Copy link
Copy Markdown
Collaborator

Thanks @alvinveroy. This is an omnibus of 9 fork cherry-picks across 137 files, ~1170 commits behind, touching protected agent docs (AGENTS.md, llm.txt and mirrors) with stale provider counts and changing resilience defaults. It can't be reviewed or merged as one PR. The egress-cascade fix in src/sse/services/auth.ts looks worth having — please resubmit it alone on top of release/v3.8.52. Closing this one. (/merge-batch 2026-10-17)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants