fix(provider): OpenRouterProvider::name() should return profile_id for named OpenAI-compatible profiles
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 82/100
Research direction
Start with crates/jcode-provider-openrouter-runtime/src/openrouter_provider_impl.rs around the OpenRouterProvider::name() implementation, then inspect the named-provider coverage in openrouter_tests.rs. Confirm both vanilla OpenRouter and named OpenAI-compatible profiles report the expected identity, and run the relevant provider tests to verify the fallback and profile name.
Written by the indexing model from the issue text.
Description
Problem
OpenRouterProvider::name() hardcodes the return value to "openrouter" regardless of the profile. When a named OpenAI-compatible profile is configured (e.g., [providers.my-gateway] with type = "open-ai-compatible"), the provider is still identified as "openrouter" instead of using the actual profile ID.
This breaks several integration points for named profiles:
- Auth refresh identity — the auth lifecycle cannot distinguish between different OpenAI-compatible profiles because they all report the same name.
- Model catalog cache namespace — cached catalogs from different profiles collide under the same
"openrouter"key. - Provider identification in logs — all named profiles log as
provider=openrouterinstead of their actual profile name, making debugging multi-gateway setups difficult. - Profile-specific behavior gates — checks like
profile_id.as_deref() != Some("fpt")exist elsewhere in the same impl, confirming that profile-aware logic is expected;name()should follow the same pattern.
Affected code
File: crates/jcode-provider-openrouter-runtime/src/openrouter_provider_impl.rs
Line: ~324
Current (v0.64.2):
fn name(&self) -> &str {
"openrouter"
}
Proposed fix
The profile_id field already exists on the struct and is used extensively throughout the same implementation for profile-specific logic. Return it when available:
fn name(&self) -> &str {
self.profile_id.as_deref().unwrap_or("openrouter")
}
This preserves backward compatibility — when profile_id is None (vanilla OpenRouter), it still returns "openrouter". When a named profile is active, it returns the actual profile name.
Additional note
I noticed the upstream repo contains a companion test named_openai_compatible_provider_reports_profile_name (in openrouter_tests.rs as of a local hotfix on v0.32.0) that validates this exact behavior — but it was never merged upstream. That test should be included alongside this fix:
#[test]
fn named_openai_compatible_provider_reports_profile_name() {
let _lock = ENV_LOCK.lock();
let _key = EnvVarGuard::set("TEST_NAMED_COMPAT_KEY", "test-key");
let profile = crate::config::NamedProviderConfig {
base_url: "https://llm.example.com/v1".to_string(),
api_key_env: Some("TEST_NAMED_COMPAT_KEY".to_string()),
default_model: Some("example-model".to_string()),
..Default::default()
};
let provider = OpenRouterProvider::new_named_openai_compatible("example-compat", &profile)
.expect("named profile should initialize");
assert_eq!(provider.name(), "example-compat");
}
Impact
This is a one-line change with zero risk to vanilla OpenRouter users (profile_id is None → falls back to "openrouter"). It unblocks production use of multiple named OpenAI-compatible profiles behind different gateways (LiteLLM, local proxies, etc.) without identity collision.
Thank you for jcode — it has been an excellent harness for our autonomous agent pipeline (SAORI).
- Dominant language
- Rust
- Stars
- 19.9k
- Forks
- 2.3k
- Avg merge
- 2d 9h
- Merged PRs (30d)
- 29
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.
More from 1jehuang/jcode
-
Difficulty 1/5 Under an hour Newbie friendliness 92/100
-
OrcaRouter is in the login catalog but has no ProviderChoice, so it can't be selected explicitly Open
Difficulty 2/5 1-3 hours Newbie friendliness 90/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 92/100
-
Session::save() skips untouched sessions, so is_debug and canary never persist (4 failing tests) Open
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
-
area: providers autonomous: clear bug triage: reproducible
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
Eynzof/Hermes-CN-Desktop#610 ·
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
gitbutlerapp/gitbutler#15998 · 1 comment ·
-
bug triage:deciding
Difficulty 1/5 Under an hour Newbie friendliness 88/100
open-telemetry/otel-arrow#4132 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100