Skip to content

Release v3.8.10 - #3140

Merged
diegosouzapw merged 28 commits into
mainfrom
release/v3.8.10
Jun 4, 2026
Merged

diegosouzapw merged 28 commits into
mainfrom
release/v3.8.10

Conversation

@diegosouzapw

@diegosouzapw diegosouzapw commented Jun 4, 2026 •

Copy link
Copy Markdown
Owner

[3.8.10] — 2026-06-04

OAuth resilience & observability release: spaced/sequential quota sync for OAuth accounts, a per-provider proactive-refresh skip list to keep short-TTL providers (Kimi) alive without re-exposing the Codex Auth0 cascade, token-expiry visibility on the provider cards, a new provider-stats dashboard, plus a wide batch of provider fixes (DeepSeek-web tool calls, Antigravity, Qoder, MiniMax, GitHub Copilot, Fireworks, llama.cpp, t3.chat-web, Kiro, Kilocode) and Podman deployment support.

✨ New Features

🔧 Bug Fixes

📝 Maintenance


Quality Gate

  • lint: pass (0 errors; pre-existing no-explicit-any warnings only)
  • typecheck:core: pass
  • check:cycles: pass (no circular deps)
  • check:docs-all: pass (docs-sync + doc-links; version-drift warnings are non-blocking)
  • test:vitest: pass (146/146)
  • test:unit: pass (release-blocker fix(providers): empty refresh must not resurface just-cleared synced models #3181 fixed; 1 remaining timing-flaky test passes in isolation)

Coverage of commits since v3.8.9

  • Range: v3.8.9..HEAD — 27 non-merge commits, all attributed in the CHANGELOG above (28 bullets).

Contributors this release

@KooshaPari · @tjengbudi · @minhtran162 · @totaltube · @gabrielmoreira · @ViFigueiredo · @herjarsa · @pizzav-xyz · @wilsonicdev · @JxnLexn · @xz-dev · @mrmm · @hartmark · @androw · @dependabot · @diegosouzapw

⚠️ After merging: run Phase 2 (Local VPS homologation on 192.168.0.15) before tagging.

Bump 3.8.9 → 3.8.10 across package.json, lockfile, electron, open-sse, and
docs/reference/openapi.yaml; add the [3.8.10] CHANGELOG section (root + 41 i18n
mirrors) as the integration target for the cycle. Entries land here as work
merges into release/v3.8.10; finalized by the release flow.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request bumps the project version from 3.8.9 to 3.8.10 across package.json, package-lock.json, electron/package.json, open-sse/package.json, and the OpenAPI specification. It also prepares the main and internationalized CHANGELOG files for the new release cycle by adding an 'Unreleased' section for version 3.8.10. There are no review comments, and I have no feedback to provide.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 406a150f15

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread package-lock.json
"": {
"name": "omniroute",
"version": "3.8.9",
"version": "3.8.10",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Regenerate the lockfile for the workspace version

This lockfile version bump is incomplete: open-sse/package.json now says 3.8.10, but the packages["open-sse"].version entry near the end of package-lock.json still says 3.8.9 (running npm install --package-lock-only updates it). Any release or audit tooling that reads workspace versions from the lockfile will still report @omniroute/open-sse as 3.8.9, so please regenerate or patch the workspace entry as part of this bump.

Useful? React with 👍 / 👎.

@kilo-code-bot

kilo-code-bot Bot commented Jun 4, 2026 •

Copy link
Copy Markdown

Code Review Summary

Status: 1 Issue Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
src/app/(dashboard)/dashboard/settings/components/ResponsesStatePolicyTab.tsx 3 Unused import useRef — imported but never used in the component
Files Reviewed (14 files)
  • src/app/(dashboard)/dashboard/settings/components/ResponsesStatePolicyTab.tsx — Unused import (WARNING)
  • src/shared/constants/responsesPreviousResponseId.ts — New constants file
  • src/shared/validation/settingsSchemas.ts — Schema validation addition
  • src/lib/db/settings.ts — Default settings addition
  • src/app/(dashboard)/dashboard/settings/ai/page.tsx — UI integration
  • src/i18n/messages/en.json — i18n strings added
  • src/i18n/messages/de.json — i18n strings added
  • open-sse/utils/responsesStatePolicy.ts — Core policy logic (new file)
  • open-sse/handlers/chatCore.ts — Policy integration in request pipeline
  • open-sse/services/responsesInputSanitizer.ts — Image URL normalization
  • open-sse/translator/request/openai-responses.ts — Image URL normalization
  • tests/unit/responses-state-policy.test.ts — Unit tests for policy
  • tests/unit/responses-input-sanitizer-name.test.ts — Sanitizer tests
  • tests/unit/provider-alias-uniqueness.test.ts — Alias collision tests
  • src/shared/constants/providers.ts — Alias collision fixes
  • src/app/(dashboard)/dashboard/api-manager/ApiManagerPageClient.tsx — Expiration UI fix
  • open-sse/config/providerRegistry.ts — Registry alias fixes

Fix Link: Fix these issues in Kilo Cloud


Reviewed by step-3.7-flash · 877,293 tokens

@github-actions

github-actions Bot commented Jun 4, 2026 •

Copy link
Copy Markdown
Contributor

CI Coverage Report

  • Coverage job: success
  • PR test policy: success

Coverage artifact was not available for this run.

Assign unique aliases to HuggingChat, Kimi Web, and Qwen Web so they no longer shadow primary providers or trigger startup warnings.

Add a unit test to enforce provider alias uniqueness and prevent future collisions. Also expand local ignore and VS Code exclude rules for agent, build, and worktree artifacts.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2eb0f0500c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .i18n-state.json
@@ -1,219 +0,0 @@
{

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Restore the i18n drift state file

Deleting this committed state file breaks the documented/CI i18n gate: scripts/i18n/check-translation-drift.mjs reads .i18n-state.json and exits 1 when it is missing, so npm run i18n:check now fails immediately with “.i18n-state.json not found — run npm run i18n:run to bootstrap.” This affects any release/check workflow that runs the i18n drift check after this commit, so the state file should be restored or the checker/workflow intentionally changed in the same PR.

Useful? React with 👍 / 👎.

wilsonicdev and others added 3 commits June 4, 2026 14:10
Normalize image_url parts across all Responses input paths. Integrated into release/v3.8.10.
Preserve API key expiration local time + clear button. Integrated into release/v3.8.10.
Strip previous_response_id for stateless Responses upstreams (auto/strip/preserve). Integrated into release/v3.8.10.
// `previous_response_id` is only safe when the upstream actually keeps
// Responses state. OmniRoute defaults to stateless upstream calls, so auto
// strips unless the connection explicitly opts into OpenAI Responses storage.
const providerSpecificData = toRecord(toRecord(credentials).providerSpecificData);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WARNING: Redundant double toRecord() call

const providerSpecificData = toRecord(toRecord(credentials).providerSpecificData);

The inner toRecord(credentials) already returns a JsonRecord. The outer toRecord() is unnecessary since .providerSpecificData on a JsonRecord returns unknown, which the outer call wraps. Simplify to:

Suggested change
const providerSpecificData = toRecord(toRecord(credentials).providerSpecificData);
const providerSpecificData = toRecord(toRecord(credentials).providerSpecificData as unknown);

Or more clearly:

Suggested change
const providerSpecificData = toRecord(toRecord(credentials).providerSpecificData);
const credentialsRecord = toRecord(credentials);
const providerSpecificData = toRecord(credentialsRecord.providerSpecificData);


type JsonRecord = Record<string, unknown>;

type ApplyResponsesPreviousResponseIdPolicyOptions = {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SUGGESTION: Options type uses unknown for all fields, losing type safety

type ApplyResponsesPreviousResponseIdPolicyOptions = {
  mode: unknown;
  sourceFormat?: unknown;
  targetFormat?: unknown;
  credentials?: unknown;
};

Consider using proper types:

  • mode: ResponsesPreviousResponseIdMode | string
  • sourceFormat?: string
  • targetFormat?: string
  • credentials?: { providerSpecificData?: Record<string, unknown> }

This would catch type mismatches at compile time and improve IDE support.

}

function normalizeResponsesReasoningEffort(value: unknown): string {
const effort = toString(value).toLowerCase();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WARNING: Duplicate imageUrlToText function

This function is identical to the one in open-sse/services/responsesInputSanitizer.ts:58-62. Consider extracting to a shared utility (e.g., open-sse/utils/imageUtils.ts) to avoid divergence.

Suggested change
const effort = toString(value).toLowerCase();
import { imageUrlToText } from "../utils/imageUtils";

Then remove the local definition.

return next;
}

function imageUrlToText(value: unknown): string {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WARNING: imageUrlToText returns empty string for invalid input

function imageUrlToText(value: unknown): string {
  if (typeof value === "string") return value;
  const record = toRecord(value);
  return typeof record?.url === "string" ? record.url : "";
}

When value is malformed (e.g., { image_url: null } or { url: 123 }), this returns "", causing downstream code to produce [Image: ] (empty URL). Consider returning a placeholder like [Invalid image] or throwing for truly invalid structures to surface data issues earlier.


useEffect(() => {
let cancelled = false;
fetch("/api/settings")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WARNING: Fetch to /api/settings without credentials/auth headers

fetch("/api/settings")

This relies on same-origin cookies for authentication. If the dashboard is served from a different origin (e.g., via tunnel/proxy) or if cookie auth is disabled, this will fail with 401. Consider using the authenticated fetch wrapper used elsewhere in the codebase, or at minimum add credentials: "include".

setStatus("");

try {
const res = await fetch("/api/settings", {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WARNING: No response type checking before .json()

const res = await fetch("/api/settings", {
  method: "PATCH",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ responsesPreviousResponseIdMode: nextMode }),
});
if (!res.ok) {
  setMode(previousMode);
  setStatus("error");
  return;
}
setStatus("saved");

If the server returns a non-JSON error response (HTML error page, plain text), res.json() on the next call (implicit in the success path) would throw. The code doesn't call .json() on success, but if the error path is taken and the response body is read elsewhere, it could fail. Add try { await res.json() } catch {} or check content-type header before parsing.

}
translatedBody.model = finalModelToUpstream;

const previousResponseIdPolicy = applyResponsesPreviousResponseIdPolicy(translatedBody, {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SUGGESTION: Verify credentials structure matches policy expectations

const previousResponseIdPolicy = applyResponsesPreviousResponseIdPolicy(translatedBody, {
  mode: settings.responsesPreviousResponseIdMode,
  sourceFormat,
  targetFormat,
  credentials,
});

The credentials object here should have providerSpecificData.openaiStoreEnabled for the auto mode to work correctly. Add a comment or type assertion documenting the expected shape, or validate at the call site. This prevents silent misconfiguration if the credentials structure changes.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 273268c18d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +47 to +51
// `previous_response_id` is only safe when the upstream actually keeps
// Responses state. OmniRoute defaults to stateless upstream calls, so auto
// strips unless the connection explicitly opts into OpenAI Responses storage.
const providerSpecificData = toRecord(toRecord(credentials).providerSpecificData);
return !isOpenAIResponsesStoreEnabled(providerSpecificData);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Honor request-level store before stripping state IDs

When a client calls /v1/responses for the OpenAI provider with store: true and a previous_response_id, auto mode still strips the ID unless the connection has providerSpecificData.openaiStoreEnabled set. Since chatCore leaves store on OpenAI requests, the upstream would actually have Responses storage enabled for this request, but the state pointer is removed and the follow-up starts without the referenced prior response. Consider treating an explicit request-level store: true as stateful for the auto policy.

Useful? React with 👍 / 👎.

@@ -0,0 +1,120 @@
"use client";

import { useEffect, useState, useRef } from "react";

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WARNING: Unused import useRef - this import is declared but never used in the component. This should be removed to keep the code clean and avoid linting warnings.

mrmm and others added 5 commits June 4, 2026 14:24
…3138)

Map caps.thinking to ModelV2.capabilities.interleaved for opencode-plugin. Integrated into release/v3.8.10.
Use synced models as authoritative local catalog for all providers (+regression test). Integrated into release/v3.8.10.
…I key→dashscope (#3149)

Bifurcate Qoder validation by token type (PAT→Cosy, regular→dashscope) +regression test. Integrated into release/v3.8.10.
Dynamic antigravity MITM model resolution in the executor (+bug fix +regression test; DB import dropped from client-reachable config). Integrated into release/v3.8.10.
Podman deployment options + larger upload body-size limits (+CONTAINER_HOST docs). Integrated into release/v3.8.10.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f0e3a9bec9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread docker-compose.yml
- DATA_DIR=/app/data # Must match the volume mount below
- PORT=${PORT:-20128}
- DASHBOARD_PORT=${DASHBOARD_PORT:-${PORT:-20128}}
- DASHBOARD_PORT=${DASHBOARD_PORT:-20128}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve PORT as the dashboard default

When a compose user sets only PORT (which .env.example documents as the canonical single-port setting), this now still exports DASHBOARD_PORT=20128 and the service port mappings below also default to 20128, so PORT=3000 docker compose --profile base up no longer starts/exposes the dashboard on 3000. The runtime helpers fall back DASHBOARD_PORT to PORT when it is unset, so the compose file should keep the same fallback instead of forcing 20128 unless DASHBOARD_PORT is explicitly provided.

Useful? React with 👍 / 👎.

diegosouzapw and others added 5 commits June 4, 2026 16:57
)

Fireworks router IDs (accounts/fireworks/routers/...) were double-prefixed
with accounts/fireworks/models/ → upstream 404. Add optional
acceptedModelIdPrefixes to the registry entry and skip the prepend when the
model already starts with an accepted prefix.

Co-authored-by: KooshaPari <KooshaPari@users.noreply.github.com>
…3136) (#3161)

llama-cpp was missing from the local-provider group in buildUrl(), so it
fell through to the OpenAI baseUrl and returned an OpenAI 401. Add the
case to resolve the connection's providerSpecificData.baseUrl.

Co-authored-by: tjengbudi <tjengbudi@users.noreply.github.com>
…ial (#3007) (#3162)

The executor read credentials.cookies/convexSessionId, but the pipeline
only stores the pasted string under apiKey → t3.chat always 400'd. Parse
both values from apiKey (fallback accessToken), mirroring validation.ts.

Co-authored-by: minhtran162 <minhtran162@users.noreply.github.com>
… (#3163)

MiniMax-M3 had no MODEL_SPECS entry and capitalized MiniMax-M2.7 missed
its lowercase spec (case-sensitive lookup) → both fell to the 8192 default
cap. Add the M3 spec (512K output), alias the capitalized ids, and make
getModelSpec lookups case-insensitive.

Co-authored-by: totaltube <totaltube@users.noreply.github.com>
…ot.com (#3120, #3121) (#3164)

The github (Copilot) provider had a static hardcoded catalog with no
discovery source, so Import Models never refreshed (#3120) and advertised
non-entitled models that 400 on use (#3121). Add a live /models fetch with
fallback to the static list.

Co-authored-by: gabrielmoreira <gabrielmoreira@users.noreply.github.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

});

assert.equal(url, "http://127.0.0.1:8080/v1/chat/completions");
assert.ok(!url.includes("api.openai.com"), `expected local URL, got ${url}`);

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0909b31f50

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +810 to +812
const allSynced = await getSyncedAvailableModels(provider);
if (Array.isArray(allSynced) && allSynced.length > 0) {
providerSyncedModels = allSynced.map((m) => ({

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Limit synced catalog fallback to the current connection

When the provider is GitHub Copilot, the catalog is per-account and the live branch below fetches with this connection's Copilot token, but this provider-wide lookup unions synced models from every GitHub connection before building the fallback/local catalog. If account A has already synced a model that account B is not entitled to, then B's auto-fetch-disabled or live-fetch-failure path will return A's cached model list, reintroducing the non-entitled model advertisement this change is trying to avoid. Use the current connection's synced models for per-account providers instead of getSyncedAvailableModels(provider).

Useful? React with 👍 / 👎.

Wants=network-online.target

[Container]
Image=docker.io/redis:7-alpine

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Use the official Redis image namespace in Quadlet

The new Quadlet service points Podman at docker.io/redis:7-alpine, but the official Redis image lives under Docker Hub's library namespace (the compose file in this same change uses docker.io/library/redis:7-alpine). With this Quadlet file, systemctl --user start omniroute-redis will try to pull the non-official redis namespace/repository and can fail before OmniRoute starts; use docker.io/library/redis:7-alpine here as well.

Useful? React with 👍 / 👎.

) (#3165)

Editing a combo did not invalidate the 10s nested-combo expansion caches
(chat.ts getCombosCachedForChat + chatCore.ts getCombosCached; the exported
clearCombosCache was dead code), so a removed nested target/model could be
served as a phantom for up to 10s. Wire a shared monotonic combos-cache
version in readCache (bumped by invalidateDbCache("combos") on every combo
write); both cache layers treat a version mismatch as a miss.

Also log the resolved DATA_DIR/SQLITE_FILE absolute path at DB init so the
reporter's 'persists across restart + volume wipe' symptom (a multi-replica
Docker volume/DATA_DIR mismatch, not a routing bug) is diagnosable from logs.

Includes consolidated CHANGELOG entries for #3133/#3136/#3007/#3141/#3120/#3121.

Co-authored-by: ViFigueiredo <ViFigueiredo@users.noreply.github.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8fb51f44d0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +1946 to +1947
const copilotToken =
toNonEmptyString(psd.copilotToken) || toNonEmptyString(accessToken) || null;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Refresh Copilot token before model discovery

When a GitHub Copilot connection has an expired providerSpecificData.copilotToken (the normal OAuth flow stores a short-lived token plus copilotTokenExpiresAt), this route still sends that stale token to /models and never uses the valid GitHub access/refresh token path that the chat executor uses to refresh Copilot credentials. The fetch then returns non-OK and falls back to the static/synced catalog, so “refresh/import models” after token expiry can again advertise non-entitled Copilot models instead of the per-account live list this branch is meant to enforce.

Useful? React with 👍 / 👎.

Parse bare JSON tool calls for deepseek-web (#2820) + fuzzy tool-name matching. Integrated into release/v3.8.10.
pizzav-xyz and others added 4 commits June 4, 2026 18:10
…ry manager (#3177)

Misc: ProviderProfile export, DeepSeek reasoning regex, binary guard. Integrated into release/v3.8.10.
Kiro social OAuth: optional targetProvider passthrough. Integrated into release/v3.8.10.
Bump hono to 4.12.23. Integrated into release/v3.8.10.
kilocode: openai format + default executor (matches kilo-gateway) + registry test. Integrated into release/v3.8.10.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 05aafa1374

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".


const connection: any = await createProviderConnection({
provider: "kiro",
provider: targetProvider || "kiro",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Clamp social OAuth target providers

When the social OAuth poll succeeds, this now trusts targetProvider from the request body verbatim; an authenticated caller (or a tampered dashboard request) can submit targetProvider: "openai"/"codex"/any string and persist Kiro/Amazon-Q tokens as that provider. The neighboring Kiro import and auto-import routes clamp this value to "amazon-q" or "kiro", so this route should apply the same allowlist before calling createProviderConnection.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

…3173)

Cross-request TTFT + gap-after-tool latency metrics (+test). Integrated into release/v3.8.10.
Provider stats dashboard + API (SQL moved to db module per Hard Rule #5, +test). Integrated into release/v3.8.10.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 76838f6594

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".


const providers = providerStats.map((p: any) => ({
...p,
provider: resolveName(p.provider, p.nodeName),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve provider ids for tool-latency lookups

When tool latency has been recorded for a provider whose display name differs from its id (for example openai → OpenAI), this rewrites provider before returning the payload while toolLatency remains keyed by the raw id from recordToolLatency. The dashboard indexes data.toolLatency[p.provider], so the new TTFT/Gap columns and sorting show no measurements for those providers; keep a separate display name or re-key the latency map consistently.

Useful? React with 👍 / 👎.

…h, actionable 401 (#3156)

Sequential+spaced OAuth quota sync, reactive force-refresh on 401, actionable 401 in UI. Integrated into release/v3.8.10.
…ort-TTL OAuth) (#3159)

Per-provider proactive-refresh skip list (OMNIROUTE_HEALTHCHECK_SKIP_PROVIDERS) to rescue short-TTL OAuth. Integrated into release/v3.8.10.
…informative) (#3178)

Show OAuth token expiry on provider cards (small, blue, informative). Integrated into release/v3.8.10.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3ac40829c0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread open-sse/utils/stream.ts
Comment on lines +1735 to +1738
if (isFinishChunk && passthroughHasToolCalls) {
toolFinishTime = Date.now();
try {
markToolFinish(sessionId);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Create the session before marking tool completion

In the Next API path, open-sse/handlers/chatCore.ts creates this stream without touching sessionManager first, and markToolFinish() only updates an already-existing session. For /api/v1/chat/completions tool-call streams this call is therefore a no-op, so the follow-up request cannot consume the tool-finish timestamp and the new cross-request TTFT-after-tool metric never records. Ensure the generated session is touched/created before marking the tool finish.

Useful? React with 👍 / 👎.

Comment thread open-sse/utils/stream.ts
Comment on lines +1941 to +1944
const translateHasContent =
typeof parsed.delta?.text === "string" ||
typeof parsed.choices?.[0]?.delta?.content === "string" ||
typeof parsed.choices?.[0]?.delta?.reasoning_content === "string";

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Ignore empty translated deltas for tool TTFT

When a translated stream emits an empty/role-only delta after a tool result, this predicate treats it as the first content token because it only checks typeof ... === "string". That records TTFT/gap immediately and sets contentAfterToolSeen, so the real first non-empty text delta is ignored and the dashboard reports artificially low tool latency for providers that send empty SSE prelude chunks. Require a non-empty string before recording the metric.

Useful? React with 👍 / 👎.

Comment on lines +29 to +30
/** Larger limit for file uploads: 500 MB */
export const MAX_BODY_BYTES_FILE = 500 * 1024 * 1024;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Match the file upload guard to the route limit

The /api/v1/files handler accepts files up to 512 * 1024 * 1024 bytes, but this new body-size guard rejects requests above 500 * 1024 * 1024 bytes before the handler runs. Uploads between 500 MiB and 512 MiB now get a 413 even though the endpoint’s own validation and proxy config allow them, so align this limit with the file route cap.

Useful? React with 👍 / 👎.

…models (#3181)

Empty refresh must not resurface just-cleared synced models (fixes the release-blocking provider-models-route test). Integrated into release/v3.8.10.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ee791000a2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

import { getProviderCallStats, getModelCallStats } from "@/lib/db/providerStats";
import { AI_PROVIDERS } from "@/shared/constants/providers";

export async function GET() {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Require management auth before returning provider stats

When the instance is reachable on a network, this new dashboard API can be called without any dashboard/API-key management check before it reads call_logs aggregates and in-memory combo metrics. That also bypasses the existing protected /api/combos/metrics route for the same combo data, so provider/model usage and latency stats are exposed to unauthenticated callers; gate this handler with the management auth guard before collecting stats.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f3d3590482

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

pdf: outMods.has("pdf"),
},
interleaved: false,
interleaved: Boolean(caps.thinking),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Don't advertise thinking-only models as interleaved

For any /v1/models entry where OmniRoute sets capabilities.thinking from generic reasoning support, this now reports capabilities.interleaved: true to OpenCode even though interleaved reasoning is a separate capability in the rest of the repo (interleaved_field/interleavedField, not thinking). With thinking-only models such as DeepSeek/MiniMax-style reasoning models, OpenCode can select an interleaved reasoning/tool flow that the upstream model/router path does not support, causing follow-up tool turns to be formatted incorrectly; keep this false unless the raw model carries an explicit interleaved signal.

Useful? React with 👍 / 👎.

@sonarqubecloud

sonarqubecloud Bot commented Jun 4, 2026

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
B Reliability Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

@diegosouzapw
diegosouzapw merged commit 68d5a0a into main Jun 4, 2026
92 of 94 checks passed
HouMinXi pushed a commit to HouMinXi/OmniRoute that referenced this pull request Aug 2, 2026
* chore(release): open v3.8.10 development cycle

Bump 3.8.9 → 3.8.10 across package.json, lockfile, electron, open-sse, and
docs/reference/openapi.yaml; add the [3.8.10] CHANGELOG section (root + 41 i18n
mirrors) as the integration target for the cycle. Entries land here as work
merges into release/v3.8.10; finalized by the release flow.

* fix(providers): resolve web provider alias collisions

Assign unique aliases to HuggingChat, Kimi Web, and Qwen Web so they no longer shadow primary providers or trigger startup warnings.

Add a unit test to enforce provider alias uniqueness and prevent future collisions. Also expand local ignore and VS Code exclude rules for agent, build, and worktree artifacts.

* fix(responses): normalize image_url parts across input paths (diegosouzapw#3150)

Normalize image_url parts across all Responses input paths. Integrated into release/v3.8.10.

* fix(api-manager): preserve API key expiration local time (diegosouzapw#3146)

Preserve API key expiration local time + clear button. Integrated into release/v3.8.10.

* Strip previous_response_id for stateless Responses upstreams (diegosouzapw#3143)

Strip previous_response_id for stateless Responses upstreams (auto/strip/preserve). Integrated into release/v3.8.10.

* fix(opencode-plugin): map thinking cap to interleaved in model+combo (diegosouzapw#3138)

Map caps.thinking to ModelV2.capabilities.interleaved for opencode-plugin. Integrated into release/v3.8.10.

* fix(providers): use synced models as fallback for all providers (diegosouzapw#3148)

Use synced models as authoritative local catalog for all providers (+regression test). Integrated into release/v3.8.10.

* fix(qoder): bifurcate validation by token type — PAT→Cosy, regular API key→dashscope (diegosouzapw#3149)

Bifurcate Qoder validation by token type (PAT→Cosy, regular→dashscope) +regression test. Integrated into release/v3.8.10.

* fix(antigravity): dynamic model resolution via MITM alias table (diegosouzapw#3144)

Dynamic antigravity MITM model resolution in the executor (+bug fix +regression test; DB import dropped from client-reachable config). Integrated into release/v3.8.10.

* Feature/batch allow big (diegosouzapw#3128)

Podman deployment options + larger upload body-size limits (+CONTAINER_HOST docs). Integrated into release/v3.8.10.

* fix(fireworks): preserve fully-qualified router/model IDs (diegosouzapw#3133) (diegosouzapw#3160)

Fireworks router IDs (accounts/fireworks/routers/...) were double-prefixed
with accounts/fireworks/models/ → upstream 404. Add optional
acceptedModelIdPrefixes to the registry entry and skip the prepend when the
model already starts with an accepted prefix.

Co-authored-by: KooshaPari <KooshaPari@users.noreply.github.com>

* fix(llama-cpp): route to configured local baseUrl instead of OpenAI (diegosouzapw#3136) (diegosouzapw#3161)

llama-cpp was missing from the local-provider group in buildUrl(), so it
fell through to the OpenAI baseUrl and returned an OpenAI 401. Add the
case to resolve the connection's providerSpecificData.baseUrl.

Co-authored-by: tjengbudi <tjengbudi@users.noreply.github.com>

* fix(t3-chat-web): parse cookies + convexSessionId from stored credential (diegosouzapw#3007) (diegosouzapw#3162)

The executor read credentials.cookies/convexSessionId, but the pipeline
only stores the pasted string under apiKey → t3.chat always 400'd. Parse
both values from apiKey (fallback accessToken), mirroring validation.ts.

Co-authored-by: minhtran162 <minhtran162@users.noreply.github.com>

* fix(minimax): stop capping MiniMax-M3 / M2.7 max_tokens at 8192 (diegosouzapw#3141) (diegosouzapw#3163)

MiniMax-M3 had no MODEL_SPECS entry and capitalized MiniMax-M2.7 missed
its lowercase spec (case-sensitive lookup) → both fell to the 8192 default
cap. Add the M3 spec (512K output), alias the capitalized ids, and make
getModelSpec lookups case-insensitive.

Co-authored-by: totaltube <totaltube@users.noreply.github.com>

* fix(github-copilot): discover model catalog live from api.githubcopilot.com (diegosouzapw#3120, diegosouzapw#3121) (diegosouzapw#3164)

The github (Copilot) provider had a static hardcoded catalog with no
discovery source, so Import Models never refreshed (diegosouzapw#3120) and advertised
non-entitled models that 400 on use (diegosouzapw#3121). Add a live /models fetch with
fallback to the static list.

Co-authored-by: gabrielmoreira <gabrielmoreira@users.noreply.github.com>

* fix(combo): invalidate nested-combo cache on edits + log DATA_DIR (diegosouzapw#3147) (diegosouzapw#3165)

Editing a combo did not invalidate the 10s nested-combo expansion caches
(chat.ts getCombosCachedForChat + chatCore.ts getCombosCached; the exported
clearCombosCache was dead code), so a removed nested target/model could be
served as a phantom for up to 10s. Wire a shared monotonic combos-cache
version in readCache (bumped by invalidateDbCache("combos") on every combo
write); both cache layers treat a version mismatch as a miss.

Also log the resolved DATA_DIR/SQLITE_FILE absolute path at DB init so the
reporter's 'persists across restart + volume wipe' symptom (a multi-replica
Docker volume/DATA_DIR mismatch, not a routing bug) is diagnosable from logs.

Includes consolidated CHANGELOG entries for diegosouzapw#3133/diegosouzapw#3136/diegosouzapw#3007/diegosouzapw#3141/diegosouzapw#3120/diegosouzapw#3121.

Co-authored-by: ViFigueiredo <ViFigueiredo@users.noreply.github.com>

* fix(web-tools): parse bare JSON tool calls (diegosouzapw#3157)

Parse bare JSON tool calls for deepseek-web (diegosouzapw#2820) + fuzzy tool-name matching. Integrated into release/v3.8.10.

* fix(misc): minor fixes across reasoning cache, account fallback, binary manager (diegosouzapw#3177)

Misc: ProviderProfile export, DeepSeek reasoning regex, binary guard. Integrated into release/v3.8.10.

* fix(kiro): minor OAuth social exchange tweaks (diegosouzapw#3176)

Kiro social OAuth: optional targetProvider passthrough. Integrated into release/v3.8.10.

* deps: bump hono from 4.12.18 to 4.12.23 (diegosouzapw#3179)

Bump hono to 4.12.23. Integrated into release/v3.8.10.

* fix(providerRegistry): update kilocode format and executor (diegosouzapw#3166)

kilocode: openai format + default executor (matches kilo-gateway) + registry test. Integrated into release/v3.8.10.

* feat(metrics): cross-request TTFT and gap latency after tool calls (diegosouzapw#3173)

Cross-request TTFT + gap-after-tool latency metrics (+test). Integrated into release/v3.8.10.

* feat(dashboard): provider stats API endpoint and dashboard page (diegosouzapw#3175)

Provider stats dashboard + API (SQL moved to db module per Hard Rule diegosouzapw#5, +test). Integrated into release/v3.8.10.

* fix(usage): sequential+spaced OAuth quota sync, reactive force-refresh, actionable 401 (diegosouzapw#3156)

Sequential+spaced OAuth quota sync, reactive force-refresh on 401, actionable 401 in UI. Integrated into release/v3.8.10.

* fix(healthcheck): per-provider proactive-refresh skip list (rescue short-TTL OAuth) (diegosouzapw#3159)

Per-provider proactive-refresh skip list (OMNIROUTE_HEALTHCHECK_SKIP_PROVIDERS) to rescue short-TTL OAuth. Integrated into release/v3.8.10.

* feat(quota): show OAuth token expiry on provider cards (small, blue, informative) (diegosouzapw#3178)

Show OAuth token expiry on provider cards (small, blue, informative). Integrated into release/v3.8.10.

* fix(providers): empty refresh must not resurface just-cleared synced models (diegosouzapw#3181)

Empty refresh must not resurface just-cleared synced models (fixes the release-blocking provider-models-route test). Integrated into release/v3.8.10.

* chore(release): v3.8.10 — 2026-06-04 (finalize CHANGELOG)

---------

Co-authored-by: Wilson <pedbookmed@gmail.com>
Co-authored-by: Xiangzhe <32761048+xz-dev@users.noreply.github.com>
Co-authored-by: Jan Leon <Jan.gaschler@gmail.com>
Co-authored-by: M.M <mr.maatoug@gmail.com>
Co-authored-by: Hernan Javier Ardila Sanchez <hjasgr@gmail.com>
Co-authored-by: Markus Hartung <mail@hartmark.se>
Co-authored-by: KooshaPari <KooshaPari@users.noreply.github.com>
Co-authored-by: tjengbudi <tjengbudi@users.noreply.github.com>
Co-authored-by: minhtran162 <minhtran162@users.noreply.github.com>
Co-authored-by: totaltube <totaltube@users.noreply.github.com>
Co-authored-by: gabrielmoreira <gabrielmoreira@users.noreply.github.com>
Co-authored-by: ViFigueiredo <ViFigueiredo@users.noreply.github.com>
Co-authored-by: PizzaV <103120356+pizzav-xyz@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Nicolas Lorin <androw95220@gmail.com>
Poid-ZA pushed a commit to Poid-ZA/OmniRoute that referenced this pull request Aug 5, 2026
* chore(release): open v3.8.10 development cycle

Bump 3.8.9 → 3.8.10 across package.json, lockfile, electron, open-sse, and
docs/reference/openapi.yaml; add the [3.8.10] CHANGELOG section (root + 41 i18n
mirrors) as the integration target for the cycle. Entries land here as work
merges into release/v3.8.10; finalized by the release flow.

* fix(providers): resolve web provider alias collisions

Assign unique aliases to HuggingChat, Kimi Web, and Qwen Web so they no longer shadow primary providers or trigger startup warnings.

Add a unit test to enforce provider alias uniqueness and prevent future collisions. Also expand local ignore and VS Code exclude rules for agent, build, and worktree artifacts.

* fix(responses): normalize image_url parts across input paths (diegosouzapw#3150)

Normalize image_url parts across all Responses input paths. Integrated into release/v3.8.10.

* fix(api-manager): preserve API key expiration local time (diegosouzapw#3146)

Preserve API key expiration local time + clear button. Integrated into release/v3.8.10.

* Strip previous_response_id for stateless Responses upstreams (diegosouzapw#3143)

Strip previous_response_id for stateless Responses upstreams (auto/strip/preserve). Integrated into release/v3.8.10.

* fix(opencode-plugin): map thinking cap to interleaved in model+combo (diegosouzapw#3138)

Map caps.thinking to ModelV2.capabilities.interleaved for opencode-plugin. Integrated into release/v3.8.10.

* fix(providers): use synced models as fallback for all providers (diegosouzapw#3148)

Use synced models as authoritative local catalog for all providers (+regression test). Integrated into release/v3.8.10.

* fix(qoder): bifurcate validation by token type — PAT→Cosy, regular API key→dashscope (diegosouzapw#3149)

Bifurcate Qoder validation by token type (PAT→Cosy, regular→dashscope) +regression test. Integrated into release/v3.8.10.

* fix(antigravity): dynamic model resolution via MITM alias table (diegosouzapw#3144)

Dynamic antigravity MITM model resolution in the executor (+bug fix +regression test; DB import dropped from client-reachable config). Integrated into release/v3.8.10.

* Feature/batch allow big (diegosouzapw#3128)

Podman deployment options + larger upload body-size limits (+CONTAINER_HOST docs). Integrated into release/v3.8.10.

* fix(fireworks): preserve fully-qualified router/model IDs (diegosouzapw#3133) (diegosouzapw#3160)

Fireworks router IDs (accounts/fireworks/routers/...) were double-prefixed
with accounts/fireworks/models/ → upstream 404. Add optional
acceptedModelIdPrefixes to the registry entry and skip the prepend when the
model already starts with an accepted prefix.

Co-authored-by: KooshaPari <KooshaPari@users.noreply.github.com>

* fix(llama-cpp): route to configured local baseUrl instead of OpenAI (diegosouzapw#3136) (diegosouzapw#3161)

llama-cpp was missing from the local-provider group in buildUrl(), so it
fell through to the OpenAI baseUrl and returned an OpenAI 401. Add the
case to resolve the connection's providerSpecificData.baseUrl.

Co-authored-by: tjengbudi <tjengbudi@users.noreply.github.com>

* fix(t3-chat-web): parse cookies + convexSessionId from stored credential (diegosouzapw#3007) (diegosouzapw#3162)

The executor read credentials.cookies/convexSessionId, but the pipeline
only stores the pasted string under apiKey → t3.chat always 400'd. Parse
both values from apiKey (fallback accessToken), mirroring validation.ts.

Co-authored-by: minhtran162 <minhtran162@users.noreply.github.com>

* fix(minimax): stop capping MiniMax-M3 / M2.7 max_tokens at 8192 (diegosouzapw#3141) (diegosouzapw#3163)

MiniMax-M3 had no MODEL_SPECS entry and capitalized MiniMax-M2.7 missed
its lowercase spec (case-sensitive lookup) → both fell to the 8192 default
cap. Add the M3 spec (512K output), alias the capitalized ids, and make
getModelSpec lookups case-insensitive.

Co-authored-by: totaltube <totaltube@users.noreply.github.com>

* fix(github-copilot): discover model catalog live from api.githubcopilot.com (diegosouzapw#3120, diegosouzapw#3121) (diegosouzapw#3164)

The github (Copilot) provider had a static hardcoded catalog with no
discovery source, so Import Models never refreshed (diegosouzapw#3120) and advertised
non-entitled models that 400 on use (diegosouzapw#3121). Add a live /models fetch with
fallback to the static list.

Co-authored-by: gabrielmoreira <gabrielmoreira@users.noreply.github.com>

* fix(combo): invalidate nested-combo cache on edits + log DATA_DIR (diegosouzapw#3147) (diegosouzapw#3165)

Editing a combo did not invalidate the 10s nested-combo expansion caches
(chat.ts getCombosCachedForChat + chatCore.ts getCombosCached; the exported
clearCombosCache was dead code), so a removed nested target/model could be
served as a phantom for up to 10s. Wire a shared monotonic combos-cache
version in readCache (bumped by invalidateDbCache("combos") on every combo
write); both cache layers treat a version mismatch as a miss.

Also log the resolved DATA_DIR/SQLITE_FILE absolute path at DB init so the
reporter's 'persists across restart + volume wipe' symptom (a multi-replica
Docker volume/DATA_DIR mismatch, not a routing bug) is diagnosable from logs.

Includes consolidated CHANGELOG entries for diegosouzapw#3133/diegosouzapw#3136/diegosouzapw#3007/diegosouzapw#3141/diegosouzapw#3120/diegosouzapw#3121.

Co-authored-by: ViFigueiredo <ViFigueiredo@users.noreply.github.com>

* fix(web-tools): parse bare JSON tool calls (diegosouzapw#3157)

Parse bare JSON tool calls for deepseek-web (diegosouzapw#2820) + fuzzy tool-name matching. Integrated into release/v3.8.10.

* fix(misc): minor fixes across reasoning cache, account fallback, binary manager (diegosouzapw#3177)

Misc: ProviderProfile export, DeepSeek reasoning regex, binary guard. Integrated into release/v3.8.10.

* fix(kiro): minor OAuth social exchange tweaks (diegosouzapw#3176)

Kiro social OAuth: optional targetProvider passthrough. Integrated into release/v3.8.10.

* deps: bump hono from 4.12.18 to 4.12.23 (diegosouzapw#3179)

Bump hono to 4.12.23. Integrated into release/v3.8.10.

* fix(providerRegistry): update kilocode format and executor (diegosouzapw#3166)

kilocode: openai format + default executor (matches kilo-gateway) + registry test. Integrated into release/v3.8.10.

* feat(metrics): cross-request TTFT and gap latency after tool calls (diegosouzapw#3173)

Cross-request TTFT + gap-after-tool latency metrics (+test). Integrated into release/v3.8.10.

* feat(dashboard): provider stats API endpoint and dashboard page (diegosouzapw#3175)

Provider stats dashboard + API (SQL moved to db module per Hard Rule diegosouzapw#5, +test). Integrated into release/v3.8.10.

* fix(usage): sequential+spaced OAuth quota sync, reactive force-refresh, actionable 401 (diegosouzapw#3156)

Sequential+spaced OAuth quota sync, reactive force-refresh on 401, actionable 401 in UI. Integrated into release/v3.8.10.

* fix(healthcheck): per-provider proactive-refresh skip list (rescue short-TTL OAuth) (diegosouzapw#3159)

Per-provider proactive-refresh skip list (OMNIROUTE_HEALTHCHECK_SKIP_PROVIDERS) to rescue short-TTL OAuth. Integrated into release/v3.8.10.

* feat(quota): show OAuth token expiry on provider cards (small, blue, informative) (diegosouzapw#3178)

Show OAuth token expiry on provider cards (small, blue, informative). Integrated into release/v3.8.10.

* fix(providers): empty refresh must not resurface just-cleared synced models (diegosouzapw#3181)

Empty refresh must not resurface just-cleared synced models (fixes the release-blocking provider-models-route test). Integrated into release/v3.8.10.

* chore(release): v3.8.10 — 2026-06-04 (finalize CHANGELOG)

---------

Co-authored-by: Wilson <pedbookmed@gmail.com>
Co-authored-by: Xiangzhe <32761048+xz-dev@users.noreply.github.com>
Co-authored-by: Jan Leon <Jan.gaschler@gmail.com>
Co-authored-by: M.M <mr.maatoug@gmail.com>
Co-authored-by: Hernan Javier Ardila Sanchez <hjasgr@gmail.com>
Co-authored-by: Markus Hartung <mail@hartmark.se>
Co-authored-by: KooshaPari <KooshaPari@users.noreply.github.com>
Co-authored-by: tjengbudi <tjengbudi@users.noreply.github.com>
Co-authored-by: minhtran162 <minhtran162@users.noreply.github.com>
Co-authored-by: totaltube <totaltube@users.noreply.github.com>
Co-authored-by: gabrielmoreira <gabrielmoreira@users.noreply.github.com>
Co-authored-by: ViFigueiredo <ViFigueiredo@users.noreply.github.com>
Co-authored-by: PizzaV <103120356+pizzav-xyz@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Nicolas Lorin <androw95220@gmail.com>
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
* chore(release): open v3.8.10 development cycle

Bump 3.8.9 → 3.8.10 across package.json, lockfile, electron, open-sse, and
docs/reference/openapi.yaml; add the [3.8.10] CHANGELOG section (root + 41 i18n
mirrors) as the integration target for the cycle. Entries land here as work
merges into release/v3.8.10; finalized by the release flow.

* fix(providers): resolve web provider alias collisions

Assign unique aliases to HuggingChat, Kimi Web, and Qwen Web so they no longer shadow primary providers or trigger startup warnings.

Add a unit test to enforce provider alias uniqueness and prevent future collisions. Also expand local ignore and VS Code exclude rules for agent, build, and worktree artifacts.

* fix(responses): normalize image_url parts across input paths (diegosouzapw#3150)

Normalize image_url parts across all Responses input paths. Integrated into release/v3.8.10.

* fix(api-manager): preserve API key expiration local time (diegosouzapw#3146)

Preserve API key expiration local time + clear button. Integrated into release/v3.8.10.

* Strip previous_response_id for stateless Responses upstreams (diegosouzapw#3143)

Strip previous_response_id for stateless Responses upstreams (auto/strip/preserve). Integrated into release/v3.8.10.

* fix(opencode-plugin): map thinking cap to interleaved in model+combo (diegosouzapw#3138)

Map caps.thinking to ModelV2.capabilities.interleaved for opencode-plugin. Integrated into release/v3.8.10.

* fix(providers): use synced models as fallback for all providers (diegosouzapw#3148)

Use synced models as authoritative local catalog for all providers (+regression test). Integrated into release/v3.8.10.

* fix(qoder): bifurcate validation by token type — PAT→Cosy, regular API key→dashscope (diegosouzapw#3149)

Bifurcate Qoder validation by token type (PAT→Cosy, regular→dashscope) +regression test. Integrated into release/v3.8.10.

* fix(antigravity): dynamic model resolution via MITM alias table (diegosouzapw#3144)

Dynamic antigravity MITM model resolution in the executor (+bug fix +regression test; DB import dropped from client-reachable config). Integrated into release/v3.8.10.

* Feature/batch allow big (diegosouzapw#3128)

Podman deployment options + larger upload body-size limits (+CONTAINER_HOST docs). Integrated into release/v3.8.10.

* fix(fireworks): preserve fully-qualified router/model IDs (diegosouzapw#3133) (diegosouzapw#3160)

Fireworks router IDs (accounts/fireworks/routers/...) were double-prefixed
with accounts/fireworks/models/ → upstream 404. Add optional
acceptedModelIdPrefixes to the registry entry and skip the prepend when the
model already starts with an accepted prefix.

Co-authored-by: KooshaPari <KooshaPari@users.noreply.github.com>

* fix(llama-cpp): route to configured local baseUrl instead of OpenAI (diegosouzapw#3136) (diegosouzapw#3161)

llama-cpp was missing from the local-provider group in buildUrl(), so it
fell through to the OpenAI baseUrl and returned an OpenAI 401. Add the
case to resolve the connection's providerSpecificData.baseUrl.

Co-authored-by: tjengbudi <tjengbudi@users.noreply.github.com>

* fix(t3-chat-web): parse cookies + convexSessionId from stored credential (diegosouzapw#3007) (diegosouzapw#3162)

The executor read credentials.cookies/convexSessionId, but the pipeline
only stores the pasted string under apiKey → t3.chat always 400'd. Parse
both values from apiKey (fallback accessToken), mirroring validation.ts.

Co-authored-by: minhtran162 <minhtran162@users.noreply.github.com>

* fix(minimax): stop capping MiniMax-M3 / M2.7 max_tokens at 8192 (diegosouzapw#3141) (diegosouzapw#3163)

MiniMax-M3 had no MODEL_SPECS entry and capitalized MiniMax-M2.7 missed
its lowercase spec (case-sensitive lookup) → both fell to the 8192 default
cap. Add the M3 spec (512K output), alias the capitalized ids, and make
getModelSpec lookups case-insensitive.

Co-authored-by: totaltube <totaltube@users.noreply.github.com>

* fix(github-copilot): discover model catalog live from api.githubcopilot.com (diegosouzapw#3120, diegosouzapw#3121) (diegosouzapw#3164)

The github (Copilot) provider had a static hardcoded catalog with no
discovery source, so Import Models never refreshed (diegosouzapw#3120) and advertised
non-entitled models that 400 on use (diegosouzapw#3121). Add a live /models fetch with
fallback to the static list.

Co-authored-by: gabrielmoreira <gabrielmoreira@users.noreply.github.com>

* fix(combo): invalidate nested-combo cache on edits + log DATA_DIR (diegosouzapw#3147) (diegosouzapw#3165)

Editing a combo did not invalidate the 10s nested-combo expansion caches
(chat.ts getCombosCachedForChat + chatCore.ts getCombosCached; the exported
clearCombosCache was dead code), so a removed nested target/model could be
served as a phantom for up to 10s. Wire a shared monotonic combos-cache
version in readCache (bumped by invalidateDbCache("combos") on every combo
write); both cache layers treat a version mismatch as a miss.

Also log the resolved DATA_DIR/SQLITE_FILE absolute path at DB init so the
reporter's 'persists across restart + volume wipe' symptom (a multi-replica
Docker volume/DATA_DIR mismatch, not a routing bug) is diagnosable from logs.

Includes consolidated CHANGELOG entries for diegosouzapw#3133/diegosouzapw#3136/diegosouzapw#3007/diegosouzapw#3141/diegosouzapw#3120/diegosouzapw#3121.

Co-authored-by: ViFigueiredo <ViFigueiredo@users.noreply.github.com>

* fix(web-tools): parse bare JSON tool calls (diegosouzapw#3157)

Parse bare JSON tool calls for deepseek-web (diegosouzapw#2820) + fuzzy tool-name matching. Integrated into release/v3.8.10.

* fix(misc): minor fixes across reasoning cache, account fallback, binary manager (diegosouzapw#3177)

Misc: ProviderProfile export, DeepSeek reasoning regex, binary guard. Integrated into release/v3.8.10.

* fix(kiro): minor OAuth social exchange tweaks (diegosouzapw#3176)

Kiro social OAuth: optional targetProvider passthrough. Integrated into release/v3.8.10.

* deps: bump hono from 4.12.18 to 4.12.23 (diegosouzapw#3179)

Bump hono to 4.12.23. Integrated into release/v3.8.10.

* fix(providerRegistry): update kilocode format and executor (diegosouzapw#3166)

kilocode: openai format + default executor (matches kilo-gateway) + registry test. Integrated into release/v3.8.10.

* feat(metrics): cross-request TTFT and gap latency after tool calls (diegosouzapw#3173)

Cross-request TTFT + gap-after-tool latency metrics (+test). Integrated into release/v3.8.10.

* feat(dashboard): provider stats API endpoint and dashboard page (diegosouzapw#3175)

Provider stats dashboard + API (SQL moved to db module per Hard Rule diegosouzapw#5, +test). Integrated into release/v3.8.10.

* fix(usage): sequential+spaced OAuth quota sync, reactive force-refresh, actionable 401 (diegosouzapw#3156)

Sequential+spaced OAuth quota sync, reactive force-refresh on 401, actionable 401 in UI. Integrated into release/v3.8.10.

* fix(healthcheck): per-provider proactive-refresh skip list (rescue short-TTL OAuth) (diegosouzapw#3159)

Per-provider proactive-refresh skip list (OMNIROUTE_HEALTHCHECK_SKIP_PROVIDERS) to rescue short-TTL OAuth. Integrated into release/v3.8.10.

* feat(quota): show OAuth token expiry on provider cards (small, blue, informative) (diegosouzapw#3178)

Show OAuth token expiry on provider cards (small, blue, informative). Integrated into release/v3.8.10.

* fix(providers): empty refresh must not resurface just-cleared synced models (diegosouzapw#3181)

Empty refresh must not resurface just-cleared synced models (fixes the release-blocking provider-models-route test). Integrated into release/v3.8.10.

* chore(release): v3.8.10 — 2026-06-04 (finalize CHANGELOG)

---------

Co-authored-by: Wilson <pedbookmed@gmail.com>
Co-authored-by: Xiangzhe <32761048+xz-dev@users.noreply.github.com>
Co-authored-by: Jan Leon <Jan.gaschler@gmail.com>
Co-authored-by: M.M <mr.maatoug@gmail.com>
Co-authored-by: Hernan Javier Ardila Sanchez <hjasgr@gmail.com>
Co-authored-by: Markus Hartung <mail@hartmark.se>
Co-authored-by: KooshaPari <KooshaPari@users.noreply.github.com>
Co-authored-by: tjengbudi <tjengbudi@users.noreply.github.com>
Co-authored-by: minhtran162 <minhtran162@users.noreply.github.com>
Co-authored-by: totaltube <totaltube@users.noreply.github.com>
Co-authored-by: gabrielmoreira <gabrielmoreira@users.noreply.github.com>
Co-authored-by: ViFigueiredo <ViFigueiredo@users.noreply.github.com>
Co-authored-by: PizzaV <103120356+pizzav-xyz@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Nicolas Lorin <androw95220@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants