1jehuang / 1jehuang/jcode

Oversized AvailableModelsUpdated frame drops provider routes, so picker misroutes multi-provider models

Open
#650 5 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

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

Description

When an AvailableModelsUpdated frame exceeds the bus frame cap, the server
downgrades it to a names-only snapshot that drops provider identity. After that,
picking a model served by more than one provider can silently resolve to a
different provider than the configured one.

Symptom

With several providers configured, selecting gpt-5.6-sol (served by both a
built-in provider and a configured OpenAI-compatible profile) routed to the
built-in provider instead of the profile. No error — just the wrong backend,
which is easy to miss because the request succeeds.

Cause

In crates/jcode-app-core/src/server/client_lifecycle.rs, an oversized frame is
replaced with a names-only copy:

// route expansion and ship a names-only snapshot; the TUI
let slim_event = names_only_available_models_event(&event);
// "Downgrading oversized bus AvailableModelsUpdated frame to names-only ..."

names_only_available_models_event drops the per-model provider routes, so the
picker sees a bare model name with no way to tell which provider should serve
it, and falls back to whichever provider claims that name first.

The size threshold is what makes this environment-dependent: it only triggers
once enough providers/models are configured to push the frame over the cap. With
a large catalog it is reliable.

Suggested direction

Compacting while preserving provider routes for the models the client can
actually select keeps the frame under the cap without losing the routing
information the picker needs. Dropping routes entirely is what makes the
selection ambiguous.

Notes on testing

Worth testing at the call site that builds the outgoing frame rather than
against the helper in isolation. A test that calls the compaction helper
directly can pass whether or not routes are preserved, because the helper is
only one branch of the decision — the bug lives in which snapshot the call site
ships. Sizing a fixture past the frame cap and asserting the emitted frame still
resolves a provider reproduces it.

I have a fix and mutation-verified tests in a fork if a reference is useful.
Filing as an issue per CONTRIBUTING; happy to share the branch.

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 in crates/jcode-app-core/src/server/client_lifecycle.rs at the call site that emits AvailableModelsUpdated frames, then inspect names_only_available_models_event and the picker’s provider resolution. Build an oversized fixture that exceeds the frame cap and run the relevant call-site tests. Done means the emitted compacted frame preserves provider routes and selecting a duplicate model resolves the configured provider.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
backend, cli
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
58/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.