Skip to content

feat(opencode): group the model picker by connected provider - #8072

Closed
Marve10s wants to merge 11 commits into
pingdotgg:mainfrom
Marve10s:ibrahim/opencode-model-sections
Closed

Marve10s wants to merge 11 commits into
pingdotgg:mainfrom
Marve10s:ibrahim/opencode-model-sections

Conversation

@Marve10s

@Marve10s Marve10s commented Aug 24, 2026 •

Copy link
Copy Markdown
Contributor

Users who connect several providers through OpenCode (a paid subscription, a GPT subscription, free models) get every model in one flat alphabetized scroll, so finding a specific model means scanning hundreds of interleaved rows.

The server now sorts OpenCode's catalog by upstream provider before model name, and the web picker folds each vendor into its own collapsible section, reusing the legacy-models fold pattern. Sections only appear when a catalog spans at least two vendors; a single vendor still renders as a plain list. The section holding the active model starts open, with the first section as fallback, favorites and custom models stay above the fold, and search keeps ranking the flat list across sections. Expansion choices persist per provider instance in client settings, so the picker reopens the way the user left it. The mobile thread-settings sheet gets the same vendor sub-sections inside an aggregator's catalog with matching open-by-default behavior. The CLI fallback inventory path used to emit raw ids like "openrouter" as provider names; it now derives readable display names so section headers match the SDK path.

Written by Fable 5 in Claude Code.


Note

Medium Risk
Adds a persisted client-settings field and changes model catalog presentation and OpenCode ordering semantics used for implicit defaults; mistakes could hide models or pick wrong defaults.

Overview
Aggregator providers such as OpenCode no longer dump every upstream model into one flat list. Each model can carry a subProvider label, and web and mobile pickers fold multi-vendor catalogs into collapsible vendor sections (only when there are at least two vendors). Favorited or vendorless models stay above the folds; search can match vendor names as well as model names.

On the server, OpenCode snapshots attach subProvider from connected upstream provider names, keep the catalog globally name-sorted so implicit defaults stay stable, and the CLI inventory fallback derives readable provider display names instead of raw ids.

The web picker persists which vendor sections are expanded per provider instance in a new modelPickerExpandedSections client setting (empty array means explicitly collapsed). Mobile thread settings use the same grouping for the session via catalogVendorRuns / sub-provider headers. User docs describe the new model picker behavior.

Reviewed by Cursor Bugbot for commit 8af1688. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Group model picker by connected provider with collapsible vendor sections

  • Adds subProvider labels to OpenCode provider models in flattenOpenCodeModels and derives human-readable provider names via providerDisplayNameFromId instead of raw CLI ids
  • Web model picker (ModelPickerContent.tsx) groups aggregator catalogs into collapsible vendor sections when two or more vendors are present; favorites and vendorless models stay above the sections
  • Mobile thread settings (ThreadSettingsSheet.tsx) renders matching collapsible sub-provider headers via catalogVendorRuns and catalogModelItems
  • Persists per-instance expanded vendor labels in a new modelPickerExpandedSections field on ClientSettingsSchema; defaults to keeping the active model's vendor open
  • Catalog search now matches vendor names in addition to model names
  • Risk: ClientSettingsSchema gains a required modelPickerExpandedSections field with empty-object default; older clients that do not send this field will get the default, but any external consumers of the settings schema must handle the new field

Macroscope summarized 8af1688.

Preview

2026-08-24.13.11.37.mov

@coderabbitai

coderabbitai Bot commented Aug 24, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 9e8609e2-74f7-4e32-9064-fcbfb8a4ec9a

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 24, 2026
Comment thread apps/web/src/components/chat/ModelPickerContent.tsx
Comment thread apps/web/src/components/chat/ModelPickerContent.tsx

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Reviewed the web model-picker changes (ModelPickerContent.tsx, modelPickerKeys.ts) for shared-primitive and Tailwind-ownership consistency. The key encoding, ComboboxItem usage, aria-expanded state, keyboard/Enter handling and scroll-fade wiring all follow the existing legacy-section pattern. Two findings on the new sub-provider section row.

Posted via Macroscope — UI Consistency

Comment thread apps/web/src/components/chat/ModelPickerContent.tsx Outdated
Comment thread apps/web/src/components/chat/ModelPickerContent.tsx Outdated
@github-actions github-actions Bot added size:XL 500-999 changed lines (additions + deletions). and removed size:L 100-499 changed lines (additions + deletions). labels Aug 24, 2026

@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: 6b9be22fad

ℹ️ 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 apps/web/src/components/chat/ModelPickerContent.tsx Outdated
Comment thread apps/server/src/provider/Layers/OpenCodeProvider.ts Outdated
Comment thread apps/web/src/components/chat/ModelPickerContent.tsx

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

One consistency finding on the new sub-provider section rows in ModelPickerContent.tsx. Everything else in the web scope (modelPickerKeys.ts encoding/parsing, key/toggle wiring, filteredItemKeys vs allItemKeys superset, aria-expanded, chevron rotation, header height matching estimatedItemSize) looks consistent with the existing picker contracts.

Posted via Macroscope — UI Consistency

Comment thread apps/web/src/components/chat/ModelPickerContent.tsx
@macroscopeapp

macroscopeapp Bot commented Aug 24, 2026 •

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR introduces a new cross-platform model-picker workflow with collapsible vendor sections, altered list visibility/navigation, and persisted expansion preferences. The additive schema and focused server fallback changes are low risk individually, but the aggregate UI and state-management behavior is substantial enough for human review.

You can add or adjust custom eligibility rules. Learn more.

@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: ee657cd2a4

ℹ️ 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 apps/web/src/components/chat/ModelPickerContent.tsx
Comment thread packages/contracts/src/settings.ts
Comment thread apps/mobile/src/features/threads/ThreadSettingsSheet.tsx

@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: 7093eac78f

ℹ️ 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 apps/mobile/src/features/threads/thread-settings-sheet-state.ts

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 7ebb9b8. Configure here.

Comment thread apps/web/src/components/chat/ModelPickerContent.tsx

@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: 8af16887b8

ℹ️ 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 on lines +513 to +515
storedChoice !== undefined &&
(storedChoice.length === 0 ||
storedChoice.some((label) => sections.some((section) => section.label === label)));

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Scope empty collapse choices to their environment

In a multi-environment client, collapsing every OpenCode vendor in environment A stores []; this trust check then unconditionally accepts that empty entry for environment B's same opencode instance, suppressing the active/first-vendor fallback even when B has a completely different catalog and opening every section collapsed. Fresh evidence beyond the earlier scope report is the newly added storedChoice.length === 0 branch, which cannot establish any catalog match; include the environment or a catalog identity in the persistence key.

AGENTS.md reference: AGENTS.md:L74-L74

Useful? React with 👍 / 👎.

ungrouped.push(model);
continue;
}
const key = modelPickerSubProviderSectionKey(model.instanceId, model.subProvider);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Group vendors by stable provider ID

When OpenCode reports two distinct connected provider IDs with the same display name, this key collapses them into one vendor because subProvider contains provider.name, not provider.id; if those are the only two providers, subProviders.size is also one and grouping is disabled entirely. The mobile catalogVendorRuns path repeats the same display-name grouping, so custom or external OpenCode inventories with duplicate labels lose the promised per-connected-provider sections on both clients; carry a stable upstream ID for keys while retaining the name as the label.

Useful? React with 👍 / 👎.

@t3dotgg

t3dotgg commented Aug 28, 2026

Copy link
Copy Markdown
Member

Note

🤖 GPT-5.6 Sol responding on behalf of Theo

We're closing this PR as we clean up the T3 Code backlog. Thank you for taking the time to put this together.

Grouping OpenCode models by upstream provider is a larger presentation change across server, web, and mobile. We are keeping the smaller label repair in #7562 for the wrong-source ambiguity instead.

If you believe we closed this in error, please reopen the PR and leave a comment explaining what we missed.

@Marve10s

Marve10s commented Sep 9, 2026

Copy link
Copy Markdown
Contributor Author

@t3dotgg @juliusmarminge Could you reconsider this for the catalog grouping?

#7562 clarifies which upstream provider a model uses. With several providers connected through OpenCode, the picker still puts their models into one flat list. This PR adds collapsible vendor sections on web and mobile so users can browse one provider's models at a time.

There is a recording attached under Preview in the PR description showing the interaction.

The closing comment calls out the larger presentation change, which is fair. Is that grouping behavior something you would consider independently of the label repair?

#10082 references this PR, but its mobile expansion and scrolling bug is separate. This PR does not claim to fix it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL 500-999 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants