diff --git a/CHANGELOG.md b/CHANGELOG.md index 7cb1a186..0d729f06 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,116 @@ +# v0.5.59 (2026-08-29) + +## Features +- **Search**: new web search providers — Antigravity (Google Search grounding + on the existing OAuth account pool, citations keyed and merged by URL) and + Xquik (X search with `x-api-key` auth, cursor pagination, credit-based + usage), both on `POST /v1/search`. Based on #3437 by @Nautilaceae +- **Search**: ollama-search and zai-search borrow a chat provider's API key + instead of requiring their own connection, driven by a new + `credentialFallback` registry field. zai-search later folded into the `glm` + provider itself so the web search page shows the shared connection +- **Models**: daily background sync of model capabilities from models.dev — + modalities keyed by model id (majority of sources must declare one), + context/output limits keyed by provider + model, strictly additive and + sitting below the hand-written tables. ETag + mtime cache, 60s startup + delay, `MODEL_CATALOG_SYNC=off` to disable +- **Models**: add GLM-5.3-Flash (1M context, natively multimodal), DeepSeek + V4 Vision, Grok 4.5/4.6 (500k context); correct glm-4.6v/4.5v video input + and output limits, backfill glm-4.6v on glm-cn +- **Usage**: show the Zed plan quota on the dashboard — plan, edit + predictions, hosted model requests and billing-cycle reset; unlimited rows + render as "N used · Unlimited" +- **Usage**: track GPT-5.3-Codex-Spark quota windows (spark_session / + spark_weekly) from the Codex usage response (#3431) +- **Antigravity**: quota-aware routing — on 409/429 fetch live quota for the + exact per-model resetAt and skip only the exhausted account/model pair; + report the earliest reset when every account is blocked (#3561) +- **Antigravity**: map image `size` to the aspect-ratio model suffix (-WxH); + add the Gemini 3.7 Flash tiers to MITM defaultModels so they show up in + the dashboard model-mapping table +- **Dashboard**: bulk import Grok CLI accounts from JSON — paste an array or + drag-drop multiple .json files, all OAuth connections created in a single + call, mirroring the codex flow +- **CLI tools**: endpoint presets shared across every tool card through one + live-resyncing store, instead of per-card localStorage copies that never + saw each other's saved endpoints +- **Token Saver**: configurable compression timeout (`headroomTimeoutMs`) — + the fixed 3000 ms made busy machines time out and send inconsistently + compressed bodies, hurting prompt caching +- **i18n**: pt-BR expanded to 1132 terms + +## Fixes +- **Stream**: record usage when a client closes on the terminal event — the + Responses API has no [DONE] sentinel, so codex closed the socket on + `response.completed` and cancelled the reader before flush() ran its usage + side effects; the tail now lives in a once-guarded finalizeStream(). Also + stop logging a disconnect for every completed Responses call +- **Stream**: parse the trailing NDJSON line an Ollama stream leaves behind + without a closing newline — the final chunk carrying `done_reason` and the + token counts was dropped +- **Session**: read the Claude Code session id from the + `x-claude-code-session-id` header — `metadata.user_id` is dropped by + Responses translation, splitting one conversation across several + `prompt_cache_key` values and missing the upstream prefix cache +- **Usage**: preserve nested `cached_tokens` — the top-level-only read + persisted `cached_tokens: 0` for every Responses-format provider (codex, + grok-cli, …), billing cache hits at the full input rate +- **Usage**: GLM quotas accept CREDIT_LIMIT plans and multi-interval windows + (5h session / 7d weekly) instead of overwriting a single "session" key +- **Models**: the catalog sync no longer erases its own output — deltas were + measured against the previous run's writes (the second run cut `providers` + from 20 entries to 5); one vote per provider in the modality tally, ETag + restored from file on startup, and the worker thread dropped after the + bundler rewrote its path into a module-not-found error +- **Executor**: CommandCode returns errors as a `type:"error"` event inside + an HTTP 200 NDJSON stream — peek the first events before committing, abort + and return a real 4xx/5xx so combo/account fallback triggers instead of + streaming the error text as content +- **Search**: scope failure locks on the credential-fallback path — a failing + search locked `modelLock___all` and took the shared glm key offline for + chat as well; locks are now attributed to the connection's owner and + scoped to `websearch:` +- **Providers**: connection tests get a 15s AbortSignal timeout instead of + hanging and exhausting the browser socket pool; guard undefined provider + names on the providers page +- **Antigravity**: sanitize competing-client branding via a config-driven + rule table (Zed's Claude-agent prompt, opencode → antigravity) — upstream + answers 429 Quota Exhausted. Applied in the executor so the shared + openai-to-gemini translator leaves gemini/vertex/zed untouched +- **MiniMax**: preserve images on the sourceFormat-matched OpenAI transport + — MiniMax-M3 resolved a Claude-shaped body posted to the OpenAI endpoint, + silently dropping `image_url` blocks (#3418) +- **Claude**: decloak tool names in same-format streaming passthrough — + OAuth-cloaked names (CLAUDE_TOOL_SUFFIX) leaked to the client and every + tool call was rejected as unknown +- **Tools**: default a missing `tools[].type` to "custom" on Claude-format + requests — strict Anthropic-compatible gateways (MiniMax) reject the + request with 400 otherwise +- **Translator**: zai thinkingFormat sends the top-level `reasoning_effort` + object GLM-5.2+ requires — every GLM-5.x request ran at the model default + (max); gated on GLM-5.2+ since older GLM does not read it (#2721) +- **RTK**: system prompt injection matches each target wire format + (Chat/Responses/Claude/Gemini/Kiro) and is exact-idempotent across retries, + so distinct prompts sharing a long prefix are no longer collapsed (#3202). + Also set the diagnostic before the silent null return on Responses + translation failure so the panel is no longer blank +- **OpenCode**: route muse-spark through /zen/v1/responses (it 500s on + chat/completions), normalizing the Chat fields the Responses API rejects + and clamping max/ultra effort to xhigh +- **CLI**: install better-sqlite3 without build tools on Node 22+ (N-API + 13.0.3 ships per-platform prebuilds, `--ignore-scripts` skips the implicit + node-gyp build); Node < 22 stays on 12.6.2, working installs untouched +- **CLI tools**: send the API key Codex actually reads — + `[model_providers.9router.http_headers]` instead of auth.json (which left + every request 401 and clobbered an existing ChatGPT login); subagent model + moved to `agents.default_subagent_model` +- **OAuth**: refresh Cline tokens with the extension JSON contract +- **Dashboard**: clamp the API key mask length — keys shorter than 8 chars + threw RangeError and crashed the media-provider detail page +- **UI**: wait for the Material Symbols font itself before revealing icons — + `document.fonts.ready` resolved before the 4MB woff2 even started loading, + leaving icons blank until a second load + # v0.5.55 (2026-08-14) ## Features diff --git a/cli/package.json b/cli/package.json index 2fe55c9c..a6618ce8 100644 --- a/cli/package.json +++ b/cli/package.json @@ -1,6 +1,6 @@ { "name": "9router", - "version": "0.5.55", + "version": "0.5.59", "description": "9Router CLI - Start and manage 9Router server", "bin": { "9router": "./cli.js" diff --git a/package.json b/package.json index f1c2c97f..f01bf454 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "9router-app", - "version": "0.5.55", + "version": "0.5.59", "description": "9Router web dashboard", "private": true, "scripts": {