Feature request: add OmniRoute as a built-in OpenAI-compatible provider profile
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 19.9k
- Forks
- 2.3k
- Avg merge
- 2d 7h
- Merged PRs (30d)
- 30
Description
Proposal
Add OmniRoute as a built-in OpenAI-compatible provider profile, following the exact same data-driven pattern as the existing openrouter, deepseek, kimi, ollama and lmstudio profiles.
OmniRoute is a free, MIT-licensed, self-hosted AI gateway: one OpenAI-compatible endpoint routing to 290+ providers (90+ free) and 500+ models, with quota-aware auto-fallback, token compression (15–95% savings) and MCP/A2A support. It is already widely used as the local router behind coding agents (Claude Code, Codex, Cursor, OpenCode, Cline, Copilot) — jcode users get all of that through a single jcode login --provider omniroute.
The project is one of the fastest-growing open-source repositories in Brazil right now:
- ⭐ 36.6k stars, 4.7k forks, 300+ code contributors — from zero in Feb/2026 to this in ~6 months
- 🇧🇷 Top-2 among Brazilian software repositories on GitHub, and just reached top-2 monthly (trending)
- Actively maintained: v3.8.50, weekly releases, 48 CI quality gates
We will also feature jcode in the OmniRoute README — we are adding a new "Tools & repositories that work with OmniRoute" section and jcode will be listed there with a link, exposing jcode to OmniRoute's user base.
Reference implementation
A complete, validated implementation is available in our fork:
PR: https://github.com/diegosouzapw/jcode/pull/1
Branch: diegosouzapw:feat/omniroute-provider (commit ee4f904e6)
The diff is small and focused: 6 files, +56/−3, no new crate, no runtime changes.
Changes
crates/jcode-provider-metadata/src/catalog.rs:OMNIROUTE_PROFILE(idomniroute, api basehttp://localhost:20128/v1,api_key_envOMNIROUTE_API_KEY,requires_api_key: true), added toOPENAI_COMPAT_PROFILES, plusOMNIROUTE_LOGIN_PROVIDERdescriptor.src/cli/provider_init.rs:ProviderChoice::OmniRoute(aliasesomniroute/omni/omniroute-ai),as_arg_value()→"omniroute", login-table entry.src/cli/commands/report_info.rs: provider-list wiring for the new choice.README.md:omnirouteadded to the built-in profile id list.- Tests: alias parse (
args/tests.rs), catalog round-trip (provider_init_tests.rs), and env hygiene — the auto no-credentials fixture now clearsOMNIROUTE_API_KEYso an ambient key can't leak into the "no credentials" invariant.
Validation
cargo check --workspace: clean, 0 errors.jcodelib suite: 205 passed / 1 failed — the single failure (configured_auth_test_targets_only_include_configured_supported_providers) is pre-existing on the base branch (environmental: no provider API keys in the local shell), unrelated to this change.jcode-provider-metadata(14 tests) andjcode-baseauth-integration registry tests pass with the 49th login provider.
Notes for the maintainer
Per your CONTRIBUTING.md, feel free to treat this as a reference and rewrite it your way — the catalog entry itself is the essential part; everything else mechanically follows the existing profile pattern. Happy to adjust anything (id, aliases, default base, menu ordering) to your preference.
A git patch is attached below for convenience.
omniroute-provider.patch (click to expand)
From ee4f904e61a8342d9dc67c4cf3e20cdf1d10a9d0 Mon Sep 17 00:00:00 2001
From: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
Date: Sat, 1 Aug 2026 09:45:17 -0300
Subject: [PATCH] feat(provider): add OmniRoute OpenAI-compatible provider (id
omniroute)
Adds OmniRoute, a self-hosted unified AI proxy/router exposing 290+ LLM
providers behind a single OpenAI-compatible endpoint, as a first-class
OpenAI-compatible provider profile. It defaults to the local server base
URL (http://localhost:20128/v1) like Ollama/LM Studio; point it at a
remote deployment and set OMNIROUTE_API_KEY for production.
- OMNIROUTE_PROFILE in the metadata catalog (api_key_env OMNIROUTE_API_KEY)
- ProviderChoice::OmniRoute (aliases omniroute/omni/omniroute-ai) + login descriptor
- README profile-list entry
- Tests: alias parse, catalog round-trip; clear OMNIROUTE_API_KEY in the
auto no-credentials fixture so the new provider does not leak a key
from the ambient environment into the "no credentials" invariant.
---
README.md | 2 +-
crates/jcode-provider-metadata/src/catalog.rs | 36 +++++++++++++++++--
src/cli/args/tests.rs | 3 ++
src/cli/commands/report_info.rs | 1 +
src/cli/provider_init.rs | 11 ++++++
src/cli/provider_init_tests.rs | 6 ++++
6 files changed, 56 insertions(+), 3 deletions(-)
diff --git a/README.md b/README.md
index 33505db8d..7f9303815 100644
--- a/README.md
+++ b/README.md
@@ -365,7 +365,7 @@ There are two ways to set one up:
jcode login --provider moonshotai
- Built-in OpenAI-compatible profile ids include:
openrouter,deepseek,zai,kimi,moonshotai,opencode(OpenCode Zen),opencode-go,302ai,baseten,cortecs,huggingface,nebius,scaleway,stackit, andfirmware. Each profile only sets the endpoint and key variable; you still pick the model with/model(or--model). Runjcode loginwith no provider to see the interactive list.
- Built-in OpenAI-compatible profile ids include:
openrouter,deepseek,zai,kimi,moonshotai,opencode(OpenCode Zen),opencode-go,302ai,baseten,cortecs,huggingface,nebius,scaleway,stackit,firmware, andomniroute. Each profile only sets the endpoint and key variable; you still pick the model with/model(or--model). Runjcode loginwith no provider to see the interactive list.
- Any other endpoint — point jcode at an arbitrary OpenAI-compatible API (hosted or local) with
jcode login --provider openai-compatibleor the scriptablejcode provider addcommand described below.
diff --git a/crates/jcode-provider-metadata/src/catalog.rs b/crates/jcode-provider-metadata/src/catalog.rs
index cc30d1a2c..5d2c40b2c 100644
--- a/crates/jcode-provider-metadata/src/catalog.rs
+++ b/crates/jcode-provider-metadata/src/catalog.rs
@@ -421,6 +421,23 @@ pub const CELERIS_PROFILE: OpenAiCompatibleProfile = OpenAiCompatibleProfile {
requires_api_key: true,
};
+// OmniRoute: a self-hosted unified AI proxy/router exposing 290+ LLM providers
+// behind a single OpenAI-compatible endpoint, with auto-fallback and combo
+// routing. It defaults to the local server's base URL (like Ollama/LM Studio);
+// point it at a remote deployment and set OMNIROUTE_API_KEY for production.
+// Like the other aggregator profiles (OpenRouter), there is no single default
+// model — routing/model is chosen at runtime, so the user picks with /model.
+pub const OMNIROUTE_PROFILE: OpenAiCompatibleProfile = OpenAiCompatibleProfile {
- id: "omniroute",
- display_name: "OmniRoute",
- api_base: "http://localhost:20128/v1",
- api_key_env: "OMNIROUTE_API_KEY",
- env_file: "omniroute.env",
- setup_url: "https://github.com/diegosouzapw/OmniRoute",
- default_model: None,
- requires_api_key: true,
+};
pub const OPENAI_COMPAT_PROFILE: OpenAiCompatibleProfile = OpenAiCompatibleProfile {
id: "openai-compatible",
display_name: "OpenAI-compatible",
@@ -432,7 +449,7 @@ pub const OPENAI_COMPAT_PROFILE: OpenAiCompatibleProfile = OpenAiCompatibleProfi
requires_api_key: true,
};
-pub(crate) const OPENAI_COMPAT_PROFILES: [OpenAiCompatibleProfile; 37] = [
+pub(crate) const OPENAI_COMPAT_PROFILES: [OpenAiCompatibleProfile; 38] = [
OPENCODE_PROFILE,
OPENCODE_GO_PROFILE,
ZAI_PROFILE,
@@ -469,6 +486,7 @@ pub(crate) const OPENAI_COMPAT_PROFILES: [OpenAiCompatibleProfile; 37] = [
CELERIS_PROFILE,
LMSTUDIO_PROFILE,
OLLAMA_PROFILE,
- OMNIROUTE_PROFILE,
OPENAI_COMPAT_PROFILE,
];
@@ -990,6 +1008,19 @@ pub const OLLAMA_LOGIN_PROVIDER: LoginProviderDescriptor = LoginProviderDescript
order: LoginProviderSurfaceOrder::new(Some(35), Some(35), Some(35), Some(35), Some(35)),
};
+pub const OMNIROUTE_LOGIN_PROVIDER: LoginProviderDescriptor = LoginProviderDescriptor {
- id: "omniroute",
- display_name: "OmniRoute",
- auth_kind: LoginProviderAuthKind::ApiKey,
- auth_state_key: LoginProviderAuthStateKey::OpenRouterLike,
- auth_status_method: "API key",
- aliases: &["omni", "omniroute-ai"],
- menu_detail: "self-hosted OpenAI-compatible router (OmniRoute); localhost by default",
- recommended: false,
- target: LoginProviderTarget::OpenAiCompatible(OMNIROUTE_PROFILE),
- order: LoginProviderSurfaceOrder::new(Some(37), Some(37), Some(37), Some(37), Some(37)),
+};
pub const OPENAI_COMPAT_LOGIN_PROVIDER: LoginProviderDescriptor = LoginProviderDescriptor {
id: "openai-compatible",
display_name: "OpenAI-compatible",
@@ -1112,7 +1143,7 @@ pub const GOOGLE_LOGIN_PROVIDER: LoginProviderDescriptor = LoginProviderDescript
order: LoginProviderSurfaceOrder::new(Some(13), None, None, None, None),
};
-pub(crate) const LOGIN_PROVIDERS: [LoginProviderDescriptor; 48] = [
+pub(crate) const LOGIN_PROVIDERS: [LoginProviderDescriptor; 49] = [
AUTO_IMPORT_LOGIN_PROVIDER,
CLAUDE_LOGIN_PROVIDER,
ANTHROPIC_API_LOGIN_PROVIDER,
@@ -1154,6 +1185,7 @@ pub(crate) const LOGIN_PROVIDERS: [LoginProviderDescriptor; 48] = [
CELERIS_LOGIN_PROVIDER,
LMSTUDIO_LOGIN_PROVIDER,
OLLAMA_LOGIN_PROVIDER,
-
OMNIROUTE_LOGIN_PROVIDER,
OPENAI_COMPAT_LOGIN_PROVIDER,
CURSOR_LOGIN_PROVIDER,
COPILOT_LOGIN_PROVIDER,
diff --git a/src/cli/args/tests.rs b/src/cli/args/tests.rs
index 74c7714e4..67d90d60b 100644
--- a/src/cli/args/tests.rs
+++ b/src/cli/args/tests.rs
@@ -49,6 +49,9 @@ fn test_provider_choice_aliases_parse() {let args = Args::try_parse_from(["jcode", "--provider", "cgc", "run", "smoke"]).unwrap();
assert_eq!(args.provider, ProviderChoice::Comtegra); -
let args = Args::try_parse_from(["jcode", "--provider", "omniroute", "run", "smoke"]).unwrap();
-
assert_eq!(args.provider, ProviderChoice::OmniRoute);
}
#[test]
diff --git a/src/cli/commands/report_info.rs b/src/cli/commands/report_info.rs
index 2e9a77891..ee853829d 100644
--- a/src/cli/commands/report_info.rs
+++ b/src/cli/commands/report_info.rs
@@ -578,6 +578,7 @@ pub(super) fn list_cli_providers() -> Vec {
ProviderChoice::Chutes,
ProviderChoice::Cerebras,
ProviderChoice::AlibabaCodingPlan,
-
ProviderChoice::OmniRoute, ProviderChoice::OpenaiCompatible, ProviderChoice::Cursor, ProviderChoice::Copilot,
diff --git a/src/cli/provider_init.rs b/src/cli/provider_init.rs
index 9fa2db29a..7b71eebe0 100644
--- a/src/cli/provider_init.rs
+++ b/src/cli/provider_init.rs
@@ -109,6 +109,11 @@ pub enum ProviderChoice {
alias = "alibaba-coding"
)]
AlibabaCodingPlan,
- // Default clap name is
omni-route(kebab of the variant);omnirouteis - // the canonical provider id, so accept it as an alias alongside the short
- //
omniand the-aiqualifier. - #[value(alias = "omniroute", alias = "omni", alias = "omniroute-ai")]
- OmniRoute,
#[value(alias = "compat", alias = "custom")]
OpenaiCompatible,
Cursor,
@@ -171,6 +176,7 @@ impl ProviderChoice {
Self::Chutes => "chutes",
Self::Cerebras => "cerebras",
Self::AlibabaCodingPlan => "alibaba-coding-plan", -
Self::OmniRoute => "omniroute", Self::OpenaiCompatible => "openai-compatible", Self::Cursor => "cursor", Self::Copilot => "copilot",
@@ -349,6 +355,10 @@ const PROVIDER_CHOICE_LOGIN_PROVIDERS: &[(ProviderChoice, LoginProviderDescripto
ProviderChoice::AlibabaCodingPlan,
crate::provider_catalog::ALIBABA_CODING_PLAN_LOGIN_PROVIDER,
),
- (
-
ProviderChoice::OmniRoute, -
crate::provider_catalog::OMNIROUTE_LOGIN_PROVIDER, - ),
(
ProviderChoice::OpenaiCompatible,
crate::provider_catalog::OPENAI_COMPAT_LOGIN_PROVIDER,
@@ -1530,6 +1540,7 @@ async fn init_provider_with_options(
| ProviderChoice::Chutes
| ProviderChoice::Cerebras
| ProviderChoice::AlibabaCodingPlan -
| ProviderChoice::OmniRoute | ProviderChoice::GeminiApi | ProviderChoice::OpenaiCompatible => { disable_subscription_runtime_mode();
diff --git a/src/cli/provider_init_tests.rs b/src/cli/provider_init_tests.rs
index f9858ea53..f193dbccb 100644
--- a/src/cli/provider_init_tests.rs
+++ b/src/cli/provider_init_tests.rs
@@ -440,6 +440,10 @@ fn choice_for_login_provider_round_trips_openai_compatible_profiles() {
choice_for_login_provider(provider_catalog::OPENAI_COMPAT_LOGIN_PROVIDER),
Some(ProviderChoice::OpenaiCompatible)
);
- assert_eq!(
-
choice_for_login_provider(provider_catalog::OMNIROUTE_LOGIN_PROVIDER), -
Some(ProviderChoice::OmniRoute) - );
}
#[test]
@@ -825,6 +829,7 @@ async fn auto_provider_noninteractive_skips_untrusted_external_auth_instead_of_b
"ANTHROPIC_API_KEY",
"OPENAI_API_KEY",
"OPENROUTER_API_KEY",
-
"OMNIROUTE_API_KEY", "GITHUB_TOKEN", "GEMINI_API_KEY", "CURSOR_API_KEY",
@@ -843,6 +848,7 @@ async fn auto_provider_noninteractive_skips_untrusted_external_auth_instead_of_b
"ANTHROPIC_API_KEY",
"OPENAI_API_KEY",
"OPENROUTER_API_KEY",
-
"OMNIROUTE_API_KEY", "GITHUB_TOKEN", "GEMINI_API_KEY", "CURSOR_API_KEY",
--
2.43.0
</details>
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with crates/jcode-provider-metadata/src/catalog.rs and the existing openrouter, deepseek, kimi, ollama, and lmstudio profiles, then trace ProviderChoice in src/cli/provider_init.rs and provider listing in src/cli/commands/report_info.rs. Update the named README and test files following the existing pattern, then run the provider metadata, CLI argument, and provider initialization tests; done means the profile, aliases, login surfaces, and no-credentials fixture pass.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- backend-api-design, cli
- Issue type
- Feature
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100