Adds Fusion as a third combo strategy alongside fallback/round-robin. A
fusion combo fans the prompt out to all member models in parallel, then a
configurable judge model synthesizes one final answer from the panel.
- handleFusionChat in open-sse/services/combo.js: quorum-grace collection
caps the straggler penalty, anonymized sources prevent judge brand-bias,
degrades to a direct answer on single survivor and 503 on total failure.
- chat.js dispatches strategy==="fusion" at both combo entry points.
- Combos dashboard: per-combo strategy Select replaces the round-robin
toggle, fusion reveals a judge picker, plus a strategy/capacity explainer.
- tests/unit/combo-fusion.test.js covers fan-out, judge routing/default,
quorum-grace straggler drop, single-survivor and total-failure degradation.
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>
Probes every chat model of every active provider with an image/audio content
block and classifies the outcome against declared capabilities. Surfaces models
where non-vision/non-audio models 400 on modality input (auto-strip candidates)
and where capability data is stale. Survey-only: logs a grouped table, never
fails on capability outcomes (cred/account noise filtered via status + message).
Co-authored-by: Cursor <cursoragent@cursor.com>
clientId/clientSecret của antigravity + gemini bị lặp 3 nơi
(registry, usage.js, src/lib/oauth). Gom vào shared.js
(ANTIGRAVITY_OAUTH_CLIENT, GOOGLE_OAUTH_CLIENT), các file spread vào.
Byte-for-byte: PROVIDERS/alias/oauth-url equal, golden 142 pass.
Thêm test guard nội dung + alias resolution.
Co-authored-by: Cursor <cursoragent@cursor.com>
Gộp switch 13 nhánh getUsageForProvider thành 1 registry object
(provider → handler), mỗi handler giữ nguyên signature/args qua ctx.
Behavior giữ nguyên (ollama vẫn chỉ nhận accessToken như cũ).
Thêm tests/unit/usage-dispatch.test.js guard dispatch.
Co-authored-by: Cursor <cursoragent@cursor.com>
Two `opencode` keys existed; the first (localhost:4096) was silently overridden
by the later one (opencode.ai, noAuth). Drop the dead entry. Resolved PROVIDERS
output unchanged (verified byte-for-byte).
Co-authored-by: Cursor <cursoragent@cursor.com>
CHAT_URL and opencode buildUrl base now read from PROVIDERS instead of repeating
the literal. Values identical; providers byte-for-byte + gate clean.
Co-authored-by: Cursor <cursoragent@cursor.com>
These translate-path builders had no runtime consumers: the translator route
uses executor.buildUrl/buildHeaders, and the barrel re-exports were unused.
Removing them eliminates the parallel URL/header build path (single source of
truth = executors). Drop their private helpers and the now-unused clineAuth
import. Golden executor snapshots + gate: no regression.
Co-authored-by: Cursor <cursoragent@cursor.com>
Snapshot buildProviderUrl/buildProviderHeaders/getTargetFormat for all providers
before merging the translate-path with executor URL/header builders.
Co-authored-by: Cursor <cursoragent@cursor.com>
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>
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>
Lock current behavior before refactor: buildUrl/buildHeaders per default-executor
provider, translateResponse streaming (claude/gemini), translateRequest body
(openai->claude/gemini/kiro). Sanitize volatile fields (tokens, kimi device-id,
kiro conversationId, timestamps) for stable snapshots.
Co-authored-by: Cursor <cursoragent@cursor.com>
Bootstrap → JWT → chat flow with auto-retry. Inject the MiMoCode
system marker required to pass the upstream 403 anti-abuse gate,
derive JWT expiry from the exp claim, and use a stable per-machine
fingerprint as the bootstrap client.
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>
Added a new translation for the message "Endpoint is exposed without an API key." to various language files, enhancing user awareness regarding API security. This update ensures that users are informed about potential risks associated with unprotected endpoints in their respective languages.
MiniMax requires reasoning_content echoed back on assistant messages in
multi-turn/tool-call conversations. Add minimax and minimax-cn to
PROVIDER_RULES (scope all), same fix as DeepSeek (#1543).
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>
Add shared OAuth credential lifecycle manager with provider-aware refresh
decisions. Implement CodexExecutor.refreshCredentials so 401/403 retry
refresh works for Codex, track lastRefreshAt and refresh before the
upstream stale-token window, preserve omitted idToken, and add
per-connection single-flight refresh to avoid refresh-token rotation races.
Merged from PR #1664.
Co-authored-by: Cursor <cursoragent@cursor.com>
MODEL_NO_MAP guard never re-routes Antigravity tab-autocomplete (tab_* models)
so latency-critical inline completion stays native. Flags gemini-3.5-flash-low
(agent/Default) as mandatory in the dashboard.
Co-authored-by: Cursor <cursoragent@cursor.com>
- Add qmodel_latest to QODER_MODEL_MAP
- Expose qmodel_latest in static Qoder provider catalog (qd)
- Generalize executor comment so model set does not go stale
- Add unit coverage for the new model key + catalog
Closes#1638
Co-authored-by: Cursor <cursoragent@cursor.com>
Kiro sends modelId "auto" for the main agent turn; without a defaultModels
slot getMappedModel returned null and the call leaked to AWS instead of the
configured provider. Adds the slot + guard test.
Co-authored-by: Cursor <cursoragent@cursor.com>
Route image model tests to /api/v1/images/generations and STT to
/api/v1/audio/transcriptions instead of forcing all non-embedding
models through chat completions. Adds kind-aware pingModelByKind,
hf->huggingface alias, and silent WAV sample for STT reachability.
Scoped to dashboard/internal model testing only; runtime inference
routing is unchanged.
Author: yicone <yicone@gmail.com>
Closes#1628