Commit Graph
157 Commits
Author SHA1 Message Date
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
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
hodtienandCursor 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
decoluaandCursor 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
Volodymyr SaakianandCursor 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
Sahrul Ramadhan HardiansyahandCursor 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
Sutarto Jordan ChrisfivoandCursor 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
decoluaandCursor 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
warelikandCursor 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
RexandCursor 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
WARELIKandCursor 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-OfficialandCursor 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
iletaiandCursor 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
Joseph YaksichandCursor 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
ntdung6868andCursor 3a866fe18d fix(reasoning): preserve effort through Codex translations
Carry Claude reasoning_effort/reasoning into OpenAI Chat, map into
OpenAI Responses reasoning.effort, and keep request-level effort
(incl. xhigh) across tool-result turns instead of collapsing to high.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-26 12:06:35 +07:00
Mink NguyenandCursor c4f80d30d8 fix provider thinking compatibility
- claude: handle DeepSeek thinking blocks defensively, unsigned placeholder; fix kept-vs-seen thinking detection
- gemini: clamp unsupported max/xhigh thinking levels to high
- testUtils: probe Cloud Code Assist for gemini-cli/antigravity with 401 refresh retry
- tests: add translator regression coverage

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-26 10:12:48 +07:00
decoluaandCursor 7baf293ccb fix(cloudflare-ai): flatten content-part arrays to string to avoid oneOf 400 (#1926)
Workers AI rejects OpenAI content-part array shape; flatten text parts
to a plain string per message before sending.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-21 16:46:21 +07:00
decoluaandCursor 45240c19e5 fix(translator): normalize tools to Anthropic-native shape for non-Anthropic providers
Strip `type` field and fold `function.{name,description,parameters}` into
top-level {name, description, input_schema} before forwarding to Claude-format
endpoints. MiniMax (and other Anthropic-compatible providers) reject tools
carrying a `type` field with error code 2013 ("invalid tool type").

Refs #1939

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-21 16:26:17 +07:00
decolua 401d93bd5c fix(claude haiku): update handling of unsupported adaptive thinking and output_config.effort 2026-06-20 16:29:15 +07:00
mustafabozkayaandCursor f6c2f7cae3 fix(gemini): preserve 'pattern' in antigravity tool schema translation
Remove "pattern" from UNSUPPORTED_SCHEMA_CONSTRAINTS so glob/grep tool
schemas keep the required "pattern" property for the antigravity provider.

Fixes decolua/9router#1368

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-20 15:31:22 +07:00
decolua 637dd7ae66 feat(ponytail): introduce "Ponytail" feature for minimalistic code generation 2026-06-20 15:08:11 +07:00
EdisonPVEandCursor 2ff11246ae fix(kiro): honor thinking effort budgets
Resolve the Kiro thinking budget from client intent (OpenAI reasoning_effort,
OpenAI Responses reasoning.effort, Claude output_config.effort, and Claude
thinking.budget_tokens) by reusing the shared thinkingUnified extractThinking
parser, then inject the resolved budget into the Kiro thinking system prefix.
Explicit none/off/disabled stops the prefix injection; synthetic -thinking
aliases keep the default budget.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-18 15:14:42 +07:00
decolua 3f9382dee4 Fix AG, Kiro, Xiaomi Provider 2026-06-18 14:58:00 +07:00
decoluaandCursor c7d07448c5 fix(image): pin DNS-resolved IP to prevent SSRF via DNS rebinding (GHSA-cmhj-wh2f-9cgx)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-17 11:02:04 +07:00
fjiaandCursor 7ae9fff663 fix(executors): strip params unsupported by provider/model
Add config-driven stripUnsupportedParams helper and use it in the default and github executors. Removes the deprecated temperature param for claude-opus-4 models (Anthropic 400) and consolidates github's scattered capability checks into one rule table.

Fixes #1748

Co-Authored-By: fjia <fjia@suntekcorps.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-17 10:34:53 +07:00
706e6513c9 feat(kiro): headless API-key auth + direct Claude/Kiro route
Adds long-lived API-key (ksk_) authentication for Kiro/AWS CodeWhisperer
and a direct claude:kiro / kiro:claude translation route that avoids the
lossy OpenAI two-hop pivot.

- translator: claude-to-kiro request + kiro-to-claude response translators,
  registered on the exact source:target pair (direct route ahead of the
  OpenAI pivot in index.js). claude-to-kiro uses shared schema constants
  (ROLE/CLAUDE_BLOCK/DEFAULT_IMAGE_MIME) per app convention.
- auth: POST /api/oauth/kiro/api-key imports + validates a key via
  ListAvailableProfiles, persists authMethod="api_key" (no refresh token).
- executor: send tokentype: API_KEY header and try *.amazonaws.com hosts
  first for api-key creds; OAuth keeps kiro.dev first.
- fix: never inject the default placeholder profileArn for api-key auth
  (CodeWhisperer 403s an ARN not owned by the key's account).
- ui: API Key method in the Kiro connect modal; surface api-key accounts
  on the Quota Tracker and provider count.
- stream: env-overridable TTFT vs stall timeouts + Kiro keepalive frame.
- tests: claude-kiro-direct + kiro-profile-arn (11 tests).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-17 10:01:30 +07:00
Khanh LeandCursor db9ec3af61 fix(antigravity): strip optional from tool schemas before Gemini
Closes #1537, #1841

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-17 09:46:41 +07:00
decolua d03f9fb823 Enhance configuration and model capabilities 2026-06-16 23:32:28 +07:00
decolua b282f05549 Refactor 2026-06-15 18:18:04 +07:00
decoluaandCursor aba4c45da6 fix(translator): ESM-safe registry + tool-id pairing + responses max_tokens; add real-creds tests
- translator/index.js: replace require() with static side-effect imports (ESM-safe),
  lazy-init registry maps to survive circular import order
- openai-responses->openai: map max_output_tokens -> max_tokens (avoid leaking field upstream)
- gemini/antigravity -> openai: derive deterministic tool_call id from name so
  functionCall/functionResponse pair correctly (fixes provider tool-pairing 400s)
- add offline unit tests (finish-reason, usage, session-manager, ollama malformed args, const guard)
- add real-creds integration tests (provider-cases + all-formats matrix: 6 inbound formats x 4 scenarios)

Includes co-located provider registry refactor (pricing/capabilities/media providers) and sessionManager updates.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-15 11:38:43 +07:00
decoluaandCursor d3f61aac2f refactor(open-sse): translator DRY + schema enums, bug fixes, dead code cleanup
- Bug B1-B7: media UI m.kind||m.type, serviceKinds, gemini mediaPriority, schema kind, models/info lookup by kind
- Dead code D1-D6: safeParseJSON, drop PROVIDER_ENDPOINTS, orphan fetcher, GITHUB_CONFIG derive, getProviderConfig internal, legacy kiro file
- Translator concerns: toOpenAIUsage, toOpenAIFinish (gemini/kiro/ollama + fix kiro tool finish), thinking effort maps
- Reorg helpers/ → concerns/ (logic) + formats/ (per-format) + schema/ (pure enums: roles/blocks/finishReasons/defaults)
- Wire ~280 hardcoded role/block/finish/default literals to schema enums across 20+ files
- collapseTextParts + extractTextContent dedup
- Normalize translator fn names to openaiToXRequest / xToOpenAIResponse
- Golden tests lock behavior; 0 regression (byte-for-byte providers/alias, 26=26 known fails)

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-14 18:49:38 +07:00
decoluaandCursor bb9e9aa91f refactor(open-sse): registry consolidation + DRY media/oauth/adhoc cleanup
- Single-source registry: oauth clientId/tokenUrl, usage URLs, image/embed
  configs, search defaultModel, codex fixedPort, google token url derive.
- Remove 29 unused OmniRoute providers (registry 100→71); media intact.
- De-adhoc: codex literals → registry format/oauth flags; reasoningInject,
  image/embed openrouter headers + xai bodyFields config-driven.
- Add REGISTRY_TEMPLATE.js + expand PROVIDER_DEFAULTS/schema JSDoc.
- Baselines updated; PROVIDERS 62 + alias 90 byte-for-byte, golden snapshots.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-14 13:15:48 +07:00
decoluaandCursor 633b66dcb6 refactor(translator): P4 concern #5 buildUsage — apply to kiro/ollama/commandcode
- Replace 3 inline {prompt,completion,total} usage objects with buildUsage()
- Preserves ?? vs total fallback semantics (commandcode)
- Golden tests pass, identical output

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-13 21:27:22 +07:00
decoluaandCursor 252bf56a9f refactor(translator): P4 concern #2 encodeDataUri — dedupe base64 data-uri building
- imageHelper.encodeDataUri(mime, base64) replaces 5 inline `data:${m};base64,${d}` templates
- Applied to gemini/claude/antigravity request + gemini response translators
- Golden tests pass, identical output

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-13 21:23:32 +07:00
decoluaandCursor 4cc667253a refactor(translator): P4 concern #6 finishReasonMap — switch-by-format, default common
- concerns/finishReasonMap.js: toOpenAIFinish/fromOpenAIFinish, switch special formats, default passthrough
- Replace 3 inline switch maps (claude→oai, oai→claude, commandcode→oai)
- Golden translator tests pass, behavior identical

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-13 21:20:22 +07:00
decoluaandCursor 6597b81e5e refactor(open-sse): add reasoningDelta helper, dedup thinking deltas (B4)
Centralize the reasoning_content delta shape (optional assistant role) used by
claude/gemini/kiro/codex/commandcode response translators. Keeps the cross-format
convention consistent for future translators. Output byte-for-byte identical;
golden + gate clean. Ollama left as-is (mutates existing delta object).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-13 18:21:46 +07:00
decoluaandCursor 997860aa1f refactor(open-sse): dedup fallback tool_call id helper (B3)
Add fallbackToolCallId() and apply to kiro/ollama/openai-responses response
translators (identical id shape). Leave commandcode (different order) and
request-side gemini/antigravity (random suffix) untouched. Golden + gate clean.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-13 18:12:40 +07:00
decoluaandCursor 39278e9613 refactor(open-sse): extract buildUsage helper, dedup token-details (B2)
Add helpers/usageHelper.js for conditional prompt/completion token details.
Apply to gemini/codex/claude response translators; keep each provider's token
math intact. No behavior change; golden + gate: no regression.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-13 17:18:15 +07:00
decoluaandCursor 17202f7111 refactor(open-sse): extract chunkBuilder, dedup chat.completion.chunk (B1)
Add helpers/chunkBuilder.js; apply to claude/gemini/kiro/ollama/commandcode/
openai-responses response translators. Caller supplies id/created/model so each
keeps exact id-generation + usage semantics. Extend golden response stream to
openai-responses (codex). No behavior change; gate: no regression.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-13 17:05:42 +07:00
decoluaandCursor b87cf0c96a refactor(open-sse): extract safeParseJSON util, dedup tryParseJSON (B5)
Consolidate two tryParseJSON variants into helpers/jsonUtil.js with explicit
fallback param. Preserve exact per-call semantics: openai-to-claude passthrough
(fallback=str), geminiHelper null. geminiHelper keeps tryParseJSON re-export.
No behavior change; gate: no regression.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-13 16:45:10 +07:00
Giang Truong VuandCursor d9b030011f fix(gemini-to-openai): route unsigned thought parts to reasoning_content
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-13 10:34:42 +07:00
weimaozhenandCursor 0aaa5ab3c2 fix(claude-to-openai): strip Anthropic billing header from system prompt
Remove dynamic x-anthropic-billing-header lines from Claude system prompts
when translating to OpenAI format to keep prompt prefixes stable and improve
prompt cache hits.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-13 10:05:12 +07:00
decolua b309261166 enhance Kiro profile ARN resolution 2026-06-13 09:28:55 +07:00
decolua 4443903900 fix: add normalization for Claude passthrough bodies 2026-06-08 15:37:01 +07:00
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 CodeandCursor 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
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
decolua a648a42bdb Fix codex 2026-05-26 11:35:39 +07:00
GodrezJr2andClaude Sonnet 4.6 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