Gemini CLI requests with small max_tokens spend the whole output budget on
thoughts after reasoning_effort maps to thinkingConfig, returning blank
content or finish=length. Raise maxOutputTokens floors per thinking level/
budget (clamped to caps.maxOutput). Also emit toolConfig
functionCallingConfig.mode=VALIDATED for Gemini CLI tool requests to avoid
MALFORMED_FUNCTION_CALL.
Co-authored-by: Cursor <cursoragent@cursor.com>
Translator only unwrapped tool.function when both tool.type==="function"
and tool.function were truthy. Loose/legacy OpenAI clients emit the bare
{ function: { name, parameters } } shape (no parent type), which fell
through and forwarded name: undefined upstream, rejected by strict
Anthropic-compatible gateways (MiniMax M3) as (2013) invalid tool type.
Unwrap tool.function whenever present. Built-in tools stay pass-through.
Adds regression coverage for the 4 tool shapes. See #2435.
Co-authored-by: Cursor <cursoragent@cursor.com>
Match captured official Antigravity IDE traffic: cloudcode-pa host,
antigravity/ide/2.1.1 User-Agent, IDE-shaped agent requestId, and drop
router-only stream/usage headers plus the legacy double system prompt.
Co-authored-by: Cursor <cursoragent@cursor.com>
Map role="developer" messages to top-level instructions alongside
role="system" in openaiToOpenAIResponsesRequest. Previously developer
messages matched no branch and were silently dropped from the Responses
request, losing GPT-5/Codex system-level prompts.
Co-authored-by: Cursor <cursoragent@cursor.com>
On the translated OpenAI->Claude path, adjustMaxTokens capped max_tokens
before applyThinking set thinking.budget_tokens, so max-effort budget
(128000) could exceed a 64k-clamped max_tokens -> Anthropic 400.
prepareClaudeRequest now reconciles after the budget is known: prefer
raising max_tokens, only shrink budget when it meets/exceeds the ceiling.
Also lift the global 64000 cap: the ceiling is now the model's real
maxOutput, so high-output models (fable/mythos, opus-4.8/sonnet-4.6) get
their full budget. adjustMaxTokens gains an optional ceiling arg (default
unchanged, callers untouched); openai-to-claude passes the model maxOutput.
Native Claude Code passthrough is unaffected.
Co-Authored-By: Claude <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
- Pass system prompt via native systemInstruction field (+ <instructions> fallback)
so Claude models stop treating it as info-only <system-reminder>
- Add Opus 4.5/4.7/4.8 (base/thinking/agentic/thinking+agentic) to Kiro registry
- normalizeModelId(): dash->dot version separator, scoped to Kiro provider only
- Replace <system-reminder> with <instructions> in claude-to-openai/openai-to-kiro
Co-authored-by: Cursor <cursoragent@cursor.com>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
## 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
- 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)
- Encode thoughtSignature into tool_call.id using _TSIG_ delimiter and base64url
- Decode _TSIG_ on request to restore thoughtSignature for Gemini multi-turn thinking
- Track pendingThoughtSignature across parts for deferred signature attachment
- Add LocalMutex (2-layer locking) to prevent ELOCKED on concurrent DB access
- Increase lockfile retries from 5 to 15 for multi-process robustness
- Restore db.json seed on first run to prevent ENOENT on lockfile.lock
- Use process.env.BASE_URL fallback in models test route
- Remove gemini-3-flash-lite-preview from provider models
Co-authored-by: kwanLeeFrmVi <quanle96@outlook.com>
Closes#450
Made-with: Cursor
- Add claudeHeaderCache.js to intercept and cache live Claude Code client headers
- Forward cached headers dynamically to api.anthropic.com via default.js
- Strip first-party identity headers (x-app, claude-code-* beta) for non-Anthropic upstreams
- Validate and sanitize tool call IDs to match Anthropic pattern (^[a-zA-Z0-9_-]+$)
- Skip thinking blocks when applying cache_control; fix max_tokens buffer (+1024)
- Strip cache_control from thinking blocks in openai-to-claude translator
- Comment out thoughtSignature in Gemini translator (kept for reference)
- Expand .gitignore to match all deploy*.sh variants
Co-authored-by: kwanLeeFrmVi <quanle96@outlook.com>
Closes#433
Made-with: Cursor
Previously only base64 data: URLs were handled in the OpenAI-to-Claude
and OpenAI-to-Gemini request translators. HTTP/HTTPS image URLs were
silently dropped, causing vision-capable models to respond with
"I don't see any image."