1jehuang / 1jehuang/jcode

fix(provider): OpenRouterProvider::name() should return profile_id for named OpenAI-compatible profiles

Open Beginner friendly
#691 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

autonomous: no priority: low question triage: needs-decision
Dominant language
Rust
Stars
19.9k
Forks
2.3k
Avg merge
2d 7h
Merged PRs (30d)
30

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:

  1. Auth refresh identity — the auth lifecycle cannot distinguish between different OpenAI-compatible profiles because they all report the same name.
  2. Model catalog cache namespace — cached catalogs from different profiles collide under the same "openrouter" key.
  3. Provider identification in logs — all named profiles log as provider=openrouter instead of their actual profile name, making debugging multi-gateway setups difficult.
  4. 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).

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

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.

Assessment

Tech stack
rust
Domain
api, backend
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
82/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.