Commit Graph

1084 Commits

Author SHA1 Message Date
Nguyen Thanh Dat
8af5e752da feat(tts): add Fish Audio as a text-to-speech provider
Registry entry plus one config-driven FORMAT_HANDLERS handler. The model id
travels in an HTTP `model` header rather than the JSON body, and the voice is
a reference_id (preset or cloned voice model).

Closes #2411
2026-08-14 16:21:11 +07:00
zmf
8ed9da7165 feat(providers): add glm-5.3 to GLM Coding and GLM (China) registries
Zhipu released GLM-5.3 on both api.z.ai and open.bigmodel.cn coding
endpoints. Verified live against both, returning model:"glm-5.3" with
native reasoning_content.

No other changes needed: the '*glm-5*' family pattern in capabilities.js
and 'glm-5*' in pricing.js already cover it.
2026-08-14 16:16:46 +07:00
decolua
7e5f5a8813 fix(claude): re-anchor passthrough cache breakpoints with 1h TTL
Passthrough kept the client's own cache_control markers, which point at
pre-normalization offsets. Once normalize/dedupe reshaped system and tools,
the breakpoints landed mid-array and the tail was re-cached every request.

- Pin the last system block and last tool at ttl 1h (was the client's 5m)
- Anchor the last assistant turn at 5m, falling back to the final message
  so a first turn still gets a breakpoint
- Fold mid-conversation system messages into the neighbouring user turn
  instead of hoisting them into body.system, where the volatile token
  counters invalidated the prefix on every request
- Run the anchoring after every token saver, at the final body

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-14 16:08:30 +07:00
Bertho Joris
345cdcf6a5 fix(combo): detect images from Hermes and attachment payloads for Vision Adapter
Inspect images[], experimental_attachments/attachments, message-level
image/image_url/audio_url, and inline data:image|audio|pdf URIs on trailing
user turns so Vision Adapter auto-switch fires for Hermes/Ollama/Vercel AI
SDK shapes. stripOpenAI now also drops msg.images and image attachments when
the active model lacks vision support.
2026-08-13 18:30:44 +07:00
Duc Nguyen
65197ad11c feat(auth): add native SAML 2.0 SSO integration
Add SAML 2.0 as a second SSO protocol alongside OIDC under a unified
authMode/ssoType model. SP flows via @node-saml/node-saml: AuthnRequest
generation, ACS POST assertion handling, SP metadata export, and admin
config test endpoint. Replay-protected via saml_state cookie (httpOnly,
SameSite=Lax) matched against InResponseTo; wantAssertionsSigned enforced.

- src/lib/auth/saml.js: SAML instance builder, X.509 cert formatter, claim pickers
- 4 routes under src/app/api/auth/saml/: start, acs, metadata, test
- settingsRepo: ssoType + saml* defaults; login/status routes dispatch by type
- profile page: SSO protocol switcher, IdP metadata XML + cert uploaders
- login page: dynamic SAML sign-in button; Header: SAML user badge
2026-08-13 17:56:34 +07:00
Fadjrir Herlambang
e02bde4a70 feat(providers): add Kimchi API key support (dual OAuth + API key)
Kimchi's transport is OpenAI-compatible (Authorization: Bearer) but the
registry declared it OAuth-only, so the dashboard, /api/providers, and
the connection test all rejected API keys. Enable dual auth
(authModes: ["oauth", "apikey"]) and add a kimchi case to
testApiKeyConnection so the Test Connection button works for both modes.
Regenerate the golden snapshot with the Kimchi entries (+ other
previously-missing providers).
2026-08-13 17:53:44 +07:00
haumanto
30fec4318e fix(models): expose snake_case token limits on /v1/models 2026-08-13 12:19:06 +07:00
CyrixJD115
67271d859e fix(opencode): send official client headers on free-tier requests
Mirror the official opencode CLI fingerprint (User-Agent, x-opencode-session, x-opencode-request, x-opencode-project) on free-tier requests so the Console no longer classifies traffic as an unidentified client and rate-limits it with FreeUsageLimitError / HTTP 429.

Session id resolves conversation-stable via resolveSessionId (client session to assistant-text hash to connection) to preserve prompt caching, normalized into opencode ses_ format with a generated fallback. When the downstream client is already opencode, its headers are forwarded as-is.
2026-08-13 12:13:51 +07:00
stoXmod
b566b20ade fix(antigravity): strip competitive system prompts to prevent 429 quota errors
Zed IDE injects a Claude-agent system prompt that Antigravity flags as
competitive, blocking the request with a 429 Quota Exhausted response.
Scan systemInstruction.parts and remove the prompt before dispatch.
2026-08-13 12:11:30 +07:00
Clayton Tavares
6d30ce6de5 fix: Fusion strip stream_options + reasoning model test probe
- combos: strip stream_options from Fusion panel fan-out to avoid DeepSeek 400 (#3024)
- dashboard: raise model-test probe budget to 1024 + soft-pass reasoning-only responses (#3010)
2026-08-13 11:56:43 +07:00
rm1dev
5b417f9bf2 fix(kiro): intercept chat via x-amz-target and prepend initial-response frame
Kiro IDE 1.0.228+ moved GenerateAssistantResponse from path
/generateAssistantResponse to POST / + x-amz-target header, so chat turns
bypassed MITM. The SmithyMessageDecoderStream also now requires an
initial-response frame at stream start, and agent/vibe mode sends
modelId "auto" which had no mappable slot.

- Add isChatRequest() header-based match for kiro in mitm/config.js
- Add buildInitialResponseFrame/withInitialFrame to emit the mandatory
  initial-response once per stream (kiro.js)
- Add "auto" model slot and update mitmDomain to runtime.us-east-1.kiro.dev
2026-08-13 11:56:31 +07:00
Cokky Turnip
b57c041345 fix(providers): add llm7 to provider test support 2026-08-13 11:56:06 +07:00
zmf
8a527fec91 fix(security): SSRF guard on search baseUrl, default-password remote login, and request-details redaction
- resolveBaseUrl() rejects client-supplied non-public baseUrls via assertPublicUrl (SSRF guard on /v1/search)
- fresh-install remote login with default password returns 403 without issuing a JWT
- /api/usage/request-details redacts request/providerRequest/providerResponse/response payloads
- declare chalk and prop-types in package.json (used but previously undeclared)
2026-08-13 11:50:25 +07:00
Nguyen Thanh Dat
70ba0024b0 fix(translator): preserve prompt_cache_key when converting chat to responses 2026-08-13 11:46:49 +07:00
brimob-sowax
80afb59907 fix(qoder): detect billing blocks at stream start, return 403 for failover
Peek the first SSE frame in wrapQoderSSE; if statusCodeValue != 200 and the
body carries a billing signature (code 112/10605 or pricingUrl), return a
synthetic 403 so chatCore marks the connection unavailable and triggers
combo/account fallback instead of leaking the error text into chat.

wrapQoderSSE becomes async; consumed peek bytes are re-processed in the
stream start() seed loop so nothing is dropped.
2026-08-13 11:43:11 +07:00
chisewaguri
10a923da11 fix(responses): don't close message on empty tool_calls array
Some providers (e.g. codebuddy/cbcn) attach an empty tool_calls array to every streaming chunk. An empty array is truthy in JS, so the guard 'if (delta.tool_calls)' closed the message on the first content token and emitted response.output_text.done early, dropping the remaining deltas. Guard on a non-empty array; finish_reason still closes the message and real tool calls still close it before emitting function_call items.

fixes #3234
2026-08-13 11:40:45 +07:00
yusei21
01858feca0 docs(i18n): add Brazilian Portuguese documentation 2026-08-13 11:40:26 +07:00
Moein Arabi
e2a4fe048f fix(hermes): add api_key parameter to model block in YAML configuration 2026-08-13 11:35:02 +07:00
nguyenha935
b44bb09f72 fix(kiro): report real output tokens and stop discarding usable turns 2026-08-13 11:33:41 +07:00
decolua
456f2a2635 feat(usage): wire force flag through client + usage route
Manual refresh (↻) sends ?force=1 so it bypasses the Claude quota cache (dedup + TTL) added in cd4003bc. Auto-refresh and multi-tab stays cached, so Anthropic's usage endpoint is no longer hammered.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-13 11:31:07 +07:00
decolua
cd4003bc8b feat(usage): dedup + cache Claude quota calls to avoid 429
Multiple tabs/accounts/auto-refresh funneled straight to Anthropic and tripped 429. Add a 120s TTL cache keyed by access token with in-flight promise dedup, serve the last good read on soft failure, and thread a force flag through getUsageForProvider for manual refresh. Also lower the dashboard poll cadence (180s to 600s) and stable group-by-provider so connection order stops jumping.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-13 11:27:57 +07:00
decolua
71dcdc1053 fix(headroom): toggle reflects enabled setting even when proxy is down
Toggle was checked={headroomEnabled && headroomRunning} and disabled when the proxy was down, so a downed proxy showed OFF while headroomEnabled stayed true in the DB. The engine only checks headroomEnabled, so it kept calling /v1/compress. Toggle now reflects the user setting; proxy up/down stays visible via the status chip.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-13 11:27:49 +07:00
decolua
15223724c3 # v0.5.50 (2026-08-05)
## Features
- **Providers**: add TokenRouter (300+ models via OpenAI-compatible gateway) with
  exact per-model pricing for 110 models and `reasoning_effort` thinking config
- **Providers**: add Self-hosted STT / TTS / Embedding — point 9Router at your own
  OpenAI-compatible speech and embedding servers (whisper.cpp, faster-whisper,
  Kokoro-FastAPI, llama-server, vLLM, Infinity). Unlike the named cloud providers
  these read `baseUrl` per connection, so one provider can front several machines
- **Combos**: default-enable vision/audio capacity adapter (auto-routes to a
  vision/audio-capable model when the target lacks that capability, falling back
  to `oc/mimo-v2.5-free`), wired into chat handler routing
- **Endpoint**: auto-provision a "Default Key" for first-time users so `/v1`
  works without a manual dashboard step
- **Codex**: support GPT-5.6 Max/Ultra reasoning-level overrides (cx/ routes only)
- **Qoder**: support PAT (Personal Access Token) connections end-to-end, alongside
  OAuth device flow
- **CLI tools**: add OpenDesign (manalkaff/opendesign) support
- **Headroom**: report effective payload savings (tool schema/history bytes broken
  out, byte-savings % reflects actual outbound reduction)
- **Ollama**: Cloud quota tracker (session + weekly) + proactive background OAuth
  token refresh scheduler for all providers

## Fixes
- **Providers**: remove Qwen (OAuth flow stopped working reliably)
- **Passthrough**: detect codex-tui/Codex Desktop as native Codex client — they
  were falling through to the translator and losing fields like `reasoning.summary`
- **OAuth**: scope antigravity header fixes to loadCodeAssist/onboardUser only
- **OAuth**: keep `open` external in the build so xAI/Grok token refresh works on
  Windows
- **OAuth**: declare missing `searchParams` in register-session handler (was a
  500 instead of JSON on error)
- **DB**: `ENABLE_REQUEST_LOGS` env var now overrides the UI setting correctly;
  observability defaults to off (opt-in)
- **Translator**: preserve Codex Responses Lite tool use across chat-native
  OpenAI-compatible providers
- **Translator**: don't drop image-only user messages in `prepareClaudeRequest`
- **Translator**: drop JSON Schema keywords Gemini rejects (`uniqueItems`,
  `contains`, `multipleOf`, `unevaluatedProperties`, `unevaluatedItems`,
  `contentSchema`)
- **Claude**: remove global header cache that leaked one client's identity
  headers onto another client/account sharing the server; gate `anthropic-beta`
  by model instead
- **Antigravity**: drop retired Gemini 3.0 quota tiers, show Gemini 3.6 Flash
  usage bars
- **Cloudflare AI**: declare API key authentication (dashboard showed "No
  connections" despite an active key)
- **GitHub Copilot**: hold monthly-exhausted accounts until UTC month reset
  instead of only cooling down 120s
- **CodeBuddy**: dodge Tencent CN content filter, add usage tracking, normalize
  codebuddy-intl messages
- **Usage**: stop losing cached prompt tokens in the forced-SSE→JSON path
- **Grok CLI**: display the public subscription tier from the OAuth token claim
- **Providers**: count apikey connections for Ollama free-tier card; free-tier/
  apikey providers without `authModes` now default to apikey (were treated
  oauth-only)
- **Build**: include static/public assets in standalone output (login page hung
  on 404s when run via PM2)
- **Server**: support IntelliJ IDEA OpenAI-compatible clients over HTTP (h2c
  upgrade handling)
- **Auth**: redirect already-logged-in sessions away from `/login`
- **CLI tools**: enable Apply button for dynamic OpenAI/Anthropic-compatible
  provider connections
- **CLI**: include complete API artifacts in the CLI package
- **TTS**: a bare self-hosted model name is the MODEL, not the voice — `kokoro`
  was parsed as a voice against a default model, 404ing or synthesising with the
  wrong one
  endpoint that drops packets never returns headers, so the request previously
  hung indefinitely
2026-08-05 16:49:14 +07:00
decolua
35f86e5828 fix(oauth): scope antigravity header fixes to loadCodeAssist/onboardUser only
Google fingerprints User-Agent/Client-Metadata on loadCodeAssist and
onboardUser, silently refusing to provision a cloudaicompanionProject
when they don't match the real IDE. Split antigravity's headers out of
the shared gemini-cli constants instead of overwriting them, so the fix
doesn't touch gemini-cli or any other provider.

Inspired by #3000 (thanks @stoXmod for flagging the resource-exhausted
issue), rewritten to keep gemini-cli untouched.
2026-08-05 16:40:09 +07:00
Dasep Moch Luay
41588bea01 feat(providers): add TokenRouter accurate pricing + thinking config
Adds exact per-model rates for 110 TokenRouter models (pulled from
TokenRouter's own pricing API) plus a dedicated thinkingFormat case
(reasoning_effort enum low/medium/high/xhigh/max) and the provider
logo. Provider registration itself already landed in a prior commit;
this fills in what PR #3043 added on top.
2026-08-05 16:31:03 +07:00
decolua
03f8487cc7 test(baseline): regenerate provider/alias snapshots
Sync alias-baseline.json and providers-baseline.json with the current
registry (poolside, tokenrouter, selfhosted-* providers already added;
stale claudeOverlay hook and Kiro X-Amz-Target header already removed).
2026-08-05 16:27:17 +07:00
decolua
99639c0540 test(capacity-adapter): remove unit test file 2026-08-05 16:25:47 +07:00
decolua
e41d85037d test(capacity-adapter): add unit coverage for the capacity adapter service
Covers pool flattening, model augmentation for required capabilities,
context-window history stripping, and the withCapacityAdapterStripping
wrapper.
2026-08-05 16:25:12 +07:00
decolua
02c66fe2bd feat(endpoint): auto-provision default API key for first-time users
- Endpoint page auto-creates a "Default Key" when no keys exist yet,
  so /v1 works out of the box without a manual dashboard step
- Show/copy key buttons stay visible instead of opacity-0 by default
2026-08-05 16:22:06 +07:00
decolua
dcdd4628b3 fix(providers): remove Qwen provider support
Qwen OAuth flow (portal.qwen.ai) stopped working reliably; drop the
executor, registry entry, OAuth provider/service, token refresh
profile, usage handler, and related test coverage and baselines.
2026-08-05 16:17:26 +07:00
decolua
6498b3122f feat(combos): wire capacity adapter into chat handler routing
- detectRequiredCapabilities: infer audioInput/videoInput from block
  type and embedded mime, not just vision/pdf
- handleChat / handleSingleModelChat: augment combo and single-model
  routing with capacity-adapter models when the target lacks a
  required capability, wrapped with history stripping for the
  adapter model's context window
2026-08-05 16:12:55 +07:00
decolua
8e59093db7 feat(combos): default-enable vision/audio adapter with mimo fallback
- Enable vision + audioInput capacity-adapter pools by default for new
  and existing users (mergeWithDefaults backward-compat)
- Fall back to oc/mimo-v2.5-free when an enabled pool has no models
  configured, both in the backend resolver and the combos UI (auto
  refill on removing the last model from a pool)
- Hide PDF/Video from the Vision Adapter UI (PDF never implemented,
  Video lacks translator support) while keeping the settings shape
- Exclude combos from the model picker when opened from the Vision
  Adapter section
- mimo-v2.5 registry entry now declares audioInput/videoInput
- Simplify combo strategy and Vision Adapter descriptions
2026-08-05 16:09:42 +07:00
decolua
cd13d904d7 fix(passthrough): detect codex-tui/Codex Desktop as native Codex client
detectClientTool only matched the legacy "codex-cli" User-Agent, so the
current codex-tui CLI and Codex Desktop (UA "Codex Desktop", originator
"codex_work_desktop") fell through to null and lost native passthrough —
their requests got re-translated, stripping/overwriting fields like
reasoning.summary instead of forwarding the client body as-is.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-05 15:53:20 +07:00
omar-nahhas
fe547f4dc0 feat(providers): self-hosted OpenAI-compatible STT, TTS and embedding providers
Add Self-hosted STT/TTS/Embedding providers that read baseUrl per connection
instead of a fixed registry endpoint, so 9Router can point at whisper.cpp,
faster-whisper, Kokoro-FastAPI, llama-server, vLLM, Infinity, and similar
OpenAI-compatible local servers.

Self-hosted Embedding refuses to run without a baseUrl rather than falling
back to api.openai.com like openaiCompatNode does, since that fallback would
silently send input text and the API key to OpenAI under a provider named
"Self-hosted". Also fixes embeddingsCore to catch adapter build errors as a
400 instead of letting them escape uncaught, and bounds the upstream fetch
with FETCH_CONNECT_TIMEOUT_MS to avoid hanging forever on a dead endpoint.

Self-hosted TTS treats a bare model value as the model rather than the voice,
since the generic OpenAI TTS convention (bare = voice) is backwards for a
provider where the model is the variable part.
2026-08-05 13:38:13 +07:00
Ubuntu
b480892952 feat(providers): add TokenRouter provider
OpenAI-compatible gateway exposing 300+ models (OpenAI, Claude, Gemini,
Qwen, DeepSeek, Kimi, GLM, and more). Registered as p116, append-only.
2026-08-05 13:32:46 +07:00
RobertsXML
3fab15ae3e fix(db): implement ENABLE_REQUEST_LOGS env var override
- Add config priority chain: ENABLE_REQUEST_LOGS > UI setting > OBSERVABILITY_ENABLED fallback
- Fix transaction callback syntax from arrow to function
- Update saveRequestDetail guard to early return instead of semicolon
- Default enableObservability to false (opt-in)
2026-08-05 13:30:28 +07:00
nguyenha935
d06e0d26c6 fix(translator): preserve Responses Lite tools across Chat providers
Codex Responses Lite clients routed to a chat-native OpenAI-compatible
provider lost tool use in three places: non-streaming Chat responses
leaked the raw chat.completion envelope instead of Responses output
items, internal reasoning continuity fields leaked into the outbound
Chat body causing some upstreams to reject the request, and the
Responses to Chat request translator ignored additional_tools,
custom_tool_call, and custom_tool_call_output items entirely.

Also fixes apiType (chat vs responses) for openai-compatible nodes
being resolved from the immutable provider ID instead of the stored
node config, so editing a node's API Type had no runtime effect.
2026-08-05 13:27:25 +07:00
decolua
b11be8be0a fix(antigravity): drop retired Gemini 3.0 tiers from quota tracker
gemini-3-flash-agent, gemini-3-flash, and gemini-3-pro-image are retired;
they no longer need a quota bar in the tracker.
2026-08-05 13:24:57 +07:00
whale9820
42c691b3ea feat(antigravity): show Gemini 3.6 Flash usage bars in quota tracker
getAntigravityUsage filtered the fetchAvailableModels response through a
hardcoded importantModels list that only contained 3.5 Flash, silently
dropping the 3.6 Flash quota buckets so no usage bar rendered.
2026-08-05 13:21:38 +07:00
cardinusantara
a7941ddab4 fix(translator): don't drop image-only user messages in prepareClaudeRequest
hasValidContent() only treated text/tool_use/tool_result blocks as valid
content, so a user message containing only an image block was filtered
out as empty. When it was the only non-system message, this left an
empty messages array and Anthropic rejected the request.
2026-08-05 13:20:27 +07:00
Sutarto Jordan Chrisfivo
646b3b9ba3 fix(cloudflare-ai): declare API key authentication
Cloudflare AI registry entry was missing authType/authModes, causing
the dashboard to report "No connections" despite an active API-key
connection. Closes #2969
2026-08-05 13:13:54 +07:00
huuanh20
baebc9a06e docs(i18n): fix port typo and add RTK Token Saver features
Fix port 201281 -> 20128/v1 typo in README.zh-CN.md diagram, add
RTK Token Saver mention to README.vi.md/README.zh-CN.md, update
Tier 3 free providers to 2026 lineup, and drop hardcoded /tmp
node_modules path from tests/package.json and tests/README.md.
2026-08-05 11:55:02 +07:00
Matt Van Horn
25e4bf1c6c fix(cli): include complete API artifacts in CLI package
Merge the complete generated .next-cli-build/server tree into the
packaged CLI after the standalone copy, since Next's standalone output
is trace-pruned and can omit route modules (e.g. /api/v1/messages) or
chunks loaded dynamically. Add a post-copy integrity check for the
required API route artifacts so an incomplete package fails during
pack:cli instead of at runtime.

Fixes #2945
2026-08-05 11:54:16 +07:00
MiQieR
c570fe33ae feat(tts): add Xiaomi MiMo text-to-speech support
Adds mimo-v2.5-tts as a Media Provider TTS through the existing
OpenAI-compatible chat-completions endpoint. Voice is selected via the
top-level audio.voice field, and an optional style/language hint is
threaded through tts.js -> ttsCore.js -> the new adapter.
2026-08-05 11:46:23 +07:00
ryanngit
d0751bcff7 fix(grok-cli): display public subscription tier
Map the Grok OAuth access-token tier claim to the public plan label
and prefer it over internal /user entitlement names. Fails open to
existing plan detection for opaque or malformed tokens; upstream
remains authoritative for access and quota enforcement.
2026-08-05 11:43:40 +07:00
alfep
948dd8f89b fix(oauth): declare searchParams in register-session POST handler
Missing declaration caused a ReferenceError -> 500 HTML response instead
of JSON when clients called POST .../register-session.
2026-08-05 11:41:10 +07:00
seakleang.nhak
86131b9ca4 feat(codex): support GPT-5.6 Max and Ultra overrides
Add "ultra" reasoning level for Codex GPT-5.6 Sol and Terra, and expose
Max for Luna (Luna falls back Ultra to Max since it is not supported
upstream). Scoped to cx/ routes only; Kiro and generic OpenAI routing
unchanged.
2026-08-05 11:39:59 +07:00
Diwak4r
651df2f0e2 feat(cli-tools): add OpenDesign (manalkaff/opendesign) support
Adds a guide-type CLI Tools entry for OpenDesign, the open-sourced
claude.ai/design skills pack. It has no standalone config - it inherits
the host agent's model/provider config - so once the host (Claude Code,
Cursor, Codex, Gemini CLI, OpenCode) points at 9Router, /opendesign
sessions route through automatically.
2026-08-05 11:36:37 +07:00
minhnhat166
da8691f866 feat(headroom): report effective payload savings
Break out tool schema and tool-history bytes in the size snapshot and
add an effective byte-savings percentage so token-saved logs reflect
the actual outbound payload reduction, not just processed content.
2026-08-05 11:32:38 +07:00
decolua
13ed14568d fix(claude): remove global header cache, gate anthropic-beta by model
The global claudeHeaderCache singleton overlaid the last-seen Claude Code
client's identity headers onto every subsequent request, leaking one
client's headers (anthropic-beta, user-agent, x-stainless-*, etc.) onto
another client/account sharing the same server. Removed the singleton and
the claudeOverlay hook entirely, falling back to static per-provider
headers. anthropic-beta is now computed per-request from the requested
model, gating heavy-agent flags (advanced-tool-use, effort) to
opus/sonnet only.
2026-08-05 11:32:14 +07:00