Commit Graph
200 Commits
Author SHA1 Message Date
decolua 64f58420db feat(i18n): add endpoint exposure notice across multiple languages
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.
2026-06-06 12:45:32 +07:00
Farhan UsmanandCursor 4fc02e67e5 fix(minimax): echo reasoning_content on follow-up turns to avoid 400
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>
2026-06-06 12:25:12 +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
decoluaandCursor 281f292f63 test(translator): add data-driven coverage, bug-exposing cases, and real provider smoke
- matrix.js generates N providers x M models from PROVIDER_MODELS
- coverage-all-models + format-roundtrip for structural/semantic checks
- bugs-* files expose known translation issues via it.fails
- real/smoke-providers runs full handleChatCore path against live providers (RUN_REAL=1), concurrent
- registerAll.js eagerly imports translators (Vitest ESM require fix)
- vitest.config: array aliases for subpaths + maxConcurrency 60

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-06 12:19:59 +07:00
Kevin LeandCursor c233c7c8fc fix(codex): durable OAuth refresh lifecycle
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>
2026-06-06 11:04:36 +07:00
Delcado19andCursor 38b73bfc6b fix(antigravity): passthrough tab-autocomplete + mark default agent slot mandatory
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>
2026-06-06 10:48:14 +07:00
therunnasandCursor 61d546627e fix(qoder): allow qmodel_latest model key
- 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>
2026-06-06 10:44:37 +07:00
Delcado19andCursor 3dda651bad fix(kiro): add mappable "auto" model slot for Kiro agent mode
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>
2026-06-06 10:31:39 +07:00
decolua 8671468360 Merge PR #1628: fix(model-test) route image and STT probes to their real endpoints
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
2026-06-06 10:03:32 +07:00
41f94ce8c8 fix(minimax): Bổ sung MiniMax-M3 + cập nhật Quota Tracker coding/CN
Squash-merge PR #1631 (decolua/9router) — chỉ lấy file code + test, bỏ docs.

- feat(minimax): add MiniMax-M3 to intl + cn provider models (targetFormat claude)
- feat(minimax): add MiniMax-M3 pricing entry
- fix(minimax): translate Claude body khi content=null (M3 thinking-only)
- fix(minimax): hiển thị quota M-series bucket "general"/"MiniMax-M*" + percent-only
- test: minimax usage / model registration / pricing

Co-Authored-By: Claude <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-06 10:01:05 +07:00
yicone c980e1f7ad Harden STT ping input and expand model-test coverage 2026-06-03 01:53:34 +08:00
yicone d4c3e6383a Fix STT model test routing 2026-06-02 21:14:42 +08:00
yicone e414975d0c Fix model test routing for image providers 2026-06-02 21:14:36 +08:00
decolua e9ae21a723 # v0.4.66 (2026-05-29)
## Features
- Add Qoder provider: device-flow OAuth, COSY signing, WAF-bypass body encoding, live model catalog, dashboard quota tracker, 11 models (#1372)
- Add new models: Claude Opus 4.8 (Claude Code), GPT 5.4 Mini (Codex)

## Fixes
- DeepSeek thinking mode: echo `reasoning_content` back on follow-up/tool-call turns so OpenCode-free and custom providers no longer 400 with "reasoning_content must be passed back" (#1543)
- Reasoning injector: match deepseek/kimi model ids case-insensitively (covers custom providers using capitalized model names)
- OpenCode suggested-models: include free models without the `-free` suffix, e.g. `big-pickle` (#1535)

## Improvements
- Codex: trim sunset models, keep gpt-5.5 / gpt-5.4 / gpt-5.3-codex family, add gpt-5.4-mini
- volcengine-ark: refresh model list (add DeepSeek-V4-Flash/Pro, drop EOL entries)
- Lower stream stall timeout 35s → 30s for faster hang detection
2026-05-29 17:48:01 +07:00
Simon Shi 69bc71cf11 refactor(qoder): mirror Kiro's OAuth service layout
Move device-flow / poll / userinfo / parseExpiry from src/lib/qoder/auth.js
into a QoderService class at src/lib/oauth/services/qoder.js, matching how
KiroService is organized. Also re-add the QoderService re-export from
services/index.js.

The split now mirrors Kiro:
  src/lib/oauth/services/qoder.js    OAuth flow            (was auth.js)
  src/lib/qoder/cosy.js              Per-request signing   (unchanged)
  src/lib/qoder/encoding.js          WAF-bypass body       (unchanged)
  src/lib/qoder/constants.js         Endpoints + model map (unchanged)

Behavior is unchanged — same functions, same signatures, just relocated
into a class so the import path lines up with `import { QoderService } from
"@/lib/oauth/services"` like every other OAuth provider. parseExpiry is now
a static method so callers and tests can use it without instantiating.

42 tests still pass; build still clean.
2026-05-29 17:36:27 +07:00
Simon Shi 935462ce8f test(qoder): add regression coverage for review-fix changes
Adds 18 new tests covering the bugs fixed in the previous commit so they
can't silently regress:

- parseExpiry (7 tests): numeric ms-epoch input, numeric strings handled
  before Date.parse so "1700000000" doesn't get year-interpreted, RFC3339
  strings, expires_in:0 honored as already-expired, 30-day fallback only
  when both inputs are missing/invalid

- normalizeMessages (4 tests): system hoisting, multipart text flatten,
  multiple system joining, empty input

- wrapQoderSSE (6 tests): the fixed cases — trailing partial line drained
  in flush(), no chunks forwarded after [DONE], embedded newlines stripped
  from inner body, error envelope produces error chunk + [DONE], non-ok
  responses returned unchanged

- expose parseExpiry from auth.js, expose normalizeMessages/wrapQoderSSE
  via __test__ from the executor (internals only — not part of the public
  API). Marked with comment so the surface is intentional.

42 tests total (24 original + 18 new). Build still clean.
2026-05-29 17:36:27 +07:00
Simon Shi a6fd84691b feat(qoder): port Kiro-style provider integration with COSY signing
Replaces the Qoder placeholder with a real free-tier provider:

- Device-flow OAuth: PKCE + nonce generated locally, user authorizes at
  qoder.com/device/selectAccounts, poll openapi.qoder.sh until token
- COSY signing (RSA-1024 + AES-128-CBC + MD5) for chat / model-list
- WAF-bypass body encoding (custom-alphabet base64 + thirds rearrange)
- Live model_config catalog from /algo/api/v2/model/list, cached 1h
- 11 models registered (auto/ultimate/performance/efficient/lite +
  6 frontier *model ids)
- Usage fetcher for openapi.qoder.sh/api/v2/quota/usage
- Dashboard live-models resolver, provider test, OAuth modal hookup
- 24 unit tests covering encoder, PKCE, COSY headers, sigPath stripping
2026-05-29 17:36:27 +07:00
DelcadoandClaude Opus 4.8 88224b80ca fix: never route GitHub Copilot Gemini/Claude models to /responses (#1062) (#1536)
GitHub Copilot's /responses endpoint only serves OpenAI (gpt/codex)
models. gemini-3.1-pro-preview was failing on /chat/completions with a
"not supported" error, getting cached as a codex model, then escalated
to /responses where it 400s with "does not support Responses API".

Add GithubExecutor.supportsResponsesEndpoint() and gate both the cached
/responses route and the 400-fallback on it, so Gemini/Claude always
stay on /chat/completions and the real upstream error surfaces.

Adds tests/unit/github-responses-routing.test.js (5 tests).

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-29 15:40:42 +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
Delcado dcc46f2eee Reuse Gemini CLI project ID for usage (#1428) 2026-05-26 11:23:47 +07:00
Hamsa_MandJoJo 315dcaa37a fix: strip empty Read pages argument in OpenAI-to-Claude translator (#1354)
Some OpenAI-compatible providers emit optional string tool parameters
as empty strings (e.g. pages: "") instead of omitting them. Claude
Code rejects pages: "" as invalid, breaking the Read tool for
non-PDF files routed through 9router.

Add sanitizeToolArguments() that parses tool-call arguments and
removes known optional empty-string fields before emitting
input_json_delta back to Claude format. Currently handles the
Read tool pages field specifically.

Includes regression test.

Fixes #1278

Co-authored-by: JoJo <noreply@github.com>
2026-05-23 09:27:13 +07:00
nguyenha935andGoClaw Operator 7bc97eae7b fix(embeddings): forward Gemini output dimensions (#1366)
Co-authored-by: GoClaw Operator <operator@goclaw>
2026-05-23 09:23:26 +07:00
Muhammad Mugni HadiandCursor d976f4cc87 feat(xai): add xAI Grok provider with OAuth + API key auth + image
Adapted from PR #1286 (mugnimaestra/feat/xai-grok-provider) to match
existing app architecture. Includes:

- OAuth 2.0 with PKCE on loopback port 56121 (Grok Build)
- API key auth path (console.x.ai)
- Token refresh wiring (open-sse + sse tokenRefresh)
- Dashboard OAuth modal with fixed-port flow + manual code fallback
- Provider registry entries (OAuth + API key)
- xAI image generation via OpenAI-compatible adapter
  (grok-2-image-1212 model, no size/quality/style params)

Excludes (intentionally, to match app patterns):
- Custom xAI Responses executor (DefaultExecutor handles /chat/completions)
- xAI-specific translators (app uses OpenAI as intermediate format)
- Image edits (not supported by current imageGenerationCore)
- Video endpoints (app has no video subsystem yet)
- CLI xai-login command

Refs decolua#1286

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 11:33:18 +07:00
decolua 026a7c9b85 Enhance security 2026-05-21 11:33:18 +07:00
Noé Rivera e3cab135ef fix: decode Composer cursor thinking output (#1310) 2026-05-21 09:52:30 +07:00
blu1606 5e1c126136 fix(security): harden public API and local-only access gates 2026-05-18 15:23:37 +07:00
Zanuar Tri Romadon e03b28138a feat(rtk): add Kiro format support for tool result compression (#1194)
- Add compressKiroFormat() to handle conversationState.history and currentMessage
- Compress toolResults[].content[].text in Kiro's AWS CodeWhisperer format
- Preserve error tool results (status === 'error')
- Add 7 comprehensive tests covering all edge cases
- Verified with real usage: 13.6% savings on npm install output
2026-05-17 15:13:37 +07:00
decolua 4a575f21a2 https://github.com/decolua/9router/pull/1167
https://github.com/decolua/9router/pull/1166
2026-05-16 11:20:08 +07:00
decolua 3cca2252a6 chore: add buildOutput RTK filter, drop legacy cloud sync, internal cleanup
- feat(rtk): buildOutput filter + autodetect for npm/yarn/cargo logs
- chore: remove unused cloud sync module and related routes
- ui: hide deprecated providers (qwen, iflow, antigravity)
- chore: minor tray/cli/internal adjustments
2026-05-16 10:54:41 +07:00
Thiên Toán 74c9879e8e feat: add minimax tts support (#1043) 2026-05-13 15:34:10 +07:00
Aleksei ea44ca049e Add Codex GPT 5.5 image support (#991) 2026-05-12 09:26:13 +07:00
decoluaandCursor b39eb61c33 chore: release v0.4.27
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-09 22:48:07 +07:00
decolua bee8dad946 feat(db): migrate from lowdb to SQLite with repos pattern
- Add modular DB layer (adapters, migrations, repos, helpers)
- Replace localDb/usageDb/requestDetailsDb monoliths with repos
- Add Tailscale tunnel integration & status check API
- Add /api/cli-tools/all-statuses aggregated endpoint
- Add settingsStore (Zustand) and mitm/dbReader
- Add DB unit tests (benchmark, concurrent, migration, vs-lowdb)
2026-05-09 17:48:20 +07:00
Aleksei 787d248030 Add Cloudflare Workers AI image generation (#973) 2026-05-09 09:53:39 +07:00
decolua ad661c1286 feat: enhance CommandCode integration with improved message handling 2026-05-07 23:02:07 +07:00
Arden Hermawan 050e56f20b Fix compatible provider API key setup (#925) 2026-05-07 16:17:03 +07:00
Abhishek Divekar 3f17ee0e21 Add sticky round-robin for combos (#831)
Made-with: Cursor
2026-05-01 16:36:36 +07:00
Rezky Hamid 30b114ab75 fix: strip output_config for MiniMax (#820) 2026-05-01 16:16:01 +07:00
decolua 8de9aae90c Feature : RTK compress 2026-04-22 15:36:51 +07:00
decolua 45731ae639 feat: add OpenCode Go provider and support for custom models
- Introduced OpenCode Go provider with relevant configurations.
- Enhanced model management by allowing users to add and delete custom models.
- Updated UI components to support model selection for image types.
- Adjusted sidebar visibility to include image media kinds.
2026-04-22 14:16:21 +07:00
decolua abb04c5366 feat: add support for Grok Web and Perplexity Web providers 2026-04-22 11:58:53 +07:00
anuragg-saxenaa d0ace2a3cf fix(codex): await image URL fetches before sending to upstream (closes #575)
Remote HTTP(S) image URLs are fetched and inlined as base64 data URIs
in a new prefetchImages() step run before super.execute(), so the body
sent to Codex contains resolved image bytes instead of URLs the backend
cannot access.

Scope is limited to the Codex executor — base executor and other
providers are untouched.

Co-authored-by: anuragg-saxenaa <anuragg.saxenaa@gmail.com>
Made-with: Cursor
2026-04-17 12:15:10 +07:00
decolua 75c4598da0 Add marked package, update Qwen executor for OAuth handling, and enhance changelog styles 2026-04-17 12:15:10 +07:00
decolua 04cdb75839 Add proactive token refresh lead times for providers and implement Codex proxy management 2026-04-14 11:41:06 +07:00
kwanLeeFrmVi 1c160cc8d9 feat(claude-code): spoof TLS fingerprint and stabilize headers for Anthropic
- 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
2026-03-30 16:27:28 +07:00
moophat 65af4328fd Add optional modelID input for custom API Key Providers testing (#315)
* feat: add modelId fallback for provider validation

- If /models endpoint unavailable, validate via /chat/completions
- Add optional Model ID input in EditCompatibleNodeModal
- Improves compatibility with providers lacking /models endpoint

* feat: improve provider validation with modelId fallback

- Add Model ID input for chat/completions fallback validation
- Reorder UI: API Key → Model ID → Check button + Badge
- Display detailed BE error messages in FE
- Add status-specific error handling (401/403/400/404/5xx)
- Add unit tests for error message helpers
- Add vitest devDependency
2026-03-16 09:21:05 +07:00
Nick Roth 75270ea755 feat: Add OpenAI API response_format support for structured JSON output
Translates OpenAI response_format parameter into Claude-compatible system
prompt instructions, enabling structured JSON output for json_schema and
json_object types.

Co-authored-by: Nick Roth <nlr06886@gmail.com>
Made-with: Cursor
2026-03-12 16:30:47 +07:00
decolua 32e3980a13 feat(ollama): Add Ollama provider support with models and configuration, including API endpoints and UI updates. 2026-03-12 15:24:02 +07:00
Aakash ThakkarandCursor d7e06c3085 fix: improve cursor auto-import reliability on macOS (#161)
The macOS auto-import was failing with "Cursor database not found" even
when Cursor was installed and logged in. This was caused by a single
hardcoded path and no fallback when the DB file existed but couldn't be
opened (e.g. WAL lock, Insiders variant).

Changes (macOS only — linux/win32 paths are unchanged):
- Probe both standard and Insiders DB locations on macOS
- Return a descriptive error when the DB file exists but can't be opened
- Try multiple known key names for token and machine ID
- Add fuzzy key fallback for future Cursor schema changes
- Normalize JSON-encoded string values from the DB

Adds unit tests covering all new and existing behavior.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-20 15:07:43 +07:00
HXD.VN e1b836168a feat: add /v1/embeddings endpoint (OpenAI-compatible) (#146)
* feat: implement /v1/embeddings endpoint (#117)

Add OpenAI-compatible POST /v1/embeddings endpoint that routes through
the existing provider credential + fallback infrastructure.

Changes:
- open-sse/handlers/embeddingsCore.js: core handler (handleEmbeddingsCore)
  * Validates input (string or array), encoding_format
  * Builds provider-specific URL and headers for openai, openrouter,
    and openai-compatible providers
  * Handles 401/403 token refresh via executor.refreshCredentials
  * Returns normalized OpenAI-format response { object: 'list', data, model, usage }
- cloud/src/handlers/embeddings.js: cloud Worker handler (handleEmbeddings)
  * Auth + machineId resolution identical to handleChat
  * Provider credential fallback loop with rate-limit tracking
- cloud/src/index.js: wire new routes
  * POST /v1/embeddings  (new format — machineId from API key)
  * POST /{machineId}/v1/embeddings  (old format — machineId from URL)

* test: add unit tests for /v1/embeddings endpoint

- Setup vitest as test framework (tests/ directory)
- embeddingsCore.test.js (36 tests):
  - buildEmbeddingsBody: single string, array, encoding_format, default float
  - buildEmbeddingsUrl: openai, openrouter, openai-compatible-*, unsupported
  - buildEmbeddingsHeaders: per-provider headers, accessToken fallback
  - handleEmbeddingsCore: input validation, success path, provider errors,
    network errors, invalid JSON, token refresh 401 handling
- embeddings.cloud.test.js (23 tests):
  - CORS OPTIONS preflight
  - Auth: missing/invalid/old-format/wrong key → 401/400
  - Body validation: bad JSON, missing model, missing input, bad model → 400
  - Happy path: single string, array, delegation, CORS header, machineId override
  - Rate limiting: all-rate-limited → 429 + Retry-After, no credentials → 400
  - Error propagation: non-fallback errors, 429 exhausts accounts

Total: 59/59 tests passing
Framework: vitest v4.0.18, Node v22.22.0

* feat: add Next.js API route for /v1/embeddings endpoint

Wire the embeddings handler into Next.js App Router.

- src/app/api/v1/embeddings/route.js: Next.js API route (POST + OPTIONS)
- src/sse/handlers/embeddings.js: SSE-layer handler mirroring chat.js pattern

Uses handleEmbeddingsCore from open-sse/handlers/embeddingsCore.js with
the same auth, credential fallback, and token refresh logic as the chat
handler. Supports REQUIRE_API_KEY env var, provider fallback loop, and
consistent logging.
2026-02-18 13:24:02 +07:00