diff --git a/apps/web/src/spa/chat/composer.tsx b/apps/web/src/spa/chat/composer.tsx index 696e8d1d..2bd2d033 100644 --- a/apps/web/src/spa/chat/composer.tsx +++ b/apps/web/src/spa/chat/composer.tsx @@ -58,7 +58,18 @@ export function Composer({ } } - const models = harness.catalog?.models ?? []; + // Scope the model options to the intentionally selected provider. With no + // provider chosen (`providerId === ''`) nothing matches, so the model select + // offers only the placeholder — never a cross-provider row. + const models = (harness.catalog?.models ?? []).filter( + (model) => model.providerId === harness.providerId, + ); + // A collision-safe composite option identity covering the full provider+model + // tuple. The controlled select mirrors the same identity so the exact catalog + // row highlights (a bare modelId would collide across providers). + const modelOptionValue = (model: { providerId: string; modelId: string }): string => + `${model.providerId}:${model.modelId}`; + const selectedModelValue = harness.modelId ? `${harness.providerId}:${harness.modelId}` : ''; return (