Group model picker by provider for ACP route models - #2465
Conversation
8e612df to
07ed492
Compare
|
cc @SawyerHood @ymichael — re-review ping; this one has had no maintainer feedback since it opened. Where it stands: bridge fix (type + map the per-option If the grouped-headers desktop treatment isn't the direction you want, the bridge half is still worth taking on its own — it's two lines and every surface that renders |
ACP agents such as omp advertise the same display name under multiple providers. Type description on the select-option schema, keep it through the catalog, and group the desktop picker by route — headers only when two or more providers are present.
07ed492 to
fde50c3
Compare
Rebase
Gates
|
Human comments
What was wrong
buildModelCatalogFromConfigOptionshard-codeddescription: ""for every ACP model select option, andacpConfigOptionSelectOptionSchemadid not typedescription(it only survived via.passthrough()). Agents such as omp senddescription: "provider/modelId"and advertise the same display name under several routes (on this machine: 279 models across 9 providers, 37 duplicate display names). The desktop picker rendered only the display name, so those rows were identical in text, tooltip, and accessible name. Issue: #2062. Closed PR #2226 had the bridge fix plus inline qualifiers; this redo keeps the bridge hunks and replaces the desktop UX with provider-grouped headers.What changed
Bridge (
packages/provider-bridge-acp):src/wire.ts:description: acpOptionalStringon the select-option schema.src/bridge/model-catalog.ts:description: option.description ?? "", mirroringbuildModelCatalogFromSessionModels.HOST_DAEMON_PROTOCOL_VERSIONbump:AvailableModel.descriptionis already a required string.Desktop (
apps/app):routeProviderId, else the first segment of a slashed id). StickyMenuSectionLabelheaders only when ≥2 routes are visible. Search that narrows to one route hides the headers (same rule).provider/). The trigger shows a distinguishing token only when the committed label is ambiguous acrossmodelOptions+moreModelOptions.span[title]with the full raw id; keyboard order matches DOM order (contiguous route runs, not merged).zai→ Z.ai,xai-oauth→ xAI, …) with a hyphen→title-case fallback. omp 18.0.5 does not expose provider display names onomp models --json; group keys and tooltips stay on raw ids..ladlefixture + story cover the omp-style multi-route catalog.The former mobile assertion (
apps/mobile/src/data/compose/execution-options.test.ts) was dropped during the rebase:apps/mobile/src/data/compose/no longer exists on main. The bridge fix itself is unchanged, so whichever surface consumesAvailableModel.descriptionnow gets the provider-qualified subtitle.Deviation from closed #2226: grouping + headers instead of always-on inline qualifiers.
How you verified
Tests (fail before, pass after):
packages/provider-bridge-acp/src/bridge/model-catalog.test.ts— catalog keeps the per-option description (17 files / 301 tests green).packages/provider-bridge-acp/src/wire.test.ts— schema returnsdescriptionand normalizesnull→undefined.apps/app/src/components/pickers/model-picker-option.test.ts— grouping, ≥2-route header gate, within-group qualifiers, trigger token, display-name map.apps/app/src/components/pickers/ModelReasoningPicker.test.tsx— grouped headers,role="group"/aria-labelledby, raw-id tooltips, single-route lists stay flat, sticky offsets, unique-trigger shape, submenu + compact drawer grouping (65 tests across the two picker files).Mutation-kills (reverted after):
hasMultipleRouteGroups→return falsefails the grouped-catalog test;titlealwaysundefinedfailsgetByTitle("zai/glm-5.3");qualifyCollidingLabelsearlyreturn new Map()fails the within-provider qualifier test.Commands (rebased onto
688eb42, thenpnpm install --frozen-lockfile):pnpm exec turbo run typecheck lint test --filter=@bb/provider-bridge-acp --filter=@bb/app --filter=@bb/mobile— 11/11 tasks green. New code carries no comments, per the repo-widebb(no-comments)rule.Manual: Ladle
pickers--model-reasoning-picker--overview, "open: acp grouped" — pretty headers (Cursor / Z.ai / CommandCode / Mistral), collision tails, full-id tooltips,role=group.Fixes #2062