Validate AWS EventStream framing, header bounds, CRCs, error frames,
and terminal stop metadata before exposing Kiro output. Classify stop
reasons into dispositions (complete / retryable / terminal_incomplete /
refusal) and retry once when the stream ends with a malformed tool call,
ellipsis-only output, or a short future-action sentence.
Fail closed: propagate streaming failures as error SSE (502) instead of
collapsing them into a successful stop, so incomplete responses no longer
leak as final answers.
Detect the observed evidence-prefixed trailing progress final without
broadening the Chinese heuristic to completed findings.
8b9cac1 swapped alicode-intl to the DashScope compatible-mode endpoint to
fix#2591 for standard DashScope keys, but that broke Coding Plan keys
(sk-sp-...) which only work on coding-intl.dashscope.aliyuncs.com. The two
key types use two different hosts and are not interchangeable.
- alicode-intl: revert to coding-intl endpoint (Coding Plan keys)
- alims-intl: new provider for dashscope-intl/compatible-mode (standard keys)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Switch baseUrl from coding-intl.dashscope.aliyuncs.com (Coding Plan keys
only) to dashscope-intl.aliyuncs.com/compatible-mode so ordinary DashScope
API keys authenticate. Path /v1/chat/completions and preserveCacheControl
quirk unchanged.
Fixes#2591
Reshape Kiro direct requests so resumed client sessions reuse Kiro's
cache-affinity fields instead of starting unrelated CodeWhisperer
conversations.
- keep conversationState.conversationId stable when the client sends an
explicit session id (x-session-id, session_id, conversation_id, Claude
Code session metadata)
- add a stable conversationState.agentContinuationId per Kiro session
- send conversationState.agentTaskType: "vibe" and agentMode: "vibe",
matching the normal Kiro CLI/KAS chat path
- move Kiro thinking instructions into Kiro-compatible systemPrompt /
additionalModelRequestFields instead of generic top-level thinking
- keep volatile timestamp context out of the top-level systemPrompt; it
remains only in user content fallback
- suppress additionalModelRequestFields for legacy 4.5-era Claude/Kiro
models that reject it, while defaulting future Claude/Kiro model ids
to supported
- preserve Kiro meteringEvent credit usage internally for accounting
without leaking provider-specific fields into OpenAI-compatible usage
- prevent unrelated headerless Kiro requests from sharing one
connection-wide continuation
- cap/evict continuation sessions so long-running processes do not grow
the continuation map unbounded
- treat generated headerless Kiro sessions as one-shot so they do not
evict real explicit-session continuations
- keep credit-only Kiro metering valid for internal persistence when
token metrics are unavailable
Add GPT-5.6 Sol/Terra/Luna and their synthetic thinking/agentic/
thinking-agentic variants to the Kiro static catalog with the observed
272k context window and credit multipliers (2.4/1.2/0.6), register MITM
mapping slots for the new base ids, and override runtime capabilities so
the GPT-5.6 family reports the 272k window instead of the generic GPT-5
profile.
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.
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.
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
Add pxpipe as an experimental fifth Token Saver: Claude-format request
bodies above a configurable size threshold are rendered as dense PNGs
via the pxpipe-proxy library API (transformAnthropicMessages) before
dispatch, cutting estimated input tokens by ~35-60% on token-dense
contexts. Integration follows the Headroom pattern: applied to the final
body in chatCore just before dispatch, fail-open on any error/timeout.
Managed npm install into DATA_DIR/pxpipe, dynamic loader with per-version
cache-bust, JSONL event log with rotation, /api/pxpipe/* endpoints, Token
Saver card (marked experimental) + /dashboard/pxpipe page, and per-request
Activated/Skipped annotation in Request Details. Disabled by default.
- Backup DB only on real SCHEMA_VERSION change, not every app version bump
- Kill idle MCP stdio bridge children to prevent orphan process leaks
- Add getDistinctProviders to avoid loading every row JSON blob (OOM fix)
- Update codex model list (gpt-5.6 sol/terra/luna, drop 5.3 codex variants)
- Reorder Claude default models (fable first)
Co-authored-by: Cursor <cursoragent@cursor.com>
Only update an existing Codex OAuth row when both rows share the same
chatgptAccountId, so a second Codex login no longer overwrites the first
account's rotated token pair. Also fall back to
workspaceId || chatgptAccountId || accountId for the chatgpt-account-id header.
Project conversationState history/currentMessage into OpenAI-style
messages for /v1/compress, then write compressed text back into the
original Kiro fields while preserving provider payload shape. Fail open
when the proxy returns malformed or reordered messages.
Co-authored-by: Cursor <cursoragent@cursor.com>
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>
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>
VolcEngine Ark caps the Kimi family at max_tokens <= 32768, but the
model's advertised ceiling is far higher (Kimi-K2.7-Code resolves to
maxOutput 262144), so clampToModelMaxOutput alone leaves it uncapped and
the request 400s. Add a Kimi-scoped rule with an explicit maxOutputCap of
32768, combined with the model ceiling via min(). Covers max_tokens,
max_completion_tokens, max_output_tokens.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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>
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>
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>
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>
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>
- 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.