Commit graph

405 commits

Author SHA1 Message Date
decolua
4443903900 fix: add normalization for Claude passthrough bodies 2026-06-08 15:37:01 +07:00
decolua
f8c59227f6 fix(kiro): auto-resolve profileArn to prevent 403 on IDC login
AWS OIDC IDC/Builder-ID tokens omit profileArn, so CodeWhisperer calls
return 403 "User is not authorized". Resolve it natively via the
ListAvailableProfiles API instead of reading Kiro IDE profile.json.

- providers.js: add fetchKiroProfileArn() and resolve on poll (new logins)
- tokenRefresh.js: backfill profileArn on refresh so existing IDC
  connections self-heal without re-login

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-08 09:45:58 +07:00
thienpv
c24efe80f0 feat(kiro): enable multi-endpoint failover for GenerateAssistantResponse
Wire the Kiro provider into BaseExecutor baseUrls fallback so a request
advances across the three CodeWhisperer surfaces (runtime kiro.dev,
codewhisperer, q) on 429 and network/5xx errors.

- providers.js: add baseUrls[] (newest endpoint first); keep baseUrl as default
- kiro.js: replace the hand-rolled single-endpoint loop with super.execute()
  delegation plus EventStream to SSE transform on success

Note: the three hosts are alternate DNS surfaces of one regional service. AWS
throttles per authenticated identity (token plus profileArn), not per hostname,
so this is edge-level failover, not extra 429 quota.

Co-authored-by: thienpv <pvtcwd@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-08 09:44:53 +07:00
Mr. Nasıl
c5815ad3f0 fix(commandcode): force stream=true in transformRequest
CommandCode upstream only speaks NDJSON streaming; the executor always
wraps it as OpenAI SSE. Force body.stream=true so non-stream client
requests still produce a parseable upstream stream (router aggregates
SSE→JSON downstream).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-08 09:21:52 +07:00
decolua
137a25e9ac fix(qoder): increase timeouts for reasoning models and improve stream handling 2026-06-08 09:17:33 +07:00
decolua
9caea88528 fix(codex): harden streaming timeouts + Responses terminal events
Raise stall/connect timeouts to 60s (configurable per-provider), accept
codex response.done, and always emit a terminal response.failed + [DONE]
for Responses passthrough when a stream closes, stalls, or aborts before
a terminal event — preventing codex clients from hanging.

Co-authored-by: jonathanli12 <jonathanli12@users.noreply.github.com>
Co-authored-by: rifuki <rifuki@users.noreply.github.com>
Co-authored-by: nguyenha935 <nguyenha935@users.noreply.github.com>
Co-authored-by: trananhtung <trananhtung@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-06 16:07:43 +07:00
Claude Code
c785051360 fix(claude): forced tool_choice 400 on cc/ OAuth route
convertOpenAIToolChoice mapped {type:"function"} verbatim and cloakClaudeTools
left tool_choice.name unsuffixed, both rejected by Claude on the cc/ path.
Map forced-function to {type:"tool",name}, allowlist Claude-valid types, and
suffix tool_choice.name when it targets a renamed client tool.

Fixes #1592

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-06 12:54:01 +07:00
arden1601
047792205f feat(caveman): add wenyan classical Chinese levels and sync upstream prompts
Add wenyan-lite/wenyan/wenyan-ultra levels for max token compression,
sync SHARED_EXAMPLES/AUTO_CLARITY/PERSISTENCE across all levels, and
expose 3 wenyan buttons in endpoint settings UI.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-06 12:35:08 +07:00
Farhan Usman
4fc02e67e5 fix(minimax): echo reasoning_content on follow-up turns to avoid 400
MiniMax requires reasoning_content echoed back on assistant messages in
multi-turn/tool-call conversations. Add minimax and minimax-cn to
PROVIDER_RULES (scope all), same fix as DeepSeek (#1543).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-06 12:25:12 +07:00
Simon Shi
8ad95542da fix(kiro): handle 400 on tool-bearing history without client tools
Kiro requires a non-empty currentMessage tools array whenever history
references any tool use, else returns "Improperly formed request" (400).
Clients trip this by omitting tools on follow-ups after client-side
compaction.

- flattenToolInteractions(): no client tools -> collapse tool_use/result
  to text so the "tools required" rule never fires
- reconcileOrphanedToolResults(): client tools -> salvage orphaned
  results as text, keep matched ones, guard co-located tools array
- safeJSONParse(): guard tool-call argument parsing against bad JSON
- merge consecutive user userInputMessageContext; null-guard
  currentMessage for assistant-only input

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-06 12:23:47 +07:00
Giao Ho
0850f0a470 fix(mitm): Kiro binary EventStream crash + add models & TTS tool filtering
- server.js: isBinaryData() skips binary AWS EventStream bodies (fix JSON parse crash)
- kiro.js: isBinaryEventStream detection + migrate to pipeTransformedEventStream pipeline
- base.js: add pipeTransformedSSE / pipeTransformedEventStream helpers
- chatCore.js: filter tool messages + tools for TTS models via getModelType()
- providerModels.js: add getModelType()
- cliTools.js: add gpt-5-mini (Copilot), glm-5 & minimax-m2.5 (Kiro)

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-06 11:31:52 +07:00
Kevin Le
c233c7c8fc fix(codex): durable OAuth refresh lifecycle
Add shared OAuth credential lifecycle manager with provider-aware refresh
decisions. Implement CodexExecutor.refreshCredentials so 401/403 retry
refresh works for Codex, track lastRefreshAt and refresh before the
upstream stale-token window, preserve omitted idToken, and add
per-connection single-flight refresh to avoid refresh-token rotation races.

Merged from PR #1664.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-06 11:04:36 +07:00
therunnas
61d546627e fix(qoder): allow qmodel_latest model key
- Add qmodel_latest to QODER_MODEL_MAP
- Expose qmodel_latest in static Qoder provider catalog (qd)
- Generalize executor comment so model set does not go stale
- Add unit coverage for the new model key + catalog

Closes #1638

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-06 10:44:37 +07:00
AbdoKnbGit
e6c09aad15 feat(antigravity): add gemini-3.5-flash-extra-low (Low) model
- Add gemini-3.5-flash-extra-low across CLI menu, provider models, usage, pricing
- Add MITM synonyms (high/medium/extra-low) and split pattern so Low no longer falls through to Medium
- Strip models/ prefix in getMappedModel for AG public name normalization

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-06 10:42:47 +07:00
Mr_NoboDy
40cfa63eb8 feat(xiaomi-tokenplan): add Claude-native MiMo V2.5 Pro alias via dedicated executor
Add mimo-v2.5-pro-claude alias routing to the Xiaomi TokenPlan Anthropic-compatible
/anthropic/v1/messages endpoint. Logic lives in a dedicated XiaomiTokenplanExecutor
(config-driven via targetFormat) instead of the shared DefaultExecutor.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-06 10:36:03 +07:00
zhangweihong
12c97ad46f feat(qoder): fetch latest model + nút import model trên dashboard
Merge PR #1642 (decolua/9router) — chỉ lấy code + i18n, bỏ test/docs/package.json.

- qoder.js: bỏ guard QODER_MODEL_MAP cứng, resolve model_config qua dynamic API (hỗ trợ qmodel_latest không cần sửa code)
- dashboard page: thêm nút "Fetch Qoder Models" tự import model list vào aliases
- i18n zh-CN: thêm key cho nút fetch

Co-Authored-By: Claude <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-06 10:22:03 +07:00
decolua
8671468360 Merge PR #1628: fix(model-test) route image and STT probes to their real endpoints
Route image model tests to /api/v1/images/generations and STT to
/api/v1/audio/transcriptions instead of forcing all non-embedding
models through chat completions. Adds kind-aware pingModelByKind,
hf->huggingface alias, and silent WAV sample for STT reachability.

Scoped to dashboard/internal model testing only; runtime inference
routing is unchanged.

Author: yicone <yicone@gmail.com>
Closes #1628
2026-06-06 10:03:32 +07:00
hodtien
41f94ce8c8 fix(minimax): Bổ sung MiniMax-M3 + cập nhật Quota Tracker coding/CN
Squash-merge PR #1631 (decolua/9router) — chỉ lấy file code + test, bỏ docs.

- feat(minimax): add MiniMax-M3 to intl + cn provider models (targetFormat claude)
- feat(minimax): add MiniMax-M3 pricing entry
- fix(minimax): translate Claude body khi content=null (M3 thinking-only)
- fix(minimax): hiển thị quota M-series bucket "general"/"MiniMax-M*" + percent-only
- test: minimax usage / model registration / pricing

Co-Authored-By: Claude <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-06 10:01:05 +07:00
yicone
e414975d0c Fix model test routing for image providers 2026-06-02 21:14:36 +08:00
decolua
e9ae21a723 # v0.4.66 (2026-05-29)
## Features
- Add Qoder provider: device-flow OAuth, COSY signing, WAF-bypass body encoding, live model catalog, dashboard quota tracker, 11 models (#1372)
- Add new models: Claude Opus 4.8 (Claude Code), GPT 5.4 Mini (Codex)

## Fixes
- DeepSeek thinking mode: echo `reasoning_content` back on follow-up/tool-call turns so OpenCode-free and custom providers no longer 400 with "reasoning_content must be passed back" (#1543)
- Reasoning injector: match deepseek/kimi model ids case-insensitively (covers custom providers using capitalized model names)
- OpenCode suggested-models: include free models without the `-free` suffix, e.g. `big-pickle` (#1535)

## Improvements
- Codex: trim sunset models, keep gpt-5.5 / gpt-5.4 / gpt-5.3-codex family, add gpt-5.4-mini
- volcengine-ark: refresh model list (add DeepSeek-V4-Flash/Pro, drop EOL entries)
- Lower stream stall timeout 35s → 30s for faster hang detection
2026-05-29 17:48:01 +07:00
Simon Shi
4baaa5c7aa Feat : qoder provider 2026-05-29 17:36:27 +07:00
Simon Shi
53c0eefa00 chore(qoder): rename display label from "Qoder AI" to "Qoder" 2026-05-29 17:36:27 +07:00
Simon Shi
af7f6b1de2 feat(qoder): show in Quota Tracker dashboard
Wire Qoder credits into the Quota Tracker card grid:

- Add `qoder` to USAGE_SUPPORTED_PROVIDERS so the connection passes the
  isUsageEligible filter at /api/providers/client and shows up in
  providerOptions on the dashboard.
- Reshape getQoderUsage so quota records (user, organization) live under
  `quotas` and scalar metadata (totalUsagePercentage, isQuotaExceeded,
  expiresAt) are siblings — the parser used to walk Object.entries(quotas)
  and would have rendered `totalUsagePercentage: 0.42` as a "0/0" row.
- Surface Qoder's expiresAt as resetAt on each quota record so the card
  shows when credits reset.
- Add a parser branch in ProviderLimits/utils.js: rename internal keys
  (user → "Personal", organization → "Organization"), drop empty org
  buckets so personal accounts don't render a misleading "0/0 Organization"
  row, and forward remaining/unit so the QuotaProgressBar can use them.
- Add Qoder's brand color (#EC4899) to ProviderLimitCard's color map.

42 tests still pass; build clean.
2026-05-29 17:36:27 +07:00
Simon Shi
935462ce8f test(qoder): add regression coverage for review-fix changes
Adds 18 new tests covering the bugs fixed in the previous commit so they
can't silently regress:

- parseExpiry (7 tests): numeric ms-epoch input, numeric strings handled
  before Date.parse so "1700000000" doesn't get year-interpreted, RFC3339
  strings, expires_in:0 honored as already-expired, 30-day fallback only
  when both inputs are missing/invalid

- normalizeMessages (4 tests): system hoisting, multipart text flatten,
  multiple system joining, empty input

- wrapQoderSSE (6 tests): the fixed cases — trailing partial line drained
  in flush(), no chunks forwarded after [DONE], embedded newlines stripped
  from inner body, error envelope produces error chunk + [DONE], non-ok
  responses returned unchanged

- expose parseExpiry from auth.js, expose normalizeMessages/wrapQoderSSE
  via __test__ from the executor (internals only — not part of the public
  API). Marked with comment so the surface is intentional.

42 tests total (24 original + 18 new). Build still clean.
2026-05-29 17:36:27 +07:00
Simon Shi
620b59ca0b fix(qoder): address review findings
Correctness:
- testUtils: drop checkExpiry so the userinfo URL probe actually runs (revoked
  tokens used to look "active" until local 30-day expiry passed)
- auth.parseExpiry: handle numeric expiresAt, swap parseInt before Date.parse
  so "2026" doesn't get interpreted as year-2026, treat expires_in:0 as
  already-expired instead of fabricating a 30-day default
- providers.mapTokens: synthesize email from userId when fetchUserInfo fails
  so OAuth dedup works (re-logins no longer accumulate "Account N" rows)

SSE wrapper:
- wrapQoderSSE: add !doneEmitted guard on success branch (chunks could leak
  past [DONE] when an error envelope shared a TCP packet with a valid one)
- flush(): finalize TextDecoder + drain trailing buffer so the chunk carrying
  finish_reason is delivered when upstream closes without a final \n
- sanitize literal \n inside inner OpenAI body so SSE framing stays intact

Robustness:
- executor: wrap buildCosyHeaders in try/catch so a missing accessToken
  returns 401 (re-auth) instead of bubbling as 500
- executor: short-circuit on missing accessToken before signing
- executor: plumb proxyOptions/signal through buildQoderRequestBody so
  proxy-only networks can fetch the model_config catalog
- qoderModels: dedupe concurrent first-time misses with an in-flight Promise
  map (parallel chat windows now do 1 upstream fetch instead of N)
- qoderModels: check signal.aborted before addEventListener so a pre-aborted
  parent signal cancels the inner fetch immediately
- auth: AbortController + 15s timeout on pollDeviceToken / fetchUserInfo to
  prevent hung sockets when openapi.qoder.sh stalls mid-response

UX:
- OAuthModal: derive polling deadline from device-code expires_in (qoder
  publishes 300s; the previous fixed 120s caused timeouts when users took
  more than 2 minutes on the consent page)

Cleanup:
- delete src/lib/oauth/services/qoder.js — referenced removed config fields
  (clientId/clientSecret/tokenUrl/authorizeUrl) and was re-exported from
  services/index.js, so any future caller would TypeError on first use
2026-05-29 17:36:27 +07:00
Simon Shi
a6fd84691b feat(qoder): port Kiro-style provider integration with COSY signing
Replaces the Qoder placeholder with a real free-tier provider:

- Device-flow OAuth: PKCE + nonce generated locally, user authorizes at
  qoder.com/device/selectAccounts, poll openapi.qoder.sh until token
- COSY signing (RSA-1024 + AES-128-CBC + MD5) for chat / model-list
- WAF-bypass body encoding (custom-alphabet base64 + thirds rearrange)
- Live model_config catalog from /algo/api/v2/model/list, cached 1h
- 11 models registered (auto/ultimate/performance/efficient/lite +
  6 frontier *model ids)
- Usage fetcher for openapi.qoder.sh/api/v2/quota/usage
- Dashboard live-models resolver, provider test, OAuth modal hookup
- 24 unit tests covering encoder, PKCE, COSY headers, sigPath stripping
2026-05-29 17:36:27 +07:00
decolua
468c61b2ac Added new models for Claude Opus 4.8 and GPT 5.4 Mini.
Disabled Cowork
2026-05-29 17:36:27 +07:00
Delcado
88224b80ca
fix: never route GitHub Copilot Gemini/Claude models to /responses (#1062) (#1536)
GitHub Copilot's /responses endpoint only serves OpenAI (gpt/codex)
models. gemini-3.1-pro-preview was failing on /chat/completions with a
"not supported" error, getting cached as a codex model, then escalated
to /responses where it 400s with "does not support Responses API".

Add GithubExecutor.supportsResponsesEndpoint() and gate both the cached
/responses route and the 400-fallback on it, so Gemini/Claude always
stay on /chat/completions and the real upstream error surfaces.

Adds tests/unit/github-responses-routing.test.js (5 tests).

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-29 15:40:42 +07:00
decolua
9742074b38 # v0.4.63 (2026-05-26)
## Fixes
- proxyFetch: restore missing `Readable` import causing runtime `ReferenceError` in DNS-bypass fetch path

## Improvements
- Lower stream stall timeout from 60s → 35s for faster hang detection
2026-05-26 23:16:21 +07:00
decolua
146310a3a3 Fix Bug 2026-05-26 23:09:19 +07:00
decolua
ac2fee7305 # v0.4.62 (2026-05-26)
## Fixes
- Codex: auto-retry when upstream drops mid-stream (no more hangs)
- Codex: fix random 400/404 errors, tool-calling failures, and unstable prompt cache
- MITM: support Antigravity 2.x
- Sanitize Read tool args to prevent retry loops from non-Anthropic models (#1144)
- Implement json_schema fallback for OpenAI-compatible providers without native Structured Output (#1343)
- Strip empty Read pages argument in OpenAI-to-Claude translator (#1354)
- Forward Gemini output dimensions for embeddings (#1366)
- Resolve setState-in-effect errors in dashboard components (#1362)
- Gemini CLI: reuse stored OAuth project IDs for quota checks and show clearer setup guidance when the project is missing (#1271, #1428)
2026-05-26 13:15:59 +07:00
decolua
0065bbbdfd # v0.4.62 (2026-05-26)
## Fixes
- Codex: auto-retry when upstream drops mid-stream (no more hangs)
- Codex: fix random 400/404 errors, tool-calling failures, and unstable prompt cache
- MITM: support Antigravity 2.x (updated IDE version detection and DNS/cert flow)
- Sanitize Read tool args to prevent retry loops from non-Anthropic models (#1144)
- Implement json_schema fallback for OpenAI-compatible providers without native Structured Output (#1343)
- Strip empty Read pages argument in OpenAI-to-Claude translator (#1354)
- Forward Gemini output dimensions for embeddings (#1366)
- Resolve setState-in-effect errors in dashboard components (#1362)
- Gemini CLI: reuse stored OAuth project IDs for quota checks and show clearer setup guidance when the project is missing (#1271, #1428)
2026-05-26 12:46:30 +07:00
mustafabozkaya
f3176b4b23 fix: implement json_schema fallback for OpenAI-compatible providers (#1343)
When json_schema response_format is sent to models that do not natively
support Structured Output (e.g. DeepSeek/Ollama/local LLMs via
openai-compatible-* providers), they often return empty or malformed
content.

Detect response_format.type === "json_schema", inject the schema into the
system prompt, and downgrade response_format to json_object so Structured
Output works transparently across openai-compatible providers.

Gated to provider.startsWith("openai-compatible-") so providers with
native Structured Output support are not downgraded.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-26 11:35:39 +07:00
decolua
a648a42bdb Fix codex 2026-05-26 11:35:39 +07:00
decolua
b876e0225a Refactor Tunnel 2026-05-26 11:35:39 +07:00
GodrezJr2
96a9a2b36d
fix: sanitize Read tool args to prevent retry loops from non-Anthropic models (#1144)
* fix: sanitize Read tool args to prevent retry loops from non-Anthropic models

* fix: sanitize invalid Read pages from tool args

Non-Anthropic models sometimes emit optional Read args like pages: "" for
non-PDF files, which Claude Code rejects before the tool runs. Drop invalid
pages values, keep valid PDF page ranges, and coerce numeric string bounds
before clamping limit/offset.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 11:33:38 +07:00
Delcado
dcc46f2eee
Reuse Gemini CLI project ID for usage (#1428) 2026-05-26 11:23:47 +07:00
Hamsa_M
315dcaa37a
fix: strip empty Read pages argument in OpenAI-to-Claude translator (#1354)
Some OpenAI-compatible providers emit optional string tool parameters
as empty strings (e.g. pages: "") instead of omitting them. Claude
Code rejects pages: "" as invalid, breaking the Read tool for
non-PDF files routed through 9router.

Add sanitizeToolArguments() that parses tool-call arguments and
removes known optional empty-string fields before emitting
input_json_delta back to Claude format. Currently handles the
Read tool pages field specifically.

Includes regression test.

Fixes #1278

Co-authored-by: JoJo <noreply@github.com>
2026-05-23 09:27:13 +07:00
YourAnsh
2604b46847
fix (#1361)
Co-authored-by: Ansh7473 <Ansh7473@users.noreply.github.com>
2026-05-23 09:26:10 +07:00
nguyenha935
7bc97eae7b
fix(embeddings): forward Gemini output dimensions (#1366)
Co-authored-by: GoClaw Operator <operator@goclaw>
2026-05-23 09:23:26 +07:00
decolua
6b0dc09239 Merge PR #1300: tailscale Windows fix, quota pagination, SSE abort handling
- fix(tunnel): cross-platform tailscale probes without shell redirection
- feat(usage): paginate provider limits with page size controls
- feat(providers): stop control for one-by-one connection testing
- fix(sse): close stream gracefully on abort/disconnect instead of pipe errors
- ui(quota): simplify header, always show pagination in one row

Co-authored-by: philau2512 <dplau25122002@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 12:15:07 +07:00
Muhammad Mugni Hadi
d976f4cc87 feat(xai): add xAI Grok provider with OAuth + API key auth + image
Adapted from PR #1286 (mugnimaestra/feat/xai-grok-provider) to match
existing app architecture. Includes:

- OAuth 2.0 with PKCE on loopback port 56121 (Grok Build)
- API key auth path (console.x.ai)
- Token refresh wiring (open-sse + sse tokenRefresh)
- Dashboard OAuth modal with fixed-port flow + manual code fallback
- Provider registry entries (OAuth + API key)
- xAI image generation via OpenAI-compatible adapter
  (grok-2-image-1212 model, no size/quality/style params)

Excludes (intentionally, to match app patterns):
- Custom xAI Responses executor (DefaultExecutor handles /chat/completions)
- xAI-specific translators (app uses OpenAI as intermediate format)
- Image edits (not supported by current imageGenerationCore)
- Video endpoints (app has no video subsystem yet)
- CLI xai-login command

Refs decolua#1286

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 11:33:18 +07:00
Noé Rivera
e3cab135ef
fix: decode Composer cursor thinking output (#1310) 2026-05-21 09:52:30 +07:00
decolua
613a0a819a # v0.4.55 (2026-05-18)
## Features
- Xiaomi MiMo Token Plan: region selector (Singapore / China / Europe) — keys are cluster-specific
- Antigravity: risk confirmation dialog before first connection
- Gemini CLI: surface upstream retry delay on 429 errors

## Fixes
- MITM: cannot kill process on macOS under sudo (lsof not found in PATH)
- Stream: false-positive stall timeout on Claude reasoning / Kiro responses
- Tunnel: cannot re-enable after disable (stuck state)
- Tunnel: cloudflared error messages now include log tail for easier debugging
- Language switcher: applies selected locale immediately on close (#1234)
- Antigravity OAuth: metadata now matches the official client

## Improvements
- Gemini CLI: bump engine to 0.34.0
- Re-hide `qwen` (OAuth EOL) and `iflow` (not ready) providers
2026-05-18 16:26:35 +07:00
NoxzRCW
3e52af35e2 feat(gemini-cli): wrap CloudCode payload and surface 429 retryDelay
- Send { project, model, request } envelope expected by Cloud Code Assist
- Parse google.rpc.RetryInfo from 429 responses to expose retry hint

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-18 15:23:38 +07:00
NoxzRCW
eaf770a28e chore(gemini-cli): bump version to 0.34.0 and refine user-agent
- GEMINI_CLI_VERSION 0.31.0 -> 0.34.0
- UA now appends `terminal` suffix and maps ia32 -> x86

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-18 15:23:38 +07:00
Z User
8daa953ef6 fix(oauth): align antigravity OAuth metadata with official client headers
Fixes #1226

The Antigravity OAuth flow sent inconsistent client metadata between
the token acquisition phase and the API usage phase. String enum values
(IDE_UNSPECIFIED, PLATFORM_UNSPECIFIED) were used during OAuth token
exchange + loadCodeAssist + onboardUser, while numeric enums (ideType: 9,
platform: <computed>, pluginType: 2) were used in runtime API calls.
Google detected this fingerprint mismatch and blocked 9router accounts.

Replace all string enum occurrences with the correct numeric values:

- src/lib/oauth/constants/oauth.js: loadCodeAssistClientMetadata now
  uses getOAuthPlatformEnum() for platform and numeric 9/2 for
  ideType/pluginType, matching getOAuthClientMetadata()
- src/lib/oauth/services/antigravity.js: getMetadata() now delegates
  to getOAuthClientMetadata() instead of returning hardcoded strings
- src/lib/oauth/providers.js: postExchange metadata now uses
  getOAuthClientMetadata() instead of inline string enums
- open-sse/services/usage.js: getGeminiSubscriptionInfo body now uses
  CLIENT_METADATA (already imported from appConstants.js) instead of
  inline string enums
2026-05-18 15:23:37 +07:00
Muhammad Zakir Ramadhan
94960c6cf5
fix: enhance stall detection in stream handling for improved disconne… (#1243)
* fix: enhance stall detection in stream handling for improved disconnect management

* fix: improve stall detection handling in pipeWithDisconnect to prevent stale aborts
2026-05-18 12:00:33 +07:00
decolua
9abbb8ad9b # v0.4.52 (2026-05-17)
## Features
- Add Vercel AI Gateway provider support (#1183)
- rtk: Kiro format tool result compression — handle conversationState.history & currentMessage, preserve error results, ~13.6% savings (#1194)

## Fixes
- openclaw: normalize agent.model object form `{primary, fallbacks}` before .startsWith → fix TypeError & 'not configured' status (#1216)
- Usage Details pagination: stay inside mobile viewport <640px (#1218)
- Fix test model error
- Fix MIMO provider in Codex
- Disable log file creation when using MITM AG
2026-05-17 16:37:26 +07:00
Ngô Tấn Tài
9326589452
Add Vercel AI Gateway provider support (#1183) 2026-05-17 15:16:25 +07:00
Zanuar Tri Romadon
e03b28138a
feat(rtk): add Kiro format support for tool result compression (#1194)
- Add compressKiroFormat() to handle conversationState.history and currentMessage
- Compress toolResults[].content[].text in Kiro's AWS CodeWhisperer format
- Preserve error tool results (status === 'error')
- Add 7 comprehensive tests covering all edge cases
- Verified with real usage: 13.6% savings on npm install output
2026-05-17 15:13:37 +07:00
decolua
4a575f21a2 https://github.com/decolua/9router/pull/1167
https://github.com/decolua/9router/pull/1166
2026-05-16 11:20:08 +07:00
decolua
3cca2252a6 chore: add buildOutput RTK filter, drop legacy cloud sync, internal cleanup
- feat(rtk): buildOutput filter + autodetect for npm/yarn/cargo logs
- chore: remove unused cloud sync module and related routes
- ui: hide deprecated providers (qwen, iflow, antigravity)
- chore: minor tray/cli/internal adjustments
2026-05-16 10:54:41 +07:00
anhvandev
75904b8c27
feat(open-sse): add blackbox provider with bb alias (#1143) 2026-05-15 10:50:19 +07:00
decolua
d26db17f5f Add xiaomi token plan provider 2026-05-15 10:29:25 +07:00
Aqil Aziz
da00a25eef
feat: add DeepSeek V4 Pro effort aliases (#950) 2026-05-14 10:39:34 +07:00
Fresent
d1613e8ad5
Fix issue with Ollama usage not being tracked and shown in 9router UI (#1102)
Co-authored-by: Abhi <abhi@fresent.com>
2026-05-14 09:58:18 +07:00
YourAnsh
eaccb19f59
feat: add DeepSeek TUI as CLI tool in dashboard (#1088)
Co-authored-by: Ansh7473 <your-github-email@example.com>
2026-05-13 22:40:42 +07:00
Thiên Toán
74c9879e8e
feat: add minimax tts support (#1043) 2026-05-13 15:34:10 +07:00
Aleksei
ea44ca049e
Add Codex GPT 5.5 image support (#991) 2026-05-12 09:26:13 +07:00
decolua
8f4d29caa4 # v0.4.30 (2026-05-11)
## Features
- MCP stdio→SSE bridge: expose local stdio MCP plugins over SSE (api/mcp/[plugin]/sse, /message)
- Dynamic Linux cert resolution + NSS DB injection (Debian/Arch/Fedora/openSUSE, Chrome/Chromium/Firefox incl. snap) (#1010)
- Cowork tool: expanded settings UI & API
- GitBook docs (DocsContent, DocsLayout)
## Fixes
- OAuth callback postMessage scoped to expected origins (CWE-1385) (#998)
- Re-enable TLS verification on DNS-bypass fetch (CWE-295) (#998)
- Normalize `developer` role → `system` for OpenAI-format providers (Deepseek, Groq, …) (#1011, closes #773)
- Respect `PORT` env in internal model-test fetch (#1014)
- Dropdown text readability in dark theme on usage page (#997)
## Improvements
- Refactor Claude CLI spoof headers into shared constant
- Tool deduper utility in open-sse handlers
2026-05-12 09:19:50 +07:00
Tran Hoang Nguyen
80a2bfcfd7
fix: normalize developer role to system for OpenAI-format providers (#1011)
Deepseek API (and likely other providers) reject messages with
role: 'developer' — only accept system, user, assistant, tool.
filterToOpenAIFormat() normalizes content blocks but never touched
message roles, so developer passed through unmodified and caused
400 errors (issue #773).

Fix: add one-line developer → system mapping in filterToOpenAIFormat()
before role-specific logic. This is the common normalization point
called for all targetFormat=openai providers (Deepseek, Groq, Mistral,
Perplexity, Together, Fireworks, Cerebras, xAI, NVIDIA, etc.)

Closes #773
2026-05-11 15:57:28 +07:00
decolua
7ad538bcf2 # v0.4.29 (2026-05-10)
## Features
- Add Cline & Kilo Code tool cards
- Tailscale TUN mode for stable Funnel TLS
- Sort APIKEY providers by usage, collapse to top 20

## Improvements
- Local Material Symbols font (no Google Fonts)
- Docker base: Bun → Node 22-alpine
- MITM reads aliases from JSON cache (no native sqlite)
- Stream stall timeout (2 min) in open-sse

## Fixes
- Fal.ai key test: use stable models endpoint
2026-05-10 21:56:40 +07:00
@aaronjmars
52c38cf94c
fix(security): scope OAuth callback postMessage targets and re-enable TLS verification on DNS-bypass fetch (#998)
Two findings, neither blocked by anything else:

1. src/app/callback/page.js — the OAuth callback page posted the
   { code, state } payload to window.opener with targetOrigin "*", so any
   page that opened the popup against the well-known redirect_uri received
   the live OAuth code. The expectedOrigins list was already computed but
   never used. Iterate over it and pass the origin per send.

2. open-sse/utils/proxyFetch.js — createBypassRequest() set
   rejectUnauthorized: false on the HTTPS request that runs after the
   Google-DNS-resolved real-IP fallback (used for cloudcode-pa.googleapis,
   GitHub Copilot, Cursor, AWS LLM endpoints). Combined with servername:
   parsedUrl.hostname this gave SNI-correct connections that nonetheless
   ignored cert validation, so an on-path attacker could swap in their
   own cert and read the user's API tokens / prompts. Drop the flag.

Detected by Aeon + semgrep (javascript.browser.security.wildcard-postmessage-configuration
+ problem-based-packs.insecure-transport.js-node.bypass-tls-verification).
Severity: HIGH (#1) / MEDIUM (#2).
CWEs: CWE-1385 (#1), CWE-295 (#2).

Co-authored-by: aeonframework <aeon@aeonframework.dev>
2026-05-10 21:10:48 +07:00
Tran Long
c734913b3f
Update DeepSeek model pricing and add V4 Pro (#938)
Update all DeepSeek model prices to match current V4 Flash pricing
($0.14/$0.28 per 1M input/output tokens), and add V4 Pro model with
its own pricing ($0.435/$0.87). Also add deepseek-v4-pro to the
provider model list.

Co-authored-by: smarthomeblack <truongbber@gmail.com>
2026-05-09 10:11:39 +07:00
Aleksei
787d248030
Add Cloudflare Workers AI image generation (#973) 2026-05-09 09:53:39 +07:00
decolua
ad661c1286 feat: enhance CommandCode integration with improved message handling 2026-05-07 23:02:07 +07:00
decolua
b72a443bd3 feat: add CommandCode provider support 2026-05-07 23:01:33 +07:00
decolua
0d61a1d546 feat: add OllamaLocalExecutor and update provider handling
- Introduced OllamaLocalExecutor to handle requests for the "ollama-local" provider.
- Removed the direct URL construction for "ollama-local" from BaseExecutor.
- Updated index.js to include the new OllamaLocalExecutor in the executors mapping.
- Enhanced the ProvidersPage component to support dynamic addition of OpenAI/Anthropic compatible providers.
2026-05-07 16:42:36 +07:00
Muhammad Mugni Hadi
7f93df3a92
feat: add audio input support for Gemini translation (#913)
Add input_audio and audio_url content type handlers to
convertOpenAIContentToParts() in geminiHelper.js, converting
OpenAI audio format to Gemini inlineData format.

Also add audio types to VALID_OPENAI_CONTENT_TYPES in
openaiHelper.js so they are not stripped by filterToOpenAIFormat().

Fixes #912
2026-05-07 15:51:30 +07:00
decolua
5c62e73cc6 - Cowork: ComboFormModal
- BaseUrlSelect: add cloud endpoint option, custom URL local state, always
  default to first option; new cliEndpointMatch helper; CLI tool cards refactor
- API: new /v1/audio/voices and /v1/models/info; /v1/models filters disabled
  models, drop unused timestamp
- initializeApp: guard tunnel/tailscale auto-resume to once-per-process
- geminiHelper: ensureObjectType for schemas with properties but no type
- skills: minor SKILL.md tweaks (chat/embeddings/image/stt/tts/web-*)
2026-05-07 15:45:09 +07:00
decolua
d4bc42e1f5 feat: add STT support, Gemini TTS, and expand usage tracking
- Speech-to-Text: full pipeline with sttCore handler, /v1/audio/transcriptions
  endpoint, sttConfig for OpenAI, Gemini, Groq, Deepgram, AssemblyAI,
  HuggingFace, NVIDIA Parakeet; new 9router-stt skill
- Gemini TTS: add gemini provider with 30 prebuilt voices and TTS_PROVIDER_CONFIG
- Usage: implement GLM (intl/cn) and MiniMax (intl/cn) quota fetchers; refactor
  Gemini CLI usage to use retrieveUserQuota with per-model buckets
- Disabled models: lowdb-backed disabledModelsDb + /api/models/disabled route
- Header search: reusable Zustand store (headerSearchStore) wired into Header
- CLI tools: add Claude Cowork tool card and cowork-settings API
- Providers: introduce mediaPriority sorting in getProvidersByKind, add
  Kimi K2.6, reorder hermes, drop qwen STT kind
- UI: expand media-providers/[kind]/[id] page (+314), enhance OAuthModal,
  ModelSelectModal, ProviderTopology, ProxyPools, ProviderLimits
- Assets: refresh provider PNGs (alicode, byteplus, cloudflare-ai, nvidia,
  ollama, vertex, volcengine-ark) and add aws-polly, fal-ai, jina-ai, recraft,
  runwayml, stability-ai, topaz, black-forest-labs
2026-05-05 10:32:59 +07:00
decolua
9c6be62a54 Feat : Skills 2026-05-04 11:29:02 +07:00
decolua
4ba546afe7 Enhance token refresh logic and improve MITM server handling
- Introduced a caching mechanism for in-flight token refresh requests to prevent race conditions and reduce unnecessary API calls.
- Added error handling for unrecoverable refresh errors, ensuring that the application can gracefully handle token reuse and invalidation scenarios.
- Updated the MITM server management to handle port 443 conflicts, allowing users to kill processes occupying the port before starting the server.
- Improved user feedback in the MitmServerCard component regarding port conflicts and admin privileges.
- Refactored the ComboList component to streamline the display of media provider combos.

This update aims to enhance the reliability and user experience of the token management and MITM functionalities.
2026-05-03 22:10:03 +07:00
Anurag Saxena
8bdaeedb28
fix: strip stream_options for qwen non-streaming Claude Code requests (closes #557) (#663) 2026-05-03 15:21:43 +07:00
Anurag Saxena
67ca219fbf
fix: update Qwen OAuth URLs from chat.qwen.ai to qwen.ai (closes #574) (#687) 2026-05-03 15:18:45 +07:00
Rezky Hamid
a463ee00ff
feat(codex): add review model quota support (#836) 2026-05-03 14:57:33 +07:00
Zhen
14ff538f2e
Improve mobile layouts and restore Cloudflare provider (#840)
Co-authored-by: Delynn Assistant <zhen@dkzhen.org>
2026-05-03 14:55:43 +07:00
decolua
f410061e70 Refactor proxyFetch and enhance MediaProviderDetailPage layout
- Removed the isCloud check from proxyFetch.js, simplifying the fetch patching logic.
- Updated MediaProviderDetailPage to include a new section for API key retrieval, improving user experience with clearer layout and additional notice text.
- Enhanced ConnectionRow to better handle email display names.
- Improved ProviderDetailPage to conditionally render provider notices and API key links.
- Refactored localDb, requestDetailsDb, and usageDb to remove unnecessary isCloud checks, streamlining database interactions.
- Updated OAuthModal to combine waiting and manual input steps for a more cohesive user flow.
- Added API key URLs to several providers in providers.js for better accessibility.
2026-05-01 17:03:13 +07:00
decolua
f8d2a9ff76 Merge branch 'master' of https://github.com/decolua/9router 2026-05-01 16:37:11 +07:00
Abhishek Divekar
3f17ee0e21
Add sticky round-robin for combos (#831)
Made-with: Cursor
2026-05-01 16:36:36 +07:00
decolua
b0da7c1211 Add Xiaomi MiMo provider support
- Introduced Xiaomi MiMo as a new provider in providerModels.js and providers.js.
- Updated model alias mapping in model.js to include Xiaomi MiMo.
- Enhanced validation route to support Xiaomi MiMo API endpoints.
- Added Xiaomi MiMo to APIKEY_PROVIDERS with relevant details.

This update expands the range of supported providers, improving integration capabilities.
2026-05-01 16:32:25 +07:00
thuanhuynhh
9ca388972c
Update providerModels.js (#818)
KIMI K2.5 will be deprecated on 05/05/2026. Update latest Minimax version
2026-05-01 16:20:40 +07:00
Rezky Hamid
30b114ab75
fix: strip output_config for MiniMax (#820) 2026-05-01 16:16:01 +07:00
decolua
936d65ae1c Enhance chat handling and introduce Caveman feature
- Refactored handleChatCore to include Caveman functionality, allowing for terse-style system prompts to reduce output token usage.
- Updated APIPageClient to manage Caveman settings, including enabling/disabling and selecting compression levels.
- Adjusted AntigravityExecutor to consolidate function declarations for compatibility with Gemini.
- Removed unnecessary console logs during translator initialization across multiple routes.
2026-04-30 18:00:38 +07:00
decolua
512e3de371 Update version to 0.4.9, enhance README with Trendshift badge, and add new embedding models to providerModels.js. Refactor TTS handling to support additional providers and improve API key validation for media providers. 2026-04-29 11:34:39 +07:00
decolua
e8aa5e2222 Fix : Add reasoning_content placeholder for DeepSeek thinking models 2026-04-29 09:34:24 +07:00
decolua
8f81363675 Enhance token refresh functionality across multiple executors
- Updated refreshCredentials methods in various executors (Antigravity, Base, Default, Github, Kiro) to accept optional proxyOptions for improved proxy handling.
- Modified token refresh logic to utilize proxy-aware fetch for better network management.
- Enhanced usage retrieval functions to support proxy options, ensuring seamless integration with proxy configurations.
- Updated ModelSelectModal and ProviderInfoCard components to incorporate kind filtering for improved user experience in model selection.
- Added validation for API keys in the provider validation route, including support for webSearch/webFetch providers.
2026-04-28 17:28:57 +07:00
decolua
1bb621317d Add Cloudflare AI provider support and enhance connection management
- Introduced Cloudflare AI as a new provider with specific configurations in providerModels.js and providers.js.
- Updated DefaultExecutor to handle account ID resolution for Cloudflare AI connections.
- Enhanced AddApiKeyModal and EditConnectionModal to include account ID input for Cloudflare AI.
- Implemented validation for Cloudflare AI API key connections in testUtils.js and route.js.
- Updated UI components to reflect changes in provider management and connection handling.
2026-04-28 11:07:39 +07:00
decolua
111e78940a Refactor cloudflared process management to improve port-specific termination and enhance tunnel management. Update Antigravity cloaking comments for clarity. 2026-04-28 10:20:31 +07:00
decolua
a3032f7a3e Merge branch 'pr-779-review' 2026-04-28 10:16:23 +07:00
Zhen
85959aac22
Fix quota reset timestamp parsing (#768)
Co-authored-by: Delynn Assistant <zhen@dkzhen.org>
2026-04-28 10:05:54 +07:00
Manuel B.
58a821d687
fix: granular reasoning_effort handling for Claude models (#791)
- github.js: split thinking vs reasoning_effort stripping
  - thinking (Claude-native format) still stripped for all Claude on Copilot
  - reasoning_effort now passed through for Opus 4.6 and Sonnet 4.6
  - still stripped for Haiku 4.5 and Opus 4.7 (rejected upstream)
  - reasoning_effort "none" stripped for all models (not all support it)
- openai-to-claude.js: map reasoning_effort → thinking.budget_tokens
  for direct Anthropic backend (none→skip, low→4096, medium→8192,
  high→16384, xhigh→32768)

Previously reasoning_effort was stripped for ALL Claude models,
meaning Opus 4.6 via Copilot never received thinking configuration.

AI-generated commit by Claude Opus 4.6 (Anthropic)
2026-04-28 09:49:27 +07:00
lukmanfauzie
c43f8c54d4 fix: Antigravity INVALID_ARGUMENT errors and Copilot agent mode parity 2026-04-26 19:53:08 +08:00
lukmanfauzie
222e22fa53 Fix GitHub Copilot agent mode with Antigravity
Co-authored-by: Copilot <copilot@github.com>
2026-04-26 17:47:13 +08:00
decolua
83418e8a9d Add codex to image providers 2026-04-25 17:01:40 +07:00
decolua
14ff69bf90 - Added BytePlus Provider 2026-04-25 17:00:39 +07:00
decolua
0b8bed5793 Enhance image and embedding provider support
- Added new image models for GPT 5.2, 5.3, and 5.4, including capabilities for text-to-image and editing.
- Updated embedding handling to include optional dimensions in requests.
- Introduced support for custom embedding providers, allowing dynamic fetching and validation of custom nodes.
- Improved image generation handling with Codex integration, including progress tracking and error handling.
- Enhanced UI components to support adding custom embeddings and displaying their status.
2026-04-25 16:22:30 +07:00
decolua
cca615eaff - Cap maximum cooldown for rate limit handling in account unavailability and single-model chat flows
- Dynamic custom model fetching for model selection
2026-04-24 16:14:18 +07:00
decolua
030fb34f88 - Updated markAccountUnavailable function to accept resetsAtMs for precise cooldown management.
- Added email backfill functionality for Codex OAuth connections to improve account information accuracy.
2026-04-24 11:36:16 +07:00