1jehuang / 1jehuang/jcode

OpenAI-compatible profile models absent in /model with model_picker_providers set

Open
#542 2 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

autonomous: likely bug priority: medium
Dominant language
Rust
Stars
19.9k
Forks
2.3k
Avg merge
2d 7h
Merged PRs (30d)
30

Description

Summary

When using a custom named provider profile in config.toml (e.g., [providers.ninerouter]) with:

[provider]
default_provider = "ninerouter"
default_model = "gcli/grok-4.5"
model_picker_providers = ["ninerouter"]

The /model endpoint does not display the full static model list from [[providers.ninerouter.models]]. It only shows the currently selected model, expanded into reasoning-effort rows, all labeled:

  • PROVIDER: auto
  • METHOD: openrouter

Example (only current model visible):

PROVIDER  MODEL                    METHOD
auto      gcli/grok-4.5 (high)     openrouter
auto      gcli/grok-4.5 (low)      openrouter
auto      gcli/grok-4.5 (med)      openrouter
...

Expected:

All configured static models under ninerouter, e.g.:

  • cx/gpt-5.6-sol
  • cx/gpt-5.6-terra
  • cx/gpt-5.6-luna
  • gcli/grok-4.5

Environment

  • macOS (aarch64)
  • jcode remote/shared-server client (remote=true in picker logs)
  • Named profile type openai-compatible with model ids that contain /
  • Shell also has OPENROUTER_API_KEY set (common; makes the OpenRouter slot look “configured”)

Reproduction Steps

  1. Configure a named profile with static models that include / in the id:
[provider]
default_provider = "ninerouter"
default_model = "gcli/grok-4.5"
model_picker_providers = ["ninerouter"]

[providers.ninerouter]
type = "openai-compatible"
base_url = "https://example.gateway/v1"
auth = "bearer"
api_key_env = "NINE_ROUTER_API_KEY"
default_model = "gcli/grok-4.5"
model_catalog = false

[[providers.ninerouter.models]]
id = "cx/gpt-5.6-sol"
[[providers.ninerouter.models]]
id = "cx/gpt-5.6-terra"
[[providers.ninerouter.models]]
id = "cx/gpt-5.6-luna"
[[providers.ninerouter.models]]
id = "gcli/grok-4.5"
  1. Ensure credentials for the named profile resolve (env var or env_file under the app config dir).
  2. Optionally leave OPENROUTER_API_KEY set in the environment.
  3. Start jcode (remote/shared-server path).
  4. Open /model.

Actual Behavior

  • Picker allowlist keeps only the current model (or only routes that don’t match ninerouter).
  • Slash model ids are labeled provider=auto, api_method=openrouter.
  • Logs look like:
    EVENT event=model_picker_open by_provider=auto:6 current_model=gcli/grok-4.5 current_provider=ninerouter routes_in=1
  • Related earlier failure mode when the profile key was missing:
    Preferred provider ‘ninerouter’ is not configured, using auto-detected default
    Failed to apply default_model ‘…’: NINE_ROUTER_API_KEY not found in environment
    (credential path is separate; the picker labeling bug remains even after the profile works.)

Expected Behavior

  • All [[providers.ninerouter.models]] entries appear in /model.
  • Routes are labeled with the profile, e.g.:
  • provider = "ninerouter"
  • api_method = "openai-compatible:ninerouter"
  • model_picker_providers = ["ninerouter"] filters to those routes, not to a single current-model OpenRouter auto row.

Context / Root Cause (from investigation)

There appear to be two related gaps:

  1. Active named profile static list skipped
    When the named profile is active, catalog building can skip re-emitting [[providers.<name>.models]] under the assumption that the shared OpenRouter-slot runtime already contributes them. With a real OPENROUTER_API_KEY, that slot often contributes a large OpenRouter catalog (auto / openrouter) instead of the profile’s static list.

  2. Remote names-only History fallback misclassifies slash model ids
    Initial History often ships model names only (available_model_routes empty for speed). The client rebuilds routes via remote_model_routes_fallback. Any model id containing / is treated as OpenRouter and labeled auto + openrouter.

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 by tracing the model_picker_open path, catalog building for active named profiles, and remote_model_routes_fallback when History contains names only. Reproduce with the ninerouter configuration and inspect how slash-containing model IDs and model_picker_providers are labeled and filtered. Done means all configured static models appear under ninerouter with the expected provider and API method.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
cli
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.