@@ -3,6 +3,8 @@ import { Button, cn } from "@heroui/react";
33import { useSettingStore } from "../../stores/setting-store" ;
44import { Settings } from "../../pkg/gen/apiclient/user/v1/user_pb" ;
55import { PlainMessage } from "../../query/types" ;
6+ import { useConversationStore } from "../../stores/conversation/conversation-store" ;
7+ import { listSupportedModels } from "../../query/api" ;
68
79type SettingKey = keyof PlainMessage < Settings > ;
810
@@ -27,6 +29,7 @@ export function createSettingsTextInput<K extends SettingKey>(settingKey: K) {
2729 password = false ,
2830 } : SettingsTextInputProps ) {
2931 const { settings, isUpdating, updateSettings } = useSettingStore ( ) ;
32+ const { setCurrentConversation } = useConversationStore ( ) ;
3033 const [ value , setValue ] = useState < string > ( "" ) ;
3134 const [ originalValue , setOriginalValue ] = useState < string > ( "" ) ;
3235 const [ isEditing , setIsEditing ] = useState < boolean > ( false ) ;
@@ -43,11 +46,39 @@ export function createSettingsTextInput<K extends SettingKey>(settingKey: K) {
4346
4447 const valueChanged = value !== originalValue ;
4548
49+ // helper normalizes model by retrieving the model (assumed to be the last segment, if '/' present)
50+ const normalizeModelId = ( modelSlug : string ) =>
51+ modelSlug . toLowerCase ( ) . trim ( ) . split ( "/" ) . filter ( Boolean ) . pop ( ) ! ;
52+
4653 const saveSettings = useCallback ( async ( ) => {
4754 await updateSettings ( { [ settingKey ] : value . trim ( ) } as Partial < PlainMessage < Settings > > ) ;
4855 setOriginalValue ( value . trim ( ) ) ;
4956 setIsEditing ( false ) ;
50- } , [ value , updateSettings ] ) ; // settingKey is an outer scope value, not a dependency
57+
58+ // If openaiApiKey was updated, fetch new model list and update current model slug
59+ if ( settingKey === "openaiApiKey" ) {
60+ const response = await listSupportedModels ( { } ) ;
61+ if ( response . models ?. length ) {
62+ const { currentConversation : latest } = useConversationStore . getState ( ) ;
63+ // try to find a model that matches the current slug
64+ // we don't do exact match but attempt exact suffix match (case insensitive); as per convention
65+ // we don't assume any provided prefix (e.g. openai/, quen/) but fair to assume model name is suffix
66+ const currentId = normalizeModelId ( latest . modelSlug ) ;
67+ const matchingModel = response . models . find ( m =>
68+ normalizeModelId ( m . name ) === currentId
69+ ) ;
70+ // fall back to the first model in the list
71+ const newSlug = matchingModel ?. slug ?? response . models [ 0 ] . slug ;
72+
73+ if ( newSlug !== latest . modelSlug ) {
74+ setCurrentConversation ( {
75+ ...latest ,
76+ modelSlug : newSlug ,
77+ } ) ;
78+ }
79+ }
80+ }
81+ } , [ value , settingKey , updateSettings ] ) ; // settingKey is an outer scope value, not a dependency
5182
5283 const handleEdit = useCallback ( ( ) => {
5384 setIsEditing ( true ) ;
0 commit comments