@@ -98,9 +98,8 @@ import {
9898import { proposedPlanTitle } from "../../proposedPlan" ;
9999import { getProviderInteractionModeToggle } from "../../providerModels" ;
100100import {
101- deriveProviderInstanceEntries ,
102101 resolveProviderDriverKindForInstanceSelection ,
103- sortProviderInstanceEntries ,
102+ resolveSelectedProviderInstanceId ,
104103 type ProviderInstanceEntry ,
105104} from "../../providerInstances" ;
106105import { type AppModelOption , getAppModelOptionsForInstance } from "../../modelSelection" ;
@@ -432,6 +431,7 @@ export interface ChatComposerProps {
432431 // Provider / model
433432 lockedProvider : ProviderDriverKind | null ;
434433 providerStatuses : ServerProvider [ ] ;
434+ providerInstanceEntries : ReadonlyArray < ProviderInstanceEntry > ;
435435 activeProjectDefaultModelSelection : ModelSelection | null | undefined ;
436436 activeThreadModelSelection : ModelSelection | null | undefined ;
437437
@@ -526,6 +526,7 @@ export const ChatComposer = memo(
526526 interactionMode,
527527 lockedProvider,
528528 providerStatuses,
529+ providerInstanceEntries,
529530 activeProjectDefaultModelSelection,
530531 activeThreadModelSelection,
531532 activeThreadActivities,
@@ -591,13 +592,6 @@ export const ChatComposer = memo(
591592 // ------------------------------------------------------------------
592593 // Model state
593594 // ------------------------------------------------------------------
594- // Instance-aware projection of the wire provider list. One entry per
595- // configured instance (default built-in + any custom `providerInstances.*`),
596- // sorted default-first per driver kind for a stable picker order.
597- const providerInstanceEntries = useMemo < ReadonlyArray < ProviderInstanceEntry > > (
598- ( ) => sortProviderInstanceEntries ( deriveProviderInstanceEntries ( providerStatuses ) ) ,
599- [ providerStatuses ] ,
600- ) ;
601595 const selectedProviderByThreadId = composerDraft . activeProvider ?? null ;
602596 const threadProvider =
603597 activeThread ?. session ?. providerInstanceId ??
@@ -629,66 +623,24 @@ export const ChatComposer = memo(
629623 providerInstanceEntries ,
630624 ] ) ;
631625
632- // Resolve which configured instance the composer is currently targeting.
633- // Priority:
634- // 1. The composer draft's `activeProvider` — the user's unsaved pick
635- // from the model picker (must win, otherwise the UI appears to
636- // ignore picker selections).
637- // 2. Thread's persisted instance id (server-side saved selection).
638- // 3. Project default's instance id.
639- // 4. First enabled entry matching the current driver kind.
640- // 5. First enabled entry overall / default instance for the kind.
641- //
642626 const selectedInstanceId = useMemo < ProviderInstanceId > ( ( ) => {
643- const candidates : Array < string | null | undefined > = [
644- composerDraft . activeProvider ,
645- activeThread ?. session ?. providerInstanceId ,
646- activeThreadModelSelection ?. instanceId ,
647- activeProjectDefaultModelSelection ?. instanceId ,
648- ] ;
649- for ( const candidate of candidates ) {
650- if ( ! candidate ) continue ;
651- const match = providerInstanceEntries . find (
652- ( entry ) => entry . instanceId === candidate && entry . enabled ,
653- ) ;
654- if ( match ) {
655- // When locked to a specific driver kind, ignore persisted instance
656- // ids from a different kind or continuation group.
657- if ( lockedProvider && match . driverKind !== lockedProvider ) continue ;
658- if (
659- lockedContinuationGroupKey &&
660- match . continuationGroupKey !== lockedContinuationGroupKey
661- ) {
662- continue ;
663- }
664- return match . instanceId ;
665- }
666- }
667- if ( explicitSelectedInstanceId ) {
668- return ProviderInstanceId . make ( explicitSelectedInstanceId ) ;
669- }
670- const byKind = providerInstanceEntries . find (
671- ( entry ) =>
672- entry . enabled &&
673- entry . driverKind === selectedProvider &&
674- ( ! lockedContinuationGroupKey ||
675- entry . continuationGroupKey === lockedContinuationGroupKey ) ,
676- ) ;
677- if ( byKind ) return byKind . instanceId ;
678- const anyEnabled = providerInstanceEntries . find ( ( entry ) => entry . enabled ) ;
679- return (
680- anyEnabled ?. instanceId ??
681- providerInstanceEntries [ 0 ] ?. instanceId ??
682- activeThreadModelSelection ?. instanceId ??
683- activeProjectDefaultModelSelection ?. instanceId ??
684- ProviderInstanceId . make ( "codex" )
685- ) ;
627+ return resolveSelectedProviderInstanceId ( {
628+ entries : providerInstanceEntries ,
629+ candidates : [
630+ composerDraft . activeProvider ,
631+ activeThread ?. session ?. providerInstanceId ,
632+ activeThreadModelSelection ?. instanceId ,
633+ activeProjectDefaultModelSelection ?. instanceId ,
634+ ] ,
635+ selectedProvider,
636+ lockedProvider,
637+ lockedContinuationGroupKey,
638+ } ) ;
686639 } , [
687640 activeProjectDefaultModelSelection ?. instanceId ,
688641 activeThread ?. session ?. providerInstanceId ,
689642 activeThreadModelSelection ?. instanceId ,
690643 composerDraft . activeProvider ,
691- explicitSelectedInstanceId ,
692644 lockedContinuationGroupKey ,
693645 lockedProvider ,
694646 providerInstanceEntries ,
0 commit comments