release: v2.8.5 — fix zombie SSE, context cache tag, KIRO MITM

Bug Fixes:
- #473: Reduce STREAM_IDLE_TIMEOUT_MS 300s→120s for faster zombie stream fallback
- #474: Fix injectModelTag() to handle first-turn (no assistant messages)
- #481: Change KIRO configType guide→mitm for dashboard MITM controls
- CI: Fix E2E test modal overlay interception

Closed External Issues:
- #468: Gemini CLI remote (superseded by #462 deprecation)
- #438: Claude write files (external CLI issue)
- #439: AppImage (documented libfuse2 workaround)
- #402: ARM64 DMG damaged (documented xattr -cr workaround)
- #460: Windows CLI PATH (documented fix)
This commit is contained in:
diegosouzapw
2026-03-19 20:29:14 -03:00
parent 92e29a6ad7
commit b62e6c5a69
7 changed files with 42 additions and 10 deletions

View File

@@ -4,6 +4,30 @@
---
## [2.8.5] — 2026-03-19
> Sprint: Fix zombie SSE streams, context cache first-turn, KIRO MITM, and triage 5 external issues.
### Bug Fixes
- **Zombie SSE Streams** (#473): Reduce `STREAM_IDLE_TIMEOUT_MS` from 300s → 120s for faster combo fallback when providers hang mid-stream. Configurable via env var.
- **Context Cache Tag** (#474): Fix `injectModelTag()` to handle first-turn requests (no assistant messages) — context cache protection now works from the very first response.
- **KIRO MITM** (#481): Change KIRO `configType` from `guide``mitm` so the dashboard renders MITM Start/Stop controls.
- **E2E Test** (CI): Fix `providers-bailian-coding-plan.spec.ts` — dismiss pre-existing modal overlay before clicking Add API Key button.
### Closed Issues
- #473 — Zombie SSE streams bypass combo fallback
- #474 — Context cache `<omniModel>` tag missing on first turn
- #481 — MITM for KIRO not activatable from dashboard
- #468 — Gemini CLI remote server (superseded by #462 deprecation)
- #438 — Claude unable to write files (external CLI issue)
- #439 — AppImage doesn't work (documented libfuse2 workaround)
- #402 — ARM64 DMG "damaged" (documented xattr -cr workaround)
- #460 — CLI not runnable on Windows (documented PATH fix)
---
## [2.8.4] — 2026-03-19
> Sprint: Gemini CLI deprecation, VM guide i18n fix, dependabot security fix, provider schema expansion.

View File

@@ -1,7 +1,7 @@
openapi: 3.1.0
info:
title: OmniRoute API
version: 2.8.4
version: 2.8.5
description: |
OmniRoute is a local-first AI API proxy router. It provides an OpenAI-compatible
endpoint that routes requests to multiple AI providers with load balancing,

View File

@@ -4,9 +4,9 @@ import { loadProviderCredentials } from "./credentialLoader.ts";
export const FETCH_TIMEOUT_MS = parseInt(process.env.FETCH_TIMEOUT_MS || "120000", 10);
// Idle timeout for SSE streams (ms). Closes stream if no data for this duration.
// Default: 300s to support extended-thinking models (claude-opus-4-6, o3, etc.)
// that may pause for >60s during deep reasoning phases. Override with STREAM_IDLE_TIMEOUT_MS env var.
export const STREAM_IDLE_TIMEOUT_MS = parseInt(process.env.STREAM_IDLE_TIMEOUT_MS || "300000", 10);
// Default: 120s balances deep-reasoning pauses with fast zombie stream detection (#473).
// Extended-thinking models rarely pause >90s between chunks. Override with STREAM_IDLE_TIMEOUT_MS env var.
export const STREAM_IDLE_TIMEOUT_MS = parseInt(process.env.STREAM_IDLE_TIMEOUT_MS || "120000", 10);
// Provider configurations
// OAuth credentials read from env vars with hardcoded fallbacks for backward compatibility.

View File

@@ -52,7 +52,15 @@ export function injectModelTag(messages: Message[], providerModel: string): Mess
// Find last assistant message with string content
const lastAssistantIdx = cleaned.map((m) => m.role).lastIndexOf("assistant");
if (lastAssistantIdx === -1) return cleaned;
// #474: If no assistant message exists yet (first turn), append a synthetic one
// so the tag is present when the client sends the next request with the response.
if (lastAssistantIdx === -1) {
return [
...cleaned,
{ role: "assistant", content: `\n<omniModel>${providerModel}</omniModel>` },
];
}
const msg = cleaned[lastAssistantIdx];
if (typeof msg.content !== "string") return cleaned;

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "omniroute",
"version": "2.8.4",
"version": "2.8.5",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "omniroute",
"version": "2.8.4",
"version": "2.8.5",
"hasInstallScript": true,
"license": "MIT",
"workspaces": [

View File

@@ -1,6 +1,6 @@
{
"name": "omniroute",
"version": "2.8.4",
"version": "2.8.5",
"description": "Smart AI Router with auto fallback — route to FREE & cheap models, zero downtime. Works with Cursor, Cline, Claude Desktop, Codex, and any OpenAI-compatible tool.",
"type": "module",
"bin": {

View File

@@ -193,8 +193,8 @@ export const CLI_TOOLS = {
image: "/providers/kiro.png",
icon: "psychology_alt",
color: "#FF6B35",
description: "Amazon Kiro — AI-powered IDE",
configType: "guide",
description: "Amazon Kiro — AI-powered IDE with MITM",
configType: "mitm",
guideSteps: [
{ step: 1, title: "Open Kiro Settings", desc: "Go to Settings → AI Provider" },
{ step: 2, title: "Base URL", value: "{{baseUrl}}", copyable: true },