Expose max in the Codex thinking dropdown for gpt-5.6-sol only (maps to
xhigh on wire; live probe rejected ultra). Include custom/kilo models
when computing provider thinking options so manually added gpt-5.6-sol
contributes its max level.
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>
Claude Code sends reasoning_effort "max" (its top level); OpenAI enum caps
at "xhigh" and rejects "max" with HTTP 400 "max effort not support".
applyFormat case "openai" now clamps "max"->"xhigh" before assigning
body.reasoning_effort; other levels pass through unchanged.
Add regression test covering client output_config.effort, direct
reasoning_effort, passthrough of xhigh/high, and budget_tokens capping.
Co-authored-by: Cursor <cursoragent@cursor.com>
isPathLike rejected any line with a colon, so Windows absolute paths
(C:\Users\me\a.js) were never recognized and find dumps went uncompacted.
find.js also split only on "/", mis-grouping backslash paths.
- autodetect: treat drive-letter prefix (X:\ or X:/) as path-like before
the general colon rejection.
- find.js: split on the last "/" or "\" separator and normalize emitted
directory labels to forward slashes.
Co-authored-by: Cursor <cursoragent@cursor.com>
- map service_tier=fast to upstream priority; drop unsupported tiers
- normalize reasoning effort max to xhigh (codex-only)
- convert 200-SSE model-capacity errors into 503 so account fallback rotates
- keep normal SSE output intact after peeking
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>
Estimate tokens for tool_use, tool_result, thinking, system, and tools
blocks instead of text only, so count_tokens no longer returns 0 for
structured content and breaks Claude Code auto-compaction (#2337).
Co-authored-by: Cursor <cursoragent@cursor.com>
Ark rejects max_tokens above 128000 for GLM-5.2. Add a config-driven STRIP_RULES entry that clamps max_tokens, max_completion_tokens and max_output_tokens down to the model maxOutput before the upstream call.
Co-authored-by: Cursor <cursoragent@cursor.com>
Add four shared Caveman prompt fragments (no invented abbreviations,
preserve user language, no self-reference, no decoration) across all six
levels, and remove ULTRA contradictions around abbreviations/arrow
shorthand. Adds regression tests for the prompt rules.
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>
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>
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>
- 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.
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>
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>
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>
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>
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>
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>
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>
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.
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>
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>
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>
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>
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>
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>
Registry exposes the dashed id claude-opus-4-7; matchPattern treats "."
as a literal, so it missed the dotted pattern and fell through to the
generic claude opus entry (200k / claude-budget). Add an exact entry so
it resolves to 1M context + adaptive thinking, plus a unit test covering
the dashed Opus ids.
Co-authored-by: Cursor <cursoragent@cursor.com>
OpenAI-compatible apikey provider (chat/embedding/image) with dynamic
model discovery via modelsFetcher + passthroughModels. No executor needed.
Co-authored-by: Cursor <cursoragent@cursor.com>
Add 1M context capability overrides for claude-opus-4.8 and -thinking
variants, and use the resolved capability contextWindow (fallback 200k)
instead of the hardcoded 200k estimate in the Kiro executor.
Co-authored-by: Cursor <cursoragent@cursor.com>
Codex (openai-responses) body.input holds Responses items, not OpenAI
messages. Translate input -> OpenAI -> compress -> back to input so the
Responses contract is preserved. Fixes#1998
Co-authored-by: Cursor <cursoragent@cursor.com>
- mask API keys in usage stats/history responses (apiKeyMasked)
- validate proxy URL scheme + reject shell metachars before env write
- escape HTML in OAuth callback page to prevent XSS
- atomic O_EXCL lock file to prevent TOCTOU race in MITM startServer
- set mitmIsRestarting guard synchronously before any await
Co-authored-by: Cursor <cursoragent@cursor.com>
Forcing reasoning_effort:"medium" + reasoning_summary:"auto" on plain
requests tripped CodeBuddy's content filter and returned an error (#2071).
Make reasoning params opt-in: only set reasoning_summary when the client
sent an explicit reasoning_effort; none/off still drops it.
Fixes#2071
Co-authored-by: Cursor <cursoragent@cursor.com>
Pass Gemini AUDIO/TTS generateContent requests through to Google's native
v1beta endpoint instead of converting to chat, with per-credential fallback
(504 timeout, 502 fetch failure). Accept client keys from Bearer,
x-goog-api-key, or ?key= while forwarding only the configured Gemini
credential upstream. Expose native v1beta model names and rewrites, and add
Gemini 3.1 Flash TTS to the catalogs.
Co-authored-by: Cursor <cursoragent@cursor.com>
Add "text" to Codex Responses API allowlist so text.format.json_schema
reaches upstream for structured outputs instead of being stripped.
Co-authored-by: Cursor <cursoragent@cursor.com>
Keep provider-required streaming when client prefers JSON. The
Accept: application/json branch no longer flips stream back to false
for forceStream providers, fixing 400 errors on stream-only providers
(e.g. Command Code) for Hermes / Claude Code / other JSON clients.
Fixes#2031
Co-authored-by: Cursor <cursoragent@cursor.com>
Resolve Gemini TTS models from shared TTS catalog and provider registry
with a safe fallback, fixing requests resolving to models/undefined when
ttsConfig.models is empty. Add gemini-3.1-flash-tts-preview to catalogs.
Co-authored-by: Cursor <cursoragent@cursor.com>
Treat configured Headroom proxy as running when its /health endpoint
responds, even if local headroom CLI is not installed. Dashboard
Start/Stop stays limited to local loopback proxies while external
Docker sidecars can be enabled via HEADROOM_URL.
Closes#1948
Co-authored-by: Cursor <cursoragent@cursor.com>
Fixes#1933 — upstream returns 403 "Illegal access" on the chat endpoint
when requests lack a browser-like User-Agent. Mirror OmniRoute mimocode
executor: rotate across 3 Chrome UA strings on both bootstrap and chat.
Co-authored-by: Cursor <cursoragent@cursor.com>