* feat(sse): add it/ru/zh caveman output instructions
* fix(sse): expose the dormant terse-prose translations through the catalog
* feat(sse): translate less-code to es/de/fr/it/ru/zh
* feat(sse): translate ponytail to es/de/fr/it/ru/zh
* feat(sse): translate i-have-adhd to es/de/fr/it/ru/zh
* test(sse): anchor wave-2 output-style translations to their own language
* feat(dashboard): offer every output-style language in the default-language selector
* feat(sse): let autoDetect pick the output-style instruction language
* docs(compression): consolidate the output-style tables and record full language parity
* fix(sse): trust finish_reason:length/max_tokens over the reasoning-ratio heuristic in response quality validation
A truncated response with empty content and reasoning_content present was
only rejected by validateResponseQuality() when reasoning consumed >=90%
of completion_tokens. A response truncated at a lower ratio (e.g. 63%)
passed through as "valid" even though the caller received no usable
content and finish_reason was explicitly "length" (or the alternate
"max_tokens" naming some providers use) -- an unambiguous truncation
signal the validator wasn't reading. Reproduced live against
nvidia/nemotron-3-super-120b-a12b: content:null, finish_reason:length,
reasoning_tokens 645/1024 (63%).
Trust finish_reason directly when it's reported, falling back to the
existing token-ratio heuristic only when it isn't. Does not affect the
deliberate-tiny-probe case (e.g. max_tokens:1 connectivity pings) --
those never produce reasoning_content, so the branch this change is in
doesn't run for them.
* docs(changelog): add fragment for #12262
---------
Co-authored-by: brick30llc-ctrl <admin@brick30.com>
getPersistedConnectionCooldownSkipReason() returned a skip for ANY connection
whose testStatus was `unavailable`, with no elapsed-cooldown check:
if (status === "unavailable") return `Skipping ...`;
That is the raw-label anti-pattern AGENTS.md warns about ("check whether code
is reading raw state instead of using getStatus()/canExecute()") — the
resilience layers are meant to recover lazily. The sibling helper directly
above it, getConnectionStatusQuotaCutoffReason(), does require
hasFutureRateLimitUntil() before treating `unavailable` as blocking.
Its stated justification — "Lazy recovery is unaffected: clearAccountError()
resets the status on first success" — does not hold on this path. This gate
runs BEFORE dispatch, so it prevents the very successful request that would
call clearAccountError(). And a row whose rateLimitedUntil is absent cannot be
rescued by the out-of-band recovery job either, because hasElapsedCooldown()
there requires a timestamp to be present.
Net effect reported in #12168: an entire combo pool answering
ALL_TARGETS_SKIPPED with recordedAttempts === 0 — zero upstream attempts, no
path back to healthy.
The original intent (do not burst into a connection AUTH just retired, before
the timestamp lands) is preserved, but bounded: the bare label is honoured only
while lastErrorAt is inside a grace window, mirroring ERROR_LABEL_GRACE_MS in
src/lib/quota/connectionRecovery.ts so the two never disagree about whether a
label is still meaningful. Past the window the request goes through, and one
real attempt either succeeds (clearing the status) or re-arms the cooldown with
a fresh timestamp.
Regression introduced by #11360, shipped in v3.8.50.
Two assertions in repro-combo-persisted-cooldown-preskip.test.ts encoded the
buggy behavior as intended ("skips an unavailable connection whose cooldown
already expired") and are realigned to the corrected contract, plus a case for
the orphan state (unavailable with no timestamps at all).
providerFailureThreshold / providerFailureWindowMs / providerCooldownMs shipped
in PROVIDER_PROFILES with no runtime consumer (2026-08-31 docs audit, P0.1).
Provider-level entries in providerCooldownTracker now honor them: the whole
provider only counts as cooling after providerFailureThreshold failures inside
providerFailureWindowMs, then cools for providerCooldownMs. Connection-level
entries keep the pre-existing exponential backoff, and the layer stays opt-in
(PROVIDER_COOLDOWN_ENABLED, default off) — default behavior is unchanged.
TDD: tests/unit/provider-cooldown-window-gate.test.ts written first (4 red on
the old behavior), then the wiring; legacy tracker suite aligned to the new
contract (23/23 green). Docs: AGENTS.md breaker section + RESILIENCE_GUIDE
opt-in layer subsection; executors soft-drift refresh (104 -> 106).
dispatchWithCooldownRetry arms a loop-safety timer (setTimeout, 10 minutes by
default) on every setTry iteration, so a combo that never produces a terminal
response still answers with a 504 instead of hanging. The only clearTimeout in
the whole file sat inside the `if (anySuccess)` branch — the comment said so
verbatim: "clear the safety timer on the happy path".
Every error exit therefore returned the response to the client while leaving a
600s timer pending, its closure retaining orderedTargets and the exhausted
provider/connection sets: all_targets_skipped, all_accounts_inactive, the
aggregated-status return, the final fallback, and the global-timeout branch.
The timer is also re-armed per setTry iteration with no clear in between.
Field evidence from the issue: two requests that failed quality validation
returned 502 to the client immediately, and "Combo loop safety timeout ...
force-terminating" was logged for both exactly 600 seconds later — the leaked
timers firing long after the requests were gone.
Fixed structurally rather than by sprinkling clearTimeout across the five
return sites: the handle is hoisted to function scope and released in a
finally, so a future `return` added to this function cannot silently
reintroduce the leak. The 504 backstop itself is unchanged.
Note the timer already called .unref(), so it never held the event loop open —
this is a memory-retention leak, not a hang.
Refresh the existing MIT-licensed miuuyy/codex-chatgpt-web vendor snapshot and its OmniRoute integration as one reviewable change.
Co-authored-by: backryun <backryun@daonlab.local>
* feat(usage): add Kilo Code balance and Kilo Pass quotas
* feat(usage): add Kilo Pass dashboard meter
* test(usage): cover Kilo Code quota integration
* docs(usage): document Kilo API endpoint override
* perf(sse): defer cloneLogPayload until after SSE collector cap check
Dropped SSE events no longer pay the structuredClone cost. The clone now
runs only for events that survive the maxEvents/maxBytes cap, eliminating
~9,800 wasted deep clones per streaming response (65-71% faster push).
Reducer snapshot isolation restored:
- OpenAI reducer stores first-chunk primitives instead of a chunk reference
- Responses reducer snapshots only needed fields, deep-cloning nested output/metadata
- getEvents() keeps defensive-copy semantics via cloneLogPayload
* chore: add changelog fragment for #12241
Local process execution failures (ENOENT spawn errors, binary missing, EPIPE, exit codes) were incorrectly treated as upstream provider failures, opening provider circuit breakers and cooling down valid connections. Added `isLocalExecutionError` guard to skip circuit breaker trips and connection disables when local host execution fails.
resolveWorkerPath() had two return branches: a process.cwd()-anchored
primary path and an import.meta.url-relative fallback. Turbopack's
dev-mode static worker-chunk detector partially resolves the
new URL(literal, import.meta.url) construct in the fallback branch
independent of which branch actually runs at runtime, producing an
inconsistent module graph node. turbo-tasks then panics on startup
with either 'inner_of_upper_lost_followers...' (aggregation_update.rs)
or 'there must be a path to a root...' (module_graph/mod.rs), and
Restart=on-failure just silently retries forever.
git bisect (443c96d28 good .. b7a0c5413 bad, 418 commits, 9 steps)
isolated this to 657d3a484 (#11732). Confirmed by isolation probe:
removing the Worker construct, or inlining a single non-branching
new Worker(new URL(literal, import.meta.url)) at the call site, both
avoid the panic; only the two-branch resolver does not.
The import.meta.url fallback was also silently dead in production:
the standalone bundle (webpack) freezes import.meta.url to the
build-machine path -- the same app-wide gotcha already documented on
GATE_DEP_REL in llmlingua/worker.ts's fail-open probe. Dropping that
branch fixes both problems with the same change: process.cwd() alone
is correct in every real runtime layout this app uses (dev via
run-next.mjs, and the production standalone bundle, where
outputFileTracingIncludes already copies the worker script preserving
its process.cwd()-relative path).
Verified live:
- Dev (Turbopack): npm run dev reaches '[Next] dev server listening on
...' cleanly; previously panicked and looped under Restart=on-failure.
- Standalone build: npm run build produced a clean webpack compile and
a working .build/next/standalone/open-sse/lib/deepseek-pow-worker.mjs
at the traced path; running the real solveDeepSeekPowAsync from cwd =
the standalone dir spawned the worker and returned the correct nonce
for a fabricated DeepSeekHashV1 challenge.
- node --test tests/unit/deepseek-pow-js-only.test.ts
tests/unit/deepseek-web.test.ts: 44/44 passing.
- eslint and tsc --noEmit: clean on the touched file (tsc's remaining
errors are pre-existing, in unrelated test files).
The leading system message was read as `typeof content === "string" ?
content : ""`, so a Chat-Completions content-part array — valid for
`system`, and what every prompt-caching client sends — collapsed the
whole system prompt into an empty `instructions`. Upstream accepted the
request and reported a normal prompt_tokens count, so the model answered
with no instructions at all and nothing in the response said so.
Mid-conversation system turns already handled the array shape (#7056);
only the first one did not. Reuses buildResponsesTextParts() and joins
the text parts, since `instructions` is a string rather than a part array.
Co-authored-by: Vadim Zhyvylo <zhyvylo@involve.software>
* fix(api): keep registry width and type on embedding models
* docs: changelog fragment for embedding registry fix
* test(api): cover embedding width and type merge
Exercises /v1/models rather than the registry in isolation: a synced
model colliding with an embeddingRegistry entry must keep the width the
registry states, and a synced model the registry names must be typed as
an embedding model.
Fails on catalog.ts before e7fbb62 (2 failures), passes after.
Refs #11759
Add a direct low-level mode for users who require explicit control over provider selection. score selects the highest configured weighted score directly while reusing the existing exploration rate.
Exact ties preserve configured candidate order. rules and all other strategies remain unchanged.
- streamReadiness: reset deadline on each received chunk (keepalive = alive)
with a hard maxTimeoutMs ceiling so truly-dead connections still fail fast.
Preserves operator's 20s/100s intent for dead pulls while allowing slow-but-alive
upstreams (reasoning warm-ups) to survive.
- chatCore + codexIdentity: auto-detect Claude Code CLI via user-agent/originator
headers and enable model echo for it. The response field now echoes
the originally-requested alias/combo (e.g. ) instead of the
resolved upstream id (e.g. ), so restores
cleanly without 'could not be restored' errors.
Refs: opensource-elearning/omniroute-fixes#1, diegosouzapw/OmniRoute#12185
Fase 2 da auditoria código×docs 2026-08-31: ~90 divergências corrigidas em README/llm.txt(+42 espelhos)/SVGs/AGENTS.md/25+ docs; correções semânticas (breaker 8/12/2 + DEGRADED, webhooks sem eventos fantasma, ROUTE_GUARD_TIERS completo, API_REFERENCE sem fantasmas, reasoning 200); gate check:docs-counts endurecido (versão em prosa, patterns anti-evasão, superfície +llm.txt/mcp-server/omni-mcp/tier-flow) +5 testes; fonte do gerador de agent-skills corrigida (107/32 → 110/33) e mesma família varrida do Copilot prompt, 39 locales, skills/README, CONTRIBUTING e 2 guias.
* fix(ci): clear the base-reds the 2026-08-30 afternoon merge batch left on release/v3.8.51 (round 5)
- docs-counts / check-docs-counts-sync test: #12103 (Perplexity Agent) made it 352
providers; README, AGENTS.md, llm.txt (+42 i18n mirrors), package.json description
and the 4 README diagrams still said 351.
- api-route-typecheck: #11971 passes a third `{ featureEnabled }` argument to
appendNoThinkingVariants() that the helper never accepted (TS2554 — and the flag
silently did nothing); the helper now honours it. src/lib/skills/interception.ts
narrowed a mapped object with a `Record<string, string>` predicate (TS2677) —
predicate typed with the actual element shape.
Gates: check:docs-counts OK (test 28/28), check:docs-sync PASS, check:api-typecheck
OK (289 frozen). Refs #12103, #11971
* docs(env): document RATE_LIMIT_EXECUTION_MAX_WAIT_MS (#12027 added it to .env.example only)
* fix(ci): round 5b — freeze the react-hooks compiler-rule violations, align 7 tests to merged contracts
No new ESLint warnings: the exact CI command (lint:json --max-warnings 0) reports 278
problems on the tip — 226 from eslint-plugin-react-hooks 7 compiler rules
(set-state-in-effect 167, immutability 36, refs/static-components/purity/
preserve-manual-memoization) that were masked until the lockfile change of
dfc84ba030 invalidated the ESLint cache, plus 46 no-explicit-any in
tests/unit/call-log-cap.test.ts (#12026). Velocity phase: frozen with
`eslint --suppress-all` (+668 suppressions); the 5 now-unused
`eslint-disable react-hooks/immutability` directives and one unused import removed.
Verified: lint:json --max-warnings 0 → 0 problems.
Tests aligned to contracts merged this afternoon (all reproduced red on the pure tip):
- providers-constants-split: 235 → 236 (Perplexity Agent, #12103)
- sse-auth: a forced pin outside allowedConnections now yields no credential
instead of silently falling back (#12080)
- with-chat-admission-10786: withInjectionGuard(postHandler, { logger: null }) (#12117)
- hard-session-lease-bypass-inventory: classify src/app/api/oauth/codex/import/route.ts (#12116)
- usage-service-hardening: OpenCode Go official usage API shape (#12124)
- i18n placeholder parity: apiManager.restrictedToConnections rewritten as a plain
ICU plural (`{count, plural, one {# connection} other {# connections}}`) in en,
vi, pt-BR and the 40 __MISSING__ mirrors — the parity extractor counts every
`{word}` including the old literal `{s}`
Refs #12103, #12080, #12117, #12116, #12124, #12026
* fix(ci): run the ESLint warnings job on the box with an 8 GB heap; reserved-prefix set 398 → 400
The cold full lint with the react-hooks 7 compiler rules is killed on the 7 GB hosted
runner with no message (status null → exit 1, JSON never written) — it only looked
green while the ESLint cache was warm. tests/unit/provider-node-reserved-prefix.test.ts
aligned to the two prefixes the afternoon batch registered (#12103).
* test(ci): document the lint-guard runner exception; #9147 event-loop gap 400 → 800 ms
quality-rail-gate-membership pinned lint-guard to ubuntu-latest; the cold full lint is
OOM-killed there, so the job now runs on omni-light with an 8 GB heap — the test keeps
fast-gates pinned and asserts the documented exception. With the catalog at 352
providers the hosted shards measure 410–633 ms gaps on 9147-catalog-eventloop-yield
(3 runs); 800 ms still fails a true pin. Re-tighten with the v4.0 catalog split.
* chore(quality): summarize the ESLint report on failure — a red lint:json printed nothing
--format json --output-file swallows every problem; a red 'No new ESLint warnings' job
gave zero output (three blind debugging rounds in #12144), and a killed process (OOM,
status null) was equally silent. On any non-zero exit the runner now prints the problem
count and the first 60 'file:line rule — message' lines from the report.
* chore(lint): freeze react-hooks/immutability for the 5 UI test harnesses in the suppressions file
The rule fires for these files in CI but not locally (compiler analysis divergence),
so the inline eslint-disable directives read as 'unused directive' warnings locally.
A suppressions entry is symmetric: suppressed where the rule fires, tolerated as
unpruned (--pass-on-unpruned-suppressions) where it does not. Found via the new
lint:json failure summary.
Honra um `context_length` definido pelo operador em tempo de requisição no roteamento do combo (supersede #12014, que estava incluída nos mesmos commits). Boa cobertura de testes, incluindo o refactor de `resolveComboContextLimit` para módulo próprio. Validado no worktree combinado (13/13). Obrigado!
Adiciona suporte ao GLM-5.3-Flash Coding Plan (endpoint OpenAI-compatible, tiers de esforço low/high/max via reasoning_effort). Boa cobertura de testes. Validado no worktree combinado.
Dois problemas resolvidos antes de mergear:
1. **Duplicata silenciosa de "glm-5.3-flash"** em `src/shared/constants/modelSpecs.ts` e `open-sse/config/glmProvider.ts` (#11830, já mergeado nesta sessão, e sua PR inserem a mesma entrada em pontos diferentes do arquivo — git não detecta como conflito textual). Removida a duplicata, preservando a ordem que o teste pré-existente `open-sse/mcp-server/__tests__/glmCodingProviderConfig.test.ts` espera (glm-5.3-flash primeiro no array `GLM_SHARED_MODELS`).
2. Conflito real em `zai/index.ts`, `default.ts`, `pricing/shared-tiers.ts` e no teste de catálogo — todos aditivos, resolvidos mantendo ambos os lados.
27/27 + 10/10 (vitest) testes focados verdes. Obrigado!
Emite `web_search_call` nativo para o fallback de web_search da Responses API, com boa cobertura (integração + unitário). Validado no worktree combinado.
Corrigi 3 problemas no próprio `tests/integration/skills-pipeline.test.ts` desta PR antes de mergear: faltava `encodeSkillToolName` no import (usado em 3 lugares, causava `ReferenceError` que se propagava como 502 no teste "matching tool calls execute the registered skill") e 2 asserções comparavam nomes decodificados (`decodeSkillToolName`) contra valores re-codificados (`encodeSkillToolName`) — copy-paste do helper usado para montar o mock. 30/30 testes focados verdes após a correção.
Desacopla a expiração de execução do rate-limit do orçamento de espera na fila, e preserva erros em artefatos de call-log oversized. Testes próprios (`call-log-cap.test.ts` + atualizações em `rate-limit-execution-timeout-message-4165.test.ts`/`ratelimit-admission-control-6593.test.ts`). Validado no worktree combinado. Obrigado!
Migra o quota fetcher do OpenCode Go para a API oficial de uso, com refactor substancial que remove ~1850 linhas de código legado e atualiza a suíte de testes existente inteira para o novo contrato. Validado no worktree combinado (typecheck limpo, testes focados verdes). Obrigado!
Vincula o refresh OAuth do Google ao client que emitiu o token, com teste próprio (`google-oauth-client-binding.test.ts`). Validado no worktree combinado. Obrigado!
Adiciona o provider Perplexity Agent API, com dois arquivos de teste próprios (provider + sanitização de chatCore). Validado no worktree combinado. Obrigado!
Injeta a tag de usuário obrigatória nas requisições de inferência do provider Nous, com teste próprio ampliado. Validado no worktree combinado. Obrigado!
Corrige o achatamento incondicional de conteúdo de mensagem no cloudflare-ai — a restrição #2539 é model-scoped, não global, e estava bloqueando entrada de imagem em modelos de visão da Cloudflare. Teste próprio atualizado. Validado no worktree combinado. Obrigado!
Mantém tokens de cache-write no formato de usage do OpenAI, com teste próprio (`cache-write-openai-shape.test.ts`) e atualização do teste existente de tokens detalhados. Validado no worktree combinado (typecheck limpo, 351/351 testes focados). Obrigado!
Corrige divergência de scoring no relatório de saúde do auto-combo, com testes atualizados em `combo-resolve-auto-strategy-split.test.ts` e `combo-scoring-inspector.test.ts`. Validado no worktree combinado. Obrigado!
Dá aos alvos de extended-thinking o orçamento de prontidão de reasoning, com cobertura de teste ampliada em `stream-readiness-policy.test.ts`. Validado no worktree combinado. Obrigado!
Envia metadata completo do loadCodeAssist (ideType/platform/pluginType como enums numéricos) para o Antigravity, com teste de regressão atualizado. Validado no worktree combinado. Obrigado!
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!
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.
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.
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.
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.