From 76a3e1a806487aa5834ec70d66708bcffcfd3a3b Mon Sep 17 00:00:00 2001 From: KooshaPari <42529354+KooshaPari@users.noreply.github.com> Date: Mon, 29 Jun 2026 22:15:15 -0700 Subject: [PATCH] test relay routing fallback headers (#5526) Integrated into release/v3.8.42 (round 3). Relay fallback header extraction + tests (drift-shed: dependabot #5415 commit dropped). --- .../api/v1/relay/chat/completions/route.ts | 6 ++-- .../relay/chat/completions/routingBackend.ts | 15 +++++++-- .../unit/api/v1/relay-routing-backend.test.ts | 32 +++++++++++++++++++ 3 files changed, 49 insertions(+), 4 deletions(-) diff --git a/src/app/api/v1/relay/chat/completions/route.ts b/src/app/api/v1/relay/chat/completions/route.ts index 27154bc574..7e70863218 100644 --- a/src/app/api/v1/relay/chat/completions/route.ts +++ b/src/app/api/v1/relay/chat/completions/route.ts @@ -20,6 +20,7 @@ import { } from "./relaySecurity"; import { getBifrostRoutingConfig, + getRoutingFallbackHeader, resolveRelayRoutingBackend, shouldTryBifrost, type BifrostRoutingConfig, @@ -335,8 +336,9 @@ export async function POST(request: Request) { const newHeaders = new Headers(response.headers); newHeaders.set("X-Relay-Token", token.tokenPrefix + "..."); newHeaders.set("X-Routing-Backend", "ts"); - if (backend === "auto" && bifrostConfig?.enabled) { - newHeaders.set("X-Routing-Fallback", "bifrost"); + const routingFallback = getRoutingFallbackHeader(backend, bifrostConfig); + if (routingFallback) { + newHeaders.set("X-Routing-Fallback", routingFallback); } return new Response(response.body, { diff --git a/src/app/api/v1/relay/chat/completions/routingBackend.ts b/src/app/api/v1/relay/chat/completions/routingBackend.ts index 36d4a6eae0..8604065c04 100644 --- a/src/app/api/v1/relay/chat/completions/routingBackend.ts +++ b/src/app/api/v1/relay/chat/completions/routingBackend.ts @@ -10,7 +10,9 @@ export interface BifrostRoutingConfig { enabled: boolean; } -export function getBifrostRoutingConfig(env: NodeJS.ProcessEnv = process.env): BifrostRoutingConfig | null { +export function getBifrostRoutingConfig( + env: NodeJS.ProcessEnv = process.env +): BifrostRoutingConfig | null { const baseUrl = env.BIFROST_BASE_URL?.replace(/\/$/, ""); if (!baseUrl) return null; const timeoutMs = Number.parseInt(env.BIFROST_TIMEOUT_MS || "", 10); @@ -24,7 +26,9 @@ export function getBifrostRoutingConfig(env: NodeJS.ProcessEnv = process.env): B }; } -export function resolveRelayRoutingBackend(env: NodeJS.ProcessEnv = process.env): RelayRoutingBackend { +export function resolveRelayRoutingBackend( + env: NodeJS.ProcessEnv = process.env +): RelayRoutingBackend { const configured = env.OMNIROUTE_RELAY_BACKEND || env.RELAY_ROUTING_BACKEND; if (configured && VALID_BACKENDS.has(configured as RelayRoutingBackend)) { return configured as RelayRoutingBackend; @@ -39,3 +43,10 @@ export function shouldTryBifrost( ): config is BifrostRoutingConfig { return Boolean(config?.enabled && backend !== "ts"); } + +export function getRoutingFallbackHeader( + backend: RelayRoutingBackend, + config: BifrostRoutingConfig | null +): "bifrost" | undefined { + return backend === "auto" && config?.enabled ? "bifrost" : undefined; +} diff --git a/tests/unit/api/v1/relay-routing-backend.test.ts b/tests/unit/api/v1/relay-routing-backend.test.ts index 1545fbb4f9..c30af34b20 100644 --- a/tests/unit/api/v1/relay-routing-backend.test.ts +++ b/tests/unit/api/v1/relay-routing-backend.test.ts @@ -2,6 +2,7 @@ import { test } from "node:test"; import assert from "node:assert/strict"; import { getBifrostRoutingConfig, + getRoutingFallbackHeader, resolveRelayRoutingBackend, shouldTryBifrost, } from "../../../../src/app/api/v1/relay/chat/completions/routingBackend.ts"; @@ -66,3 +67,34 @@ test("relay routing backend falls back on invalid timeout values", () => { assert.equal(getBifrostRoutingConfig(env)?.timeoutMs, 30000); }); + +test("relay routing backend exposes TS fallback header only for enabled auto bifrost fallback", () => { + const config = getBifrostRoutingConfig({ + BIFROST_BASE_URL: "http://127.0.0.1:8080", + }); + + assert.equal(getRoutingFallbackHeader("auto", config), "bifrost"); + assert.equal(getRoutingFallbackHeader("ts", config), undefined); + assert.equal(getRoutingFallbackHeader("bifrost", config), undefined); + assert.equal( + getRoutingFallbackHeader( + "auto", + getBifrostRoutingConfig({ + BIFROST_BASE_URL: "http://127.0.0.1:8080", + BIFROST_ENABLED: "0", + }) + ), + undefined + ); + assert.equal(getRoutingFallbackHeader("auto", null), undefined); +}); + +test("relay routing backend keeps strict bifrost failures out of auto fallback accounting", () => { + const config = getBifrostRoutingConfig({ + BIFROST_BASE_URL: "http://127.0.0.1:8080", + }); + + assert.equal(shouldTryBifrost("bifrost", config), true); + assert.equal(getRoutingFallbackHeader("bifrost", config), undefined); + assert.equal(resolveRelayRoutingBackend({ OMNIROUTE_RELAY_BACKEND: "bifrost" }), "bifrost"); +});