Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
84 commits
Select commit Hold shift + click to select a range
a4026e0
fix(executors): disable parallel tools for Codex Responses Lite (#7171)
fenix007 Jul 19, 2026
29259ed
feat(providers): add xAI OAuth PKCE provider (#7399)
fenix007 Jul 19, 2026
e22fb0f
fix(api): enforce image generation API key auth (#8306)
fenix007 Jul 28, 2026
83799b0
fix(affinity): evict the sticky session pin on a combo per-model time…
fenix007 Aug 16, 2026
07b60bb
fix(api): retry Codex image generation by account
Aug 20, 2026
deb497e
ci(fork): publish stable fork image to ghcr.io/fenix007/omniroute
Aug 20, 2026
68d393d
ci(fork): build platforms in separate jobs and merge the manifest
Aug 20, 2026
d32c9c6
docs(fork): document the stable-fork process and patch set
Aug 20, 2026
d104ebc
ci(fork): keep amd64 building when arm64 fails
Aug 20, 2026
cbcbdd1
fix(docker): pin base image to node 24.18.0 for better-sqlite3 12.x
Aug 20, 2026
a9a3b01
fix(codex): surface capacity errors embedded in 200-OK SSE streams (#…
diegosouzapw Jul 10, 2026
a0b4b87
fix(codex): non-stream chat 502 'Response body is already used' (sing…
diegosouzapw Jul 17, 2026
70cfe1c
fix(codex): #7536 check content-type before touching response.body in…
diegosouzapw Jul 17, 2026
63d682b
fix(sse): preserve parallel_tool_calls for GPT-5.6 delegation under C…
diegosouzapw Jul 21, 2026
35287b5
fix(sse): bound Codex SSE peek read with per-read timeout (#8020) (#8…
diegosouzapw Jul 22, 2026
651d86f
fix(images): refresh OAuth and rotate accounts on 401 (#9231)
Bl0ck154 Aug 6, 2026
e3def43
fix(settings,auth): default debugMode to false and skip account rotat…
HouMinXi Aug 18, 2026
e339a01
docs(fork): record the fork.2 tier-1 patch set
Aug 20, 2026
0a7e404
fix(combo): recover provider circuit breaker from HALF_OPEN on succes…
HouMinXi Aug 11, 2026
16470cc
fix(rate-limit): patch Bottleneck doExpire capacity leak (#9328)
HouMinXi Aug 11, 2026
e1ea352
fix(combo): network errors must not trip provider circuit breaker (#9…
HouMinXi Aug 11, 2026
e0f2ce4
fix(rate-limit): separate queue wait from execution timeout (#9164)
Zartharas Aug 11, 2026
2575eff
test(fork): align the ported breaker/queue tests with this base
Aug 20, 2026
b3d4ac2
fix(combo): clear LKGP pin when its target fails, not only set it on …
hartmark Aug 13, 2026
feb12f9
fix(combo): isolate session stickiness by combo (#10137)
hydraxman Aug 13, 2026
b04b854
fix(combo): make failoverBeforeRetry actually skip the same-model ret…
hartmark Aug 13, 2026
5275968
fix(account-fallback): classify 'insufficient credits' as credits-exh…
Chewji9875 Aug 16, 2026
cc58938
fix(sse): clear quota_exhausted cooldown when real window recovers (#…
SnCr90 Aug 18, 2026
de2b0cd
fix(resilience): retry Codex pre-output transport failures on the sam…
Prudhvivuda Aug 20, 2026
bb30e05
docs(fork): record the fork.3 tier-2/tier-3 patch set
Aug 20, 2026
6635d05
chore(quality): rebaseline file-size for the fork.3 ported fixes
Aug 20, 2026
f96a5c1
fix(sse): widen the keepalive commit window so failures keep their st…
Aug 20, 2026
098261b
fix(sse): make in-band error frames actionable for the client
Aug 20, 2026
5b83791
feat(compat): allow the JSON stream default to be set deployment-wide
Aug 20, 2026
cef89ff
docs(fork): document the fork.4 error-status knobs and patch set
Aug 20, 2026
916b7bc
chore(quality): rebaseline both complexity ratchets for the fork ports
Aug 20, 2026
792285c
fix(sse): emit Responses-shaped error frames on /v1/responses
Aug 21, 2026
25dd63b
fix(compat): let the deployment-wide stream default reach real keys
Aug 21, 2026
3090f53
docs(fork): record the fork.6 gap fixes found verifying fork.5
Aug 21, 2026
77184ac
fix(sse): detect the terminal marker in oversized client chunks
Aug 21, 2026
7bca05f
test(sse): split the terminal-marker suite out of stream-handler tests
Aug 22, 2026
7a0f711
fix(kiro): carry response_format into the Kiro prompt
Aug 22, 2026
3c7b612
fix(kiro): strip the JSON code fence when response_format asked for JSON
Aug 22, 2026
fe26399
fix(kiro): detect the JSON contract on the translated payload
Aug 22, 2026
16a56a8
fix(trae): preserve upstream error status
Aug 26, 2026
06cda56
fix(fork): backport OmniRoute 3.8.50 stability fixes
Aug 29, 2026
015b674
fix(codex): fail over invalidated oauth accounts immediately
Aug 30, 2026
c500242
fix(sse): prevented no-cache request coalescing
Aug 31, 2026
457b344
fix(codex): reported incomplete responses as length
Aug 31, 2026
9931770
fix(translation): classify invalid prompts as client errors
Sep 1, 2026
e954468
fix(responses): preserve later system turns as developer input
Sep 3, 2026
35359a0
fix(combo): abort timed-out provider attempts
Sep 3, 2026
67a9c3e
fix(opencode): route Go models by protocol
Sep 3, 2026
b7d6a11
security(trae): secured OAuth callback persistence
Sep 3, 2026
0c13729
fix(cache): hardened semantic response caching
Sep 3, 2026
49e5605
fix(api): harden upstream request validation
Sep 4, 2026
75727e2
fix(auth): require management access for OAuth routes
Sep 4, 2026
7f414e5
fix(quota): use official OpenCode Go usage API
Sep 4, 2026
21c7de4
feat(usage): expose Codex reset credit expiries
Sep 4, 2026
7ce2b2f
feat(ui): show fork version in admin sidebar
Sep 4, 2026
0105b6f
fix(usage): fence Codex reset credit redemption
Sep 4, 2026
f8bc414
feat(providers): add GPT-6 Astra to the Codex and OpenAI catalogs
Sep 4, 2026
290a8e7
fix(codex): make GPT-6 Astra usable and align it with upstream limits
Sep 5, 2026
b359d86
fix(vscode): split GPT-6 Astra extended effort aliases off the base m…
Sep 5, 2026
214e687
fix(security): close credential, network and cache isolation gaps
Sep 7, 2026
9a96284
refactor(core): split oversized modules and tests [skip ci]
Sep 8, 2026
e5ed4b1
fix(gemini): preserve cached usage in Claude streams [skip ci]
Sep 8, 2026
fc71f2d
fix(gemini): preserve keyword-named schema properties [skip ci]
Sep 9, 2026
7d05c4f
fix(routing): bound empty-response retries and preserve failure reasons
Sep 9, 2026
8ddd8ee
feat(images): add GPT Image 2.5 models
Sep 9, 2026
e8d831f
fix(ci): identify fork in branch image builds
Sep 9, 2026
7af6579
fix(updates): track published stable fork builds
Sep 9, 2026
b487429
feat(tts): add Inference.sh OmniVoice provider
Sep 9, 2026
5c226c1
perf(memory): bound background fact extraction
Sep 9, 2026
a39b546
fix(codex): re-derive plan tier on refresh and stop masking a free plan
Sep 10, 2026
d076d7b
fix(security): redact provider API key headers [skip ci]
Sep 11, 2026
f2e0449
fix(combo): preserve interrupted request reasons
Sep 11, 2026
397aedf
feat(audio): add SaluteSpeech transcription provider
Sep 11, 2026
8c0c324
feat(audio): add SaluteSpeech live transcription
Sep 11, 2026
5a1b218
fix(models): cache catalog responses longer
Sep 11, 2026
d4d86b1
fix(security): isolate live STT signing secret
Sep 11, 2026
5e03170
fix(routing): preserved empty-response fallback and enforced compatib…
Sep 14, 2026
4194ed9
fix(combo): keep estimated context limits advisory
Sep 14, 2026
e7e9d0e
fix(codex): hide backend account quota headers
Sep 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
41 changes: 28 additions & 13 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,12 @@ NEXT_PUBLIC_CLOUD_URL=
# Values: true/loopback (trust loopback proxy peers), private/lan (also trust LAN peers).
# OMNIROUTE_TRUST_PROXY=

# Client IP trust for login lockout/audit: additional exact proxy IPs or CIDRs.
# Loopback is trusted by default. Only list controlled proxies that overwrite XFF
# or append their immediate peer; block direct public access to the backend.
# Example for a dedicated Docker bridge: 172.19.0.0/16
# OMNIROUTE_TRUSTED_PROXY_IPS=

# Public callback URL for asynchronous image/audio jobs (kie.ai, etc.).
# Used by: open-sse/utils/kieTask.ts — overrides callbackUrlFromBaseUrl().
# Honor order: KIE_CALLBACK_URL → OMNIROUTE_KIE_CALLBACK_URL → OMNIROUTE_PUBLIC_URL.
Expand All @@ -504,19 +510,11 @@ NEXT_PUBLIC_CLOUD_URL=
# open-sse/services/usage.ts.
#OMNIROUTE_CROF_USAGE_URL=https://crof.ai/usage_api/
#OMNIROUTE_CODEWHISPERER_BASE_URL=https://codewhisperer.us-east-1.amazonaws.com
#OMNIROUTE_OPENCODE_QUOTA_URL=https://opencode.ai/zen/go/v1/quota
#OMNIROUTE_OPENCODE_GO_QUOTA_URL=https://api.z.ai/api/monitor/usage/quota/limit
#OMNIROUTE_OPENCODE_GO_DASHBOARD_URL=https://opencode.ai/workspace
# Official OpenCode Go usage endpoint, authenticated with the connection API key.
# Override only for relays or test fixtures.
#OMNIROUTE_OPENCODE_QUOTA_URL=https://opencode.ai/zen/go/v1/usage
#OMNIROUTE_OLLAMA_CLOUD_USAGE_URL=https://ollama.com/settings

# OpenCode Go dashboard quota scraping. Prefer configuring these per connection
# in Dashboard → Providers → OpenCode Go. Env vars are useful for headless
# deployments or shared server defaults. The cookie is sensitive.
#OPENCODE_GO_WORKSPACE_ID=wrk_...
#OMNIROUTE_OPENCODE_GO_WORKSPACE_ID=wrk_...
#OPENCODE_GO_AUTH_COOKIE=auth=...
#OMNIROUTE_OPENCODE_GO_AUTH_COOKIE=auth=...

# OpenCode Go/Zen VPS egress (#5997): on a datacenter VPS, Cloudflare in front of
# opencode.ai/zen/go 403s chat requests that lack OpenCode CLI identity headers.
# When your clients don't already send them, set this to synthesize the CLI headers
Expand Down Expand Up @@ -994,7 +992,7 @@ CLAUDE_USER_AGENT="claude-cli/2.1.207 (external, cli)"
# stream with a misleading 400 out-of-extra-usage placeholder. Set to true to
# forward the original names verbatim (debugging only).
# CLAUDE_DISABLE_TOOL_NAME_CLOAK=false
CODEX_USER_AGENT="codex-cli/0.144.1 (Windows 10.0.26200; x64)"
CODEX_USER_AGENT="codex-cli/0.153.4 (Windows 10.0.26200; x64)"
GITHUB_USER_AGENT="GitHubCopilotChat/0.54.0"
ANTIGRAVITY_USER_AGENT="antigravity/2.0.1 linux/arm64 google-api-nodejs-client/10.3.0"
KIRO_USER_AGENT="AWS-SDK-JS/3.0.0 kiro-ide/1.0.0"
Expand All @@ -1015,7 +1013,7 @@ CURSOR_USER_AGENT="Cursor/3.4"

# Override Codex client version sent in headers independently of the
# CODEX_USER_AGENT string. Used by: open-sse/config/codexClient.ts.
# CODEX_CLIENT_VERSION=0.144.1
# CODEX_CLIENT_VERSION=0.153.4

# Kill-switch to strip non-standard `codex.*` SSE events (e.g. codex.rate_limits)
# from the Codex Responses stream. These frames break the OpenAI SDK's
Expand Down Expand Up @@ -1173,6 +1171,19 @@ CURSOR_USER_AGENT="Cursor/3.4"
# STREAM_READINESS_TIMEOUT_MS=80000 # Time to receive the first non-ping SSE event
# STREAM_READINESS_MAX_TIMEOUT_MS=180000 # Cap for adaptive first-event extensions
# # (large/tool-heavy/high-reasoning requests).
# ── Early SSE keepalive / stream default (fork.4) ──
# How long a streaming route waits for the handler before committing a 200 SSE
# keepalive. Before the commit an upstream failure still reaches the client as a real
# HTTP status; after it, the status is pinned to 200 and the error can only be sent
# in-band. Must stay under Codex CLI reqwest's ~5s idle-read timeout: values >4500 or
# <0 fall back to the default. Set 2000 to restore the pre-fork.4 behavior.
# OMNIROUTE_KEEPALIVE_THRESHOLD_MS=4000
#
# Default stream resolution for clients that omit `stream` and send a wildcard Accept
# (python-httpx et al.). "legacy" streams them; "json" routes them through the
# non-streaming path, where upstream 502/429 statuses survive to the client.
# A per-key streamDefaultMode always overrides this.
# OMNIROUTE_STREAM_DEFAULT_MODE=legacy
# OMNIROUTE_AGENT_GOAL_POLICY_ENABLED=true # Kill-switch for the /goal heuristic below.
# # Set to false to fully disable detection —
# # readiness timeouts and stream recovery are
Expand Down Expand Up @@ -1293,6 +1304,10 @@ APP_LOG_TO_FILE=true
# not the cgroup limit, so leaving it to a RAM heuristic can oversize the heap and
# get the container OOM-killed. (#2939)
# OMNIROUTE_MEMORY_MB=512
# Maximum concurrent background fact-extraction jobs. Keep at 1 on small VPS instances.
# OMNIROUTE_MEMORY_EXTRACTION_CONCURRENCY=1
# Maximum queued background fact-extraction jobs. New jobs are dropped when this is full.
# OMNIROUTE_MEMORY_EXTRACTION_QUEUE_MAX=100

# Heap-pressure shed threshold (MB) — chatCore returns 503 when V8 heapUsed exceeds
# it, to avoid hard OOM under concurrent large-context load.
Expand Down
156 changes: 156 additions & 0 deletions .github/workflows/fork-image-fenix007.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
name: Fork Image (fenix007)

# Builds the stable-branch fork image (v3.8.48 + our patch set) and publishes it
# to GHCR. Tag scheme deliberately avoids the upstream "v*" pattern so the
# inherited release workflows (docker-publish, electron-release) never fire.
#
# Platforms build in separate jobs (like upstream docker-publish.yml): the
# Dockerfile's shared apt cache mounts deadlock when two platforms build
# concurrently in one buildx invocation.
on:
push:
branches: [stable]
tags:
- "*-fork.*"
workflow_dispatch:

permissions:
contents: read

env:
IMAGE_NAME: ghcr.io/fenix007/omniroute

jobs:
build:
name: Build ${{ matrix.arch }}
if: github.repository == 'fenix007/OmniRoute'
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
include:
- arch: amd64
platform: linux/amd64
runner: ubuntu-latest
- arch: arm64
platform: linux/arm64
runner: ubuntu-24.04-arm
permissions:
contents: read
packages: write
steps:
- name: Checkout
uses: actions/checkout@v7
with:
persist-credentials: false

- name: Resolve fork version label
id: fork-version
env:
REF_TYPE: ${{ github.ref_type }}
REF_NAME: ${{ github.ref_name }}
run: |
if [ "$REF_TYPE" = "tag" ]; then
printf 'version=%s\n' "$REF_NAME" >> "$GITHUB_OUTPUT"
else
printf 'version=fork · sha-%s\n' "${GITHUB_SHA:0:7}" >> "$GITHUB_OUTPUT"
fi

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4

- name: Login to GitHub Container Registry
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

# target mirrors upstream docker-publish.yml's main image (plain tag =
# runner-base; the -web variant is not built here).
- name: Build and push by digest
id: build
uses: docker/build-push-action@v7
with:
context: .
target: runner-base
platforms: ${{ matrix.platform }}
outputs: type=image,push-by-digest=true,name-canonical=true,push=true
tags: ${{ env.IMAGE_NAME }}
build-args: |
OMNIROUTE_FORK_VERSION=${{ steps.fork-version.outputs.version }}
cache-from: type=gha,scope=fork-${{ matrix.arch }}
cache-to: type=gha,scope=fork-${{ matrix.arch }},mode=max

- name: Export digest
env:
DIGEST: ${{ steps.build.outputs.digest }}
run: |
mkdir -p /tmp/digests
touch "/tmp/digests/${DIGEST#sha256:}"

- name: Upload digest
uses: actions/upload-artifact@v6
with:
name: digests-${{ matrix.arch }}
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1

merge:
name: Merge manifest and tag
if: github.repository == 'fenix007/OmniRoute'
needs: build
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Download digests
uses: actions/download-artifact@v7
with:
path: /tmp/digests
pattern: digests-*
merge-multiple: true

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4

- name: Login to GitHub Container Registry
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@v6
with:
images: ${{ env.IMAGE_NAME }}
tags: |
type=raw,value=stable,enable=${{ github.ref == 'refs/heads/stable' }}
type=sha,prefix=sha-
type=ref,event=tag
labels: |
org.opencontainers.image.title=omniroute
org.opencontainers.image.description=OmniRoute stable fork (v3.8.48 + fenix007 patch set)
org.opencontainers.image.url=https://github.com/fenix007/OmniRoute
org.opencontainers.image.source=https://github.com/fenix007/OmniRoute
org.opencontainers.image.licenses=MIT

- name: Create manifest list and push
working-directory: /tmp/digests
run: |
tags=()
while IFS= read -r tag; do
[ -n "$tag" ] && tags+=(-t "$tag")
done <<< "$DOCKER_METADATA_OUTPUT_TAGS"
refs=()
for d in *; do
refs+=("${IMAGE_NAME}@sha256:${d}")
done
docker buildx imagetools create "${tags[@]}" "${refs[@]}"

- name: Inspect image
run: docker buildx imagetools inspect "${IMAGE_NAME}:${{ steps.meta.outputs.version }}"
11 changes: 10 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# ── Common base with runtime deps ──────────────────────────────────────────
FROM node:24-trixie-slim AS base
# Pinned to the node version upstream built the working v3.8.48 images with
# (NODE_VERSION=24.18.0 in diegosouzapw/omniroute:3.8.48). Newer node:24 minors
# SIGABRT better-sqlite3 12.11.1 (this base's lockfile) inside the Next.js
# build worker on both amd64 and arm64.
FROM node:24.18.0-trixie-slim AS base
WORKDIR /app

# `apt-get upgrade` pulls the security-patched versions of the Debian (trixie)
Expand Down Expand Up @@ -98,6 +102,11 @@ ENV OMNIROUTE_MITM_STUB=1
ARG OMNIROUTE_BUILD_MEMORY_MB=4096
ENV NODE_OPTIONS="--max-old-space-size=${OMNIROUTE_BUILD_MEMORY_MB}"

# Tagged fork builds expose their release identifier in the client bundle so the
# admin sidebar can distinguish the frozen upstream base from the deployed patch set.
ARG OMNIROUTE_FORK_VERSION=""
ENV NEXT_PUBLIC_OMNIROUTE_FORK_VERSION=${OMNIROUTE_FORK_VERSION}

COPY . ./
RUN --mount=type=cache,id=next-cache,target=/app/.build/next/cache \
mkdir -p /app/data && npm run build
Expand Down
Loading