Commit Graph

4813 Commits

Author SHA1 Message Date
Diego Rodrigues de Sa e Souza
5b8d9ebbb5 Merge remote-tracking branch 'origin/release/v3.8.47' into tmp/implement-prs-6697-b 2026-07-09 19:58:00 -03:00
janeza2
9906dfc1ba fix(providers): update web model discovery (#6308)
Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
2026-07-09 19:54:05 -03:00
Moseyuh333
b9d18dd8c4 Continue fix bugs and upgrade skill_collector (#6294)
* fix(skills): gate skill-collector CLI detection behind management auth + loopback

PR #6294 fork-main bundled genuinely new skill-collector CLI-detection routes
(GET /api/skills/collect/detect, POST /api/skills/collect/install) on top of
content already shipped via #6186. This reconstructs the PR against the
current release tip, keeping only the new detect/install routes and their
SKILL.md, and drops the 3 already-merged commits so two post-merge quality
fixes on /api/github-skills (Zod validation + sanitizeErrorMessage) are not
reverted.

- GET /api/skills/collect/detect spawned a child process per CLI_TOOL_IDS
  entry via getCliRuntimeStatus(), unauthenticated and reachable over any
  tunnel. All 3 routes (github-skills GET/POST, skills/collect/detect,
  skills/collect/install) now require requireManagementAuth(), matching
  every sibling /api/skills/* route.
- Classified /api/skills/collect/ in LOCAL_ONLY_API_PREFIXES and
  SPAWN_CAPABLE_PREFIXES (routeGuard.ts / spawnCapablePrefixes.ts) and added
  src/app/api/skills/collect to SPAWN_CAPABLE_ROUTE_ROOTS in
  check-route-guard-membership.ts so the automated gate actually scans it
  (Hard Rules #15 + #17).
- omniroute_github_skills_install MCP tool now reports the honest
  action: "planned" instead of "installed", matching the REST route.
- Dropped docker-compose.drive-d.yml, start.sh, and the unrelated
  @types/node/settings.ts changes (personal dev-machine / out-of-scope).
- Added route-level tests for all 3 routes + the 3 MCP tools (auth-required
  and no-stack-trace-leak assertions) and a route-guard regression test.

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

* fix(quality): register new routeGuard covering test in stryker.conf.json

check:mutation-test-coverage --strict (Fast Quality Gates) flagged
tests/unit/authz/route-guard-skills-collect.test.ts as a covering unit test
for src/server/authz/routeGuard.ts that was missing from tap.testFiles, so
its mutant kills would silently not count toward the mutation-test baseline.

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

* chore: resync CHANGELOG after merging release/v3.8.47

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

---------

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
Co-authored-by: Moseyuh333 <Moseyuh333@users.noreply.github.com>
2026-07-09 19:43:43 -03:00
Diego Rodrigues de Sa e Souza
3cccbfa143 fix(changelog): re-restore #6697 bullet after #6700 release sync 2026-07-09 18:58:25 -03:00
nowhats-br
2a5a819dbe fix: update Dockerfile with --allow-scripts for better-sqlite3 compil… (#6700)
* fix(docker): compile better-sqlite3 via direct node-gyp rebuild in the Dockerfile

The `builder` stage installs dependencies with `npm ci --ignore-scripts` (deliberate
supply-chain hardening) and then re-enables the native build for the one package
that needs it. `npm rebuild better-sqlite3` re-runs that indirectly through the
package's own install script, which under npm 11 depends on npm's script-allowlist
machinery correctly re-enabling it — some self-hosted build environments (e.g.
Dokploy) hit a broken/mismatched native binding through that indirection.

Invoke `node-gyp rebuild` directly inside `node_modules/better-sqlite3` instead,
bypassing npm's script-running layer entirely, so the compile step is deterministic
regardless of npm version or ignore-scripts allowlist behavior.

Rebased onto the current release/v3.8.47 tip: dropped this branch's stale
electron/package.json + package-lock.json diff (would have reverted the
electron 42->43 ABI-148 fix from #6605) and the unconsumed root `allowScripts`
package.json field (npm does not read that key; has zero effect).

Regression guard: tests/unit/dockerfile-better-sqlite3-node-gyp-6700.test.ts.

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

* fix(changelog): restore CHANGELOG bullets eaten by release sync

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

* fix(changelog): re-restore CHANGELOG bullet after further release sync

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

* fix(changelog): re-restore CHANGELOG bullet after further release sync

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

* fix(changelog): re-restore CHANGELOG bullet after further release sync

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

* fix(changelog): correct CHANGELOG restoration (previous attempt had a script-path bug)

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

* fix(changelog): re-restore #6700 bullet after #6496 release sync

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

* fix(changelog): re-restore CHANGELOG bullet after further release sync

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

---------

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
Co-authored-by: nowhats-br <nowhats-br@users.noreply.github.com>
2026-07-09 18:57:06 -03:00
Diego Rodrigues de Sa e Souza
2001ca522a fix(changelog): re-restore CHANGELOG bullet after further release sync 2026-07-09 18:45:11 -03:00
SeaXen
889fffddbe fix(cloudflare-relay): use Service Worker syntax with body_part metadata (#6416) (#6496)
* fix(providers): Cloudflare relay Worker uses Service Worker syntax + body_part

CONTEXT: #6416/#6618 fixed the multipart Content-Type but the emitted
worker source still used ES-module syntax (`export default { fetch }`)
with `main_module` metadata. Cloudflare's Workers upload API parses a
plain `application/javascript` script part as Service Worker syntax
regardless of `main_module`, and `main_module` requires the script to
actually be an ES module — so the upload was still rejected.

CHANGE: buildCloudflareWorkerScript() now emits Service Worker syntax
(`addEventListener("fetch", ...)`, no top-level `export`) and the
upload metadata uses `body_part` instead of `main_module`.

Also restores the SSRF-guard bracket-stripping regex for bracketed
IPv6 hosts (`[::1]`, `[fd00::1]`) that an earlier revision of this
change accidentally double-escaped, with regression coverage added to
tests/unit/relay-deploy-5128.test.ts. Updates the sibling
tests/unit/proxy-pool-cloudflare-workers-deployer.test.ts assertion
that still expected the old ES-module contract.

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

* fix(changelog): restore CHANGELOG bullets eaten by release sync

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

* fix(changelog): re-restore CHANGELOG bullet after further release sync

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

* fix(changelog): re-restore CHANGELOG bullet after further release sync

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

* fix(changelog): re-restore CHANGELOG bullet after further release sync

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

* fix(changelog): correct CHANGELOG restoration (previous attempt had a script-path bug)

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

---------

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
Co-authored-by: SeaXen <SeaXen@users.noreply.github.com>
2026-07-09 18:43:19 -03:00
Diego Rodrigues de Sa e Souza
8b31fa343d fix(changelog): re-restore #6697 bullet after release sync (#6678 landed) 2026-07-09 18:25:47 -03:00
Diego Rodrigues de Sa e Souza
0012a9ea2d Merge remote-tracking branch 'origin/release/v3.8.47' into tmp/implement-prs-6697-b 2026-07-09 18:23:23 -03:00
SeaXen
6557f44bd2 feat(settings): 9router-style Routing Strategy card + sticky parity (#6678)
* feat(dashboard): 9router-parity Routing Strategy card + provider/combo sticky override (#6678)

Add a Routing Strategy settings card (Settings -> Routing) surfacing account
round-robin/sticky-limit knobs plus a new combo-level sticky round-robin
(comboStickyRoundRobinLimit), and a per-provider account-routing override
(providerStrategies) wired into getProviderCredentials() ahead of the global
fallback strategy. Rebased onto release/v3.8.47 (credit-preserving
reconstruction: unrelated package.json/electron/proxyDispatcher drift from the
PR's stale base was dropped, only the author's own 12 files were re-applied).
Split ProviderAccountRoutingCard/RoutingStrategyCard into smaller
hook+subcomponent pieces to stay under the frozen complexity/file-size gates;
rebaselined ProviderDetailPageClient.tsx/auth.ts's frozen file-size caps for
the small additive growth.

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

* chore(quality): register combo-rr-sticky-9router.test.ts in stryker tap.testFiles (#6678)

CI's Fast Quality Gates -> check:mutation-test-coverage --strict flagged the new
test as missing from stryker.conf.json's tap.testFiles (it covers the mutated
module open-sse/services/combo/rrState.ts). Adds the single entry, alphabetized
next to the existing combo-rr-fallback-advance-948.test.ts.

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

* fix(changelog): restore CHANGELOG bullets eaten by release sync

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

* fix(changelog): re-restore CHANGELOG bullet after further release sync

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

* fix(changelog): re-restore CHANGELOG bullet after further release sync

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

---------

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
Co-authored-by: SeaXen <SeaXen@users.noreply.github.com>
2026-07-09 18:22:43 -03:00
Diego Rodrigues de Sa e Souza
b12f3721ea fix(changelog): re-restore CHANGELOG bullet after further release sync 2026-07-09 17:40:26 -03:00
Diego Rodrigues de Sa e Souza
2fcf1032de Merge remote-tracking branch 'origin/release/v3.8.47' into tmp/implement-prs-6697-b 2026-07-09 17:40:20 -03:00
Arthur Bodera
d76aa40ee6 fix(chatgpt-web): render citations as markdown links (#6635)
* fix(providers): render ChatGPT-web citation markers as Markdown links

ChatGPT Web responses leaked raw chatgpt.com UI citation markup (private-use
marker tokens like `citeturn0search0`, `entity[...]`) instead of real
Markdown links, since these are normally resolved client-side by chatgpt.com's
own JS using `message.metadata.content_references`.

cleanChatGptText() now resolves content_references (grouped webpages, footnote
sources, inline webpage/url mentions) into `[label](url)` Markdown links for
the streaming and non-streaming response builders and the GPT-5.5 Pro
stream_handoff polled-answer path, falling back to stripping any marker with
no resolvable source.

The citation parsing/rendering logic was extracted into a new pure sibling
module (open-sse/executors/chatgpt-web/citations.ts), decomposed into small
per-reference-type helpers, to keep the executor under the frozen file-size
cap and the complexity/cognitive-complexity ratchets. Regression tests moved
to a dedicated tests/unit/chatgpt-web-citations.test.ts for the same reason.

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

* fix(changelog): restore CHANGELOG bullets eaten by release sync

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

* fix(changelog): re-restore CHANGELOG bullet after further release sync

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

* fix(changelog): re-restore CHANGELOG bullet after further release sync

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

---------

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
Co-authored-by: Thinkscape <thinkscape@users.noreply.github.com>
2026-07-09 17:37:20 -03:00
Diego Rodrigues de Sa e Souza
48a8e602ca fix(changelog): re-restore CHANGELOG bullet after further release sync 2026-07-09 17:35:23 -03:00
Diego Rodrigues de Sa e Souza
03571617be Merge remote-tracking branch 'origin/release/v3.8.47' into tmp/implement-prs-6697-b 2026-07-09 17:35:11 -03:00
Chirag Singhal
237bd59173 fix(api): sanitize catch-block error.message in middleware/hooks routes (#6645)
* fix(api): sanitize catch-block error.message in middleware/hooks routes

POST /api/middleware/hooks and PUT /api/middleware/hooks/[name] returned
the raw error?.message in their 500 response bodies (Hard Rule #12),
which could leak internal SQLite error text/paths on a DB failure. Both
now route through sanitizeErrorMessage() from open-sse/utils/error.ts,
matching the pattern already used elsewhere in the codebase.

Regression guard: tests/unit/middleware-hooks-error-sanitization.test.ts

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

* test(mutation): register middleware-hooks-error-sanitization in stryker tap.testFiles

The mutation test-coverage gate (check:mutation-test-coverage --strict)
flagged tests/unit/middleware-hooks-error-sanitization.test.ts as
covering open-sse/utils/error.ts but missing from stryker.conf.json's
tap.testFiles list.

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

* fix(changelog): restore CHANGELOG bullets eaten by release sync

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

* fix(changelog): re-restore CHANGELOG bullet after further release sync

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

---------

Co-authored-by: Chirag Singhal <chirag127@users.noreply.github.com>
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
2026-07-09 17:31:52 -03:00
Hernan Javier Ardila Sanchez
912ff8d1c4 fix(vision-bridge): auto-reroute non-vision models to fastest vision model when images detected (#6640)
* fix(electron): bump electron 42→43 + build better-sqlite3 from source (ABI 148) (#6605)

fix(electron): bump electron 42→43 + rebuild better-sqlite3 from source against the Electron ABI (148).

Electron 43 raises NODE_MODULE_VERSION to 148; better-sqlite3@12.11.1 has no electron-v148 prebuild, so the packaged app died with 'Nenhum driver SQLite disponível'. prepare-electron-standalone now compiles better-sqlite3 from source against the electron headers into build/Release (where 'bindings' resolves it). Validated by Electron Package Smoke (green) + local (node_register_module_v148).

Supersedes #6378. (--admin: the only reds are SonarQube/SonarCloud failing on a coverage-report artifact digest-mismatch — a GitHub Actions infra flake, not this diff; Sonar is green on main and the diff touches only the electron build.)

* deps: bump the development group across 1 directory with 6 updates (#6588)

deps: bump the development group (6 updates). Rebased onto current main; all checks green after the electron-smoke fix (#6605).

* fix(proxy): force CONNECT tunnel for HTTP proxied requests (undici 8.7) + production deps bump (#6620)

fix(proxy): force CONNECT tunnel for HTTP proxied requests (undici 8.7) + production deps bump.

undici 8.6+ changed ProxyAgent to forward plain-HTTP via request-proxy instead of CONNECT, breaking OAuth refresh through a connection proxy (501). proxyDispatcher now passes proxyTunnel:true. Validated: Unit Tests 3/8 (the OAuth-proxy test) green, new regression test green (fails without the fix on undici 8.7), SonarQube green.

Supersedes #6380. (--admin: the only red is Electron Package Smoke failing on a next-build artifact 'digest-mismatch' — a GitHub Actions infra flake corrupting the asar ('file data stream has unexpected number of bytes'); the better-sqlite3 rebuild itself succeeded (gyp ok) and the electron path is unchanged from #6605 which passed the smoke. Not this diff.)

* fix(vision-bridge): auto-reroute non-vision models to fastest vision model when images detected

The VisionBridgeGuardrail was describing images as text via a vision model
and sending text to the original (non-vision) model. This defeated the purpose
when the final target was already vision-capable (auto/vision, combos with
vision targets) and never actually rerouted requests to a vision model.

Changes:
- Individual non-vision models + images → reroute  to the fastest
  available vision-capable model (via getBestVisionModel), keeping images intact
- Auto/ prefix models (auto/vision, auto) → skip guardrail entirely, letting
  the auto-combo resolver handle vision-capable model selection
- Combo mappings with non-vision targets → keep existing describe behavior
  (fallback path via checkModelHasComboMapping)
- chat.ts: sync modelStr from body.model after guardrail execution so downstream
  routing uses the rerouted model

* fix(vision-bridge): use getBestVisionModel auto-routing instead of fixed model

Address Gemini review feedback: getBestVisionConfig({}) with empty object
bypassed auto-routing by always defaulting to a fixed model. Auto-select
the best vision model from available providers instead.

* fix: compact modelStr sync to stay under file-size cap (1632)

* fix: remove debug log, orphaned brace to keep file under cap

* chore: trigger CI re-run with file-size fix and PR evidence

* chore: rebaseline chat.ts frozen cap to 1754 (PR #6640 +3 lines)

* fix(auto-combo): respect hidden models from dashboard toggle

getHiddenModelsByProvider() only queried modelCompatOverrides and
customModels namespaces, missing the hiddenModels namespace used by
the dashboard hide/unhide toggle. Auto-combo candidates now filter
out models the user explicitly hid.

* fix(changelog): restore CHANGELOG bullets eaten by release sync

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

---------

Co-authored-by: Diego Rodrigues de Sa e Souza <8016841+diegosouzapw@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: herjarsa <herjarsa@users.noreply.github.com>
Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
2026-07-09 17:15:53 -03:00
Diego Rodrigues de Sa e Souza
067d1fccc9 fix(changelog): restore CHANGELOG bullets eaten by release sync 2026-07-09 16:56:50 -03:00
Diego Rodrigues de Sa e Souza
d681ce241d Merge remote-tracking branch 'origin/release/v3.8.47' into tmp/implement-prs-6697-b 2026-07-09 16:56:37 -03:00
Diego Rodrigues de Sa e Souza
5e5447a2ba fix(sse): count gate/combo-rejected requests in per-api-key usage (#6698)
Requests rejected before handleChatCore — a pipeline-gate rejection
(provider circuit breaker OPEN / model cooldown) or a combo whose
targets were all exhausted — short-circuited in chat.ts and only wrote
a call_logs row (dashboard/logs). They never reached persistFailureUsage,
so no usage_history row was created and the per-api-key usage counter
(getApiKeyUsageRows reads usage_history) never incremented. An API key
whose traffic was entirely gate/breaker-rejected showed zero requests
despite real usage.

Route both rejection paths through recordRejectedRequestUsage(), which
writes the call_logs row (unchanged visibility) AND a usage_history row
attributed to the api key with success:false, mirroring persistFailureUsage.

Regression guard: tests/unit/rejected-request-usage.test.ts.
2026-07-09 16:50:29 -03:00
MikeTuev
0d20205f92 fix(sse): preserve server-tool literal names in message history and tool_choice (#6586)
* fix(sse): preserve server-tool literal names in message history and tool_choice

The v3.8.36 guard (isAnthropicServerToolType, #2943) protects Anthropic
server tools (web_search_20250305, bash_20250124, ...) from the tool-name
cloak only in the tools[] array. The same reserved literal names were still
rewritten in message-history tool_use blocks and in tool_choice, and
remapToolNamesInRequest had no guard at all (bash -> Bash).

The resulting asymmetry — tools[] keeps 'web_search' while the history
reference becomes 'WebSearch' — makes Anthropic reject every follow-up turn
of a native web-search conversation:

  [400] Tool 'WebSearch' not found in provided tools

Collect the declared server-tool names once per request and skip them in
every rewrite path of both remapToolNamesInRequest and
cloakThirdPartyToolNames (tools[], message history, tool_choice). Plain
custom tools with the same names (no server type) remain remapped/cloaked
exactly as before, symmetrically in all sections.

Surfaced on Claude Code 2.1.x native WebSearch; same class as CLIProxyAPI
#1094/#1179. TDD: 5 failing repro tests -> guard -> 7/7 green (92/92 across
the remapper suite), typecheck:core clean.

* fix(sse): skip null entries in tools[] before server-tool type check

Review follow-up (gemini-code-assist): a null element in tools[] made the
new isAnthropicServerToolType(tool.type) check throw. The crash path is
pre-existing (String(tool.name) on the next line threw identically), but
the guard is cheap and mirrors the null checks already used in
cloakThirdPartyToolNames. Adds a regression test (8/8 green).
2026-07-09 16:49:59 -03:00
Xiangzhe
edae0cf33f Expose per-combo reasoning token buffer toggle (#6702)
* fix(combos): default reasoning token buffer off

* feat(combos): expose reasoning token buffer toggle

* fix(combos): keep reasoning-token buffer default enabled, opt-out toggle

#6702 shipped bundled with #6536's own commit (identical SHA
37ac38f17f), flipping the combo-wide reasoningTokenBufferEnabled
default from true to false. #6536 was subsequently closed by the
author in favor of #6714, which explicitly keeps the existing
default-enabled buffer behavior and instead clamps the buffer to the
model's known output cap. Reconciled #6702 with that resolution:
dropped the default-flip changes across comboConfig.ts, combo.ts,
comboSetup.ts, ComboDefaultsTab.tsx, and the combo-defaults settings
route (plus their test assertions), and inverted the new per-combo
ReasoningTokenBufferToggle to opt-out semantics (`!== false`) so an
existing combo's behavior is unchanged unless the operator explicitly
unchecks it.

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

---------

Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
2026-07-09 16:49:20 -03:00
KooshaPari
abfced8b28 feat(sandbox): native Apple Container, WSL, OrbStack, Podman runtime support (#6611)
* feat(sandbox): native Apple Container, WSL, OrbStack, Podman runtime support

* fix(skills): align sandbox fallback kill container-name convention

sandbox.ts's docker-fallback kill path (used only when cachedProvider is
unexpectedly null) still targeted the pre-PR omniroute-sandbox-${id}
container name, while containerProvider.ts's SANDBOX_NAME now produces
omniroute-${id}. Align the fallback naming so it matches the provider
convention, with a regression test covering kill()/killAll() before a
provider has ever been resolved.

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

* fix(docs): document SKILLS_SANDBOX_RUNTIME and drop unrelated env leftovers

Two fixes surfaced by CI's env/docs contract gate:

- Add the SKILLS_SANDBOX_RUNTIME row to docs/reference/ENVIRONMENT.md so
  the new container-runtime override introduced by this PR is documented,
  matching .env.example.
- Remove the Substrate/Bifrost/OTEL .env.example blocks that leaked in
  from this branch's stale main-based history during the release-branch
  sync merge — none of that belongs to this PR (native container
  runtimes for the skill sandbox) and none of it exists on
  release/v3.8.47 yet.

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

---------

Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
2026-07-09 16:48:49 -03:00
enjoyer-hub
e697670046 fix(cli): detect WinGet Claude Code on Windows (#6647)
* fix(electron): bump electron 42→43 + build better-sqlite3 from source (ABI 148) (#6605)

fix(electron): bump electron 42→43 + rebuild better-sqlite3 from source against the Electron ABI (148).

Electron 43 raises NODE_MODULE_VERSION to 148; better-sqlite3@12.11.1 has no electron-v148 prebuild, so the packaged app died with 'Nenhum driver SQLite disponível'. prepare-electron-standalone now compiles better-sqlite3 from source against the electron headers into build/Release (where 'bindings' resolves it). Validated by Electron Package Smoke (green) + local (node_register_module_v148).

Supersedes #6378. (--admin: the only reds are SonarQube/SonarCloud failing on a coverage-report artifact digest-mismatch — a GitHub Actions infra flake, not this diff; Sonar is green on main and the diff touches only the electron build.)

* deps: bump the development group across 1 directory with 6 updates (#6588)

deps: bump the development group (6 updates). Rebased onto current main; all checks green after the electron-smoke fix (#6605).

* fix(proxy): force CONNECT tunnel for HTTP proxied requests (undici 8.7) + production deps bump (#6620)

fix(proxy): force CONNECT tunnel for HTTP proxied requests (undici 8.7) + production deps bump.

undici 8.6+ changed ProxyAgent to forward plain-HTTP via request-proxy instead of CONNECT, breaking OAuth refresh through a connection proxy (501). proxyDispatcher now passes proxyTunnel:true. Validated: Unit Tests 3/8 (the OAuth-proxy test) green, new regression test green (fails without the fix on undici 8.7), SonarQube green.

Supersedes #6380. (--admin: the only red is Electron Package Smoke failing on a next-build artifact 'digest-mismatch' — a GitHub Actions infra flake corrupting the asar ('file data stream has unexpected number of bytes'); the better-sqlite3 rebuild itself succeeded (gyp ok) and the electron path is unchanged from #6605 which passed the smoke. Not this diff.)

* fix(cli): detect WinGet Claude Code on Windows

* chore(merge): drop unrelated main-drift from PR fork (deps/electron/proxy files belong to #6620, not this PR)

Restores electron/package-lock.json, electron/package.json, package-lock.json,
package.json, open-sse/utils/proxyDispatcher.ts, scripts/build/prepare-electron-standalone.mjs
and tests/unit/proxy-dispatcher-family.test.ts to origin/release/v3.8.47's content.
The PR fork branched from a state of main that already includes #6620 (proxy CONNECT
tunnel fix + deps bump), which is not yet synced into release/v3.8.47 — the 3-way
merge would otherwise silently carry that unrelated content into this doc-only PR.

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

* chore(quality): rebaseline cliRuntime.ts file-size freeze for #6647 (1100->1110)

The file was already exactly at the frozen 1100-line cap on release/v3.8.47.
PR #6647's WinGet Claude Code detection path adds 10 lines (irreducible —
the 62-char package folder name forces Prettier's 100-char width to break
the path.join call across the same multi-line form used by every other
long path in this function), tripping the Fast Quality Gates check:file-size
job. Bumping the frozen cap to the file's real new size per the documented
allowlist-with-justification policy (this is a pass/fail policy gate, not
the ratchet metrics system).

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

---------

Co-authored-by: Diego Rodrigues de Sa e Souza <8016841+diegosouzapw@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: quanturbo <faralechko@gmail.com>
Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
2026-07-09 16:46:41 -03:00
Chirag Singhal
2b33c6c635 docs(routing): reconcile 17 vs 18 public-strategy count in AUTO-COMBO (#6646)
* fix(electron): bump electron 42→43 + build better-sqlite3 from source (ABI 148) (#6605)

fix(electron): bump electron 42→43 + rebuild better-sqlite3 from source against the Electron ABI (148).

Electron 43 raises NODE_MODULE_VERSION to 148; better-sqlite3@12.11.1 has no electron-v148 prebuild, so the packaged app died with 'Nenhum driver SQLite disponível'. prepare-electron-standalone now compiles better-sqlite3 from source against the electron headers into build/Release (where 'bindings' resolves it). Validated by Electron Package Smoke (green) + local (node_register_module_v148).

Supersedes #6378. (--admin: the only reds are SonarQube/SonarCloud failing on a coverage-report artifact digest-mismatch — a GitHub Actions infra flake, not this diff; Sonar is green on main and the diff touches only the electron build.)

* deps: bump the development group across 1 directory with 6 updates (#6588)

deps: bump the development group (6 updates). Rebased onto current main; all checks green after the electron-smoke fix (#6605).

* fix(proxy): force CONNECT tunnel for HTTP proxied requests (undici 8.7) + production deps bump (#6620)

fix(proxy): force CONNECT tunnel for HTTP proxied requests (undici 8.7) + production deps bump.

undici 8.6+ changed ProxyAgent to forward plain-HTTP via request-proxy instead of CONNECT, breaking OAuth refresh through a connection proxy (501). proxyDispatcher now passes proxyTunnel:true. Validated: Unit Tests 3/8 (the OAuth-proxy test) green, new regression test green (fails without the fix on undici 8.7), SonarQube green.

Supersedes #6380. (--admin: the only red is Electron Package Smoke failing on a next-build artifact 'digest-mismatch' — a GitHub Actions infra flake corrupting the asar ('file data stream has unexpected number of bytes'); the better-sqlite3 rebuild itself succeeded (gyp ok) and the electron path is unchanged from #6605 which passed the smoke. Not this diff.)

* docs(routing): reconcile 17 vs 18 public-strategy count in AUTO-COMBO

* chore(merge): drop unrelated main-drift from PR fork (deps/electron/proxy files belong to #6620, not this PR)

Restores electron/package-lock.json, electron/package.json, package-lock.json,
package.json, open-sse/utils/proxyDispatcher.ts, scripts/build/prepare-electron-standalone.mjs
and tests/unit/proxy-dispatcher-family.test.ts to origin/release/v3.8.47's content.
The PR fork branched from a state of main that already includes #6620 (proxy CONNECT
tunnel fix + deps bump), which is not yet synced into release/v3.8.47 — the 3-way
merge would otherwise silently carry that unrelated content into this doc-only PR.

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

---------

Co-authored-by: Diego Rodrigues de Sa e Souza <8016841+diegosouzapw@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Chirag Singhal <chirag127@users.noreply.github.com>
Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
2026-07-09 16:46:11 -03:00
Chirag Singhal
484abed8c1 docs: sync routing-strategy count to 18 across README + AGENTS.md (#6644)
* fix(electron): bump electron 42→43 + build better-sqlite3 from source (ABI 148) (#6605)

fix(electron): bump electron 42→43 + rebuild better-sqlite3 from source against the Electron ABI (148).

Electron 43 raises NODE_MODULE_VERSION to 148; better-sqlite3@12.11.1 has no electron-v148 prebuild, so the packaged app died with 'Nenhum driver SQLite disponível'. prepare-electron-standalone now compiles better-sqlite3 from source against the electron headers into build/Release (where 'bindings' resolves it). Validated by Electron Package Smoke (green) + local (node_register_module_v148).

Supersedes #6378. (--admin: the only reds are SonarQube/SonarCloud failing on a coverage-report artifact digest-mismatch — a GitHub Actions infra flake, not this diff; Sonar is green on main and the diff touches only the electron build.)

* deps: bump the development group across 1 directory with 6 updates (#6588)

deps: bump the development group (6 updates). Rebased onto current main; all checks green after the electron-smoke fix (#6605).

* fix(proxy): force CONNECT tunnel for HTTP proxied requests (undici 8.7) + production deps bump (#6620)

fix(proxy): force CONNECT tunnel for HTTP proxied requests (undici 8.7) + production deps bump.

undici 8.6+ changed ProxyAgent to forward plain-HTTP via request-proxy instead of CONNECT, breaking OAuth refresh through a connection proxy (501). proxyDispatcher now passes proxyTunnel:true. Validated: Unit Tests 3/8 (the OAuth-proxy test) green, new regression test green (fails without the fix on undici 8.7), SonarQube green.

Supersedes #6380. (--admin: the only red is Electron Package Smoke failing on a next-build artifact 'digest-mismatch' — a GitHub Actions infra flake corrupting the asar ('file data stream has unexpected number of bytes'); the better-sqlite3 rebuild itself succeeded (gyp ok) and the electron path is unchanged from #6605 which passed the smoke. Not this diff.)

* docs: sync routing-strategy count to 18 across README + AGENTS.md

* chore(merge): drop unrelated main-drift from PR fork (deps/electron/proxy files belong to #6620, not this PR)

Restores electron/package-lock.json, electron/package.json, package-lock.json,
package.json, open-sse/utils/proxyDispatcher.ts, scripts/build/prepare-electron-standalone.mjs
and tests/unit/proxy-dispatcher-family.test.ts to origin/release/v3.8.47's content.
The PR fork branched from a state of main that already includes #6620 (proxy CONNECT
tunnel fix + deps bump), which is not yet synced into release/v3.8.47 — the 3-way
merge would otherwise silently carry that unrelated content into this doc-only PR.

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

---------

Co-authored-by: Diego Rodrigues de Sa e Souza <8016841+diegosouzapw@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Chirag Singhal <chirag127@users.noreply.github.com>
Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
2026-07-09 16:45:42 -03:00
Chirag Singhal
6e16ae7b32 docs(claude): fix p2c casing to match ROUTING_STRATEGY_VALUES (#6643)
* fix(electron): bump electron 42→43 + build better-sqlite3 from source (ABI 148) (#6605)

fix(electron): bump electron 42→43 + rebuild better-sqlite3 from source against the Electron ABI (148).

Electron 43 raises NODE_MODULE_VERSION to 148; better-sqlite3@12.11.1 has no electron-v148 prebuild, so the packaged app died with 'Nenhum driver SQLite disponível'. prepare-electron-standalone now compiles better-sqlite3 from source against the electron headers into build/Release (where 'bindings' resolves it). Validated by Electron Package Smoke (green) + local (node_register_module_v148).

Supersedes #6378. (--admin: the only reds are SonarQube/SonarCloud failing on a coverage-report artifact digest-mismatch — a GitHub Actions infra flake, not this diff; Sonar is green on main and the diff touches only the electron build.)

* deps: bump the development group across 1 directory with 6 updates (#6588)

deps: bump the development group (6 updates). Rebased onto current main; all checks green after the electron-smoke fix (#6605).

* fix(proxy): force CONNECT tunnel for HTTP proxied requests (undici 8.7) + production deps bump (#6620)

fix(proxy): force CONNECT tunnel for HTTP proxied requests (undici 8.7) + production deps bump.

undici 8.6+ changed ProxyAgent to forward plain-HTTP via request-proxy instead of CONNECT, breaking OAuth refresh through a connection proxy (501). proxyDispatcher now passes proxyTunnel:true. Validated: Unit Tests 3/8 (the OAuth-proxy test) green, new regression test green (fails without the fix on undici 8.7), SonarQube green.

Supersedes #6380. (--admin: the only red is Electron Package Smoke failing on a next-build artifact 'digest-mismatch' — a GitHub Actions infra flake corrupting the asar ('file data stream has unexpected number of bytes'); the better-sqlite3 rebuild itself succeeded (gyp ok) and the electron path is unchanged from #6605 which passed the smoke. Not this diff.)

* docs(claude): fix p2c casing to match ROUTING_STRATEGY_VALUES

* chore(merge): drop unrelated main-drift from PR fork (deps/electron/proxy files belong to #6620, not this PR)

Restores electron/package-lock.json, electron/package.json, package-lock.json,
package.json, open-sse/utils/proxyDispatcher.ts, scripts/build/prepare-electron-standalone.mjs
and tests/unit/proxy-dispatcher-family.test.ts to origin/release/v3.8.47's content.
The PR fork branched from a state of main that already includes #6620 (proxy CONNECT
tunnel fix + deps bump), which is not yet synced into release/v3.8.47 — the 3-way
merge would otherwise silently carry that unrelated content into this doc-only PR.

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

---------

Co-authored-by: Diego Rodrigues de Sa e Souza <8016841+diegosouzapw@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Chirag Singhal <chirag127@users.noreply.github.com>
Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
2026-07-09 16:45:11 -03:00
Paijo
1291e9bf26 fix(providers): web-cookie fallback validation reports unsupported instead of a false valid (#6309)
validateWebCookieProvider() previously required a providerRegistry.ts entry and
returned "Provider not found in registry" for web-cookie-only providers like
lmarena, gemini-business, poe-web, venice-web and v0-vercel-web. A fallback to
WEB_COOKIE_PROVIDERS[provider].website was proposed, but live verification showed
probing `${website}/models` does not reliably signal session validity for these
(redirects/SPA 200s regardless of cookie validity) — it would report an expired
or garbage cookie as valid, which is worse than an honest "not supported". Until
each provider has a verified, side-effect-free auth probe against its real API
host, the fallback now returns `unsupported: true` with no network call. Also
reverts the probe transport from validationRead back to directHttpsRequest,
which fixes a globalThis.fetch mock/patch-timing mismatch that made the
pre-existing tests/unit/provider-validation-web-cookie-auth007.test.ts hit the
live network in CI, and adds the missing Cookie header to the probe request.

Regression guard: tests/unit/web-cookie-validation-fallback.test.ts.

Co-authored-by: oyi77 <oyi77@users.noreply.github.com>
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
2026-07-09 16:45:01 -03:00
Hamsa_M
aba98fd227 fix(cli): per-agent DNS, startup guards, and batched Windows hosts writes (#6338)
DNS toggle in AgentBridge was broken for 8 of 9 agents: addDNSEntry/
removeDNSEntry always resolved the legacy Antigravity default hosts
regardless of which agent's dns_enabled flag was flipped. Both now
accept an optional agentId and resolve hosts via ALL_TARGETS; the
[id]/dns route passes id through and returns 404 for an unknown agent
instead of silently falling back to the defaults.

startMitmInternal() now wraps generateCert(), the provisionDnsEntries()
call, and the PID-file write in try/catch so a mid-startup failure
can't orphan the already-spawned MITM child process.

On Windows, addDNSEntries/removeDNSEntries batch every missing/present
entry into a single elevated PowerShell invocation instead of one UAC
prompt per host line.

Scope note: this PR originally bundled an unrelated SkillOpt feature
(DB migration, 6 API routes, dashboard UI) and a checks-free CI build
workflow alongside this DNS/startup fix. Both were dropped here as
out-of-scope per review-group-prs analysis (2-implementing plan);
only the DNS/startup-guard delta (dnsConfig.ts, manager.ts, the [id]/dns
route, and their tests) is applied.

Co-authored-by: hamsa0x7 <hamsa0x7@users.noreply.github.com>
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
2026-07-09 16:44:50 -03:00
Septianata Rizky Pratama
606d1cbbd3 fix: move tier-flow SVG images to public directory (#6538)
Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
2026-07-09 16:44:39 -03:00
backryun
0e4145d257 fix(providers): remove obsolete providers (glhf, kluster, cablyai, inclusionai) (#6675)
Drop dead catalog/registry entries, keep Synthetic as the GLHF replacement path,
regenerate provider reference/docs counts, and lock APIKEY family-split + file-size
gates so CI stays green.

Ignore prettier on freeModelCatalog.data.ts so dense one-line budget rows are not
expanded past the 800-line new-file cap.
2026-07-09 16:44:28 -03:00
Diego Rodrigues de Sa e Souza
f4fb0d310b docs(readme): update star badges and star history chart links 2026-07-09 01:33:33 -03:00
Diego Rodrigues de Sa e Souza
902e66805c chore(vscode): update search exclude patterns and add documentation
Add several directories to the search exclude list to improve search
performance and add a comment explaining why certain directories are
not being hidden from the file explorer.
2026-07-08 23:30:38 -03:00
Diego Rodrigues de Sa e Souza
f4643a2476 docs(changelog): add v3.8.47 Contributors section (32 contributors) 2026-07-08 22:33:35 -03:00
Diego Rodrigues de Sa e Souza
2241b394dd feat(oauth): accept 9router camelCase Codex export in bulk import (#6665) 2026-07-08 19:22:54 -03:00
Diego Rodrigues de Sa e Souza
5144712ab6 ci(vps): honor VPS_ALWAYS_ON — release teardown is a no-op on the dedicated 24/7 host (#6693)
The .113 VM is now a dedicated, always-on CI host so day-to-day quality.yml PRs
(PR→release/**) use the 32-core VPS, not just release CI. release-runner-down.sh must not
flip USE_VPS_RUNNER=false / shut the VM down when VPS_ALWAYS_ON=true, or every PR after a
release would fall back to ubuntu-latest. Legacy on-demand teardown still applies when the
var is unset/false.
2026-07-08 18:37:04 -03:00
Diego Rodrigues de Sa e Souza
632d304939 ci(quality): route the 3 heavy fast-path jobs to the self-hosted VPS pool when USE_VPS_RUNNER is on (#6691)
Extends the same dynamic-runner gate ci.yml already uses (build/test-unit/test-vitest)
to quality.yml's fast-gates/fast-vitest/fast-unit — the ~9min-on-ubuntu jobs that run on
every PR→release/**. Inert until USE_VPS_RUNNER flips to true (falls back to ubuntu-latest
when the var is unset/false OR the PR is a fork — own-origin branches only, never the LAN
runner for fork code). lint-guard/merge-integrity stay on ubuntu-latest (trivial; keeps VPS
concurrency low). No behavior change today.
2026-07-08 17:45:32 -03:00
Diego Rodrigues de Sa e Souza
a6ea6074cb fix(cli): compression REST fallback uses canonical defaultMode + JSON object cells (#6571) (#6682)
* fix(cli): compression REST fallback uses canonical defaultMode + JSON object cells (#6571)

* test(cli): align existing compression-command tests to the #6571 canonical field contract (engine→strategy/defaultMode)
2026-07-08 16:50:11 -03:00
ThongAccount
1188847f0f feat: add setting for provider/model-specific parameters (#6649)
* fix(electron): bump electron 42→43 + build better-sqlite3 from source (ABI 148) (#6605)

fix(electron): bump electron 42→43 + rebuild better-sqlite3 from source against the Electron ABI (148).

Electron 43 raises NODE_MODULE_VERSION to 148; better-sqlite3@12.11.1 has no electron-v148 prebuild, so the packaged app died with 'Nenhum driver SQLite disponível'. prepare-electron-standalone now compiles better-sqlite3 from source against the electron headers into build/Release (where 'bindings' resolves it). Validated by Electron Package Smoke (green) + local (node_register_module_v148).

Supersedes #6378. (--admin: the only reds are SonarQube/SonarCloud failing on a coverage-report artifact digest-mismatch — a GitHub Actions infra flake, not this diff; Sonar is green on main and the diff touches only the electron build.)

* deps: bump the development group across 1 directory with 6 updates (#6588)

deps: bump the development group (6 updates). Rebased onto current main; all checks green after the electron-smoke fix (#6605).

* fix(proxy): force CONNECT tunnel for HTTP proxied requests (undici 8.7) + production deps bump (#6620)

fix(proxy): force CONNECT tunnel for HTTP proxied requests (undici 8.7) + production deps bump.

undici 8.6+ changed ProxyAgent to forward plain-HTTP via request-proxy instead of CONNECT, breaking OAuth refresh through a connection proxy (501). proxyDispatcher now passes proxyTunnel:true. Validated: Unit Tests 3/8 (the OAuth-proxy test) green, new regression test green (fails without the fix on undici 8.7), SonarQube green.

Supersedes #6380. (--admin: the only red is Electron Package Smoke failing on a next-build artifact 'digest-mismatch' — a GitHub Actions infra flake corrupting the asar ('file data stream has unexpected number of bytes'); the better-sqlite3 rebuild itself succeeded (gyp ok) and the electron path is unchanged from #6605 which passed the smoke. Not this diff.)

* feat(db): add provider param filter config store (key_value namespace)

Add paramFilters.ts module for CRUD against provider_param_filters
namespace in the key_value table, with in-memory cache + generation
counter invalidation. Supports denylist/allowlist per provider and
per model, plus auto-learn flag.

Migration 118 documents the namespace (no schema change).

Issue: #6625

* feat(proxy): add detectUnsupportedParam regex for auto-learning

Add UNSUPPORTED_PARAM_RE and detectUnsupportedParam() to extract
the offending parameter name from upstream 400 error messages like
'Unsupported parameter(s): thinking'.

Issue: #6625

* feat(proxy): extend stripUnsupportedParams with config-driven denylist/allowlist

Add applyConfigFilters() called after hardcoded STRIP_RULES in
stripUnsupportedParams(). Config-driven rules (DB-backed via
paramFilters.ts) support provider-level and model-level:
  1. Provider denylist (delete body[key])
  2. Model denylist (delete body[key])
  3. Provider allowlist (restore from pre-strip snapshot)
  4. Model allowlist (restore from pre-strip snapshot)

Allowlist only restores keys the client actually sent — never
introduces new params.

Issue: #6625

* feat(proxy): wire auto-learn of unsupported params into 400-downgrade loop

When a provider returns 400 with 'Unsupported parameter: X' and the
provider config has autoLearn enabled, auto-detect the param name
via detectUnsupportedParam(), persist it to the provider's block
list via addParamToBlocklist(), then strip and retry.

Issue: #6625

* test: add tests for provider param filter denylist/allowlist/auto-learn

Three new test files:
- param-filters-apply.test.ts — hardcoded rules regression + direct
  applyConfigFilters tests (no DB dependency)
- param-filters-db.test.ts — CRUD against key_value, cache invalidation,
  full filter pipeline (DB-backed config → stripUnsupportedParams),
  16 tests in isolated temp DB
- param-filters-auto-learn.test.ts — UNSUPPORTED_PARAM_RE regex matching
  and detectUnsupportedParam edge cases

All existing tests unchanged and passing.

Issue: #6625

* feat(proxy): add global auto-learn flag for unsupported params

Add isAutoLearnGloballyEnabled() and setGlobalAutoLearnEnabled() to
paramFilters.ts. The global flag (stored as key __global__ in the
provider_param_filters namespace) acts as a master switch: when
enabled, ALL providers auto-learn unsupported params from 400 errors.

In base.ts, the auto-learn check now evaluates:
  shouldAutoLearn = isAutoLearnGloballyEnabled() || perProviderConfig?.autoLearn

Global flag defaults to false (opt-in). Tests cover enable/disable/
default/no-interference-with-per-provider-config.

Issue: #6625

* fix: apply PR#6649 review feedback — model-scoped auto-learn and precedence order

Fixes from gemini-code-assist[bot] review:
- HIGH: Auto-learn now scoped to the specific model that triggered the 400
  (addParamToBlocklist(this.provider, autoLearned, model)) instead of
  adding to the provider-level blocklist globally
- HIGH: Reordered applyConfigFilters so model-level operations run AFTER
  provider-level operations (model denylist → model allowlist override
  provider allowlist → provider denylist)
- MEDIUM: Include model name in auto-learn log message

Adds regression test verifying model-level denylist beats provider-level
allowlist.

Issue: #6625
PR: #6649

* feat(ui): add provider-level param filter section to detail page

Add ProviderParamFilterSection component rendered on each provider
detail page, backed by GET|PUT|DELETE /api/providers/[id]/param-filters.

UI allows operators to configure:
- Blocked params (comma-separated, stripped from outgoing requests)
- Allowed params (comma-separated, re-added after denylist stripping)
- Auto-learn toggle (per-provider, enables auto-learning from 400 errors)

Wired into ProviderDetailPageClient.tsx between the Playground panel
and the Modals section.

Issue: #6625
PR: #6649

* feat(ui): add model-level param filter fields in compat popover

Extend ModelCompatPopover with Blocked params and Allowed params
text inputs for model-level denylist/allowlist overrides.

Model-specific block/allow data is persisted via the param-filters
API endpoint (PUT /api/providers/:id/param-filters) with the model
scope under the models key.

Both ModelRow and PassthroughModelRow now pass providerId and modelId
to the popover.

Issue: #6625
PR: #6649

* chore: gitignore .claude-flow/

* fix(param-filters): review follow-ups — auth gate, error sanitization, Zod body validation, typecheck, file-size, i18n keys

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

* chore(param-filters): drop unrelated main-drift from the fork branch (deps/electron/proxy files belong to #6620/#6605/#6588, not this PR)

* refactor(param-filters): split oversized functions — keep complexity gate at baseline

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

* refactor(param-filters): decompose config parser helpers — keep cognitive-complexity gate at baseline

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

* fix(changelog): restore sibling #6648 bullet eaten by merge auto-resolve + re-insert #6649 entry

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

---------

Co-authored-by: Diego Rodrigues de Sa e Souza <8016841+diegosouzapw@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
2026-07-08 14:55:00 -03:00
PizzaV
2d9f85d587 fix(mimocode): handle 400 with cooldown + account rotation (#6648)
* fix(electron): bump electron 42→43 + build better-sqlite3 from source (ABI 148) (#6605)

fix(electron): bump electron 42→43 + rebuild better-sqlite3 from source against the Electron ABI (148).

Electron 43 raises NODE_MODULE_VERSION to 148; better-sqlite3@12.11.1 has no electron-v148 prebuild, so the packaged app died with 'Nenhum driver SQLite disponível'. prepare-electron-standalone now compiles better-sqlite3 from source against the electron headers into build/Release (where 'bindings' resolves it). Validated by Electron Package Smoke (green) + local (node_register_module_v148).

Supersedes #6378. (--admin: the only reds are SonarQube/SonarCloud failing on a coverage-report artifact digest-mismatch — a GitHub Actions infra flake, not this diff; Sonar is green on main and the diff touches only the electron build.)

* deps: bump the development group across 1 directory with 6 updates (#6588)

deps: bump the development group (6 updates). Rebased onto current main; all checks green after the electron-smoke fix (#6605).

* fix(proxy): force CONNECT tunnel for HTTP proxied requests (undici 8.7) + production deps bump (#6620)

fix(proxy): force CONNECT tunnel for HTTP proxied requests (undici 8.7) + production deps bump.

undici 8.6+ changed ProxyAgent to forward plain-HTTP via request-proxy instead of CONNECT, breaking OAuth refresh through a connection proxy (501). proxyDispatcher now passes proxyTunnel:true. Validated: Unit Tests 3/8 (the OAuth-proxy test) green, new regression test green (fails without the fix on undici 8.7), SonarQube green.

Supersedes #6380. (--admin: the only red is Electron Package Smoke failing on a next-build artifact 'digest-mismatch' — a GitHub Actions infra flake corrupting the asar ('file data stream has unexpected number of bytes'); the better-sqlite3 rebuild itself succeeded (gyp ok) and the electron path is unchanged from #6605 which passed the smoke. Not this diff.)

* fix(mimocode): handle 400 with cooldown + account rotation

Treat HTTP 400 responses the same as 429: mark the account on cooldown
and continue to the next fingerprint/proxy. Previously, 400 fell through
to markSuccess and returned immediately, so only 1 of N accounts was ever
tried per request.

Refs: #5925

* chore(mimocode): drop unrelated dependency/electron drift from PR #6648's stale fork

package.json/package-lock.json (bun/eslint-config-next/cyclonedx bumps), electron/package.json,
electron/package-lock.json, open-sse/utils/proxyDispatcher.ts, prepare-electron-standalone.mjs
and tests/unit/proxy-dispatcher-family.test.ts were already present in the contributor's single
commit but are unrelated to the mimocode 400-handling fix — restored to release/v3.8.47's
versions so the PR stays scoped to open-sse/executors/mimocode.ts.

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

* fix(mimocode): classify 400 body before rotating — rate-limit-text 400s rotate, malformed 400s fail fast (#2101/#4976 guard)

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

* refactor(mimocode): extract auth-retry + 429/400 gating helpers — keep execute() under the cognitive-complexity gate

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

---------

Co-authored-by: Diego Rodrigues de Sa e Souza <8016841+diegosouzapw@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: pizzav-xyz <pizzav-xyz@users.noreply.github.com>
Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
2026-07-08 14:08:48 -03:00
Diego Rodrigues de Sa e Souza
d0c775564a docs(claude): atualiza nomes da família de skills review/triage/implement (Hard Rule #21) (#6663) 2026-07-08 11:31:33 -03:00
Diego Rodrigues de Sa e Souza
a14bbccf17 chore(deps): bump omniglyph to ^1.0.2 (security: ReDoS fixes) (#6661)
The lockfile pinned omniglyph@1.0.0, which carries the polynomial-ReDoS regex
paths fixed in 1.0.1/1.0.2 (all upstream CodeQL alerts resolved). Bump the range
to ^1.0.2 and refresh the lock so `npm ci` installs 1.0.2. No change to the
omniglyph engine behavior — 1.0.1/1.0.2 touched only regex hot paths and docs;
the dependency tree is unchanged (gpt-tokenizer ^3.4.0).

Co-authored-by: diegosouzapw <souzamiriamrodrigues790@gmail.com>
2026-07-08 11:31:18 -03:00
Diego Rodrigues de Sa e Souza
fd7e4c10e5 feat(compression): omniglyph engine (context-as-image, Fable 5 direct) — stack + single mode (#6556)
* feat(compression): dependência omniglyph (file:) + smoke de import

* feat(compression): engine omniglyph — contexto-como-imagem com gates fail-closed

* fix(compression): omniglyph adapter fail-open no transform (try/catch)

* feat(compression): registra omniglyph no registry e catálogo (single mode, stackPriority 90)

* feat(compression): modo único omniglyph (async), selecionar o modo é o enable

* feat(compression): plumbing supportsVision + providerTransport até os engines

* feat(compression): estimador de tokens image-aware — modo stacked mantém a saída do omniglyph

* docs(compression): corrige comentário do prefixo base64 no decode PNG (64 chars)

* feat(compression): registra omniglyph nas listas de modo/engine (db, combo, deriveDefaultPlan, mcp)

* feat(dashboard): dedicated OmniGlyph engine screen (context-as-image)

Adds a per-engine detail page at /dashboard/context/omniglyph, alongside the
other compression engines in the sidebar. Four sections: the economics (measured
savings), a REAL before→after (dense text vs the rendered PNG page, not a mockup),
the fail-closed gate flow, and the enable control wired to /api/settings/compression
(preview engine, off by default). Sidebar entry + i18n label across all locales.

* chore(compression): consume published omniglyph@^1.0.0 from the npm registry

Replaces the local file: dependency used during the preview phase — npm ci
now resolves omniglyph from the registry with integrity, unblocking CI.

* fix(compression): satisfy v3.8.47 quality gates for the omniglyph engine

- dependency-allowlist: approve omniglyph (own package, published from
  diegosouzapw/OmniGlyph; supply-chain review done by the maintainer)
- ladder maps (#6533 guard): rank omniglyph 80 (stackPriority 90, runs after
  every text engine) with expectedReductionFactor 0.35 (measured 0.23-0.33)
- drop the two explicit any casts in omniglyph tests (no-explicit-any is
  error-level in tests since #6218)

* chore(compression): rebaseline strategySelector for the omniglyph mode dispatch

+18 lines of cohesive dispatch/type wiring at the existing mode chokepoints
(sync no-op + async single-mode branch + providerTransport on the options
types) — not extractable without hiding the dispatch boundary, mirroring the
prior compression rebaselines. Also drops an unused eslint-disable directive
in image-aware-tokens.test.ts (warning-level red under --max-warnings 0).

* chore(quality): register inherited base tests in stryker tap.testFiles

masked-200-exhaustion-fallback-6427 and headroom-codex-quota-snapshot-6379
arrived via the base merge without their stryker registration —
check:mutation-test-coverage --strict requires covering tests to be listed.

* refactor(compression): keep omniglyph wiring under the complexity gate

- extract the async single-mode resolution to engines/omniglyphSingleMode.ts
  (runCompressionAsync was at complexity 17 after the mode branch; back <=15)
- split OmniglyphContextPageClient into section components (was 161 lines in
  one function; every function now under the 80-line cap)
- complexity baseline 2052->2053: the +1 is inherited base drift (the ratchet
  does not run on fast-path merges — same pattern as the v3.8.44/46
  rebaselines); this PR's own code is measured complexity-net-zero

* chore(quality): register 3 more inherited base tests in stryker tap.testFiles

route-guard-middleware-local-only, combo-diagnostics-trace and
idempotency-fusion-collision arrived via the latest base merge without their
stryker registration (fast-path merges skip check:mutation-test-coverage).

* chore(quality): cognitive-complexity baseline 883->884 (inherited base drift)

check:cognitive-complexity measures 884 identically on the pristine
origin/release/v3.8.47 tip and on this HEAD — the PR itself is
cognitive-net-zero (single-mode resolution extracted to its own module,
page client split into section components). Same inherited-drift pattern
as the v3.8.4x release rebaselines.

---------

Co-authored-by: diegosouzapw <diegosouzapw@devbox.local>
2026-07-08 07:56:44 -03:00
Jillur Rahman
95e4bf72d4 fix(playground): accept a dashboard session for presets under REQUIRE_API_KEY (#6554)
Merged — thank you, @developerjillur! Accept a valid dashboard session for /api/playground/presets under REQUIRE_API_KEY (the Playground page authenticates via cookie, not an API key). Integrated into release/v3.8.47.
2026-07-08 01:36:12 -03:00
Jillur Rahman
ed0b9c73de perf(health): short-TTL cache for GET /api/monitoring/health (#6553)
Merged — thank you, @developerjillur! Short-TTL (1s) cache for the frequently-polled GET /api/monitoring/health, invalidated on DELETE (circuit-breaker reset). Integrated into release/v3.8.47.
2026-07-08 01:36:03 -03:00
Jillur Rahman
63d15bcb93 feat(combo): sanitized diagnostic trace on auto-combo terminal failure (#6545)
Merged — thank you, @developerjillur! Sanitized diagnostic trace on an auto-combo terminal failure (ids/reason-codes only, capped), plus an actionable reasoning-budget-exhausted message. Integrated into release/v3.8.47.
2026-07-08 01:35:55 -03:00
Jillur Rahman
8d59e1f660 fix(security): fail-closed CORS for cloud-agent management routes (#6543)
Merged — thank you, @developerjillur! Fail-closed CORS for the cookie/session-authed cloud-agent management routes (allowlist echo, credentials only for an explicitly allowlisted origin). Integrated into release/v3.8.47.
2026-07-08 01:35:46 -03:00
Jillur Rahman
899c40da67 fix(security): SSRF-guard provider validation probes (block cloud metadata) (#6542)
Merged — thank you, @developerjillur! SSRF-guards the provider-validation probes (block-metadata + no redirect) so a caller-controllable baseUrl can't relay to cloud metadata. Integrated into release/v3.8.47.
2026-07-08 01:35:38 -03:00
Jillur Rahman
2c42599e33 fix(security): loopback-gate /api/middleware/* (arbitrary JS via vm.Script) (#6541)
Merged — thank you, @developerjillur! Loopback-gates /api/middleware/* (arbitrary JS via vm.Script) for RCE parity with /api/plugins/*. Integrated into release/v3.8.47.
2026-07-08 01:35:29 -03:00
Jillur Rahman
db0830e60a fix(fusion): judge replayed a panel answer via idempotency-key collision (#6558)
Merged — thank you, @developerjillur! Namespaces the idempotency key by target provider/model + a messages digest so fusion panel/judge sub-requests can't collide on a shared client Idempotency-Key. Existing chatCore extracted-module tests were aligned to the composed-key contract. Integrated into release/v3.8.47.
2026-07-08 01:35:01 -03:00