Skip to content

fix(clients): show model provider prefixes in model subtitles - #17

Merged
Fryuni merged 4 commits into
mainfrom
t3code/fix-model-prefix-display
Sep 17, 2026
Merged

Fryuni merged 4 commits into
mainfrom
t3code/fix-model-prefix-display

Conversation

@Fryuni

@Fryuni Fryuni commented Sep 17, 2026

Copy link
Copy Markdown
Owner

What Changed

Model subtitles now include the provider qualifier from the model slug (slash prefixes like anthropic/, nested prefixes like loem/azure., and dot qualifiers like openai.), instead of only showing the optional subProvider field.

  • Added getModelProviderLabel to packages/shared/src/model.ts, which derives a provider label from the slug while avoiding duplication when subProvider already covers the qualifier.
  • Web (ModelListRow.tsx) and mobile (modelOptions.ts) model subtitles now use this helper.
  • Added tests in packages/shared/src/model.test.ts and apps/mobile/src/lib/modelOptions.test.ts.

Why

Models served through gateways or nested providers (e.g. loem/azure.glm-5.3-Flash) previously rendered with an empty or misleading subtitle, since subProvider alone doesn't capture the slug's provider prefix. This surfaces the full provider path consistently across web and mobile without duplicating information already shown.

UI Changes

Model picker subtitles in web and mobile now show provider prefixes such as Loem · azure where they previously showed only Loem or nothing. Screenshots to be attached.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes
  • I included a video for animation/interaction changes

Model slugs with nested slash or dot qualifiers (e.g. loem/azure.glm-5.3-Flash) showed no provider info or only subProvider. Add a shared getModelProviderLabel helper that derives the qualifier from the slug and use it in web model rows and mobile model options.
Copilot AI lite review requested due to automatic review settings September 17, 2026 20:40
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 17, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-17T21:06:37.902946Z 3cb0c36 New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 14f0405195

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/shared/src/model.ts Outdated
Comment thread apps/web/src/components/chat/ModelListRow.tsx

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Provider-label inference misses valid qualified model slugs and separator differences.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Updates web and mobile model subtitles to display provider prefixes inferred from model slugs.

Changes:

  • Added shared provider-label inference and tests.
  • Applied provider labels to web and mobile model pickers.
  • Added coverage for qualified and nested providers.
File summaries
File Description
packages/shared/src/model.ts Adds provider-label inference.
packages/shared/src/model.test.ts Tests provider-label behavior.
apps/web/src/components/chat/ModelListRow.tsx Displays derived labels on web.
apps/mobile/src/lib/modelOptions.ts Displays derived labels on mobile.
apps/mobile/src/lib/modelOptions.test.ts Tests mobile subtitles.
Review details

Suppressed comments (1)

packages/shared/src/model.ts:248

  • This only recognizes a dot qualifier when the text after the dot exactly matches name or shortName, so valid qualified Codex entries such as openai.gpt-5.6-luna with the friendly name Luna (see apps/server/src/provider/Layers/CodexProvider.test.ts:133-138) return no provider label at all. The new web/mobile subtitles will therefore still be blank for this real model shape; infer the provider prefix from the qualified slug using an explicit provider rule/metadata, and add a regression test for the Luna case.
  const inferDotQualifier = (value: string): string | undefined => {
    const lowerValue = value.toLowerCase();
    for (const name of names) {
      const suffix = `.${name.toLowerCase()}`;
      if (lowerValue.endsWith(suffix)) {
        return value.slice(0, -suffix.length) || undefined;
  • Files reviewed: 5/5 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread packages/shared/src/model.ts Outdated
- Match name suffixes by stripping separators and casing so variants like `minimax-m2` vs `Minimax M2` still strip the qualifier
- Split at the first dot instead of requiring an exact string suffix
Copilot AI review requested due to automatic review settings September 17, 2026 20:51

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 06ce965647

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/shared/src/model.ts

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Duplicate provider detection should normalize punctuation and casing before approval.

Review details

Suppressed comments (1)

packages/shared/src/model.ts:270

  • The duplicate check only uses localeCompare, so it does not treat slug punctuation as equivalent to the friendly provider name. For a dot-qualified model such as github-copilot.claude-fable-5 with subProvider: "GitHub Copilot", this returns GitHub Copilot · github-copilot even though the qualifier is already represented. Use the existing normalizeName comparison here so hyphens, spaces, and case are handled consistently.
    qualifier && subProvider?.localeCompare(qualifier, undefined, { sensitivity: "accent" }) === 0
      ? undefined
      : qualifier;
  • Files reviewed: 5/5 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

Copilot AI review requested due to automatic review settings September 17, 2026 21:02

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Three moderate provider-label inference issues remain unresolved.

Review details

Suppressed comments (3)

packages/shared/src/model.ts:263

  • This unconditionally drops the first slash segment whenever subProvider is present, even if that segment is not the provider represented by the display name. OpenCode builds the slug from provider.id and subProvider from provider.name independently (apps/server/src/provider/Layers/OpenCodeProvider.ts:272-275), so a configured provider whose ID and name differ can lose part of its route (for example, loem/upstream/model with subProvider: "Azure" becomes Azure · upstream, hiding loem). Only remove the segment when its normalized value matches subProvider (while still allowing github-copilot / GitHub Copilot), and otherwise retain it.
  if (subProvider) {
    slashParts.shift();
  }

packages/shared/src/model.ts:264

  • This treats every slash component before the final component as a provider qualifier whenever subProvider is present. OpenCode constructs slugs as ${provider.id}/${model.id}, but model.id itself may contain slashes (for example openrouter/qwen/qwen3-coder, as covered by apps/server/src/provider/opencodeRuntime.cliParsers.test.ts:139-155), so this helper will render OpenRouter · qwen even though qwen is part of the model ID. Use the known subProvider boundary and avoid inferring additional slash qualifiers from the remainder (or carry explicit qualifier metadata), and add a regression case for slash-containing model IDs.
  if (subProvider) {
    slashParts.shift();
  }
  const qualifiers = slashParts.filter(Boolean);

packages/shared/src/model.ts:255

  • This loop scans every dot, so a normal versioned slug such as gpt-5.6-sol with name Sol matches the final .sol and returns gpt-5.6 as a provider. The added test expects undefined, so the shared helper currently fails its own regression test and would show version text as a provider subtitle; only consider the first dot as the provider/model boundary (while retaining the explicit Codex case above).
    for (let index = value.indexOf("."); index > 0; index = value.indexOf(".", index + 1)) {
      const suffix = normalizeName(value.slice(index + 1));
      if (
        suffix &&
        (suffix === normalizeName(model.name) ||
          (model.shortName && suffix === normalizeName(model.shortName)))
      ) {
        return value.slice(0, index);
      }
    }
  • Files reviewed: 8/8 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

Copilot AI review requested due to automatic review settings September 17, 2026 21:09
@Fryuni

Fryuni commented Sep 17, 2026

Copy link
Copy Markdown
Owner Author

[from Codex]: Addressed the remaining applicable Copilot duplicate-label finding in e07701d: provider-name deduplication now normalizes spaces, hyphens, underscores, and case. The new GitHub Copilot regression failed before the fix and passes afterward.

The three suppressed findings on 3cb0c36 do not warrant changes:

  • OpenCode constructs the first slash component from provider.id and subProvider from that same provider.name; a customized display name still represents that provider. Repeating its ID is not needed.
  • Showing intermediate model-ID namespaces is the requested behavior: Loem/upstream/model must expose upstream. Removing nested qualifiers would recreate the reported bug; OpenRouter/qwen/model follows the same display convention.
  • gpt-5.6-sol contains a dot before 6, not before sol. Its suffix does not match Sol, and the unqualified regression passes.

Known qualified Codex IDs with shortened friendly names and searching the visible web provider qualifiers were addressed in 3cb0c36.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Preserve model IDs containing slash segments when deriving provider qualifiers.

Review details

Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

packages/shared/src/model.ts:264

  • OpenCode constructs slugs as ${provider.id}/${model.id}, and model.id can itself contain / (for example openrouter/qwen/qwen3-coder). When subProvider is present, this removes only the first segment and then treats every remaining segment as a provider, so the model is shown as OpenRouter · qwen and qwen becomes searchable as a provider qualifier. Preserve the provider/model-id boundary (or pass an explicit qualifier from the adapter) instead of treating every pre-final slash segment as a provider prefix.
  • Files reviewed: 8/8 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

@Fryuni
Fryuni merged commit 77c6642 into main Sep 17, 2026
9 checks passed
@Fryuni
Fryuni deleted the t3code/fix-model-prefix-display branch September 17, 2026 21:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants