1+ import { ProjectKnowledgeEntry } from "../../components/ProjectKnowledgeEntry" ;
12import { useSidebarWorkspaceTabs } from "../workspace/useSystemWorkspaceTabBar" ;
23import { Button } from "../../components/ui/Button" ;
34import * as Dialog from "../../components/ui/Dialog" ;
@@ -52,6 +53,8 @@ import Animated, {
5253import { useUniwindTheme } from "../../lib/useUniwindTheme" ;
5354import { themeColorWithAlpha } from "../../lib/mobileTheme" ;
5455import { armAgentAwarenessLiveActivityForLocalWork } from "../agent-awareness/remoteRegistration" ;
56+ import { updateThreadDraftModelSelection } from "../../state/use-thread-composer-state" ;
57+ import { withRememberedModelOptions } from "../../state/use-model-option-memory" ;
5558import { scopedThreadKey } from "../../lib/scopedEntities" ;
5659import {
5760 getComposerDraftSnapshot ,
@@ -235,6 +238,7 @@ export interface ThreadComposerProps {
235238 ) => Promise < MessageId | null > ;
236239 readonly onShowUsageLimits : ( report : UsageLimitsReport | null ) => void ;
237240 readonly canSwitchProvider : boolean ;
241+ readonly onUpdateModelSelection ?: ( modelSelection : ModelSelection ) => void ;
238242 readonly onUpdateInteractionMode ?: ( interactionMode : ProviderInteractionMode ) => void ;
239243 readonly onHeightChange ?: ( height : number ) => void ;
240244 readonly onEditorFocusChange ?: ( focused : boolean ) => void ;
@@ -517,6 +521,7 @@ export const ThreadComposer = function ThreadComposer(props: ThreadComposerProps
517521 props . selectedThread . modelSelection . instanceId ,
518522 props . serverConfig ?. providers ?? [ ] ,
519523 props . serverConfig ?. usageLimitSources ?? [ ] ,
524+ // oxlint-disable-next-line react/purity -- The submit and menu handlers read usage limits only after a user action.
520525 Date . now ( ) ,
521526 ) ;
522527 onShowUsageLimits ( report ) ;
@@ -526,6 +531,16 @@ export const ThreadComposer = function ThreadComposer(props: ThreadComposerProps
526531 return report !== null ;
527532 } ;
528533
534+ const lockedProviderInstanceId = props . canSwitchProvider
535+ ? undefined
536+ : currentModelSelection . instanceId ;
537+ const modelOptions = buildModelOptions (
538+ props . serverConfig ,
539+ currentModelSelection ,
540+ lockedProviderInstanceId ,
541+ props . selectedThread . projectId ,
542+ "composer" ,
543+ ) ;
529544 const composerMenu = useComposerCommandMenu ( {
530545 draftMessage : draftMessage ,
531546 ownerKey : composerDraftKey ,
@@ -551,6 +566,21 @@ export const ThreadComposer = function ThreadComposer(props: ThreadComposerProps
551566 offersUsageLimits : usageLimitsOffered ,
552567 onUsageLimits :
553568 usageLimitsOffered && draftAttachments . length === 0 ? openUsageLimits : undefined ,
569+ modelOptions,
570+ modelProviders : props . serverConfig ?. providers ,
571+ onSelectModel :
572+ props . interactionLocked === true
573+ ? undefined
574+ : ( option ) => {
575+ const selection = withRememberedModelOptions ( option . selection ) ;
576+ if ( props . onUpdateModelSelection ) props . onUpdateModelSelection ( selection ) ;
577+ else
578+ updateThreadDraftModelSelection (
579+ composerOwnerKey ,
580+ selection ,
581+ props . serverConfig ?. providers ?? [ ] ,
582+ ) ;
583+ } ,
554584 } ) ;
555585 const voiceInput = useVoiceInputController ( {
556586 ownerKey : composerDraftKey ,
@@ -689,16 +719,6 @@ export const ThreadComposer = function ThreadComposer(props: ThreadComposerProps
689719 } ) ;
690720 } ;
691721
692- const lockedProviderInstanceId = props . canSwitchProvider
693- ? undefined
694- : currentModelSelection . instanceId ;
695- const modelOptions = buildModelOptions (
696- props . serverConfig ,
697- currentModelSelection ,
698- lockedProviderInstanceId ,
699- props . selectedThread . projectId ,
700- "composer" ,
701- ) ;
702722 const currentModelOption =
703723 modelOptions . find (
704724 ( option ) =>
@@ -858,6 +878,15 @@ export const ThreadComposer = function ThreadComposer(props: ThreadComposerProps
858878 />
859879 ) : null }
860880
881+ { ! props . hidden && composerDraftKey ? (
882+ < ProjectKnowledgeEntry
883+ environmentId = { props . environmentId }
884+ projectId = { props . selectedThread . projectId }
885+ draftKey = { composerDraftKey }
886+ disabled = { isSubmissionLocked }
887+ />
888+ ) : null }
889+
861890 < ComposerSurface
862891 animateLayout = { false }
863892 style = { {
@@ -978,7 +1007,6 @@ export const ThreadComposer = function ThreadComposer(props: ThreadComposerProps
9781007 hidden = { props . hidden }
9791008 draftKey = { composerDraftKey }
9801009 environmentId = { props . environmentId }
981- projectId = { props . selectedThread . projectId }
9821010 onOpenMention = { ( path ) => {
9831011 Keyboard . dismiss ( ) ;
9841012 if ( props . isDraft ) {
0 commit comments