Commit Graph

905 Commits

Author SHA1 Message Date
luoyide
2629218b04 fix(models): populate capabilities for live-catalog LLM models 2026-07-16 11:50:15 +07:00
joachimBrindeau
c9926897ba feat(rtk): add X-9Router-Token-Saver header to bypass token savers per request 2026-07-16 11:27:42 +07:00
liamgnc
88a8c72d2d fix(models): list compatible provider models in /v1/models
Replace the overly-broad UPSTREAM_CONNECTION_RE regex (which matched all
provider IDs with UUID suffixes) with an x-9r-internal-models-fetch
header to detect cross-instance recursive /models fetches.

fetchCompatibleModelIds now sends the header when fetching upstream
/models; the GET handler detects it and skips dynamic fetching, breaking
the recursion loop while letting compatible providers (MLX, Ollama, vLLM)
list their models. Fixes #2626.
2026-07-16 11:18:09 +07:00
luoyide
ba508f2506 fix(thinking): send explicit thinking:{type:adaptive} alongside output_config.effort 2026-07-16 11:17:08 +07:00
decolua
a077ee85bd gitignore 2026-07-16 11:16:57 +07:00
qianze
e567ba800f fix(translator): strip client_metadata when converting openai-responses to openai
client_metadata is an OpenAI Responses API-specific field. When translating
openai-responses requests to openai (Chat Completions), it leaked through
to providers like NVIDIA, which rejected it with a 400 "Unsupported
parameter". Strip it in the Responses-specific cleanup block alongside
input, instructions, store, and reasoning.
2026-07-15 17:38:53 +07:00
luoyide
542a088c04 feat(github): route Claude models through Copilot's native /v1/messages
GitHub Copilot's /chat/completions and /responses endpoints never surface
prompt-cache token counts for Claude models. Route Claude models (detected
by name pattern) to Copilot's Anthropic-native /v1/messages shim via a new
executeWithMessagesEndpoint(), translating OpenAI-shape requests to Claude
natively so cache_control gets injected and cached_tokens surface.

Also fixes translateRequest()'s internal _toolNameMap being sent upstream,
which made Anthropic's strict schema reject tool-call requests with a 400 —
now stripped and threaded through response state. Removes the now-dead
response_format Claude JSON-mode workaround.
2026-07-15 17:34:08 +07:00
Moradii.Mohammadreza
9173c29b66 feat(translator): drop temperature for all Claude models
Broaden strip rule from /claude-opus-4/i to /claude/i so temperature is
removed for every Claude model, not just opus-4. Fixes Anthropic 400 on
OpenAI-compatible routes. #1748
2026-07-15 17:08:41 +07:00
decolua
eceac9d7ae gitignore 2026-07-15 16:40:41 +07:00
nguyenha935
4dadab9d5f feat: add provider quota visibility settings 2026-07-04 23:26:49 +07:00
decolua
7f436e2792 # v0.5.18 (2026-07-03)
## Features
- **Usage**: track cached tokens + correct input/output/cache cost (#2209) — hodtien
- **Codex**: show reset credit expiry details (#2290) — Rafli Ahmad Zulfikar
- **NVIDIA**: add new models and capabilities — decolua
- **ClinePass**: add provider support — sternelee

## Fixes
- **Usage**: dedupe streaming request-details log entries — Qin Li
- **Claude**: drop foreign thinking signatures in passthrough — decolua
- Prevent non-SSE stream pipe crash and cross-IdP account overwrites (#2244) — KunN-21
- **Kiro**: route IdC auth to regional CodeWhisperer surface (#2297) — Volodymyr Saakian
- **Kiro**: add Claude Sonnet 5 model support (#2264) — Edison42
- **Xiaomi-tokenplan**: region selector, key validation, multi-connection (#2251) — MiQieR
- **Translator**: strict Anthropic content block compliance (#2225) — Sahrul Ramadhan Hardiansyah
- **Kimchi**: strip reasoning_content echo to bound multi-turn input tokens — KunN-21
- **Kimchi**: bump User-Agent to kimchi/0.1.40 (#2256) — Ansh7473
- **Codebuddy-cn**: strip empty tool_calls arrays to preserve reasoning — zmf
- **Antigravity**: preserve Claude tool delta index (#2223) — Sutarto Jordan Chrisfivo
- **MITM**: generate root CA on server startup (#2228) — Sutarto Jordan Chrisfivo
2026-07-03 15:37:17 +07:00
hodtien
54e3245ace feat(usage): track cached tokens + correct input/output/cache cost (#2209)
Normalize every provider to one cache-inclusive convention via
canonicalizeUsage() before persist, and price cached + cache_creation as
subsets of prompt_tokens in calculateCostFromTokens() to stop
double-counting. usageRepo now delegates cost math to a single source.
Surface Cached tokens/cost across dashboard (overview, tokens, cost,
details). Merge Claude message_start cache with message_delta output so
cache counts survive. Compatible LLM nodes now allow multiple API-key
connections (key pool).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-03 15:18:27 +07:00
Qin Li
960f8a0379 fix(usage): dedupe streaming request-details log entries
handleStreamingResponse and buildOnStreamComplete each generated their
own streamDetailId for what should be one logical record — the
placeholder row (0 tokens) and the final row (real usage) never shared
an id, so the DB's ON CONFLICT(id) upsert never merged them, leaving a
permanent 0-token stub for every streaming request.

Share the id from buildOnStreamComplete with handleStreamingResponse
so both writes hit the same row.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-03 15:14:49 +07:00
Rafli Ahmad Zulfikar
5cc4f222f8 feat(codex): show reset credit expiry details (#2290)
Add read-only GET to inspect per-credit reset inventory (status, granted,
expiry, remaining) with a Quota Tracker modal. DRY the route via shared
connection/refresh helpers; keep existing consume POST unchanged.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-03 15:07:45 +07:00
decolua
cd557a2552 fix(claude): drop foreign thinking signatures in passthrough
Combo mixes models, so non-Claude thinking signatures leak into
conversation history. Native passthrough forwarded them verbatim and
Anthropic rejected the request. Validate signatures and drop invalid
thinking blocks, re-inserting a placeholder when tool_use requires one.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-03 15:06:19 +07:00
decolua
ced51ed62f feat(nvidia): add new models and capabilities for NVIDIA provider
- Updated capabilities for NVIDIA models to enforce OpenAI-compatible reasoning formats.
- Added new models: MiniMax M3, GLM 5.2, DeepSeek V4 Pro, DeepSeek V4 Flash, Kimi K2.6, and Nemotron 3 Ultra to the NVIDIA registry.

This enhances the provider's functionality and aligns with OpenAI standards.
2026-07-03 12:15:58 +07:00
KunN-21
cb0135b695 fix: prevent non-SSE stream pipe crash and cross-IdP account overwrites (#2244)
- streamingHandler: when upstream returns non-SSE/JSON (e.g. Cloudflare
  5xx HTML), read body, sanitize <title>, notify streamController and
  return a clean JSON error instead of crashing the pipe.
- connectionsRepo: dedup OAuth connections on (email + username) so
  cross-IdP accounts sharing an email no longer overwrite each other;
  workspace providers keep workspace-id matching.
- kimchi: bump User-Agent to 0.1.50, add svg asset + browser-login
  service, and 21 unit tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-03 11:11:07 +07:00
Volodymyr Saakian
abc0add031 fix(kiro): route IdC auth to regional CodeWhisperer surface (#2297)
IAM Identity Center (authMethod=idc) tokens failed every request with 403
"bearer token invalid". Treat idc like api_key/external_idp:

- executors/kiro.js: route idc to *.amazonaws.com CodeWhisperer surface,
  region-aware from credentials.region instead of hardcoded us-east-1.
- openai-to-kiro.js / claude-to-kiro.js: send resolved profileArn or empty
  for idc/external_idp, never the shared builder-id placeholder ARN.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-03 11:06:40 +07:00
MiQieR
9102c4c6d8 fix(xiaomi-tokenplan): region selector, key validation, multi-connection (#2251)
- Add top-level regions array so Add/Edit modals render region <Select>
- EditConnectionModal: load/persist region generically for region-aware providers
- validate: accept 403 for xiaomi-tokenplan valid keys, add 8s fetch timeout
- Remove single-connection guard for compatible/embedding nodes

Co-authored-by: MiQieR <122154116+MiQieR@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-03 11:03:18 +07:00
Sahrul Ramadhan Hardiansyah
ce6120ce7b fix(translator): strict Anthropic content block compliance (#2225)
Filter empty text blocks from thoughtSignature-only parts, preserve
tool_calls when functionResponse and functionCall coexist in the same
content, and skip empty regular text parts before they reach Claude.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-03 10:58:39 +07:00
KunN-21
7afaecd617 fix(kimchi): strip reasoning_content echo to bound multi-turn input tokens
Clients echo full message history each turn including reasoning_content,
which the Kimchi OpenAI gateway counts as input tokens. Multi-turn convos
balloon to 100k+ tokens and the model returns empty content.

KimchiExecutor.transformRequest now strips reasoning_content from assistant
messages when it exceeds an 8-char threshold, preserving the 1-char
placeholder injectReasoningContent sets and keeping content intact.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-03 10:58:31 +07:00
Edison42
a5363b83b5 fix(kiro): add Claude Sonnet 5 model support (#2264)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-03 10:54:15 +07:00
sternelee
b08751c4ea feat(clinepass): add ClinePass provider support
Register clinepass provider (OAuth + API-key) using Cline's
OpenAI-compatible API with 10 curated models, live /v1/models
resolver, refreshCline-based token refresh with workos: prefix,
and dashboard OAuth login handler.

Reference: https://github.com/jellydn/pi-clinepass-provider
Closes #2261

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-03 10:53:41 +07:00
Ansh7473
76752a4396 fix(kimchi): bump User-Agent to kimchi/0.1.40 (#2256)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-03 10:49:53 +07:00
zmf
602ee4054b fix(codebuddy-cn): strip empty tool_calls arrays to preserve reasoning
CodeBuddy CN includes "tool_calls": [] in every SSE streaming delta.
@ai-sdk/openai-compatible checks delta.tool_calls != null — an empty
array passes ([] != null is true in JS), triggering premature
reasoning-end on every reasoning chunk (0/1ms durations in OpenCode).

Strip empty tool_calls arrays in passthrough before hasValuableContent.
Zero side-effect: real tool_calls always have at least one element.

Closes #2176

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-01 09:39:31 +07:00
Sutarto Jordan Chrisfivo
8f81f17b99 fix(antigravity): preserve Claude tool delta index (#2223)
Gemini response translation wrote OpenAI-shaped bookkeeping into the
shared state.toolCalls map, which the downstream openai-to-claude
translator uses for Claude block metadata. That pre-population skipped
blockIndex creation, so Anthropic input_json_delta events lost index.

Track Gemini function calls via state.geminiToolCallCount instead,
leaving state.toolCalls clean for the Claude translator.

Closes #2218

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-01 09:36:43 +07:00
Sutarto Jordan Chrisfivo
182c849979 fix(mitm): generate root ca on server startup (#2228)
Direct MITM server startup read rootCA.key/.crt immediately and exited
when either was missing, bypassing the manager.js CA setup path.

- generate Root CA from server.js when key/cert is missing
- make generateRootCA()/generateCert() synchronous to avoid a startup
  race before readFileSync
- add unit test covering synchronous Root CA creation

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-01 09:30:52 +07:00
decolua
0b3c794075 # v0.5.15 (2026-06-29)
## Features
- Add Kimchi OAuth provider — Nant361
- Refine Qwen vision/video + thinking model patterns — decolua
- Opt-in Codex auto-ping quota keep-alive — Emirhan

## Fixes
- **Responses**: handle response.done terminal events (#2142) — rifuki
- **Headroom**: skip unsafe responses tool history (#2132) — Sutarto Jordan Chrisfivo
- **Translator**: map mid-conversation system message to user (claude→openai) — decolua
- **Gemini**: normalize contents to prevent 400 invalid_argument (#2192) — warelik
- **Gemini**: backfill thoughtSignature + suppress stream done sentinel — WARELIK
- **Alicode**: preserve cache_control for DashScope providers (#2069) — Rex
- **Antigravity**: strip deprecated/readOnly/writeOnly from tool schemas — iletai, Yudhistira-Official
- **CodeBuddy CN**: show bonus packs as one-time, not monthly-replenishing — whale9820
- **Kiro**: strip leaked <thinking> tags from content stream (#2158) — hamsa0x7
- **Tray**: make Windows context menu DPI-aware — Emirhan
- **Kilocode**: expose full gateway catalog in combo model picker — jellylarper
- **OpenCode**: fix Go GLM — decolua
2026-06-29 16:23:33 +07:00
rifuki
a9785a5f70 fix(responses): handle response.done terminal events (#2142)
Treat response.done as a terminal OpenAI Responses stream event so
passthrough streams ending with response.done are not flagged incomplete
and no synthetic response.failed is emitted. Restore the data: [DONE]
sentinel for same-format Responses passthrough streams.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-29 16:05:29 +07:00
Sutarto Jordan Chrisfivo
373850ee36 fix(headroom): skip unsafe responses tool history (#2132)
Guard openai-responses compression: skip Headroom when body.input
contains non-message items (function_call, function_call_output,
reasoning) to preserve the Responses contract instead of collapsing
them into chat messages.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-29 15:59:21 +07:00
decolua
749c2e3f9c fix(translator): map mid-conversation system message to user in claude-to-openai
Claude Code chèn role:system cuối messages[], trước đây bị map thành assistant
khiến hội thoại không kết thúc bằng user → provider OpenAI-compat (LiteLLM)
dịch ngược Anthropic trả 400 "assistant message prefill". Map system -> user
và wrap <system-reminder> để giữ ngữ nghĩa instruction.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-29 15:53:26 +07:00
decolua
7fa2e7f029 feat(capabilities): refine Qwen vision/video and thinking model patterns
Add qwen omni (audio/video input), qwen3.5/3.6/3.7 (native vision/video),
and mark qwen coder & max as text-only reasoning models.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-29 15:51:56 +07:00
warelik
8d1db46beb fix(gemini): normalize contents to prevent 400 invalid_argument (#2192)
Merge adjacent same-role blocks and strip empty parts before sending to
Gemini, avoiding 400 INVALID_ARGUMENT on consecutive same-role messages.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-29 15:38:03 +07:00
Rex
9e3866658a fix(alicode): preserve cache_control for DashScope providers (#2069)
Opt-in quirk preserveCacheControl keeps cache_control on content blocks
for alicode/alicode-intl, enabling DashScope prompt caching. signature
is always stripped; all other providers unchanged.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-29 15:29:49 +07:00
Nant361
8a664d619d feat(kimchi): add Kimchi OAuth provider support
Add Kimchi as a browser-token OAuth provider routed through its
OpenAI-compatible gateway. Discover live models for /v1/models and
provider models, normalize Claude-compatible requests, and wire up
provider connection tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-29 15:29:17 +07:00
WARELIK
2d94fffe3b fix(gemini): backfill thoughtSignature and suppress stream done sentinel
Backfill DEFAULT_THINKING_AG_SIGNATURE onto functionCall parts missing it
(client history replay) and on Claude tool_use blocks, fixing 400
INVALID_ARGUMENT from Gemini-family APIs. Suppress the OpenAI-style
data: [DONE] sentinel for antigravity/gemini/vertex to avoid parser crashes.

Fixes #2193.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-29 15:28:03 +07:00
Yudhistira-Official
319caa2d7b fix(antigravity): strip 'deprecated' from tool schemas before Gemini
Gemini rejects the non-standard 'deprecated' keyword in nested tool
schemas with INVALID_ARGUMENT (400). Add it to UNSUPPORTED_SCHEMA_CONSTRAINTS
alongside 'optional' so it gets stripped during translation.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-29 15:28:02 +07:00
whale9820
95bfc64f06 fix(codebuddy-cn): show bonus packs as one-time, not monthly-replenishing
CodeBuddy CN bonus packs ("Bonus Pack N") are one-shot credits whose
CycleEndTime equals DeductionEndTime — they expire for good and never
replenish. The dashboard rendered their resetAt as "Reset in Xd",
implying a monthly refill.

Tag bonus packs recurring:false (refill packs recurring:true) in the
usage handler, forward the flag through parseQuotaData, and word the
quota table / progress bar as "Expires in" / "Expires at" for
one-shot packs.
2026-06-29 15:22:47 +07:00
hamsa0x7
eff81b1242 fix(kiro): strip leaked <thinking> tags from content stream (#2158)
CodeWhisperer leaks literal <thinking> blocks into assistantResponseEvent,
duplicating reasoning already routed via reasoningContentEvent. Track
inThinking state to strip these tags during SSE transform, handling split
chunks across tag boundaries.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-29 15:14:15 +07:00
Emirhan
b66b5c68ce feat(quota): add opt-in Codex auto-ping
Generalize Claude 5h auto-ping into a provider-generic scheduler and add
opt-in Codex auto-ping that warms the next 5h window via a tiny gpt-5.5
request when session.resetAt slides. Default off, per-connection toggle,
failure cooldown, blocking-quota skip, drains stream before success.

Closes #2107

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-29 15:13:17 +07:00
Emirhan
fc8722e897 fix(tray): make Windows context menu DPI-aware
Set process DPI awareness (Per-Monitor V2 with fallbacks) and enable
WinForms visual styles before creating the tray NotifyIcon, so the
Windows context menu renders sharply on DPI-scaled displays.

Closes #2161

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-29 15:12:24 +07:00
jellylarper
713c563765 fix(kilocode): expose full gateway catalog in combo model picker
Add modelsFetcher + passthroughModels so the dynamic Kilo Gateway
catalog surfaces in the combo model picker, matching openrouter.js.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-29 15:12:18 +07:00
iletai
3d20a4ccd2 fix(antigravity): strip deprecated/readOnly/writeOnly from tool schemas
Gemini/Antigravity generateContent rejects the JSON Schema annotation
keywords deprecated, readOnly, writeOnly with a 400 INVALID_ARGUMENT.
MCP tool schemas (e.g. Claude Code) commonly set deprecated:true, making
every request with such a tool fail. Add them to
UNSUPPORTED_SCHEMA_CONSTRAINTS so cleanJSONSchemaForAntigravity removes
them recursively before the request is sent.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-29 15:12:17 +07:00
decolua
526235872a Fix OpenCode Go GLM 2026-06-29 15:00:03 +07:00
decolua
cce47dd809 # v0.5.12 (2026-06-26)
## Features
- Add token-saver dashboard page — decolua
- Add bulk delete for provider connections — teddytkz
- Resolve GitHub Copilot model catalog from upstream — caiqinzhou
- Add Venice AI provider — Brokenc0de
- Add Kiro external_idp import for Microsoft SSO (CLIProxyAPI) — Stevanus Pangau
- Overhaul Blackbox provider catalog + WebUI test support — suryacagur

## Fixes
- Provider thinking compatibility (DeepSeek/Gemini) — Mink Nguyen
- Stop double-counting streaming usage at source — decolua
- Usage logging dedupe to reduce stats churn — Mink Nguyen
- Prevent non-JSON SSE lines / duplicate [DONE] from breaking clients (PR #2046) — qianze
- Resolve Gemini TTS models from catalog — nguyenha935
- Support Kiro IDC (organization) token import — quanturbo
- Preserve forced streaming for JSON clients (#2031) — Joseph Yaksich
- Preserve Responses text format (Codex) — tenglong
- Support Gemini native TTS generateContent endpoint — nguyenha935
- Add missing zh-CN endpoint key label (i18n) — weimaozhen
- CodeBuddy: only send reasoning params when client requests reasoning (#2071) — Rex
- Show custom provider models in combo picker — Sapto
- Docker: add docker-compose.yml with headroom enabled by default — nitsuahlabs
- Clarify token diagnostics vs provider billing (headroom, #1998) — Sutarto Jordan Chrisfivo
- Translate openai-responses input through OpenAI for compression (#1998) — Ankit
- Kiro: report 1M context window for claude-opus-4.8 — EdisonPVE
- Avoid stale redirects after auth changes (#2100) — Emirhan
- Mark Claude Opus 4.7 (dashed id) as 1M context — Brokenc0de
- Preserve reasoning effort through Codex translations — ntdung6868
- Token-saver: full width card layout — decolua
- Antigravity: retry transient upstream failures — Sutarto Jordan Chrisfivo
- Param-support: handle strip rules without match/drop (#1960) — Joseph Yaksich
- Translator: resolve custom provider prefix in debug endpoint (#1083) — hamsa0x7
2026-06-26 18:05:07 +07:00
hamsa0x7
90b336d9dd fix(translator): resolve custom provider prefix in debug endpoint
Use getModelInfo instead of parseModel in /api/translator/translate
so custom OpenAI/Anthropic-compatible provider prefixes resolve
correctly, aligning the debug path with the runtime chat path.

Fixes #1083

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-26 17:22:02 +07:00
Joseph Yaksich
4a54824f7f fix(param-support): handle strip rules without match/drop
Cloudflare AI rule only sets flattenContent. Treat missing match as
provider-wide and missing drop as empty list to avoid crash. Fixes #1960.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-26 17:20:09 +07:00
Sutarto Jordan Chrisfivo
639f1204d0 fix(antigravity): retry transient upstream failures
Retry short-lived 5xx/capacity errors (500/502/503/504 + message
patterns) with bounded backoff capped at 15s; honor Retry-After/reset
hints and skip when wait is too long. Keep 400 non-retryable. Enable the
retry hook for 500 alongside existing 429/503.

Deduplicate sanitized Antigravity tool names before emitting the single
functionDeclarations group to avoid upstream "Tool names must be unique"
rejections.

Add Headroom size diagnostics and phantom-savings warning when reported
token delta does not shrink the outbound payload.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-26 17:19:46 +07:00
decolua
2deacf69b1 fix(token-saver): full width card layout
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-26 17:16:27 +07:00
decolua
8ac631d615 fix(ssrf): block IPv6-mapped IPv4 addresses (GHSA-hj98-rc6w-m8cw)
isBlockedIpv6() did not normalize ::ffff:<ipv4>, allowing the SSRF
filter to be bypassed. Extract and validate via isBlockedIpv4().

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-26 12:14:30 +07:00