Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
4920295
feat: add kie media provider support
wauputr4 Apr 23, 2026
550d15b
Update open-sse/handlers/videoGeneration.ts
wauputr4 Apr 23, 2026
18f2f04
Update open-sse/handlers/imageGeneration.ts
wauputr4 Apr 23, 2026
25e1be8
Update open-sse/handlers/imageGeneration.ts
wauputr4 Apr 23, 2026
bbfcd65
feat(providers): add KIE text models and expand video models catalog
wauputr4 Apr 23, 2026
ee55ab5
feat(ui): update media dashboard with new KIE video models
wauputr4 Apr 23, 2026
19bf035
refactor(providers): robust KIE handlers with dynamic polling and imp…
wauputr4 Apr 23, 2026
49a5a55
refactor(providers): address code review feedback for KIE provider
wauputr4 Apr 23, 2026
9089817
chore(providers): prune redundant provider icon assets (#1992)
backryun May 6, 2026
d7eb92b
feat(gemini-cli): add custom projectId support (UI, DB, executor) (#1…
nickwizard May 6, 2026
1985af8
docs: update CHANGELOG and bump version to 3.8.0
May 6, 2026
1064b85
fix(mitm): add Linux cert install and skip sudo password when root
NekoMonci12 May 6, 2026
22d5627
fix(cli): resolve .env loading failure for global npm installations
May 6, 2026
e7b5ced
fix: remove Anthropic-Beta header from non-Anthropic providers to fix…
May 6, 2026
dda5269
chore(release): bump to v3.8.0 — changelog, docs, version sync
May 6, 2026
8a9d0d3
fix(dashboard): resolve Unknown plan display in Provider Limits
May 6, 2026
0ab613e
fix(dashboard): revert GLM and Claude legacy plan fallbacks to Unknown
May 6, 2026
770aa1b
feat: add kie media provider support
wauputr4 May 6, 2026
f1cd774
fix: address kie provider review feedback
wauputr4 May 6, 2026
fb0361f
fix: preserve kie market model ids
wauputr4 May 6, 2026
a591b4f
merge main into kie media provider branch
wauputr4 May 6, 2026
667ce4d
fix: address kie provider pr review
wauputr4 May 6, 2026
c5dded8
fix(mitm): prevent stub from loading at runtime via bypass module
NekoMonci12 May 7, 2026
b4ba837
chore: Remove Deprecated Models (#2033)
backryun May 7, 2026
a7e00fb
docs(env): add GITLAB_DUO_OAUTH_CLIENT_ID to .env.example (#2031)
wucm667 May 7, 2026
8495514
fix(catalog): auto-calculate combo context_length from target model l…
herjarsa May 7, 2026
312f2f3
Update claude md and update glm-cn max context to 200k (#2027)
bypanghu May 7, 2026
a13d2f9
fix(chatgpt-web): plumb proxy through to native tls-client (#2022) (#…
xssdem May 7, 2026
d96f0c2
fix(codex): expose native model ids in catalog (#2012)
Tr0sT May 7, 2026
eb2579e
feat(sse): refresh Claude OAuth wire image to claude-cli/2.1.131 (#2011)
Tentoxa May 7, 2026
7214efa
fix: add fuzzy auto-combo routing for 'auto/*' model prefix (#2010)
oyi77 May 7, 2026
e9d96fa
Fix API key identity in usage analytics (#2008)
AveryanAlex May 7, 2026
40cc0d1
fix(docker): include OpenAPI spec in runtime image (#2007)
tatsster May 7, 2026
4cd7ee1
fix: allow Unicode letters in API key name validation (#1996)
rodrigogbbr-stack May 7, 2026
a430381
chore: apply review suggestions and missing layers
May 7, 2026
61fb2ac
chore: resolve merge conflicts in claude.ts
May 7, 2026
72d0e1f
chore: resolve merge conflicts in Dockerfile
May 7, 2026
7330947
fix: resolve model alias persistence double stringification preventin…
May 7, 2026
0e84457
fix: dynamically filter bare model auto-resolution by active provider…
May 7, 2026
57d3786
fix: add Google Gemini embeddings compatibility via OpenAI-compatible…
May 7, 2026
321f607
docs: update CHANGELOG.md for v3.8.0 (#2006, #2018, #2029)
May 7, 2026
f1af90e
feat(antigravity): overhaul identity, fingerprinting & envelope format
Gi99lin May 7, 2026
e775369
ci: update build-fork workflow to build from main branch
Gi99lin May 7, 2026
31da6a0
debug: add AG_REQUEST_HEADERS and AG_REQUEST_ENVELOPE debug logs
Gi99lin May 8, 2026
eeb836d
fix(antigravity): don't inject default maxOutputTokens when client om…
Gi99lin May 8, 2026
cababfe
fix(antigravity): align identity protocol and behavior with official AM
Gi99lin May 8, 2026
16febc0
fix(antigravity): add duplex half for streaming bodies
Gi99lin May 8, 2026
f09c2d6
refactor: address PR review feedback
Gi99lin May 8, 2026
9875b40
deps: bump hono from 4.12.14 to 4.12.18 (#2065)
dependabot[bot] May 8, 2026
afdebbc
fix(sse): use Gemini schema for Antigravity Claude (#2063)
ivan-mezentsev May 8, 2026
962faa8
feat(chat): dynamic tool limit detection with proactive truncation (#…
oyi77 May 8, 2026
fc84e5a
Fix bare GPT-5.5 routing for Codex-only installations (#2054)
guanbear May 8, 2026
80d52d9
fix(db): preserve legacy SQLite database path on Windows to prevent d…
May 7, 2026
ef23e70
docs: update changelog for issue 1973 resolution
May 7, 2026
4331e12
chore(release): v3.8.0 — optimize cache control preservation and alig…
May 8, 2026
ad966b1
fix(core): restore Claude Code adaptive thinking defaults and resolve…
May 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,13 @@ ANTIGRAVITY_OAUTH_CLIENT_SECRET=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
# ── GitHub Copilot ──
GITHUB_OAUTH_CLIENT_ID=Iv1.b507a08c87ecfe98

# ── GitLab Duo ──
# Register an OAuth app at: https://gitlab.com/-/profile/applications
# Set redirect URI to: http://localhost:20128/callback (or your NEXT_PUBLIC_BASE_URL + /callback)
# Required scopes: api, read_user, openid, profile, email
# GITLAB_DUO_OAUTH_CLIENT_ID=***
# GITLAB_DUO_OAUTH_CLIENT_SECRET=*** # optional — PKCE flow does not require a secret

# ── Qoder ──
QODER_OAUTH_CLIENT_SECRET=4Z3YjXycVsQvyGF1etiNlIBB4RsqSDtW

Expand Down
5 changes: 3 additions & 2 deletions .github/workflows/build-fork.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
name: Build Fork Image (ghcr.io)

on:
push:
branches: [main]
workflow_dispatch:

permissions:
Expand All @@ -15,7 +17,7 @@ jobs:
- name: Checkout
uses: actions/checkout@v6
with:
ref: fix/xiaomi-mimo-provider
ref: main

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
Expand All @@ -35,7 +37,6 @@ jobs:
platforms: linux/amd64
push: true
tags: |
ghcr.io/gi99lin/omniroute:fix-xiaomi-mimo-provider
ghcr.io/gi99lin/omniroute:latest
cache-from: type=gha
cache-to: type=gha,mode=max
88 changes: 88 additions & 0 deletions CHANGELOG.md

Large diffs are not rendered by default.

135 changes: 135 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,141 @@ API routes follow a consistent pattern: `Route → CORS preflight → Zod body v

---

## Resilience Runtime State

OmniRoute has three related but distinct temporary-failure mechanisms. Keep their
scope separate when debugging routing behavior.

### Provider Circuit Breaker

**Scope**: whole provider, e.g. `glm`, `openai`, `anthropic`.

**Purpose**: stop sending traffic to a provider that is repeatedly failing at the
upstream/service level, so one unhealthy provider does not slow down every request.

**Implementation**:

- Core class: `src/shared/utils/circuitBreaker.ts`
- Chat gate/execution wiring: `src/sse/handlers/chatHelpers.ts`, `src/sse/handlers/chat.ts`
- Runtime status API: `src/app/api/monitoring/health/route.ts`
- Shared wrappers: `open-sse/services/accountFallback.ts`
- Persisted state table: `domain_circuit_breakers`

**States**:

- `CLOSED`: normal traffic is allowed.
- `OPEN`: provider is temporarily blocked; callers get a provider-circuit-open response
or combo routing skips to another target.
- `HALF_OPEN`: reset timeout has elapsed; allow a probe request. Success closes the
breaker, failure opens it again.

**Defaults** (`open-sse/config/constants.ts`):

- OAuth providers: threshold `3`, reset timeout `60s`.
- API-key providers: threshold `5`, reset timeout `30s`.
- Local providers: threshold `2`, reset timeout `15s`.

Only provider-level failure statuses should trip the provider breaker:

```ts
(408, 500, 502, 503, 504);
```

Do not trip the whole-provider breaker for normal account/key/model errors like most
`401`, `403`, or `429` cases. Those usually belong to connection cooldown or model
lockout. A generic API-key provider `403` should be recoverable unless it is classified
as a terminal provider/account error.

The breaker uses lazy recovery, not a background timer. When `OPEN` expires, reads such
as `getStatus()`, `canExecute()`, and `getRetryAfterMs()` refresh the state to
`HALF_OPEN`, so dashboards and combo candidate builders do not keep excluding an
expired provider forever.

### Connection Cooldown

**Scope**: one provider connection/account/key.

**Purpose**: temporarily skip one bad key/account while allowing other connections for
the same provider to continue serving requests.

**Implementation**:

- Write/update path: `src/sse/services/auth.ts::markAccountUnavailable()`
- Account selection/filtering: `src/sse/services/auth.ts::getProviderCredentials...`
- Cooldown calculation: `open-sse/services/accountFallback.ts::checkFallbackError()`
- Settings: `src/lib/resilience/settings.ts`

Important fields on provider connections:

```ts
rateLimitedUntil;
testStatus: "unavailable";
lastError;
lastErrorType;
errorCode;
backoffLevel;
```

During account selection, a connection is skipped while:

```ts
new Date(rateLimitedUntil).getTime() > Date.now();
```

Cooldowns are also lazy: when `rateLimitedUntil` is in the past, the connection becomes
eligible again. On successful use, `clearAccountError()` clears `testStatus`,
`rateLimitedUntil`, error fields, and `backoffLevel`.

Default connection cooldown behavior:

- OAuth base cooldown: `5s`.
- API-key base cooldown: `3s`.
- API-key `429` should prefer upstream retry hints (`Retry-After`, reset headers, or
parseable reset text) when available.
- Repeated recoverable failures use exponential backoff:

```ts
baseCooldownMs * 2 ** failureIndex;
```

The anti-thundering-herd guard prevents concurrent failures on the same connection from
repeatedly extending the cooldown or double-incrementing `backoffLevel`.

Terminal states are not cooldowns. `banned`, `expired`, and `credits_exhausted` are
intended to stay unavailable until credentials/settings change or an operator resets
them. Do not overwrite terminal states with transient cooldown state.

### Model Lockout

**Scope**: provider + connection + model.

**Purpose**: avoid disabling a whole connection when only one model is unavailable or
quota-limited for that connection.

Examples:

- Per-model quota providers returning `429`.
- Local providers returning `404` for one missing model.
- Provider-specific mode/model permission failures such as selected Grok modes.

Model lockout lives in `open-sse/services/accountFallback.ts` and lets the same
connection continue serving other models.

### Debugging Guidance

- If all keys for a provider are skipped, inspect both provider breaker state and each
connection's `rateLimitedUntil`/`testStatus`.
- If a provider appears permanently excluded after the reset window, check whether code
is reading raw `state` instead of using `getStatus()`/`canExecute()`.
- If one provider key fails but others should work, prefer connection cooldown over
provider breaker.
- If only one model fails, prefer model lockout over connection cooldown.
- If a state should self-recover, it should have a future timestamp/reset timeout and a
read path that refreshes expired state. Permanent statuses require manual credential
or config changes.

---

## Key Conventions

### Code Style
Expand Down
5 changes: 5 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ COPY --from=builder /app/node_modules/split2 ./node_modules/split2
# traced by Next.js standalone output — copy them explicitly.
COPY --from=builder /app/src/lib/db/migrations ./migrations
ENV OMNIROUTE_MIGRATIONS_DIR=/app/migrations
# MITM server.cjs is spawned at runtime via child_process — not traced by nft
COPY --from=builder /app/src/mitm/server.cjs ./src/mitm/server.cjs
# OpenAPI spec is read from disk by /api/openapi/spec at runtime for the
# Endpoints dashboard. Next.js standalone tracing does not include it.
COPY --from=builder /app/docs/openapi.yaml ./docs/openapi.yaml

COPY --from=builder /app/scripts/run-standalone.mjs ./run-standalone.mjs
COPY --from=builder /app/scripts/runtime-env.mjs ./runtime-env.mjs
Expand Down
9 changes: 4 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,28 +136,28 @@ _Connect any AI-powered IDE or CLI tool through OmniRoute — free API gateway f
</td>
<td align="center" width="110">
<a href="https://github.com/openai/codex">
<img src="./public/providers/codex.png" alt="Codex CLI" width="48"/><br/>
<img src="./public/providers/codex.svg" alt="Codex CLI" width="48"/><br/>
<b>Codex CLI</b>
</a><br/>
<sub>⭐ 60.8K</sub>
</td>
<td align="center" width="110">
<a href="https://github.com/anthropics/claude-code">
<img src="./public/providers/claude.png" alt="Claude Code" width="48"/><br/>
<img src="./public/providers/claude.svg" alt="Claude Code" width="48"/><br/>
<b>Claude Code</b>
</a><br/>
<sub>⭐ 67.3K</sub>
</td>
<td align="center" width="110">
<a href="https://github.com/google-gemini/gemini-cli">
<img src="./public/providers/gemini-cli.png" alt="Gemini CLI" width="48"/><br/>
<img src="./public/providers/gemini-cli.svg" alt="Gemini CLI" width="48"/><br/>
<b>Gemini CLI</b>
</a><br/>
<sub>⭐ 94.7K</sub>
</td>
<td align="center" width="110">
<a href="https://github.com/Kilo-Org/kilocode">
<img src="./public/providers/kilocode.png" alt="Kilo Code" width="48"/><br/>
<img src="./public/providers/kilocode.svg" alt="Kilo Code" width="48"/><br/>
<b>Kilo Code</b>
</a><br/>
<sub>⭐ 15.5K</sub>
Expand Down Expand Up @@ -1519,4 +1519,3 @@ MIT License - see [LICENSE](LICENSE) for details.
<sub><a href="https://omniroute.online">omniroute.online</a></sub>
</div>
<!-- GitHub Discussions enabled for community Q&A -->

1 change: 1 addition & 0 deletions bin/omniroute.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ function loadEnvFile() {
}

envPaths.push(join(process.cwd(), ".env"));
envPaths.push(join(ROOT, ".env"));

for (const envPath of envPaths) {
try {
Expand Down
8 changes: 4 additions & 4 deletions docs/i18n/ar/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,28 +130,28 @@ _Connect any AI-powered IDE or CLI tool through OmniRoute — free API gateway f
</td>
<td align="center" width="110">
<a href="https://github.com/openai/codex">
<img src="./public/providers/codex.png" alt="Codex CLI" width="48"/><br/>
<img src="./public/providers/codex.svg" alt="Codex CLI" width="48"/><br/>
<b>Codex CLI</b>
</a><br/>
<sub>⭐ 60.8K</sub>
</td>
<td align="center" width="110">
<a href="https://github.com/anthropics/claude-code">
<img src="./public/providers/claude.png" alt="Claude Code" width="48"/><br/>
<img src="./public/providers/claude.svg" alt="Claude Code" width="48"/><br/>
<b>Claude Code</b>
</a><br/>
<sub>⭐ 67.3K</sub>
</td>
<td align="center" width="110">
<a href="https://github.com/google-gemini/gemini-cli">
<img src="./public/providers/gemini-cli.png" alt="Gemini CLI" width="48"/><br/>
<img src="./public/providers/gemini-cli.svg" alt="Gemini CLI" width="48"/><br/>
<b>Gemini CLI</b>
</a><br/>
<sub>⭐ 94.7K</sub>
</td>
<td align="center" width="110">
<a href="https://github.com/Kilo-Org/kilocode">
<img src="./public/providers/kilocode.png" alt="Kilo Code" width="48"/><br/>
<img src="./public/providers/kilocode.svg" alt="Kilo Code" width="48"/><br/>
<b>Kilo Code</b>
</a><br/>
<sub>⭐ 15.5K</sub>
Expand Down
8 changes: 4 additions & 4 deletions docs/i18n/bg/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,28 +130,28 @@ _Connect any AI-powered IDE or CLI tool through OmniRoute — free API gateway f
</td>
<td align="center" width="110">
<a href="https://github.com/openai/codex">
<img src="./public/providers/codex.png" alt="Codex CLI" width="48"/><br/>
<img src="./public/providers/codex.svg" alt="Codex CLI" width="48"/><br/>
<b>Codex CLI</b>
</a><br/>
<sub>⭐ 60.8K</sub>
</td>
<td align="center" width="110">
<a href="https://github.com/anthropics/claude-code">
<img src="./public/providers/claude.png" alt="Claude Code" width="48"/><br/>
<img src="./public/providers/claude.svg" alt="Claude Code" width="48"/><br/>
<b>Claude Code</b>
</a><br/>
<sub>⭐ 67.3K</sub>
</td>
<td align="center" width="110">
<a href="https://github.com/google-gemini/gemini-cli">
<img src="./public/providers/gemini-cli.png" alt="Gemini CLI" width="48"/><br/>
<img src="./public/providers/gemini-cli.svg" alt="Gemini CLI" width="48"/><br/>
<b>Gemini CLI</b>
</a><br/>
<sub>⭐ 94.7K</sub>
</td>
<td align="center" width="110">
<a href="https://github.com/Kilo-Org/kilocode">
<img src="./public/providers/kilocode.png" alt="Kilo Code" width="48"/><br/>
<img src="./public/providers/kilocode.svg" alt="Kilo Code" width="48"/><br/>
<b>Kilo Code</b>
</a><br/>
<sub>⭐ 15.5K</sub>
Expand Down
8 changes: 4 additions & 4 deletions docs/i18n/bn/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,28 +130,28 @@ _Connect any AI-powered IDE or CLI tool through OmniRoute — free API gateway f
</td>
<td align="center" width="110">
<a href="https://github.com/openai/codex">
<img src="./public/providers/codex.png" alt="Codex CLI" width="48"/><br/>
<img src="./public/providers/codex.svg" alt="Codex CLI" width="48"/><br/>
<b>Codex CLI</b>
</a><br/>
<sub>⭐ 60.8K</sub>
</td>
<td align="center" width="110">
<a href="https://github.com/anthropics/claude-code">
<img src="./public/providers/claude.png" alt="Claude Code" width="48"/><br/>
<img src="./public/providers/claude.svg" alt="Claude Code" width="48"/><br/>
<b>Claude Code</b>
</a><br/>
<sub>⭐ 67.3K</sub>
</td>
<td align="center" width="110">
<a href="https://github.com/google-gemini/gemini-cli">
<img src="./public/providers/gemini-cli.png" alt="Gemini CLI" width="48"/><br/>
<img src="./public/providers/gemini-cli.svg" alt="Gemini CLI" width="48"/><br/>
<b>Gemini CLI</b>
</a><br/>
<sub>⭐ 94.7K</sub>
</td>
<td align="center" width="110">
<a href="https://github.com/Kilo-Org/kilocode">
<img src="./public/providers/kilocode.png" alt="Kilo Code" width="48"/><br/>
<img src="./public/providers/kilocode.svg" alt="Kilo Code" width="48"/><br/>
<b>Kilo Code</b>
</a><br/>
<sub>⭐ 15.5K</sub>
Expand Down
8 changes: 4 additions & 4 deletions docs/i18n/cs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,28 +130,28 @@ _Connect any AI-powered IDE or CLI tool through OmniRoute — free API gateway f
</td>
<td align="center" width="110">
<a href="https://github.com/openai/codex">
<img src="./public/providers/codex.png" alt="Codex CLI" width="48"/><br/>
<img src="./public/providers/codex.svg" alt="Codex CLI" width="48"/><br/>
<b>Codex CLI</b>
</a><br/>
<sub>⭐ 60.8K</sub>
</td>
<td align="center" width="110">
<a href="https://github.com/anthropics/claude-code">
<img src="./public/providers/claude.png" alt="Claude Code" width="48"/><br/>
<img src="./public/providers/claude.svg" alt="Claude Code" width="48"/><br/>
<b>Claude Code</b>
</a><br/>
<sub>⭐ 67.3K</sub>
</td>
<td align="center" width="110">
<a href="https://github.com/google-gemini/gemini-cli">
<img src="./public/providers/gemini-cli.png" alt="Gemini CLI" width="48"/><br/>
<img src="./public/providers/gemini-cli.svg" alt="Gemini CLI" width="48"/><br/>
<b>Gemini CLI</b>
</a><br/>
<sub>⭐ 94.7K</sub>
</td>
<td align="center" width="110">
<a href="https://github.com/Kilo-Org/kilocode">
<img src="./public/providers/kilocode.png" alt="Kilo Code" width="48"/><br/>
<img src="./public/providers/kilocode.svg" alt="Kilo Code" width="48"/><br/>
<b>Kilo Code</b>
</a><br/>
<sub>⭐ 15.5K</sub>
Expand Down
Loading
Loading