Commit Graph

2608 Commits

Author SHA1 Message Date
Xiangzhe
79478a6676 test(vitest): pay heavy module imports at collection time, not out of the per-test budget
The remaining ui-shard reds were one class, not six bugs: every one of them did
`await import(<heavy component>)` INSIDE an `it()`, so Vite's transform of the
dependency graph was billed to that test's timeout. Measured costs against the
budgets they had to fit in:

  ProxyRegistryManager   86s import vs 30s / 60s / 5s budgets (render itself: 567ms)
  claudeTlsClient       ~12s import vs 5s default
  useProviderConnections  1050-line hook, whole dashboard graph, vs 5s default

That is why they looked like cross-file pollution: on an idle box the import
squeaked under the limit, and under the ui suite's 20 parallel workers it did not.
Running claudeTlsClient ALONE on a loaded box reproduces it — the trigger is CPU
contention, not a neighbouring file. The sibling chatgptTlsClient/grokTlsClient
tests import the same graph and never fail, because they import statically at
module scope, where the cost falls on the collection phase which has no per-test
budget. Every fix here does the same: static import or a beforeAll with its own
budget.

AutoComboCatalog also explains its own blast radius: the timeout aborted inside an
open act(), leaking an unbalanced act scope that then failed the file's three
remaining tests in ~20ms with 'overlapping act() calls'. One slow import, four reds.

CoolingConnectionsPanel is the one production change. It imported providerText from
the ../providerPageHelpers barrel, but that symbol is DEFINED in the
../providerCredentialText leaf and only re-exported by the barrel — which drags
providerRegistry (352 providers) and the rest of the provider-page graph into a
"use client" component for one string helper. Verified before accepting: the
component used nothing else from the barrel, the barrel has no top-level
side-effect to lose (the empty-registry hazard this repo has hit before does not
apply), typecheck:core is clean, and the panel's first test drops from ~4s to 95ms.
The import was suboptimal, never broken — the screen was not failing for users.

No assertion was weakened anywhere. expect() counts are unchanged (25/25, 4/4) or
up by one (AutoComboCatalog 11 -> 12); the #8855 autofill sentinels, the
data-1p-ignore / data-lpignore guards and the dead-status round-trip are intact.

The #5918 TDZ guard was proven still live by mutation, not by absence of red:
moving useProxyBatchOperations(load) above its const reproduced
'ReferenceError: Cannot access load before initialization' in 207ms, then the
production file was restored (diff empty).

tests/unit/ui under load: 17 failed files / 45 failed tests -> 4 failed files /
4 failed tests, none of them these. The four left are compression-guidance-7530,
compressionPanel, compressionUltraTier and lobe-provider-icons-stepfun, untouched
and uninvestigated.

Refs #10692
2026-08-25 10:27:32 -03:00
Xiangzhe
dd3a0f0189 test(vitest): realign five sibling-test contracts unmasked by the green mcp shard
None of these are cycle regressions. The Vitest job runs test:vitest (mcp shard)
then test:vitest:ui; the mcp shard was failing on a missing glm-5.3-max and aborted
the job before the ui shard ever ran. Fixing that shard this cycle unmasked 34 ui
failures that had been broken since 18-23 Aug — four separate PRs that moved a
contract and updated their own tests but not their siblings.

- ProviderCard gained useRouter() in #10448; four test files render it without
  mocking next/navigation and died on 'invariant expected app router to be mounted'.
  The sibling created alongside #10448 already had the mock — it just was not
  applied to the other four consumers.

- SkillCoverage gained a required config category. The four fixtures in
  agent-skills-page still described only api/cli, so the component read
  config.have off undefined. Values were chosen per scenario rather than pasted:
  full coverage gets 2/2 so its bar stays emerald, the amber fixture gets 3/4 so it
  stays amber. CoverageBar renders api -> config -> cli, so the new bar lands in the
  MIDDLE and the cli assertions moved from index [1] to [2]; without that the cli
  checks would have passed while measuring the config bar. The aria test now pins
  all three bars.

- CliAgentsPage hardcoded AGENT_IDS, which had already drifted once (6 -> 8 with
  omp/letta, per its own comment) and drifted again with prime-agent (#11166). It is
  now derived from CLI_TOOLS. This is why an agent missing from that list is not
  cosmetic: it never enters the status map, defaults to not_installed, and adds a
  phantom card to the filter and count tests. Deriving keeps the fixture in sync by
  construction instead of waiting for the next agent.

- claudeTlsClient asserted proxyUrl was undefined inside a test literally named
  'falls back to env var when per-call proxyUrl not provided' — it pinned the old
  behaviour where testOverride bypassed proxy resolution. #10910 moved resolution
  ahead of the override on purpose ('so test overrides and the real path both see
  it'), so the assertion now checks the fallback the test name promises.

test:vitest:ui goes from 34 failures to 14. The remaining 14 sit in six files none
of this commit touches (AutoComboCatalog, CoolingConnectionsPanel, ProxyRegistryManager
x2, connectionsSearchFilter) plus one claudeTlsClient case that passes in isolation
and only fails in the full run — i.e. cross-file pollution. They need a clean
environment to judge: this devbox resolves part of its tree through a stray pnpm
store and has already produced one phantom failure count this cycle.

Refs #10692
2026-08-25 09:48:12 -03:00
Xiangzhe
e4f730a2b2 fix(release): drain two v3.8.50 base-reds (volcengine vision metadata, antigravity BYOP contract)
Two unrelated real reds on the release tip:

* fix(providers): flag MiniMax M3 as multimodal on the Volcengine Ark plans.
  d732cf615 ("feat(volcengine): add Ark plan providers") added
  volcengine-agent-plan/minimax-m3 and volcengine-coding-plan/minimax-m3
  without supportsVision, breaking the LEDGER-4 invariant that every
  minimax-m3 registry entry except PromptQL (text-only upstream) is flagged
  multimodal. Every other provider carrying the model (opencode-zen,
  opencode-go, bazaarlink, ollama-cloud, codebuddy-cn, trae) sets it.
  Registry metadata defect, not a stale test.

* test(antigravity): align the empty-projectId onboarding test to the
  contract shipped by #11284/#11358 (6de542b9b). That change made an
  onboardUser 200 whose body carries NO cloudaicompanionProject mean Google
  BYOP — no project was created and none ever will be — so it short-circuits
  before the retry loadCodeAssist. The older test still mocked onboardUser
  with the bare { done: true } BYOP shape while asserting the retry path, so
  it pinned a contract that was deliberately moved. The mock now returns a
  real onboarding-success body; every assertion is kept, and the id in the
  onboard body deliberately differs from the expected one so the test still
  proves the projectId came from the retry discovery.

Refs #11284
2026-08-25 08:11:23 +00:00
diegosouzapw
fc0d61950b fix(release): drain the v3.8.50 docs/golden/GLM base-reds and restore a masked assert
Second base-red batch from the release pre-flight, measured on the .113 with a
clean npm ci (the devbox tree resolves eslint-plugin-react-hooks 7.1.1 from a
stray pnpm store instead of the lockfile 7.0.1 and reports 925 phantom errors).

Provider count 350 -> 352, one root cause behind three reds. Two providers
landed this cycle (volcengine-agent-plan, volcengine-coding-plan) without
regenerating the artifacts that quote the count:

  - docs/reference/PROVIDER_REFERENCE.md regenerated (gen:provider-reference).
  - README / AGENTS / llm.txt (+42 mirrors) / package.json description / 4 SVG
    diagrams updated, including the section heading AND the anchor that links to
    it, so the link does not break.
  - tests/snapshots/provider/translate-path.json regenerated. The diff is purely
    additive: 46 insertions, 0 deletions, exactly the two new providers.

GLM effort tiers. #11415 added the explicit glm-5.3-max tier and left two
sibling vitest specs pinning the old 16-model inventory and an empty tier list
for it. Aligned to the shipped contract (inventory order matches glmProvider.ts;
glm-5.3-max declares ["max"]).

Test-masking. Four assert reductions surfaced once the deleted-file signal was
resolved. Three are legitimate and are allowlisted with their reasoning:
#11355 inverted the startup-cooldown contract (preserve future quota cooldowns),
#11280 replaced two unrolled hops with a 3-hop loop that asserts MORE, and the
Gemini 3.5 Flash retirement removed the models those capability asserts described.

The fourth was real masking: #10960 rewrote the oneproxy status test to install a
stream mock, immediately overwrite it with a passthrough to the real fetch, and
assert `calls.length >= 0` — always true. Restored to assert what the test name
claims (the JSON-RPC tools/call carries omniroute_oneproxy_stats and its result
reaches the caller), with a scope note that it pins the MCP client contract
rather than the commander wiring.

Also allowlists the Gemini 3.5 Flash test deletion as _deletedWithReplacement
(the model was retired by 2764812ee4; gemini-models-parser.test.ts pins the new
"excluded from the parsed list" contract), and rebaselines bundleSize
8045 -> 8461 with per-entry measurements — every entrypoint stays far below its
absolute budget.
2026-08-25 07:47:27 +00:00
Diego Rodrigues de Sa e Souza
1d0c5a36db fix(security): match cookie domains by suffix, not substring (#11429)
CodeQL js/incomplete-url-substring-sanitization, alerts #860 and #861:
volcengineConsoleAutoLogin accepted any cookie whose `domain` merely *contained*
"volcengine.com".

That check is an authorization decision, not a string test. The console
auto-login harvests `digest`, `AccountID`, `csrfToken` and `userInfo` out of the
Playwright context and persists them as the operator's Volcengine credentials,
so a cookie set by `volcengine.com.attacker.tld` — or `notvolcengine.com` — was
captured and stored as a provider connection.

Add `matchesCookieDomain()` (open-sse/utils/cookieDomain.ts): exact host or
dot-boundary suffix, leading dots and case normalized on both sides, failing
closed on an empty expected domain. Same shape as the existing
`isAdobeCookieDomain` in adobeFireflyBrowserLogin.ts, which already got this
right.

While sweeping the class, inAppLoginService's cookie capture had the identical
weakness — `c.domain.includes(domain.replace(/^\./, ""))` — with the identical
consequence: a look-alike host's cookie stored as the operator's credential.
CodeQL did not flag it because the expected domain comes from
TOKEN_EXTRACTION_CONFIGS rather than a literal. Both callsites now share the
helper.

tests/unit/volcengine-cookie-domain-suffix.test.ts — 5 tests, red before the
fix, covering the real domains, seven look-alikes, empty/missing input, and the
config-supplied path.

Co-authored-by: Xiangzhe <bakryun0718@proton.me>
2026-08-24 19:44:12 -03:00
PhuongDoan
9464792cfc feat(sse): add glm-5.3-max explicit effort tier (#11415)
Validado em lote combinado (batch-0824g) contra o tip de release/v3.8.50: typecheck:core limpo, gates estáticos OK, 62/62 testes focados passando (23/23 do PR entre glm-5.3-catalog-and-effort-tiers.test.ts e zai-catalog-glm52.test.ts).

Aditivo, espelha exatamente o padrão já existente glm-5.2-max. Obrigado pela contribuição, primeira PR bem-vinda!
2026-08-24 17:23:58 -03:00
Jacob Stoner
ddee064f1b fix(sse): preserve auto scoring order (#11400)
Validado em lote combinado (batch-0824f, junto de #11399/#11402/#11407) contra o tip de release/v3.8.50: typecheck:core limpo, file-size/changelog/complexity/cognitive-complexity OK, 56/56 testes focados passando incluindo os deste PR (tests/unit/combo-task-aware.test.ts).

Remove `auto` da lista de estratégias task-routing genéricas — coerente com o #11399, que também protege a ordem já computada pelo `auto` contra reordenação por outro pós-processamento. Obrigado pela contribuição!
2026-08-24 14:16:04 -03:00
Jacob Stoner
b1fdfd5ea4 fix(sse): preserve auto-selected first target (#11399)
Validado em lote combinado (batch-0824f, junto de #11400/#11402/#11407) contra o tip de release/v3.8.50: typecheck:core limpo, file-size/changelog/complexity/cognitive-complexity OK (abaixo do baseline), 56/56 testes focados passando incluindo os deste PR (tests/unit/8370-priority-affinity-reorder.test.ts).

Aditivo e coerente: protege a ordem já decidida pelo `auto` contra reordenação pelo pós-processamento de prompt-cache-affinity — mesma linha do #11400. Obrigado pela contribuição!
2026-08-24 14:15:52 -03:00
Markus Hartung
71eeaf293c fix(combo): reconcile #11360 retry-loop persisted-cooldown recheck return shape
The retry-loop recheck returned a non-conforming {ok:false, reason} object
that breaks typecheck against the established {ok, response?} contract used
everywhere else in this function. Aligns with the pre-dispatch skip pattern
(return null after fallbackCount++), matching the PR's own intent: skip this
target and move to the next, not error the whole attempt.

This is a live fix — the broken shape reached origin/release/v3.8.50 via
#11360's own squash-merge and was breaking typecheck:core until now.
2026-08-24 12:32:09 -03:00
deploy
8f15b79a84 feat(volcengine): phone/SMS auto-login for console with MFA + identity selection
- Session-based headless login service (volcengineConsoleAutoLogin)
- API: POST /connect {phone} + /code /status /cancel /resend /identity sub-routes
- Dashboard modal: phone → SMS code → MFA step-up → identity selection
- Falls back to the legacy headful manual flow on risk-control/TOTP-binding
- Route guard: connect subtree stays LOCAL_ONLY + spawn-capable
2026-08-24 12:22:00 -03:00
yangsiyuan.rengar
d732cf615d feat(volcengine): add Ark plan providers 2026-08-24 12:21:59 -03:00
Yao Lu
f58e8bef6f fix(opencode): close Muse Responses streams at completion 2026-08-24 12:21:51 -03:00
Nicolas Duran Garces
13e29f2f39 fix(translator): preserve Claude tool call state 2026-08-24 12:21:44 -03:00
Bob.Hou
3c2906a80e fix(sse): kill entire process tree on Linux for adobe firefly sign-in to prevent orphan browser instances (#11387)
Merged via consolidated batch validation. Fixes orphaned browser processes on Linux for Adobe Firefly sign-in: spawns Chrome as a process-group leader (detached:true) and kills -pid instead of the single PID, with self-termination guards. Own test passes.
2026-08-24 12:13:40 -03:00
Bob.Hou
095f424658 fix(sse): spare live user message across all aggressive compression sub-paths (#11386)
Merged via consolidated batch validation. Aggressive compression could collapse the live user's active prompt into a [COMPRESSED:summary] marker; now spares the last user message across all sub-paths (applyAging, fallback summarizer, caveman/lite). Own test passes.
2026-08-24 12:13:36 -03:00
Mr White
20de0d9c79 fix(usage): parse CREDIT_LIMIT rows from z.ai coding-plan quota API (#11378)
Merged via consolidated batch validation. Z.ai's quota API now returns CREDIT_LIMIT rows for GLM Coding Plan subscription keys instead of TOKENS_LIMIT, breaking the dashboard quota card. Own test passes.
2026-08-24 12:13:19 -03:00
MSiva
37e71915db fix(translator): preserve functionCall id in Gemini to OpenAI request translation (#11365)
Merged via consolidated batch validation. Fixes geminiToOpenAIRequest discarding functionCall.id in favor of a random generated id, causing multi-turn tool-call id mismatches against OpenAI-compatible upstreams. Own test passes.
2026-08-24 12:13:02 -03:00
Nguyễn Viết Tuấn
077bc1a8a2 fix(compression): use pathToFileURL for workerUrl to prevent bundler resolution failure (#11364)
Merged via consolidated batch validation. Fixes Webpack/Turbopack production build failure (Module not found: compressionWorker.js) by using pathToFileURL(join(...)) instead of new URL(..., import.meta.url), which static bundler scanning misidentifies as an asset import.
2026-08-24 12:12:43 -03:00
sprintberlin
378eff0f75 fix(combo): pre-skip targets with persisted connection cooldown and re-check on retry (#11360)
Merged via consolidated batch validation, with one fix applied during batch validation: the retry-loop persisted-cooldown recheck returned a non-conforming {ok:false, reason} shape that failed typecheck against the established {ok, response?} contract — aligned it with the pre-dispatch skip pattern (return null after fallbackCount++), matching this PR's own intent (skip the target, don't error the whole attempt). Pre-skips combo targets with a persisted connection cooldown and re-checks fresh before transient retries. Own regression suite (13/13, including the fixed retry-recheck path) passes.
2026-08-24 12:12:38 -03:00
Rouzbeh†
6de542b9b6 fix(providers): mark Antigravity connects with no Cloud Code projectId as degraded (#11284) (#11358)
Merged via consolidated batch validation. Production evidence (VPS docker instance): Antigravity OAuth connects ending without a Cloud Code projectId were persisted as silently active while every model call failed; now persisted as degraded. Own tests pass.
2026-08-24 12:12:33 -03:00
sprintberlin
e1c2b347f9 fix(quota): parse absolute ISO datetime reset timestamps in weekly quota fallback (#11353)
Merged via consolidated batch validation. Fixes GLM/Z.AI weekly quota fallback: parseDayGranularityResetMs only recognized 'reset in N days', dropping the real multi-day cooldown when upstream returns a full absolute ISO datetime. Own repro test passes.
2026-08-24 12:12:26 -03:00
stanley
2af1326adf fix(catalog): add Stealth Ox Alpha (stealth/ox-alpha) to the openrouter free roster (#11337)
Merged via consolidated batch validation. Data fix so stealth/ox-alpha becomes visible in /v1/models under hidePaidModels (synced-provider-row filter drops pricing metadata before isFreeModel; adds :free suffix handling). Own test passes.
2026-08-24 12:11:52 -03:00
Diego Rodrigues de Sa e Souza
12b8df02dd fix(catalog): keep large builds event-loop responsive (#11367)
Merged via consolidated batch validation (worktree `.claude/worktrees/batch-0824d`, 11-PR video-bridge/catalog/ops batch, tip `dafb4ae8`). Fixes the #9147 catalog-scale event-loop regression: reuses one build-local capability snapshot, yields cooperatively during catalog/virtual-pool construction, reads only persisted TTL settings. Static gates: typecheck:core, file-size, changelog-integrity, complexity, cognitive-complexity all green. Own regression test (tests/unit/9147-catalog-eventloop-yield.test.ts) reproduced the RED→GREEN transition in isolated runs per the PR's own evidence; under current shared-devbox load (10-15, multiple parallel sessions) the test intermittently reports INFRA-RED exactly as the PR body pre-disclosed (documented starvation signature, not a code defect). Thanks for the careful RED/GREEN + INFRA-RED discipline.
2026-08-24 09:24:59 -03:00
Erick Kinnee
338c05dc6a fix(models): expose Ollama Cloud native effort tiers (#11307)
Validated on a 17-PR combined board: models-catalog-combo-metadata + ollama-cloud-reasoning-effort-tiers-10788 within the board's 287/287, typecheck:core clean, check:open-sse-typecheck clean, vitest 405/405. Publishes Ollama Cloud's native none/low/medium/high/max effort vocabulary for reasoning-capable passthrough/tagged models with no exact registry declaration, adds none to DeepSeek V4/GLM 5.x, and preserves narrower exact-model vocabularies (GPT-OSS) via intersection. Refs #10788. Thank you @ekinnee!
2026-08-24 01:55:47 -03:00
Ravi Tharuma
9b14896a6c feat(api): add Google AI Studio Gemini TTS (#11315)
Validated on a 17-PR combined board: gemini-tts + vertex-media + audio-speech-handler (41/41) within the board's 287/287, typecheck:core clean. Registers public google/gemini-*-tts speech models and translates OpenAI-compatible /v1/audio/speech to the AI Studio generateContent audio contract, reusing the Vertex inline-audio/PCM/WAV conversion path. Batch TTS only, Gemini Live is out of scope. Thank you @RaviTharuma!
2026-08-24 01:50:44 -03:00
Ravi Tharuma
29f26293c3 feat(compression): isolate sync engines in bounded worker pool (#11318)
Validated on a 17-PR combined board: compression-worker + colocate-standalone-esm-scope within the board's 287/287, typecheck:core clean, env-doc-sync clean. Offloads eligible sync compression engines into a bounded worker_threads pool with a strict serializable DTO boundary and fail-open on spawn/worker/timeout failure. Closes #11023. Thank you @RaviTharuma!
2026-08-24 01:50:39 -03:00
Ravi Tharuma
5ee646e68e fix(github): verify access tokens during health checks (#11320)
Validated on a 17-PR combined board: token-health-check + token-health-no-refresh-token-expired-5326 + token-refresh-service within the board's 287/287, typecheck:core clean. GitHub access-token-only connections are now actively verified on each due health interval (via the existing Copilot token exchange); the parent credential is marked expired only on a confirmed 401, never on 403/429/5xx/network failures; response bodies and transport messages no longer enter token-refresh logs. Closes #10352. Thank you @RaviTharuma!
2026-08-24 01:50:30 -03:00
Diego Rodrigues de Sa e Souza
adca3b881c fix(kie): map remaining google-imagen Market ids to their real KIE upstream ids (#11326)
Merging --admin with red discrimination (merge-gates §4). Fails: ESLint warnings ratchet drift (inherited base-red), Unit Tests shards containing stream-timing.test.ts (CPU-contention timing flake, assert.ok(total >= 15)ms — unrelated to this PR's scope, open-sse/handlers/imageGeneration.ts), and dast-smoke (advisory, isRequired:null).
2026-08-24 01:10:23 -03:00
Diego Rodrigues de Sa e Souza
3192eb88d5 fix(providers): unify learned and declared reasoning-effort clamps on nearest-tier semantics (#11295) (#11305)
Merging --admin with red discrimination (merge-gates §4). 5/6 failing tests are the compression/i18n-vi/kiro/memory mini-cluster fixed by #11306 (this branch predates it). The 6th (token-health-check-kimi, 'jittered expiration window') is a timing-sensitive test — reproduces GREEN locally, name itself indicates randomized jitter, not a deterministic regression from this PR's reasoning-effort clamp change (zero file overlap). ESLint warnings + dast-smoke (advisory, isRequired:null) also inherited.
2026-08-23 22:17:12 -03:00
Diego Rodrigues de Sa e Souza
5518916725 fix(chat): detect severity-classifier format in claudeClassifierCompat short-circuit (#11289) (#11304)
Validated on a 4-PR combined board: claude-classifier-compat 15/15 + 8189-classifier-compat-auto-narrow 5/5 sibling sweep, typecheck:core clean, gates within baseline. Detects the newer Claude Code severity-classifier request shape (stop_sequences carrying </severity>) and replies with <severity>0</severity> instead of the legacy <block>no</block> — the mismatch was failing both classifier stages closed and blocking gated tool calls (Bash, WebSearch). Closes #11289.
2026-08-23 21:34:54 -03:00
Óscar Fonseca
a3c3117254 fix(translator): preserve omitted subagent session IDs (#11297)
Validated on a 3-PR combined board: openai-responses-opencode-subagent-sessionid within the board's 20/20, typecheck:core + check:open-sse-typecheck clean, gates within baseline. Uses null as the omission sentinel for OpenCode's optional default-less subagent.sessionID under Responses/Codex strict mode (which required every declared property) — models can now omit the field to spawn a new child instead of inventing filler IDs; the null is stripped before OpenCode sees the call, real child IDs pass through unchanged. Thank you @ofonseca-pyming!
2026-08-23 21:03:16 -03:00
Diego Rodrigues de Sa e Souza
67fba53190 fix(tests): drain base-red cluster from 2026-08-23 merges (#9985) (#11280)
Validated on a 2-PR combined board: 158/158 across the drain's 17 focused test files (incl. integration qdrant-routes), typecheck:core + dashboard-typecheck clean, env-doc-sync, mutation-test-coverage, cli-i18n, file-size, changelog-integrity all green. Every red discriminated per-item as stale-test (contract intentionally moved, citing the origin PR) or real bug (fixed, never masked) across 3 base-advance waves (#9985): stryker registration, i18n gaps (health.* namespace mismatch + pt-BR parity), combo-token-window pins (872K), CLI catalog counts (prime-agent), the isComboStep single-target reasoning-transport-fallback regression, container-guard hermeticity, and 26 unsuppressed ESLint errors from the wave (typed qdrant adapter, import trim, justified disable with precedent). Drains the accumulated base-red cluster.
2026-08-23 20:32:46 -03:00
Diego Rodrigues de Sa e Souza
9cb91dee74 fix(security): close round-3 advisories (v7g9, x7vm, j7j4, jcm5) + exposure warning (wmgv) (#11261)
Validated on a 2-PR combined board: routeGuard 36/36 (within the 68/68 focused-file total), a2a-task-owner-idor 7/7, a2a-tasks-auth, search-baseurl-ssrf-guard, cli-serve-hostname, spawn-capable-prefixes-client-safe all green, typecheck:core + dashboard-typecheck clean, gates within baseline. Five real High-severity advisories fixed with TDD (each failing-then-passing): settings export/import-json ALWAYS_PROTECTED completion, MITM route LOCAL_ONLY+SPAWN_CAPABLE gating, search baseUrl SSRF/IMDS guard, A2A REST task auth+ownership (previously none at all), and the loud boot exposure warning. GHSA-cjv9 confirmed already closed on this base (verified). Round 3 of the advisory sweep.
2026-08-23 20:32:42 -03:00
Diego Rodrigues de Sa e Souza
2904cf849d fix(security): clear new CodeQL code-scanning alerts (round 4) (#11293)
- open-sse/executors/github.ts: replace the Math.random() fallback in
  the Copilot correlation-id generators (x-request-id,
  x-interaction-id, x-client-session-id, x-agent-task-id) with a
  CSPRNG-backed randomIdFallback() (node:crypto randomBytes) — closes
  js/insecure-randomness with no behavior change (crypto.randomUUID
  stays the primary path).
- tests/unit/cli/_helpers/shellArgs.mjs: collapse the two sequential
  global .replace() unescape passes into a single left-to-right regex
  replace with alternation — closes js/double-escaping. The prior
  two-pass form let the first pass's output feed the second, which is
  exactly the double-(un)escaping bug pattern the query flags (e.g. an
  escaped-backslash-then-quote sequence could be misread depending on
  pass order).

Co-authored-by: Markus Hartung <mail@hartmark.se>
2026-08-23 19:06:53 -03:00
backryun
2764812ee4 fix(providers): eliminate Gemini 3.5 Flash 2026-08-23 18:13:11 -03:00
Marcel Wysocki
29caad9f3d feat(sse): discover Anthropic partner models on Vertex AI (#11279)
Validated on the combined 8-PR board + the branch itself: vertex-anthropic-models 4/4 (new — pushed to your branch as a fix-in-place commit per Hard Rule #8, covering the parser's global/project-scoped resource names, malformed-input handling, and the claude-* → targetFormat heuristic on vertex/vertex-partner), 88/88 across the board's focused suites, typecheck:core clean, gates within baseline. Anthropic partner models on Vertex AI now discover dynamically via the Model Garden publisher endpoint and route through the Claude translator even for models outside the static registry. Thank you @maci0!
2026-08-23 18:12:37 -03:00
Praveen K Palaniswamy
6d4c4843e9 fix(ollama): route models by advertised capability (#11087) — port of #11088 to the release line (#11271)
Validated on the combined 8-PR board: ollama-local-capabilities-routing 3/3, managed-model-import 9/9 (including the integration with the carried Gemini-3.5-Flash cleanup from #11259), 88/88 across the board's focused suites, typecheck:core + dashboard-typecheck clean, gates within baseline. This brings #11088 to the release line — it had squash-merged to main by base error (mine) — AND fixes the two defects the port caught: the global filter drop that leaked image/video models into OpenAI chat selections (now scoped to self-hosted providers) and the unregistered hard-lease credential site. Exemplary port discipline: byte-identical carry + the corrections in a separate reviewable commit + the superpowers docs deliberately left out. main still needs the same two-line fix. Thank you @yourspraveen!
2026-08-23 18:11:21 -03:00
Harvey Doan
9adeb3b673 fix(providers): clamp reasoning_effort to the declared vocabulary of models that expose one (#11274)
Validated on the combined 8-PR board: the declared-vocabulary clamp integrates with #11232's learned-set clamp (both fire in sequence; REASONING_EFFORT_ORDER import added), reasoning quartet 57/57 including the new opencode-go suite 7/7, 88/88 across the board's focused suites, typecheck:core + dashboard-typecheck clean, all static gates within baseline. Retargeted main→release/v3.8.50 and rebased onto the release tip (authorship preserved; the branch carried main history, so only the real commit was carried). The generic explicit-capability clamp closes the Console Go 400 [1210] loop for models with a declared effort vocabulary. Thank you @linhdmn — the live-probe table in the PR body is exactly the evidence standard we want.
2026-08-23 18:10:21 -03:00
Armin Anton” ∴
10276821cd Integration: security tier + self-hosted operator blockers (rebased onto v3.8.51) (#10952)
Validated on the resolved merge against the current tip (527da656 + the post-#11281 rebaseline): the single conflict was a comment-only collision in providers/[id]/models/route.ts (kept the tip's #10828-ordering note). Focused suites 125/125 across all 13 touched test files (build-sqlite-stub, cc-compatible, copilot-claude-messages, copilot-gemini-route, executor-github, ghe-copilot, github-copilot-discovery-token, github-copilot-model-discovery, noauth-sibling-7620, provider-header-profiles, provider-models-config, request-log-payloads, upstream-error-passthrough), typecheck:core clean, file-size/changelog-integrity OK. Merged --admin over the inherited 2026-08-23 base-red cluster (#9985) — the reds are proven tip failures (CLI catalog cluster + @testing-library allowlist, being drained by #11280), not from this diff. Note: the rebase means several items the body listed (relay x-relay-path SSRF, /v1/search blocked-providers, #10736 rotation fence, #10903, #10865, #10899, #10916) already landed upstream and are NOT in this delta — the delta is: better-sqlite3 build guard + build heap/worker caps + telemetry-off (#10060 re-derived), credential-echo passthrough refusal + OCR/moderation redaction + call-log key redaction, Copilot CLI 1.0.81-6 wire identity + Claude→/v1/messages name-matched routing + discovery token fix, CC model_not_found 400, compat overrides for no-auth aliases (#7620-pinned). The Copilot wire-identity change is the one to watch in production. Thank you @arminanton — and the ported-author credits in the commit history (@rqzbeh, yidecode, the #10899/#10916 authors) are preserved. Your config-posture finding (REQUIRE_API_KEY default vs 0.0.0.0) is noted for a maintainer decision, as you scoped it.
2026-08-23 16:51:25 -03:00
Diego Rodrigues de Sa e Souza
bdf63d2171 fix(security): harden codex app-server transport (#11205 post-merge review) (#11281)
TDD: 4 red-to-green tests reproducing the two review findings + 6 new cases; 30/30 in tests/unit/codex-app-server.test.ts; typecheck/eslint/env-doc-sync/file-size clean. Merged --admin over the inherited 2026-08-23 base-red cluster (#9985): the remaining reds (CLI catalog/registry tests, @testing-library allowlist) are proven tip failures unrelated to this diff — shard logs show only CLI-cluster failures, and this PR itself drains the mutation-test-coverage red (stryker registration for #11267's test). Behavior change for app-server deployments is documented in the PR body (sandbox default + binding refusal).
2026-08-23 16:49:19 -03:00
Diego Rodrigues de Sa e Souza
d077e88456 fix(providers): complete Hack Club AI removal from shared catalog (#11176) (#11262)
* fix(providers): complete Hack Club AI removal from shared catalog (#11176)

PR #11118/#11123 removed hackclub from the open-sse REGISTRY but the
canonical shared catalog kept the entry, so the dashboard, alias resolver,
icon registry, onboarding i18n strings and the generated provider reference
kept advertising a provider the router no longer serves.

Removed:
- APIKEY_PROVIDERS hackclub entry (id + "hc" alias) in apikey/gateways.ts
- hackclub from ProviderIcon KNOWN_SVGS + public/providers/hackclub.svg asset
- providers.onboardingProviderDescriptions.hackclub from all 43 locales
- stale comments referencing hackclub as a living provider (web-cookie.ts,
  registry/huggingchat, registry/g4f-groq, registry/freetheai, test prose)

Count cascade 351 -> 350 (measured per-file; the live catalog union across
all 11 provider collections goes 351 -> 350):
- README.md, AGENTS.md, llm.txt + 42 i18n llm.txt mirrors (byte-identical
  bodies, docs-sync gate green), package.json description
- docs/reference/PROVIDER_REFERENCE.md regenerated (gen-provider-reference)
- canonical numbers in readme-hero/promise-pillars/comparison-table/
  cli-terminal SVGs (docs-counts-sync STRICT gate green)

Kept intentionally (historical records, not catalog):
- CHANGELOG.md + docs/i18n/*/CHANGELOG.md entries from when the provider
  was added (#2339, #2611) — release history
- src/lib/db/migrations/162_remove_hackclub_provider.sql — the removal
  migration itself
- tests/unit/remove-hackclub-11118.test.ts — the REGISTRY removal guard

Validation: new tests/unit/hackclub-removed.test.ts (5 asserts: catalog
absence, hc alias free, structural grep over provider sources, icon/asset
gone, i18n key gone) fails before / passes after; provider sibling tests
46 pass; provider-catalog consumer batch 268 pass; typecheck:core clean;
eslint clean on touched files; check:provider-consistency OK (350
canonical); check:docs-counts-sync + check:docs-sync green.

Closes #11176

* test(providers): align APIKEY split count after hackclub removal (232 -> 231) (#11176)

---------

Co-authored-by: Xiangzhe <bakryun0718@proton.me>
2026-08-23 14:40:12 -03:00
Dizzle
00c80fd14a feat(models): surface learned reasoning_effort sets in catalog, variants, and dispatch (#11252)
Validated on the combined 12-PR batch board + the resolved merge against the post-#11232 tip: focused suites 73/73 (learned-reasoning-effort-caps, synced-capabilities-learned-effort-override, synced-effort-suffix-learned-validation, effort-tiers-loop-catalog-e2e, reasoning-effort-clamp-and-retry, reasoning-effort-learned-capability) + opencode-plugin effort-tier-variants 4/4, typecheck:core clean, gates within baseline. The stacked-branch conflict after #11232 squash-landed was resolved by hand (the learned-caps module keeps both the Set API and the new model-scoped lookup). The effort_tiers loop is closed end-to-end: catalog advertises exactly what the upstream accepts, and -<tier> suffix variants resolve against the learned set. Thank you @maxmad64bis!
2026-08-23 14:38:57 -03:00
Diego Rodrigues de Sa e Souza
92a083ab8c fix(resilience): honor dashboard quota snapshots in opencode-go preflight (#11234) (#11267)
The opencode-go quota preflight ignored the dashboard quota snapshots, so
priority combos kept selecting connections whose weekly window was already
drained. Two gaps, two fixes:

A) fetchOpencodeQuota only consulted the live upstream endpoint, which has
   no public quota API (404 — the module JSDoc already admits this). Every
   preflight therefore evaluated null and proceeded (fail-open) even with a
   connection at 0% weekly remaining in plain sight on the dashboard. The
   fetcher now synthesizes its triple-window QuotaInfo from the cached
   dashboard snapshots when the live endpoint yields nothing, mapping
   session→window_5h, weekly→window_weekly, mcp_monthly→window_monthly and
   mirroring getQuotaWindowStatus semantics (expired resetAt = window rolled
   over = must not count as exhausted; fractionReported=false = unknown,
   never exhaustion). Read-only via src/domain/quotaCache.ts accessors —
   never SQL, never a re-scrape on the hot path — and gated on the
   connection actually having dashboard scrape config, so unconfigured
   connections never touch the snapshot store. Fail-open is preserved:
   no snapshots → null, exactly as before. The quotaCache import is dynamic
   because a static edge would close an initialization cycle
   (fetcher → quotaCache → usage.ts → usage/opencode.ts → fetcher).

B) The sibling-selection latency gate in getProviderCredentialsWithQuotaPreflight
   never consulted resilience.quotaPreflight.enabled
   (QUOTA_PREFLIGHT_CUTOFF_ENABLED) — that flag only armed the auto-strategy
   candidate builder and the per-target cutoff for pinned connections, so a
   priority combo over sibling opencode-go connections (connectionId null at
   combo level) skipped preflight entirely. The flag now arms the gate as
   well; the default (flag off) is unchanged.

TDD (Hard Rule #18), tests/unit/quota-exhaustion-cutoff-opencode.test.ts:
- fetcher 404 + seeded snapshots weekly=0%/session=80% → cutoff blocks
  (RED before, GREEN after); also asserts the bridge is read-only (single
  upstream fetch, no re-scrape).
- weekly 0% with next_reset_at in the past → not blocked (window dropped).
- per-window threshold override resolves against the mapped window_weekly
  key (50% override blocks at 40% remaining; factory 2% does not).
- fail-open guard: configured dashboard with no snapshots still returns null.
- selector level: flag on, two opencode-go sisters, priority-1 exhausted →
  selection skips to the healthy one (RED before, GREEN after).

Sibling suites green: opencode-quota-fetcher (18), quota-preflight,
combo-priority-quota-exhaustion-cutoff-5923, issue-6686, 8431, throttle-6911,
sse-auth*, quota fetchers, combo strategies, snapshot/hydration tests
(~500 tests). eslint (with suppressions) and typecheck:core clean.

Closes #11234

Co-authored-by: Xiangzhe <bakryun0718@proton.me>
2026-08-23 14:28:19 -03:00
Diego Rodrigues de Sa e Souza
5cf16028fe fix(cli): real OpenRouter key validation + auth export argument wiring (#11226) (#11264)
Two defects exposed by #11226 (the 401 "User not found." itself is upstream
OpenRouter's response to a bad key — not an OmniRoute bug):

1. OpenRouter key validation was vacuous. Both the dashboard Check (via
   validateProviderApiKey -> validateOpenAILikeProvider) and 'omniroute
   providers test' (bin/cli/provider-test.mjs) probed /api/v1/models, which is
   PUBLIC and answers 200 to any key — so invalid keys were saved/marked valid
   and only failed on real chat traffic. OpenRouter's authenticated key-info
   endpoint (GET /api/v1/auth/key, 200 = valid / 401 = invalid) is now the
   probe: registered as testKeyModelsUrl on the openrouter registry entry
   (same mechanism as perplexity) and as keyCheckPath in the CLI test configs.
   No other provider's probe changes; error results keep using canned strings,
   never the raw upstream body (Hard Rule #12).

2. 'omniroute auth export' crashed with "cmd.optsWithGlobals is not a
   function". .command("auth export") does not register a two-word command:
   commander parses the bare word 'export' as a required positional argument,
   so the action received (exportArgValue, options, command) while expecting
   (options, command). Registered 'export' as a proper nested subcommand of
   'auth' — the documented CLI surface 'omniroute auth export [--force]
   [--id] [--format] [--out]' is unchanged, and unknown positionals
   (e.g. 'omniroute auth bogus') are now rejected instead of silently running
   the export.

TDD: tests/unit/openrouter-key-validation-auth-endpoint.test.ts (stub mimics
the real OpenRouter: /models public-200, /auth/key 401 'User not found.') and
tests/unit/cli-auth-export-wiring.test.ts (real commander wiring via
createProgram) were RED before the fix and are GREEN after.

Co-authored-by: Xiangzhe <bakryun0718@proton.me>
2026-08-23 14:26:08 -03:00
Paco Cartones
a55ee5dc05 feat(combo): make the global attempt budget operator-configurable (#11134) (#11239)
Validated on the combined 12-PR batch board: combo-max-global-attempts-config 4/4 plus the neighboring combo suites green, typecheck:core clean, gates within baseline. clampGlobalAttempts mirrors clampComboDepth with a 200 hard cap, so a bad config can never disable the budget. Closes the configurability item from #11134. Thank you @pacocartones!
2026-08-23 14:24:45 -03:00
Diego Rodrigues de Sa e Souza
158c6ec233 fix(embeddings): honor configured LM Studio connection URL via lm-studio alias (#11233) (#11260)
The dashboard stores LM Studio connections under the hyphenated provider id
"lm-studio", but the embedding registry keys the provider as "lmstudio"
with no alias. As a result, "lm-studio/<model>" embedding requests failed
with a 400 unknown-provider error, and "lmstudio/<model>" requests always
hit the hardcoded http://localhost:1234/v1/embeddings endpoint, ignoring the
baseUrl of the configured connection.

Mirror the ollama-local pattern from #2824/#9225:

- embeddingRegistry: add "lm-studio" -> "lmstudio" to
  EMBEDDING_PROVIDER_ALIASES (registry key unchanged so existing
  "lmstudio/<model>" clients keep working).
- embeddings service: extend the optional keyless-connection hydration to
  lmstudio; getProviderCredentials("lmstudio") already resolves the
  "lm-studio" connection via the provider search pool/alias, and a
  selection/rate-limit failure still proceeds without credentials.
- embeddings handler: apply the same baseUrl override + normalization
  (strip trailing slashes and /v1, /v1/chat/completions, /v1/embeddings
  suffixes, then rebuild <host>/v1/embeddings) to lmstudio, keeping the
  static localhost fallback when no connection or empty baseUrl.

TDD: tests/unit/lmstudio-connection-baseurl-11233.test.ts failed on the
alias, override and service-hydration asserts before the fix and passes
after; ollama-local (#2824) and lmstudio registry (#7601) sibling tests
remain green.

Co-authored-by: Xiangzhe <bakryun0718@proton.me>
2026-08-23 14:23:52 -03:00
Dizzle
a054ac408f feat(providers): allow per-connection maxWaitMs rate-limit override (#11251)
Validated on the combined 12-PR batch board: focused node:test suites green (incl. provider-rate-limit-overrides-schema + ratelimit-admission-control-6593 isolated 11/11 + the new EditConnectionModal vitest 3/3), typecheck:core clean, all static gates within baseline. Pushed one follow-up commit to your branch with the real Vietnamese translations for the two new keys (repo convention: vi never ships __MISSING__ placeholders). Per-connection maxWaitMs override lands, folding the zai-web exception into the general mechanism. Thank you @maxmad64bis!
2026-08-23 14:21:55 -03:00
Dizzle
7fdd2e0f2a fix(sse): learn accepted reasoning_effort sets and clamp downgrade-only (#11232)
Validated on the combined 12-PR batch board (worktree off origin/release/v3.8.50 @ 8f390eff): focused node:test suites 183/184 (the single red was a load-induced pollUntil flake — 11/11 when re-run isolated, this file included), typecheck:core clean, file-size/changelog/complexity/cognitive gates all within baseline, mutation-coverage gate no-drift. Learned effort sets now cost at most one 400 per provider+model. Thank you @maxmad64bis!
2026-08-23 14:21:27 -03:00
Armin Anton” ∴
8f390efffd feat(codex): self-contained codex app-server transport (executor + provider + sign-in) (#11205)
Merged after conflict resolution: the 5 conflicting test files were the base-red drains that #11201 already landed on the tip — kept the tip versions; the feature content is untouched. Validated on the combined batch board + this branch: codex-app-server + codex-gpt56-catalog 25/25, typecheck:core clean, docs-counts green (351 providers), provider-consistency 268/351/0. The opt-in codex-app-server transport (JSON-RPC-over-WS, turn/completed-awaited close, Responses SSE bridge) leaves the default codex path untouched. Thank you @arminanton — a 3.4k-line transport with the docs wave and tests to match!
2026-08-23 10:20:06 -03:00
adevwithpurpose
90ba281e7f fix(sse): default single-target incompatible reasoning to drop for agentic replay (#10959) (#11178)
Merged after conflict resolution onto the post-#10961 tip (verified no clobber of today's plaintext-wins work — the resolver functions were appended and the chatCore call-site swapped; a first --theirs attempt was caught reverting #10961 and redone hunk-by-hunk). resolveIncompatibleReasoningAction now defaults single-target incompatible reasoning to drop while combos keep their explicit strategy, with the x-omniroute-reasoning-fallback header override. 21/21 reasoning suites green, typecheck clean. Fixes #10959. Thank you @adevwithpurpose!
2026-08-23 10:00:17 -03:00