diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d38f2a13d..e69de29bb2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,2086 +0,0 @@ -# Changelog - -All notable changes to OmniRoute are documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - ---- - -## [Unreleased] - ---- - -## [2.3.5] — 2026-03-12 - -> ### Hotfix: Permanent @swc/helpers MODULE_NOT_FOUND Fix - -### 🐛 Bug Fixes - -- **`@swc/helpers` MODULE_NOT_FOUND crash on `npm install -g`** — Next.js standalone tracer does not always include `@swc/helpers` in `app/node_modules/`, causing an immediate server crash after install. Fixed in two layers: - - `scripts/prepublish.mjs` — now explicitly copies `@swc/helpers` from root `node_modules/` into the standalone `app/node_modules/` before packaging. The npm tarball will always include it from now on. - - `scripts/postinstall.mjs` — added a fallback that copies `@swc/helpers` from root into `app/node_modules/@swc/` if it's missing after install. Handles older versions and edge cases. - ---- - -> ### UI Polish — Endpoint Music Section, Always-Visible Buttons & Provider Logos - -### ✨ Improvements - -- **Endpoint page: Music Generation section** — `/v1/music/generations` now appears in the "Media & Multi-Modal" category alongside Image, Audio Transcription, and Text-to-Speech. Music models (ComfyUI Stable Audio, MusicGen) show up in the endpoint's model count. -- **Provider connections: action buttons always visible** — Edit, Delete, Proxy Config, and Reauthenticate buttons on the provider connection rows are no longer hidden until hover. Improves discoverability on touch and keyboard-only navigation. -- **Combos: action buttons always visible** — Test, Duplicate, Proxy Config, Edit, and Delete buttons on combo cards are no longer hidden until hover on desktop screens. -- **Provider logos: SVG fallback chain** — `ProviderCard` and `ApiKeyProviderCard` now try `.png` → `.svg` → text initials, enabling proper logo rendering for providers without a PNG. - -### 🎨 New Provider Logos - -| Provider | Logo | Brand Colors | -| ------------ | ------------------ | -------------------------------------- | -| ElevenLabs | `elevenlabs.svg` | `#6C47FF` purple, double-bar "11" mark | -| Hyperbolic | `hyperbolic.svg` | dark + cyan→purple gradient "H" | -| AssemblyAI | `assemblyai.svg` | `#0062FF` blue waveform | -| PlayHT | `playht.svg` | dark + gradient play triangle | -| Inworld | `inworld.svg` | dark + `#5B4FFF`→cyan "i" | -| NanoBanana | `nanobanana.svg` | dark + yellow banana icon | -| Ollama Cloud | `ollama-cloud.png` | Official Ollama logo | - -### 🔧 CI Fixes (included in commit `8630557`) - -- **docs-sync** — Updated `docs/openapi.yaml` version to `2.3.3` -- **Unit tests** — Added missing `import { test } from 'node:test'` in `model-parse.test.mjs` -- **Electron `.deb`** — `electron/package.json` `author` changed from string to object with `email` field (required by `fpm`) -- **Docker build** — Added `COPY scripts/native-binary-compat.mjs` to `Dockerfile` (fixes `ERR_MODULE_NOT_FOUND` during `npm ci`) - ---- - -## [2.3.3] — 2026-03-12 - -> ### Providers Test All Fix - -### 🐛 Bug Fixes - -- **Providers page crash when clicking 'Test All'** — Clicking 'Testar Todos' could trigger the error boundary ('Failed to load providers') when the batch test timed out or returned a non-JSON response. Fixed with: - - `AbortController` (90s timeout) on the `handleBatchTest` fetch - - Inner `try/catch` for `res.json()` — truncated/non-JSON responses no longer crash the component - - Null/type guard in `ProviderTestResultsView` — malformed results can no longer trigger a render exception - - New i18n key `providerTestTimeout` for friendly timeout message (PR #330) - ---- - -## [2.3.2] — 2026-03-12 - -> ### Claude 1M Context, Postinstall Fix, New Models & OAuth Remote Docs - -### ✨ New Features - -- **Claude 1M extended context window support** — Use `[1m]` suffix on Claude model names (e.g. `claude-sonnet-4-6[1m]`) to activate Anthropic's 1M token context via the `Anthropic-Beta: context-1m-2025-08-07` header. Supported: `claude-opus-4-6`, `claude-sonnet-4-6`, `claude-sonnet-4-5`, `claude-sonnet-4`. (PR #311 — @DavyMassoneto) -- **New provider models** — Added `coder-model` (Qwen3.5) to Qwen and `iflow-rome-30ba3b`, `qwen3-max`, `qwen3-vl-plus`, `kimi-k2-0905`, `deepseek-v3.2`, `qwen3-235b` variants to iFlow; `kimi-for-coding` to Kimi. (PR #326 — @nyatoru) - -### 🐛 Bug Fixes - -- **Postinstall native binary regression fix** — PR #313's `process.exit(1)` caused npm to rollback the full package on rebuild failure. New approach copies the already-compiled binary from root `node_modules/` instead of rebuilding inside `app/` (which is a no-op). New `native-binary-compat.mjs` reads ELF/Mach-O/PE headers for reliable platform detection. (PR #327 — @ardaaltinors, fixes #321) -- **README: English Remote OAuth guide added** — The OAuth Remote Server guide existed only in Portuguese. English version now appears first; PT moved to a collapsible section. Fixes the 🔗 anchor `#oauth-on-a-remote-server` referenced from `OAuthModal.tsx` since v2.3.1. (PR #329, fixes #318) - -### 🧪 Tests - -- Added 3 unit tests for `parseModel([1m])` suffix parsing (`model-parse.test.mjs`) - ---- - -## [2.3.1] — 2026-03-11 - -> ### TypeScript Fixes & UI Polish - -### 🐛 Bug Fixes - -- **OAuth Modal displayed Portuguese text regardless of language setting (#314)** — Two hardcoded PT-BR strings in `OAuthModal.tsx` (remote-access info banner and `redirect_uri_mismatch` error message) are now in English for all users (PR #325). -- **TypeScript errors in Kimi usage parser (`usage.ts`)** — `dataObj.five_hour`, `dataObj.seven_day`, and `dataObj.user` were typed as `unknown`. Wrapped with `toRecord()` before passing to typed functions — fixes 6 compiler errors on lines 921–948. -- **`await` missing on `getSettings()` in `instrumentation.ts` (#316 follow-up)** — `getSettings()` is declared `async`; calling it without `await` made `settings` a `Promise` causing 4 TS errors when accessing `settings.modelAliases`. - ---- - -## [2.3.0] — 2026-03-11 - -> ### Bug Fixes - -### 🐛 Bug Fixes - -- **Custom Model Alias (Pattern→Target) ignored during routing (#315)** — `chatCore.ts` now calls `resolveModelAlias()` before the routing format lookup so aliases configured in Settings → Model Aliases → Pattern→Target are applied correctly (PR #317). -- **Custom Model Aliases lost after server restart (#316)** — Next.js startup hook (`src/instrumentation.ts`) now restores custom aliases from `settings.modelAliases` in the DB at boot, preventing the in-memory state from resetting to empty on restart (PR #317). -- **`better-sqlite3` postinstall rebuild fails silently on macOS ARM (#312)** — Replace unreliable `process.dlopen()` detection with explicit `process.platform`/`process.arch` comparison. Rebuild now fail-fasts with a clear error on non-linux-x64 platforms (PR #313 by @ardaaltinors). - ---- - -## [2.2.9] — 2026-03-11 - -> ### Features, Bug Fixes & Dependency Updates - -### ✨ New Features - -- **Edit custom model endpoints (#307)** — Provider detail page now shows per-row **Edit / Save / Cancel** controls for custom models. Changes to `apiFormat` and `supportedEndpoints` are now persisted via the new `PUT /api/provider-models` endpoint instead of resetting on navigation (PR #307 by @hijak). - -### 🐛 Bug Fixes - -- **`@swc/helpers` MODULE_NOT_FOUND on startup (#306)** — Added `@swc/helpers@0.5.19` as an explicit `dependency` and `override` in `package.json`. Global npm install (`npm install -g omniroute`) now reliably includes this transitive dependency on all platforms including Windows (PR #308). -- **Claude quota display inverted (#299)** — Claude Code's OAuth API returns `utilization` as _percent used_, not percent remaining. The quota bar was backwards: 87% used on Claude.ai = 87% "remaining" (green) in OmniRoute. Fixed `open-sse/services/usage.ts`: `remaining = 100 - utilization` (PR #309). - ---- - -## [2.2.8] — 2026-03-11 - -> ### Bug Fixes - -### Bug Fixes - -- **Docker healthcheck wrong endpoint (#296)** — `scripts/healthcheck.mjs` now queries `/api/monitoring/health` instead of `/api/settings`. Aligns the healthcheck with all other health monitoring components (PR #301). -- **429 causes endless queue / requests hang forever (#297)** — Added `maxWait=120000` (2 min) to all Bottleneck instances. When all provider quotas are exhausted, requests now fail-fast with a clean error instead of queueing indefinitely. Configurable via `RATE_LIMIT_MAX_WAIT_MS` env var (PR #302). - ---- - -## [2.2.7] — 2026-03-10 - -> ### Bug Fixes & Dependency Updates - -### Bug Fixes - -- **Docker startup crash (#292)** — Fixed missing `bootstrap-env.mjs` in the runtime image. The Dockerfile runner stage now copies the file from the builder stage (PR #293). -- **Google CLI stale projectId (#394)** — Antigravity and Gemini CLI executors now prefer the OAuth-stored `projectId` over `body.project` to prevent 403/404 errors from stale cached values. Includes type-safe body assignment (PR #294). -- **Tool-calling 400 errors (#291)** — Empty `name: ""` fields in `messages[]` and `input[]` are now stripped before forwarding to upstream providers (OpenAI, Codex) that reject them (PR #300). - -### Dependencies - -- Bump `hono` from 4.12.4 to 4.12.7 (security patch) (PR #298) - ---- - -## [2.2.6] — 2026-03-10 - -> ### 🐛 Fix Claude Thinking Tokens Invisible in Passthrough Mode - -### Bug Fixes - -- **Claude thinking tokens not visible (#289)** — When routing through Antigravity OAuth or any Claude provider, thinking blocks were being emitted as regular `delta.content` with `/<\/think>` XML wrappers. Fixed: now correctly maps `thinking_delta` events to `delta.reasoning_content` so clients like Claude Code, Cursor, and Windsurf display the thinking panel properly. - ---- - -## [2.2.5] — 2026-03-10 - -> ### 🔧 Zero-Config Bootstrap · 🐛 Electron Black Screen Fix - -### Features - -- **Zero-config bootstrap (#252, #249)** — OmniRoute now auto-generates required secrets on first run across all deployment modes (npm, Docker, Electron Desktop App): - - `JWT_SECRET` (64-byte hex) — required for auth/sessions - - `STORAGE_ENCRYPTION_KEY` (32-byte hex) — required for SQLite encryption - - `API_KEY_SECRET` (32-byte hex) — required for API key signing - - Secrets are persisted to `{DATA_DIR}/server.env` and survive restarts, Docker volume remounts, and upgrades - - Friendly startup warnings if OAuth secrets (Antigravity, iFlow, Gemini) are not configured - - New **`scripts/bootstrap-env.mjs`** module — single source of truth for zero-config initialization - -### Bug Fixes - -- **Electron black screen on macOS/Windows/Linux** — The Next.js server was crashing silently because `JWT_SECRET` and `STORAGE_ENCRYPTION_KEY` are never present in desktop OS environments. Fixed by calling `bootstrapEnv()` before spawning `server.js`, with secrets persisted to Electron's `userData` directory. -- **Dashboard bootstrap banner** — Added dismissable amber warning banner on the dashboard home when running in zero-config mode, showing where `server.env` is stored and how to customize secrets. - -### Note for Docker users - -Previously, `--env-file .env` was required to pass secrets to the container. Now OmniRoute will generate and persist them automatically in the mounted volume. Existing `DATA_DIR` secrets are always respected. - ---- - -## [2.2.4] — 2026-03-10 - -> ### 🔧 CI Fixes - -### CI - -- **docs-sync fix** — Updated `docs/openapi.yaml` version from `2.2.0` to `2.2.3` (was out of sync with `package.json`, causing CI lint failure) -- **CHANGELOG format** — Added required `## [Unreleased]` section at top of `CHANGELOG.md` (required by `check:docs-sync` script) -- **Electron Linux** — Added `gem install fpm` step to `electron-release.yml` Linux build job; `fpm` is required by `electron-builder` to package `.deb` installers but was not pre-installed on `ubuntu-latest` runners -- **Docker publish** — Added `DOCKER_BUILDKIT_INLINE_CACHE` env; previous `502 error writing layer blob` was a transient Docker Hub network error - ---- - -## [2.2.3] — 2026-03-10 - -> ### 🐛 Bug Fixes · 🔧 Reliability - -### Bug Fixes - -- **Antigravity/Gemini CLI: remove fake projectId fallback (#285)** — OmniRoute was generating random fallback project IDs (e.g. `useful-fuze-a04c5`) when OAuth credentials lacked a real GCP `projectId`. This caused confusing `Permission denied on resource project` and `Verify your account` errors from Google. Now throws a clear actionable error: _reconnect OAuth so OmniRoute can load your real Cloud Code project_. Affects `antigravity.ts`, `openai-to-gemini.ts`, `geminiHelper.ts`. -- **Claude Code: filter empty-named tool_use blocks across all message roles (#288)** — Pass 1.4 only filtered empty tool names from `assistant` messages. Extended to all roles (user, system). Also filters `tool_result` blocks missing `tool_use_id`, and top-level `body.tools` declarations with empty names. Prevents `Invalid input[x].name: empty string` 400 errors from Claude API. -- **Docker: explicit @swc/helpers copy (#288)** — Added `COPY --from=builder /app/node_modules/@swc/helpers` to Dockerfile `runner-base` stage. The standalone tracer doesn't always include this package, causing runtime `MODULE_NOT_FOUND` crashloops. - ---- - -## [2.2.2] — 2026-03-10 - -> ### ✨ New Features · 🔀 Model Aliases - -### New Features - -- **system-info.mjs (#280)** — New `npm run system-info` command that collects Node.js version, OmniRoute version, OS info, CLI tool versions (iflow, gemini, claude, codex, antigravity, droid, openclaw, kilo, cursor, aider), Docker/PM2 status, and system packages. Outputs `system-info.txt` for easy attachment to bug reports. - -### Model Aliases - -- **Kimi K2/K2.5 Fireworks aliases (#265)** — Built-in aliases added: `fireworks/accounts/fireworks/models/kimi-k2p5` and `kimi-k2p5` → `moonshotai/Kimi-K2.5`; same for `kimi-k2` → `moonshotai/Kimi-K2`. Fireworks long path model names now auto-resolve. -- **Mistral short aliases (#278)** — `mistral-large` → `mistral-large-latest`, `mistral-small` → `mistral-small-latest`, `codestral` → `codestral-latest`. -- **Llama short aliases** — `llama-3.3` → `llama-3.3-70b-versatile`, `llama-3-70b` → `llama-3.3-70b-versatile`, `llama-3-8b` → `llama3-8b-8192`. -- **Custom aliases** — Users can define their own aliases in **Settings → Model Aliases** tab. Example: `gpt-5.4` → `cx/gpt-5.4`. - ---- - -## [2.2.1] — 2026-03-10 - -> ### 🐛 Bug Fixes · 🔐 Security · 🔧 CI - -### Bug Fixes - -- **Gemini image routing (#273)** — `gemini-3.1-flash-image-preview` was missing from the `antigravity` image provider registry in `imageRegistry.ts`, causing image generation to fall through to the chat handler. Added alongside `gemini-2.5-flash-preview-image-generation`. -- **Ollama Cloud model listing (#276)** — `ollama-cloud` was absent from `PROVIDER_MODELS_CONFIG` in the models route, causing 400 errors when listing models from `api.ollama.com`. Entry added. -- **Missing apiKey error clarity (#277)** — When login is disabled and a provider has no API key configured, the model import route now returns `400` with a clear message instead of a generic `401 Unauthorized`. - -### Security - -- **TLS validation re-enabled (GHSA-50)** — `mitm/server.ts`: `rejectUnauthorized` now defaults to `true`. Opt-out only via `MITM_DISABLE_TLS_VERIFY=1`. -- **Path traversal hardening (GHSA-41–49)** — Added `safePath()`, `safeProfilePath()`, `safeLogPath()` helpers across `backupService.ts`, `db/backup.ts`, `codex-profiles/route.ts`, and `mitm/server.ts`. All user-supplied IDs/filenames are now anchored within their allowed directories using `path.resolve()` + bounds check. -- **Prototype pollution fix (GHSA-18–20)** — `usageHistory.ts`: `pendingRequests` maps now use `Object.create(null)` + `hasOwnProperty` guards, preventing `__proto__` / `constructor` injection via crafted provider IDs. -- **Dependency: dompurify updated to ^3.3.2** — Resolves CVE-2026-0540 (XSS in rendered HTML). -- **GitHub Actions: added `permissions: contents: read`** — Prevents token over-permission in CI jobs. - -### CI - -- **Lock file sync** — Added `@swc/helpers: "^0.5.19"` override in `package.json`; regenerated `package-lock.json`. Fixes `npm ci` failures across `ci.yml` and `docker-publish.yml`. -- **npm-publish: skip if version exists** — Workflow now checks registry before publishing; exits cleanly with a warning instead of failing with `E403` if the version is already on npm. -- **npm-publish: use `npm install` instead of `npm ci`** — Prevents publish failures when a tag commit's lock file is slightly out of sync. -- **Lint: `cursor.ts` any-budget** — Replaced `any` with `unknown` + type narrowing in `isToolBoundaryAbort()`. - ---- - -## [2.2.0] — 2026-03-10 - -> ### 🔧 Bug Fixes · Provider Support · CI Recovery - -### Bug Fixes - -- **Cursor tool-call loop (#275/#274)** — Stabilized Cursor executor to stop double-translating tool results. Set-based `finalizedIds` for O(1) dedup, byte guard (`0x7b`) before payload `.toString()`, `escapeXml()` to prevent tag injection, and converted all debug `console.log` to `debugLog()`. Fixes the 400 Bad Request loop that corrupted multi-turn Cursor sessions. -- **A/V provider validation (#281)** — Added `validateElevenLabsProvider` (GET `/v1/voices` with `xi-api-key`) and `validateInworldProvider` (POST `/tts/v1/voice` with Basic auth) so both providers can be test-connected without false 400 errors. -- **OpenAI-compatible Add Connection button (#272)** — "Add Connection" button was hidden behind `!isCompatible` guard in the Connections card. Button now appears for compatible providers when 0 connections exist, limited to 1 (matches single-key-per-node policy). -- **CI: unit tests** — Fixed circuit breaker tests using wrong instance keys (`combo:groq` → `combo:groq/llama-3.3-70b`). -- **CI: E2E protocol-visibility** — Updated spec to click "Protocols" tab before asserting MCP/A2A links (now tabs inside `/dashboard/endpoint`). -- **CI: i18n** — Added missing `header.mcp`, `header.mcpDescription`, `header.a2a`, `header.a2aDescription` keys to `en.json`. - -### New Features - -- **Kimi Coding plan quota display (#279)** — New `getKimiUsage()` with `X-Msh-*` device headers. Parses weekly quota + rate-limit breakdown from `/v1/usages`. Wires `kimi-coding` into the provider usage switch; adds quota capability flag. - -### Dependencies - -- **Dev dependencies** — Bumped `@playwright/test`, `@types/react`, `eslint-plugin-*` and 2 others (#264). -- **Prod dependencies** — Bumped 2 production packages (#263). - ---- - -## [2.1.2] — 2026-03-09 - -> ### 🔨 CI Green + Electron .deb + Link Fixes - -### Bug Fixes - -- **CI: `check:docs-sync`** — fixed 2 failures: bumped `docs/openapi.yaml` version to 2.1.1 (was 2.0.0), added required `## [Unreleased]` section to CHANGELOG. -- **CI: npm-publish workflow** — rewrote to use `npm ci --ignore-scripts` + explicit `node scripts/prepublish.mjs` with `JWT_SECRET` env; fixes the prepublish loop that caused every npm CI publish to fail. -- **README.md language bar** — fixed all 29 broken links that pointed to root `README..md` (now `docs/i18n//README.md`). -- **docs/i18n READMEs** — fixed back-links to English (`../../README.md`) and cross-links to sibling languages. - -### New Features - -- **Electron Linux `.deb` package** — added `deb` target (x64 + arm64) to `electron/package.json`; updated `electron-release.yml` to collect and attach `.deb` files to GitHub releases alongside `.AppImage`. - -> ### 🔧 CI Fix + Docs Reorganization - -### Bug Fixes - -- **CI: fixed `any`-budget violation in `open-sse/services/usage.ts`** — replaced 5 explicit `any` annotations with proper TypeScript types (`UsageQuota`, `JsonRecord`, `Error`), restoring the green CI lint gate. -- **Deleted all duplicate draft GitHub releases** — automated workflow was creating unnamed draft releases on each push; cleaned up all draft artifacts for v2.0.17–v2.1.0. - -### Documentation - -- **Root cleanup**: moved all 29 `README..md` files from the project root into their correct `docs/i18n//README.md` locations. The root now contains only `README.md` (English). -- **i18n sync**: all 11 `docs/*.md` files synced with language bar headers to all 30 `docs/i18n//` directories (319 file updates across ar, bg, da, de, es, fi, fr, he, hu, id, in, it, ja, ko, ms, nl, no, phi, pl, pt, pt-BR, ro, ru, sk, sv, th, uk-UA, vi, zh-CN). - ---- - -## [2.1.0] — 2026-03-09 - -> ### 🗺️ Full Provider-UI Gap Audit — All Backends Now Accessible from Dashboard - -### ✨ New Features - -- **7 missing API-key providers added to Providers page** — ElevenLabs, Cartesia, PlayHT, Inworld, SD WebUI, ComfyUI, and Ollama Cloud now all appear in `/dashboard/providers` with API key configuration cards. Previously these providers existed only in the backend with no UI entry point. - -- **Media page: provider + model selectors for all 5 modalities** — `/dashboard/media` now has a **Provider** dropdown and a **Model** dropdown for every tab. Selecting a provider shows only its models: - - 🖼️ **Image**: OpenAI, xAI, Together, Fireworks, Nebius, Hyperbolic, NanoBanana, SD WebUI, ComfyUI (9 providers) - - 🎬 **Video**: ComfyUI (AnimateDiff, SVD), SD WebUI (2 providers) - - 🎵 **Music**: ComfyUI (Stable Audio Open, MusicGen) - - 🔊 **Speech**: OpenAI, ElevenLabs, Deepgram, Hyperbolic, NVIDIA, Inworld, Cartesia, PlayHT, HuggingFace, Qwen (10 providers). Voice dropdown updates per provider. - - 🎙️ **Transcription**: New tab — OpenAI Whisper, Groq, Deepgram, AssemblyAI, NVIDIA, HuggingFace, Qwen (7 providers). File upload instead of text prompt. - -- **Playground: 4 new endpoint options** — Audio Transcription (`/v1/audio/transcriptions`), Video Generation (`/v1/videos/generations`), Music Generation (`/v1/music/generations`), Rerank (`/v1/rerank`). Previously only Chat, Responses, Images, Embeddings, Speech were available. - -- **CLI Tools: OpenCode + Kiro** — Both tools now appear in `/dashboard/cli-tools` with step-by-step setup guides. OpenCode was already detected in Agents but had no configuration screen. - -- **Agents: expanded CLI fingerprint providers** — kiro, cursor, kimi-coding, kilocode, cline added to the CLI fingerprint toggle list (previously only codex, claude, github, antigravity). - -### 🧹 Maintenance - -- Deleted 3 stale remote branches (`features-agente-mcp-a2a`, `fix/issue-218-round-robin-lastUsedAt`, `fix/resolve-open-issues`) — all their changes were already in main. -- Added minimal `layout.tsx` to all error-page routes (`400`, `401`, `403`, `408`, `429`, `500`, `502`, `503`) to fix Next.js standalone build. - -### 📁 Files Changed - -| File | Change | -| --------------------------------------------------------- | ---------------------------------------------------------- | -| `src/shared/constants/providers.ts` | Add 7 missing APIKEY_PROVIDERS | -| `src/shared/constants/cliTools.ts` | Add opencode, kiro entries | -| `src/app/(dashboard)/dashboard/media/MediaPageClient.tsx` | Full rewrite — provider/model selectors, transcription tab | -| `src/app/(dashboard)/dashboard/playground/page.tsx` | Add 4 new endpoint options | -| `src/app/(dashboard)/dashboard/agents/page.tsx` | Expand cliCompatProviders list | -| `src/app/{400..503}/layout.tsx` | Add minimal layouts to fix Next.js build | - ---- - -## [2.0.20] — 2026-03-09 - -> ### 🔊 TTS Expansion + 📱 Mobile UX + 🏷️ Friendly Names - -### ✨ New Features - -- **Inworld TTS provider** (`#248`) — Cloud TTS via `https://api.inworld.ai/tts/v1/voice`; Basic auth; JSON response with base64 `audioContent` decoded to binary. Use prefix `inworld/`. Available models: `inworld-tts-1.5-max`, `inworld-tts-1.5-mini`. - -- **Cartesia TTS provider** (`#248`) — Cloud TTS via `https://api.cartesia.ai/tts/bytes`; `X-API-Key` + `Cartesia-Version: 2024-06-10` headers; returns binary audio stream. Use prefix `cartesia/`. Available models: `sonic-2`, `sonic-3`. Voice is mapped via voice ID. - -- **PlayHT TTS provider** (`#248`) — Cloud TTS via `https://api.play.ht/api/v2/tts/stream`; dual auth `X-USER-ID` + `Authorization: Bearer` (store token as `userId:apiKey`). Use prefix `playht/`. Available models: `PlayDialog`, `Play3.0-mini`. - -- **ElevenLabs voice presets in dashboard** (`#248`) — `/dashboard/media` → Speech tab now shows provider-aware voice dropdowns: ElevenLabs (9 premade voices), Cartesia (3 preset voices), Deepgram Aura (5 voices), Inworld (2 voices), OpenAI (6 standard voices). Voice list updates automatically based on the model prefix typed. - -- **Speech tab in `/dashboard/media`** (`#248`) — New "Text to Speech" tab alongside Image/Video/Music. Includes model text input (supports all provider prefixes), voice/format selectors, and an inline `