Commit Graph

2713 Commits

Author SHA1 Message Date
Rahul sharma
131e413cbd fix: mark Vercel AI Gateway as passthroughModels (#11771)
Correção pequena e correta — `passthroughModels: true` para o Vercel AI Gateway. Validado no worktree combinado do lote (typecheck limpo, gates estáticos verdes). Obrigado!
2026-08-30 09:09:13 -03:00
Paco Cartones
66e02ec737 fix(plugins): deliver onStreamComplete to disk-installed plugins (#11825) (#11934)
Resynced onto release/v3.8.51 (originally targeted main; retargeted since the default branch is release/v3.8.51). One real conflict in open-sse/handlers/chatCore.ts, but it was entirely unrelated to this PR's actual purpose: the antigravity-aware lockExactModel branching and deferAntigravityQuotaStateToCaller state exist on main but haven't been synced to release/v3.8.51 yet (confirmed by diffing your branch against its own main merge-base — the only change there was a Prettier reformat, not new logic). Discarded that unrelated drift and kept the release tip's current quota-lock shape; the onStreamComplete plugin wiring itself is untouched and intact. typecheck:core clean, 13/13 plugin delivery tests pass. Thanks for the thorough three-layer root-cause writeup.
2026-08-30 05:29:26 -03:00
Paco Cartones
15b164866c feat(providers): expose a usage-fetch capability in the provider plugin manifest (#11903)
Boarded with 8 other PRs in one combined worktree: typecheck:core, check:file-size, check:changelog-integrity, check:complexity, check:cognitive-complexity, check:cycles, check-native-deps all green; 75/75 focused tests pass. Discovery-only as claimed — nothing reads the new tag yet, dashboard quota widget stays gated by USAGE_SUPPORTED_PROVIDERS. Thanks.
2026-08-30 05:28:38 -03:00
Paco Cartones
41c6135257 fix(ollama): preserve multi-byte UTF-8 content split across stream chunks (#11921)
Boarded with 8 other PRs in one combined worktree: typecheck:core, check:file-size, check:changelog-integrity, check:complexity, check:cognitive-complexity, check:cycles, check-native-deps all green. Retargeted from main to release/v3.8.51. Confirmed ollamaTransform.ts was the only streaming transform not using a persistent { stream: true } decoder — matches the pattern already established in responsesTransformer.ts. TDD repro included. Thanks for finding an unreported bug.
2026-08-30 05:28:07 -03:00
echel0n
22011437f8 fix(providers): route OrcaRouter chat requests to /v1/chat/completions (#11923)
Boarded with 8 other PRs in one combined worktree: typecheck:core, check:file-size, check:changelog-integrity, check:complexity, check:cognitive-complexity, check:cycles, check-native-deps all green. Retargeted from main to release/v3.8.51. One-line baseUrl fix with a live endpoint probe documenting the exact 404→401 transition — solid verification. Thanks.
2026-08-30 05:27:57 -03:00
Bl0ck
79b2e92c4e fix(codex): fail over image generation for imported free plans (#11948)
Boarded with #11954/#11953/#11951/#11952 in one combined worktree: typecheck:core, check:file-size, check:changelog-integrity, check:complexity, check:cognitive-complexity, check:cycles all green; 85/85 focused tests pass. Verified both halves of the gap directly: isCodexFreePlan() (open-sse/executors/codex/tools.ts) only checks workspacePlanType, while codexImport.ts normalizes the JWT plan into providerSpecificData.chatgptPlanType — confirmed imported free-plan accounts would bypass the existing guard. Thanks for tracing the full import-to-guard path.
2026-08-30 05:10:39 -03:00
Bl0ck
e96e40c035 fix(images): forward Antigravity image size (#11952)
Boarded with #11954/#11953/#11951/#11948 in one combined worktree: typecheck:core, check:file-size, check:changelog-integrity, check:complexity, check:cognitive-complexity, check:cycles all green; 85/85 focused tests pass. Confirmed the Antigravity Gemini path only forwarded aspectRatio into generationConfig, dropping the requested size tier entirely. Thanks for the fix and the 3:4/2K regression coverage.
2026-08-30 05:10:11 -03:00
Bl0ck
097226b617 fix(codex): normalize non-stream responses (#11951)
Boarded with #11954/#11953/#11952/#11948 in one combined worktree: typecheck:core, check:file-size, check:changelog-integrity, check:complexity, check:cognitive-complexity, check:cycles all green; 85/85 focused tests pass. Confirmed the codex registry entry was missing forceStream: true while every other JSON-only-client provider (cline, clinepass, ghe-copilot, kimi, zed-hosted, chatgpt-web-codex) already has it. Clean reuse of the existing bridge, no Codex-specific response handling needed. Thanks!
2026-08-30 05:09:48 -03:00
brick30llc-ctrl
2e3cd599b6 feat(routing): add LiquidAI LFM2.5-2.6B free tier via OpenRouter (#11752)
Resynced onto the release tip — the FREE_CATALOG_CURATED_AT bump conflicted with a later bump already on the tip; resolved to today's date since real content is landing. typecheck:core clean, 23/23 focused tests pass (free-model-catalog, free-models). Verified live against OpenRouter's own /api/v1/models pricing as claimed. Thanks for the new free-tier entry.
2026-08-30 04:31:31 -03:00
Syed Raheemuddin
d26fe03801 feat(routing): add relayMode for schema-locked context handoffs (#11839)
Boarded with #12003/#11841/#11840 in one combined worktree: typecheck:core, check:file-size, check:changelog-integrity, check:complexity, check:cognitive-complexity, check:cycles all green; 24/24 focused tests pass. relayMode is opt-in and defaults to standard, so this is backward-compatible as claimed — verified the plumbing through resolveUniversalHandoffConfig/resolveContextRelayConfig/selectMessagesForSummary. Thanks for the clean, well-tested addition.
2026-08-30 02:52:10 -03:00
Syed Raheemuddin
2ec24e7c0b fix(core): resolve DB init race condition and reasoning translation (#12003)
Boarded with #11841/#11840/#11839 in one combined worktree: typecheck:core, check:file-size, check:changelog-integrity, check:complexity, check:cognitive-complexity, check:cycles all green; 24/24 focused tests pass. Both fixes are surgical and well-reasoned: explicit ensureDbInitialized() call for MCP stdio (verified the function exists at src/lib/db/core.ts:1496) avoids a startup race, and the reasoningContent fallback prevents empty message.content when only reasoning was returned. Thanks for tracking down both root causes.
2026-08-30 02:51:18 -03:00
Webman
50bc8ab8aa fix(barrel): delete the @/lib/localDb barrel — every consumer migrated (#11795 Phase 5) (#12055)
Resynced onto the release tip after #12051/#12052/#12053 landed. Same LKGP-clear conflict as #12053 (kept the current clearStaleLKGP() helper at both call sites). One additional issue this final phase's combined-worktree validation surfaced: clearStaleLKGP() itself (added by #12013, which none of the 4 phase PRs could have seen since it landed after they were authored) still had a dynamic `await import("@/lib/localDb")` — a real break once this PR deletes the barrel. Fixed to `await import("@/lib/db/settings")`, matching the direct-import pattern used at every other call site. typecheck:core, check-db-rules, check:cycles, and the eslint-import-boundaries regression test (3/3, including "G14 rejects localDb barrel imports") all green after resync — zero barrel-importing production files remain. Nice clean 5-phase migration, and thanks for taking on the full #11795 cleanup.
2026-08-30 02:36:26 -03:00
Webman
4e11887085 fix(barrel): migrate open-sse, src/shared, src/sse, src/models, src/domain off the @/lib/localDb barrel import (#11795 Phase 4) (#12053)
Resynced onto the release tip after #12051/#12052 landed. One real conflict in open-sse/services/combo.ts at both LKGP-clear call sites (handleComboChat + round-robin path): the release tip already has #12013's clearStaleLKGP() helper, which this PR's branch predates — kept the current helper call at both sites, discarding the pre-refactor inline pattern. typecheck:core and the open-sse test suite (vitest, 9/9 on volumeDetector) both green after resync. Thanks for the well-scoped Phase 4 migration.
2026-08-30 02:31:09 -03:00
Bob.Hou
38e2baa879 fix(resilience): clear persisted LKGP pin on target exhaustion and skip (#11911) (#12013)
When an auto/*/lkgp combo target failed into exhaustion (e.g. an unauthenticated free-tier 401) or was skipped pre-dispatch (cooldown, model lockout, unavailability), the Last Known Good Provider pin was never cleared — so subsequent requests kept re-selecting the same dead provider, causing repeated failures and mass-skipping instead of falling through to a healthy target. Centralizes invalidation into clearStaleLKGP(), invoked from both handleComboChat and handleRoundRobinCombo on exhaustion, pre-dispatch skip, and body-specific 400 termination.
2026-08-29 19:52:06 -03:00
Bob.Hou
d3420d29f1 fix(admission): exclude reclaimable page cache from the cgroup pressure ratio (#12017)
Real production incident (2026-08-29): the resource-pressure guard ratioed raw cgroup v2 memory.current (which counts reclaimable page cache) against memory.max, so a busy host with ~3GiB of page cache latched a global 503 across every model for 26 minutes even though PSI/OOM/memory.events all showed zero real pressure — the kernel would have reclaimed those pages instantly. Fix: ratio the working set (current - file) for the trip/recovery check, falling back to the raw ratio when memory.stat is missing/stale/zero (never clamping to a false zero-pressure reading).

12 new tests including direct incident reproduction (raw 95%/workingset 32% stays normal) + bug-injection round trips. Full resource-pressure + admission suites green (48/48, re-verified in this batch together with the other 3 PRs: 57/57).
2026-08-29 19:52:02 -03:00
Diego Rodrigues de Sa e Souza
2b8d3a8291 fix(radar): restore D12 public boundary (#12057) 2026-08-29 17:37:26 -03:00
Diego Rodrigues de Sa e Souza
34e2f84c04 feat(api): explicit model exposure allow/deny list for /v1/models (#11481) (#11997)
Adds opt-in modelVisibilityAllowlist/modelVisibilityDenylist settings so an operator can curate exactly which models GET /v1/models advertises, mirrored into auto/* combo candidate pools (the same trap #6512 fixed for hidePaidModels). Default off, no behavior change for anyone who doesn't opt in.

TDD: 4 new test files, 22/22 passing (16 node:test + 6 vitest) + regression sweep across virtual-auto-combo/hide-paid/hide-auto-no-think suites (21/21).

Rebased onto the updated tip (a sibling #9133 landed first, same file) — kept both rebaseline annotations in file-size-baseline.json and set the value to the real measured line count after both merged.
2026-08-29 15:40:32 -03:00
Diego Rodrigues de Sa e Souza
d32c76f85a fix(config): correct Hermes-4-405B display label from 7B to 405B (#11861) (#11993)
Fixes a copy-paste label typo (Hermes-4-405B mislabeled "7B") in both the registry and the free-model catalog data, spotted in the #11861 comment thread. TDD: 3/3 tests, generic parameter-size consistency check + exact regression guard.
2026-08-29 15:27:49 -03:00
Diego Rodrigues de Sa e Souza
e6de61f0c2 fix(sse): stop the auto-combo candidates inspector from dropping blocked rows (#9133) (#11994)
* fix(sse): stop the auto-combo candidates inspector from dropping blocked rows (#9133)

prepareVirtualAutoComboInputs applied filterResilienceBlockedCandidates
before the #7819 read-only candidate inspector ever saw the pool, so a
model-locked or cooled-down candidate silently disappeared from
/auto-combo/*/candidates instead of showing up as reachable:false with a
reason (modelLocked/connectionCooldown/breakerState were dead fields by
construction). Add an opt-in `skip` parameter so the inspector builds its
own unfiltered pool; routing (createVirtualAutoCombo/createBuiltinAutoCombo
called without a prepared override) is unchanged. Also aligns
isModelLocked's model argument to the bare model id, matching every lock
writer and the routing-side filter, instead of the "provider/model" string.

Regression test: tests/unit/auto-combo-candidates-locked-model-visible.test.ts
(red before the fix — locked account's row silently missing; green after).

* chore(quality): register the #9133 regression test in stryker tap.testFiles

tests/unit/auto-combo-candidates-locked-model-visible.test.ts covers
open-sse/services/accountFallback.ts (via isModelLocked) but wasn't listed,
so its mutant kills wouldn't count toward mutation coverage.

---------

Co-authored-by: Markus Hartung <mail@hartmark.se>
2026-08-29 08:10:40 -03:00
Diego Rodrigues de Sa e Souza
71093eda77 fix(codex): keep parallel_tool_calls:false on translated Responses Lite path (#11707) (#11984)
enforceCodexResponsesLiteParallelToolCalls() forces parallel_tool_calls:false
at the top of CodexExecutor.execute(), but transformRequest() early-returns
the body before its RESPONSES_API_ALLOWLIST field filter only when
_nativeCodexPassthrough is set. Any request that reaches the codex
executor via the translated (non-native-passthrough) path never gets that
flag, so the allowlist filter silently deleted parallel_tool_calls right
before the fetch body was sent, reproducing the reported upstream
rejection ('X-OpenAI-Internal-Codex-Responses-Lite requires
parallel_tool_calls to be false') for every model.

Add parallel_tool_calls to RESPONSES_API_ALLOWLIST so the value survives
the translated path too. Update the sibling #2608 allowlist test that
previously asserted parallel_tool_calls gets stripped like other Chat
Completions-only fields -- it is a legitimate Responses API field that
must now survive.

Co-authored-by: Markus Hartung <mail@hartmark.se>
2026-08-29 08:10:26 -03:00
Diego Rodrigues de Sa e Souza
d2ad71cf56 fix(kie): route flux/kontext to its dedicated endpoint, not the Market createTask flow (#11296) (#11985)
flux/kontext is catalogued with isMarket: true, so handleKieImageGeneration
routed it through KIE's unified Market createTask endpoint with
model: "flux/kontext". KIE does not expose Flux Kontext through the Market
catalog at all -- it lives under a dedicated API tree
(POST /api/v1/flux/kontext/generate, poll GET /api/v1/flux/kontext/record-info,
models flux-kontext-pro/flux-kontext-max) -- so the Market endpoint rejected it
with "model name not supported", matching the reporter's exact error text.

Special-case flux/kontext ahead of the isMarket branch so it hits the
dedicated endpoint/payload shape instead of being treated as a Market entry.
z-image/4.0-*/4.5-* remains intentionally untouched (still blocked on
reporter/live confirmation per the existing in-code comment).

Co-authored-by: Markus Hartung <mail@hartmark.se>
2026-08-29 08:10:13 -03:00
Tobias Andersen
d8879371ea fix(combo): lock GitHub models rejected as "not supported" for future requests (#11781)
Follow-up to #11762/#11774, same bug class in combo's own model-lockout wiring: GitHub rejects several models (gpt-5.4, gpt-5.3-codex, etc.) with a 400 that's permanently unavailable for this account's Copilot integration, but nothing recorded a cross-request lockout — combo's #5249 in-request advance guard is correct but doesn't persist, so the same doomed model gets retried from scratch on every new request, indefinitely.

Fix: on a model-scoped 400 (`isModelScoped400`), call `lockModelIfPerModelQuota(provider, connectionId, rawModel, "model_capacity", 1h)`. GitHub already has per-model-quota enabled, so only the rejected model locks — siblings keep working. `isModelLocked()` is already checked pre-dispatch, so no other wiring needed.

Validated: 3/3 new tests + fixed a pre-existing test-isolation gap in combo-model-scoped-400-advance.test.ts (shared model name across sub-tests without clearing lockout state). Thanks!
2026-08-29 05:21:50 -03:00
Tobias Andersen
91f9a01fda fix(resilience): stop hammering permanently-moved endpoints and billing-suspended accounts (#11774)
Follow-up to #11762, same bug class hitting freeaiapikey (410 permanently-moved endpoint) and fireworks (412 billing-suspension) — both fell through checkFallbackError's generic transient-cooldown branch and got retried every ~1 minute for a full day.

Fix: `ENDPOINT_PERMANENTLY_MOVED_PATTERNS`/`isEndpointPermanentlyMoved()` → 24h lockout; `ACCOUNT_SUSPENDED_BILLING_PATTERNS`/`isAccountSuspendedForBilling()` → treated as credits-exhausted (1h cooldown), independent of status code so it also catches Fireworks' 412.

#11762 landed first and touched the same file — rebased/re-merged onto the updated tip (additive, no logic changes) and re-validated: 13/13 tests pass. Thanks for tracing this with real production logs again!
2026-08-29 05:19:15 -03:00
Tobias Andersen
87b3bdf85e fix(resilience): lock permanently retired models instead of short backoff (Gemini ban prevention) (#11762)
Root-caused via a real Gemini-ban incident log: deprecated-model 404/410s (e.g. gemini-2.5-flash "no longer available to new users") fell through checkFallbackError's generic transient-cooldown branch, so combo/auto-routing kept re-selecting a permanently dead model every cooldown window forever — the hammering that got the account flagged as abusive.

Fix: `MODEL_PERMANENTLY_UNAVAILABLE_PATTERNS` + `isModelPermanentlyUnavailable()` classify these as a 24h lockout instead, surfaced via `quotaResetHintMs` so combo's per-request model-lockout honors it in full.

Validated: 6/6 new tests + 133/133 existing accountFallback/error-classification tests, no regressions. Thanks for tracing this end-to-end with real production logs!
2026-08-29 05:09:37 -03:00
Diego Rodrigues de Sa e Souza
3b752f9d4c chore(quality): type the 55 no-explicit-any sites frozen under #11924 (#11975)
Production (open-sse/utils/socksConnectorWithFamily.ts, 4 sites): every cast was
redundant — undici's buildConnector.BuildOptions already has `timeout?: number | null`,
socks' SocksClientOptions has `timeout?: number`, and Agent.Options' `connect` /
`connectTimeout` narrow to the connector's parameter types on their own. Behaviour
unchanged; check:open-sse-typecheck stays at the frozen 5.

Tests (51 sites): the socks-timeout mocks now carry the real types — the patched
SocksClient.createConnection is typed as the static it replaces, the fake
buildConnector returns buildConnector.connector, the proxy is a SocksProxy, the
dynamic import is typed as the module it loads; the e2e suite passes a SocksProxy and
Agent.Options and no longer casts undici's fetch init (its RequestInit already has
`dispatcher`); the isFree suites narrow getCustomModels()' JSON to a declared row
shape, feed deliberately-wrong values through `unknown`, and stop casting for
zod's safeParse, which takes unknown.

The six files' suppression entries are removed: 1238 → 1232 files, 5487 → 5432
suppressed. ESLint without the suppressions file reports 0 problems on all six;
with it, no stale entry is left. The five suites pass (4, 2, 5, 4, 4).
2026-08-29 03:06:50 -03:00
Diego Rodrigues de Sa e Souza
d0f69e4c70 chore(quality): re-freeze the ESLint suppressions on release/v3.8.51 from a clean-room run (#11955)
* chore(quality): re-freeze the ESLint suppressions on release/v3.8.51 from a clean-room run

`No new ESLint warnings` failed on every PR against release/v3.8.51 with exit 2:
"There are suppressions left that do not occur anymore". Measured in a depth-1 clone
with `npm ci` from the branch's own lockfile and the job's exact command
(`npm run lint:json -- --max-warnings 0`): 56 errors — 55 `no-explicit-any` in six
files that landed while the base was red (#11843 isFree tests: 22; b7102140d5 socks
connect timeout: 33) plus one `no-unused-vars` — and stale entries for files that no
longer violate. The devbox figure previously quoted in #11924 (280, with 224
react-hooks/*) does not reproduce on the lockfile install and is withdrawn.

- config/quality/eslint-suppressions.json: `--prune-suppressions` (two stale file
  entries removed) and the 55 pre-existing `any` frozen at their exact counts — the
  file is a ratchet, counts only go down; the debt stays tracked in #11924.
- open-sse/services/adobeFireflyCatalog.ts: remove `GPT_SIZE_MAP`, a constant the
  f3d9279b44 split left behind with no reader (the real violation, fixed not frozen).

Verification in the clean room after both changes, same command as CI: exit 0,
0 errors, 0 warnings (1238 files / 5487 suppressions).

* chore(quality): tighten openapiCoverage.pct to the measured 39 (require-tighten)

With ESLint back to 0/0 on this PR, the job's next step (check-quality-ratchet
--require-tighten) started failing: openapiCoverage.pct improved from 38.4 to 39
(delta 0.6 > slack 0.5) and the baseline must be tightened in the same PR. 39 is
the value CI collect-metrics measured on run 33213844112 and a clean-room checkout
of 777d9d1629 reproduces it; the cycle's new routes landed documented in
docs/openapi.yaml. Only this metric moves; annotation follows the file's convention.
2026-08-28 22:07:40 -03:00
diegosouzapw
9968e1ce6e Merge remote-tracking branch 'origin/release/v3.8.51' into chore/sync-main-into-3851-20260828b 2026-08-28 17:27:31 -03:00
diegosouzapw
5ade9e0851 fix(sync): repair the two regressions the v3.8.50 sync-back left on release/v3.8.51
Fifteen unit files were red on this branch's PRs; running them on the pre-sync
tip (d5dfcfff58) and on the synced one showed thirteen already failed before
the sync — the cycle's own drift — and exactly two regressed:

- open-sse/services/tokenExtractionConfig.ts: git kept BOTH sides' identical
  volcengine-console config (23 entries instead of 22). The duplicate is gone.
- src/lib/usage/providerLimits.ts: the sync took release/v3.8.50's cooldown
  release helper, which is looser than this branch's #11277 contract (it frees
  an extra_usage block when the policy is off and a window with no reset
  evidence). tests/unit/provider-limits-recovery.test.ts pins the contract;
  the pre-sync call site is restored and the unused helper and its imports
  dropped. 20/20 again, siblings unchanged.
2026-08-28 16:41:42 -03:00
Bob.Hou
6b259812a7 fix(sse): preserve store parameter semantics for openai-compatible responses (#11826) (#11916)
stripStore() now forces store=false for stateless OpenAI-compatible Responses-API targets unless the connection explicitly opts in via providerSpecificData.openaiStoreEnabled, instead of only handling the openai/agentrouter cases — a client-supplied store value previously passed through untouched to backends that don't actually persist responses server-side. Closes #11826. Thanks!
2026-08-28 16:25:19 -03:00
Diego Rodrigues de Sa e Souza
dd35750e5f fix(sse): defer OpenAI-to-Claude finish emission until real usage arrives (#11915 follow-up on #11883) (#11933)
Merges #11883's already-merged usage-harvesting extraction with #11915's finish-deferral mechanism, verified to fix a real remaining bug: the client-visible message_delta carried stale/zero usage when finish_reason arrived before the trailing usage chunk. 86/86 tests passing across 16 translator regression files.
2026-08-28 16:11:38 -03:00
NoxzRCW
b8c7ee599d fix(translator): keep upstream usage from trailing empty-choices chunks (#11883)
openaiToClaudeResponse() returned early on !chunk.choices?.[0], dropping the trailing usage-only chunk many OpenAI-compatible upstreams send when stream_options.include_usage is set (confirmed on Fireworks kimi-k3) — state.usage stayed undefined and billing fell back to an uncached token estimate. 154/154 focused assertions across the fix + regression suite. Thanks for tracking down the billing impact!
2026-08-28 15:49:14 -03:00
diegosouzapw
f2825bad75 fix(typecheck): guard the optional connectionId before the reactive model sync
release/v3.8.51 fails typecheck:core on its own (verified on a pristine
checkout): maybeTriggerReactiveModelSync(provider, connectionId: string) is
called with credentials.connectionId, which base.ts declares optional. No
connection row means there is no synced catalog to refresh, so skip instead of
passing undefined. Surfaced by the release-green gate of the v3.8.50 sync-back,
which refuses to push a tree with a hard typecheck failure.
2026-08-28 14:36:34 -03:00
diegosouzapw
b68af3f090 chore(release): merge release/v3.8.50 tip into release/v3.8.51 — sync-back step 1/2
The v3.8.50 close left 134 post-freeze commits on release/v3.8.50 that never
reached the cycle branch (the freeze cut release/v3.8.51 at 3192eb88d5). A
plain merge of main reproduces all of them through the `Release v3.8.50`
squash against a July merge-base and conflicted on 551 files; merging the
release tip first, against the recent common ancestor, narrows the real
conflicts to 102 (51 generated, 51 judged file by file with a proof each —
see _tasks/postmortems/2026-08-25-release-v3.8.50-pipeline-eficiencia.md,
Parte IV). Step 2 brings main's own post-tag fixes and the finalized
CHANGELOG through scripts/release/sync-next-cycle.mjs.

Resolution rules applied, in order of evidence:
- generated files regenerated with the repo's own generators
  (sync-llm-mirrors, gen-budget-card-svg, gen-provider-reference);
- where release/v3.8.51 already carried the same fix in a newer shape
  (#11524 search sweep, #11551 catalog scheduler, Google BYOP retry, KIE
  Market id map, Docker worker budget measured in #7518) its version stays;
- where release/v3.8.50 carried the newer shape (Volcengine cookie-domain
  CodeQL fix + shared Zod schemas, #11355/#10534 cooldown release helper,
  positive-anchor tests for security-hardening and cli-oneproxy) it wins;
- GPL-retired Raycast/Hailuo (#11691) stay retired: nothing of theirs comes
  back and the public-route test keeps the retired route out;
- the ten changelog.d fragments of v3.8.50 are dropped — they are already
  aggregated in main's CHANGELOG and would double-aggregate at v3.8.51.

Three things git's auto-merge silently produced were caught by a per-line
detector and fixed: providerLimits.ts lost T's imports and the
windowStillExhaustedAfterRealReset helper; catalogCache.ts and
providerLimits.ts kept both sides' identical copies of three declarations;
contextHandoff.ts's new provider-allowlist skip returned undefined against
the #11552 outcome type. Every decision was re-run through the tests both
sides own for it.
2026-08-28 14:07:39 -03:00
Dizzle
b7102140d5 fix(socks): forward Agent.connectTimeout to SocksClient and TLS, unify family null (#11842)
Fixes a SOCKS proxy timeout bypass: Agent.connectTimeout now reaches both the SocksClient.createConnection handshake and the TLS buildConnector phases (previously a stalled/blackholed SOCKS connection could hang past the configured budget), and the fetch-socks family===null path is unified onto createSocksDispatcherWithFamily. Verified against a faux RFC 1928 SOCKS server exercising both pre-grant and post-grant stalls. 6/6 focused tests passing. Thanks!
2026-08-28 12:37:32 -03:00
Bob.Hou
00b7b71bd3 feat(routing): expand connection-aware quota prefilter across combo strategies (#11682) (#11850)
Expands per-connection quota-aware pre-filtering across all 20 combo strategies so exhausted accounts are filtered before strategy resolution instead of causing avoidable upstream errors. Closes #11682. 15/15 + 131/131 + 457/457 (vitest) focused tests passing. Thanks!
2026-08-28 12:22:18 -03:00
Bob.Hou
1b39873ea9 fix(sse): preserve coherent markdown token boundaries across stream translation chunks (#11606) (#11851)
Preserves markdown token boundaries (bold/italic markers, code fences/spans, escape-backslash parity) split across stream translation chunks by tracking boundary state and flushing held buffers correctly instead of emitting broken markdown mid-stream. Closes #11606. 38/38 + 74/74 focused tests passing. Thanks!
2026-08-28 12:22:09 -03:00
Paco Cartones
808992a717 fix(antigravity): cap unverified body retry hints (#11823)
Preserves whether a 429 retry hint came from transport headers, structured google.rpc.RetryInfo, or unverified response-body text, and caps body-derived cooldowns at the operator's configured maxCooldownMs so an unverified upstream hint can no longer force an arbitrarily long model/semaphore lockout — authoritative header/structured resets stay intact across combo, chat, and Responses paths. Closes #11695. 29/29 focused tests passing. Thanks!
2026-08-28 11:14:24 -03:00
Paco Cartones
3f35f3afad fix(open-sse): sample stream TTFT/ITL from a monotonic clock (#11873)
Switches stream TTFT/ITL sampling from Date.now() (wall clock) to performance.now() (monotonic) — an NTP correction or manual clock adjustment mid-stream was poisoning routing metrics (inflated TTFT on forward steps, silently-dropped negative TTFT on backward steps). Matches the existing earlyStreamKeepalive.ts precedent on the same streaming path. Thanks!
2026-08-28 11:13:08 -03:00
MumuTW
f3d9279b44 refactor(quality): split adobeFireflyClient.ts (2,952 lines) into nine leaf modules (#11728)
Mechanical split of the 2952-line adobeFireflyClient.ts into nine leaf modules, each under the
1000-line cap — follows the existing Adobe Firefly family decomposition pattern
(adobeFireflySecurity.ts, ModelSnapshot, References, Upscale, Models, Session, BrowserLogin).
No behavior change. Thanks for the cleanup!
2026-08-28 09:30:57 -03:00
Diego Rodrigues de Sa e Souza
675bca8c9c feat(models): reactive discovery sync after Antigravity model-not-found 404 (#11888)
Recreated from #11688 (MumuTW) onto the active release/v3.8.51 — commit cherry-picked cleanly
with author preserved; 9/9 focused tests + file-size all green on this tip. Thanks for the fix!
2026-08-28 09:28:01 -03:00
Diego Rodrigues de Sa e Souza
7d57d9f4a1 fix(providers): retire common ChatGPT Web provider (#11754)
Rebased onto the current release/v3.8.51 tip as part of a combined provider-retirement/provenance merge batch (Designer Web, Felo Web, Runtime, GPL-derived removal, Qwen Web already landed). Large conflict set (this is the biggest PR in the batch — the common ChatGPT Web provider touches chat, images, count-tokens, session leases, and combos). Conflicts resolved:

- `open-sse/config/providers/registry/chatgpt-web/*`, `open-sse/executors/chatgpt-web*`, `open-sse/handlers/imageGeneration/providers/chatgptWeb.ts`, and their tests: kept deleted, matching the PR's stated scope.
- `open-sse/config/providers/registry/minimax/web/index.ts`, `open-sse/handlers/imageGeneration/providers/geminiWeb.ts`, `open-sse/executors/gemini-web.ts`'s stale image-mode branch: base-drift collisions against already-merged sibling retirements (#11691, #11708) — kept deleted / dropped the dead code, since this PR's own branch forked before those merged.
- `src/shared/constants/reservedProviderPrefixes.ts`, `open-sse/executors/index.ts`, `executorProxy.ts`, `virtualFactory.ts`, `autoStrategy.ts`, `src/lib/db/providers.ts`, `src/sse/handlers/chat.ts`: combined the Designer + Runtime (Felo/Qwen) + common-ChatGPT-Web retirement guard calls at each shared chokepoint — compute-once-then-OR pattern, consistent with prior combinations in this batch.
- `src/sse/services/model.ts` / `src/sse/handlers/chatHelpers.ts`: adopted this PR's new `getModelInfoOrRetirementResponse()` central wrapper (a real improvement over ad-hoc try/catch), and extended it to also catch the Designer + Runtime retirement errors it didn't originally cover, so the consolidation doesn't regress the other two mechanisms.
- `src/app/api/v1/images/edits/route.ts`: this PR moved the retirement check earlier (before `enforceApiKeyPolicy`) but left the old later call+catch block in place from base drift — removed the now-redundant duplicate `resolveImageRouteModel()` call and merged the Designer catch into the earlier one.
- `open-sse/config/imageRegistry.ts`, `tests/snapshots/executors/executor-map.json` (`keyCount` recomputed to 133), `tests/snapshots/provider/translate-path.json`: same "both sides inserted a different retired provider at the same slot" pattern — resolved by dropping both.
- `tests/unit/chatcore-executor-proxy.test.ts`, `provider-node-reserved-prefix.test.ts`, `combo-auto-candidate-expansion.test.ts`, `messages-count-tokens-route.test.ts`, `virtual-auto-combo.test.ts`: split into independent per-mechanism test blocks (established pattern); `virtual-auto-combo.test.ts`'s old "includes cookie web-session providers" positive-inclusion test (which used chatgpt-web as its example) was retired along with the provider and replaced by this PR's negative-exclusion test for the same slot.
- `docs/architecture/ARCHITECTURE.md`, `CODEBASE_DOCUMENTATION.md` (+ 4 i18n mirrors), `README.md`, `FREE-TIERS-GUIDE.md`, `docs/diagrams/free-tier-budget.svg`, `docs/screenshots/free-tier-budget-card.svg`, `docs/reference/PROVIDER_REFERENCE.md`: recomputed every stale count from the real merged state — 104 executors (`countFiles` gate logic), 351 providers (regenerated via `gen:provider-reference`), 152/351 `hasFree` entries, 445/438/7 free-tier catalog rows, 13 ToS-avoid providers, budget-card regenerated via its real generator script. One doc conflict (`oauth/` module list) needed picking HEAD's side specifically — theirs still listed the already-removed `raycast` module instead of the real `openference`.
- `config/quality/test-masking-allowlist.json`: additive merge of the PR's 17 `_deletedWithReplacement` entries alongside the batch's existing ones (one real duplicate-key mistake in my first pass, caught and fixed via a `object_pairs_hook` duplicate-key check before finalizing).

Also fixed two real, unrelated-to-my-merge issues surfaced by the focused suite:
- `tests/unit/resolve-web-provider-host.test.ts`: the PR's own test had a typo — it asserted `perplexity-web`'s resolved host as `"perplexity.ai"`, but the provider's registered `website` is `"https://www.perplexity.ai"` and the resolver returns the URL's `host` verbatim (no www-stripping), so the correct value is `"www.perplexity.ai"` (consistent with the same test's own `url` assertion).
- `tests/unit/hard-session-lease-bypass-inventory.test.ts`: this golden call-site inventory was already stale on the pristine post-#11713 tip (confirmed via a throwaway probe worktree) — `src/lib/db/providers.ts`'s 3 connection-fallback sites and a third `src/app/api/providers/route.ts` site were never added to the golden list by the earlier-merged #11698/#11720 PRs. Updated it to the real current inventory (dated inline comments explain each delta and which PR introduced it), plus this PR's own legitimate deltas (image-edits duplicate-call removal, `ChatGptWebExecutor.execute()` site removed).

Focused suite green (433/433 across executor-proxy, reserved-prefix, hard-session-lease-bypass-inventory, resolve-web-provider-host, retirement/runtime-block/source-retirement/management-retirement/image-handler-retirement, migration-168, combo-auto-candidate-expansion, virtual-auto-combo, executor-map-golden and siblings), plus `typecheck:core`, `check-file-size`, and `check-changelog-integrity` clean. Thanks for the thorough provenance-hold retirement work — appreciated.
2026-08-28 06:52:46 -03:00
Diego Rodrigues de Sa e Souza
f48e25194f fix(providers): retire Qwen Web pending provenance review (#11713)
Rebased onto the current release/v3.8.51 tip as part of a combined provider-retirement/provenance merge batch (Designer Web, Felo Web, Runtime, GPL-derived removal all landed together already). Conflicts resolved:

- `src/shared/constants/providerRetirement.ts`: add/add conflict — combined `felo-web`/`felo` (already-merged) with `qwen-web`/`qw` into one `RUNTIME_RETIRED_PROVIDER_IDS` set, kept both `assertRuntimeProviderAvailable`/`assertRuntimeModelProviderAvailable` helpers.
- `open-sse/config/providers/registry/minimax/web/index.ts`: modify/delete — kept deleted (file is hailuo-web's registry entry, already retired by #11691; this PR's own change to it was just a comment reword on a since-removed target).
- `open-sse/executors/index.ts`, `executorProxy.ts`, `virtualFactory.ts`, `autoStrategy.ts`, `model.ts`, `chat.ts`, `chatHelpers.ts`, `auth.ts`, `src/lib/db/providers.ts`, `reservedProviderPrefixes.ts`: combined the Designer + Runtime (Felo + Qwen) retirement guard calls at each shared chokepoint — compute-once-then-OR pattern, consistent with the prior Designer+Felo combination.
- `src/shared/constants/providers/web-cookie.ts`, `tests/snapshots/provider/translate-path.json`, `tests/snapshots/executors/executor-map.json`: both sides had inserted a different retired provider (qwen-web vs. already-retired raycast/hailuo-web) at the same dict position — resolved by dropping both. `executor-map.json`'s `keyCount` recomputed to 135 (matches actual merged `entries`).
- `tests/unit/chatcore-executor-proxy.test.ts`, `tests/unit/provider-node-reserved-prefix.test.ts`: split into independent Felo/Qwen test blocks (established pattern for coexisting retirement-mechanism tests); recomputed `RESERVED_PREFIX_COUNT` to 398 (Designer+Felo+Qwen tombstones on top of the post-#11691 REGISTRY, verified via direct module evaluation, not hand-derived).
- `config/quality/test-masking-allowlist.json`: additive merge of Qwen's `_deletedWithReplacement` entries alongside Designer's.
- `README.md` + all `docs/i18n/*/README.md` mirrors, `docs/getting-started/FREE-TIERS-GUIDE.md`, `docs/reference/FREE_TIERS.md`, `docs/diagrams/free-tier-budget.svg`, `docs/screenshots/free-tier-budget-card.svg`: recomputed the free-tier catalog counts (447 entries / 440 active / 7 discontinued) from the actual merged `freeModelCatalog.data.ts`, regenerated the budget-card SVG via its real generator (`scripts/research/gen-budget-card-svg.mjs`), and dropped the retired Qwen quick-start row / QWEN MODELS section from every i18n README (identical unlocalized block across all 34 locales).
- Also fixed a duplicate-import merge artifact in `src/lib/db/providers.ts` (`isRuntimeRetiredProviderId` imported twice) caught by `typecheck:core`, and rebaselined `file-size-baseline.json` for the combined retirement-guard growth (`virtualFactory.ts` +3, with justification).

Focused suite green (345/345 across executor-proxy, reserved-prefix, migration-167, qwen-web-retirement, virtual-auto-combo, web-cookie/session, executor-map-golden and siblings), plus `typecheck:core` and `check-file-size`/`check-changelog-integrity` clean. Thanks for the provenance-hold retirement work — appreciated.
2026-08-28 06:01:21 -03:00
Diego Rodrigues de Sa e Souza
0ad03316e8 chore(providers): retire GPL-derived Raycast and Hailuo integrations (#11691)
Rebased onto the current release/v3.8.51 tip as part of a combined provider-retirement/provenance merge batch (Designer Web, Felo Web, Runtime, and this GPL-derived Raycast/Hailuo Web removal all landed together). Conflicts resolved:

- `config/quality/test-masking-allowlist.json`: additive merge of the Hailuo-Web/Raycast-auth/Raycast-local-extract entries alongside prior sibling retirement entries.
- `docs/reference/PROVIDER_REFERENCE.md`: kept the branch's generated content (deferred to a future `npm run gen:provider-reference` regeneration pass).
- `src/app/api/providers/[id]/test/webSessionTestDispatch.ts`: comment-only, dropped stale retired-provider examples.
- `tests/snapshots/executors/executor-map.json`: recomputed `keyCount` to 137 (matches the actual merged `entries` object).
- `tests/unit/provider-test-token-web-session-dispatch.test.ts`: kept both sibling assertions (hailuo-web + t3-chat-web), avoided duplicating the dedicated microsoft-designer-web test already present.

Also recomputed the golden `RESERVED_PREFIX_COUNT` (397, down from 400) to reflect the 3 GPL-derived ids/aliases this PR removes from `REGISTRY`, and rebaselined `file-size-baseline.json` for the combined retirement-guard growth accumulated across the sibling PRs in this batch.

Focused suite green (86 tests across authz/oauth-autoimport, public-route-exact-match, gpl-derived-provider-removals, migration-166, muse-spark-ws-auth-token, oauth-providers-config, provider-alias-uniqueness, provider-test-token-web-session-dispatch, providers-constants-split, ts7-executor-override-signatures, executor-map-golden, provider-node-reserved-prefix), plus `typecheck:core` and `check-file-size` clean. Thanks for the GPL-license cleanup — appreciated.
2026-08-28 05:16:59 -03:00
Diego Rodrigues de Sa e Souza
84504e3f1f chore(providers): retire Felo Web on provenance hold (#11698)
Merged via /merge-batch (v3.8.51 provenance sweep). Boarded and validated together with the batch's other retirement PRs in a combined worktree — full gate suite green. This PR's conflicts (against #11720's Designer retirement, both introducing a retirement-guard mechanism across executors/index.ts, executorProxy.ts, providers.ts, reservedProviderPrefixes.ts, auth.ts, chat.ts, chatHelpers.ts, model.ts) were reconciled by combining both guards at every chokepoint, with the shared reserved-prefix count recomputed (not guessed) at 400. Re-validated with this PR's own 72 node:test + 20 vitest focused tests, all passing, and pushed before merge. Thank you.
2026-08-28 05:03:51 -03:00
Diego Rodrigues de Sa e Souza
890cbfbfde fix(sse): retire Microsoft Designer Web runtime (#11720)
Merged via /merge-batch (v3.8.51 provenance sweep). Boarded and validated together with the batch's other retirement PRs in a combined worktree — full gate suite green. This PR's own conflicts (against #11711's EdgeTTS retirement, both touching test-masking-allowlist.json and the "Image / video / audio generation" README bullet) were reconciled additively/subtractively (both retirements now correctly reflected), re-validated with this PR's own 62 focused tests, and pushed before merge. Thank you.
2026-08-28 04:49:02 -03:00
Diego Rodrigues de Sa e Souza
dd8575eb2c chore(audio): retire EdgeTTS pending provenance review (#11711)
Merged via /merge-batch (v3.8.51 provenance sweep). Boarded and validated together with the batch's other provenance/retirement PRs in a combined worktree — full gate suite green, including the audio/speech-combo regression suites. Thank you.
2026-08-28 04:45:17 -03:00
Diego Rodrigues de Sa e Souza
657d3a484a fix(deepseek-web): replace unlicensed PoW artifacts (#11732)
Merged via /merge-batch (v3.8.51 provenance sweep). Boarded and validated together with the batch's other provenance/dependency PRs in a combined worktree — full gate suite green. Thank you.
2026-08-28 04:44:34 -03:00
Diego Rodrigues de Sa e Souza
a81895847d fix(sse): retire Gemini Web image generation (#11708)
Merged via /merge-batch (v3.8.51 provenance sweep). Boarded and validated together with the batch's other provenance/retirement PRs in a combined worktree — full gate suite green, including the video/image regression suites and the new gemini-web-image-retirement test file (fixed a getExecutor async-signature drift found during the combined validation pass; Gemini Web chat and legitimate Gemini image providers unaffected). Thank you.
2026-08-28 04:40:13 -03:00
Diego Rodrigues de Sa e Souza
3f5b08f2a6 fix(providers): correct g4f.space gateway claims (#11738)
Merged via /merge-batch (v3.8.51 provenance sweep). Boarded and validated together with the batch's other provider/provenance PRs in a combined worktree — full gate suite green. Thank you.
2026-08-28 04:38:48 -03:00
Diego Rodrigues de Sa e Souza
7c04e75e54 docs(dedup): correct the CodeQL claim on the tenant-namespace comment (#11712)
Obrigado! Correção honesta e bem documentada — só comentário, nenhuma mudança de lógica.

- Corrige a alegação de que omitir `tenantId` do digest evita o falso-positivo do CodeQL `js/insufficient-password-hash`; documenta que o alerta #874 já foi levantado no `createHash` de qualquer forma e foi dispensado por HR#14 (documentação de segurança, não código).
- Deixa explícito por que não "consertar" com um KDF: quebraria o determinismo de que o dedup depende.
2026-08-28 01:57:27 -03:00