diff --git a/web/src/pages/user-setting/setting-model/index.tsx b/web/src/pages/user-setting/setting-model/index.tsx index 476fe5985b..dcf3d203a2 100644 --- a/web/src/pages/user-setting/setting-model/index.tsx +++ b/web/src/pages/user-setting/setting-model/index.tsx @@ -56,6 +56,10 @@ const SettingModelV2: FC = () => { // cancelled independently; saving removes the draft from this list and // triggers a refetch that surfaces the newly-saved instance above. const [draftIds, setDraftIds] = useState([]); + + const [newlySavedInstanceName, setNewlySavedInstanceName] = useState< + string | null + >(null); // Monotonic counter so each draft card has a stable, unique React key. const draftIdCounterRef = useRef(0); // Tracks whether the user explicitly cancelled the auto-shown draft @@ -90,6 +94,7 @@ const SettingModelV2: FC = () => { useEffect(() => { cancelledRef.current = false; setDraftIds([]); + setNewlySavedInstanceName(null); }, [selection]); // If the user switches to a provider with no existing instances and @@ -135,6 +140,7 @@ const SettingModelV2: FC = () => { // and `draftIds` are empty and would otherwise re-trigger // `addDraft()`). cancelledRef.current = true; + setNewlySavedInstanceName(values.instance_name); removeDraft(id); queryClient.invalidateQueries({ queryKey: LlmKeys.providerInstances(providerQueryName), @@ -154,10 +160,12 @@ const SettingModelV2: FC = () => { // "Save name" button inside the draft card). Remove the draft and // pin the auto-show guard so a new placeholder draft is not // auto-injected during the brief window between draft removal and - // the providerInstances refetch landing. + // the providerInstances refetch landing. Remember the saved name so + // the persisted card mounts expanded. const handleNameSaved = useCallback( - (id: string) => { + (id: string, instanceName: string) => { cancelledRef.current = true; + setNewlySavedInstanceName(instanceName); removeDraft(id); }, [removeDraft], @@ -207,7 +215,10 @@ const SettingModelV2: FC = () => { key={instance.instance_name} providerName={selection as string} instance={instance} - defaultOpen={index === 0} + defaultOpen={ + index === 0 || + instance.instance_name === newlySavedInstanceName + } /> ))} {draftIds.map((id) => ( @@ -217,7 +228,9 @@ const SettingModelV2: FC = () => { instance={draftInstance} isDraft onDelete={() => handleDraftCancel(id)} - onNameSaved={() => handleNameSaved(id)} + onNameSaved={(instanceName) => + handleNameSaved(id, instanceName) + } onSaved={(values) => handleDraftSave(id, values)} /> ))} diff --git a/web/src/pages/user-setting/setting-model/instance-card/bedrock-instance-card.tsx b/web/src/pages/user-setting/setting-model/instance-card/bedrock-instance-card.tsx index 46f48e89a9..a711628c89 100644 --- a/web/src/pages/user-setting/setting-model/instance-card/bedrock-instance-card.tsx +++ b/web/src/pages/user-setting/setting-model/instance-card/bedrock-instance-card.tsx @@ -77,7 +77,7 @@ interface BedrockInstanceCardProps { instance: IProviderInstance; isDraft?: boolean; onSaved?: (values: Record) => void | Promise; - onNameSaved?: () => void; + onNameSaved?: (instanceName: string) => void; onDelete?: () => void; /** * When true, this card starts expanded and fetches its instance @@ -324,7 +324,7 @@ export function BedrockInstanceCard({ instance_name: trimmed, } as any); if (ret?.code === 0) { - onNameSaved?.(); + onNameSaved?.(trimmed); } }, [draftName, addProviderInstance, providerName, onNameSaved]); diff --git a/web/src/pages/user-setting/setting-model/instance-card/hooks.tsx b/web/src/pages/user-setting/setting-model/instance-card/hooks.tsx index b39576a17a..e9265f8e57 100644 --- a/web/src/pages/user-setting/setting-model/instance-card/hooks.tsx +++ b/web/src/pages/user-setting/setting-model/instance-card/hooks.tsx @@ -336,7 +336,7 @@ export function useVerifyProvider( export function useSaveInstanceName( providerName: string, draftName: string, - onNameSaved?: () => void, + onNameSaved?: (instanceName: string) => void, ) { const { addProviderInstance } = useAddProviderInstance(); return useCallback(async () => { @@ -347,7 +347,7 @@ export function useSaveInstanceName( instance_name: trimmed, } as any); if (ret?.code === 0) { - onNameSaved?.(); + onNameSaved?.(trimmed); } }, [draftName, addProviderInstance, providerName, onNameSaved]); } diff --git a/web/src/pages/user-setting/setting-model/instance-card/interface.ts b/web/src/pages/user-setting/setting-model/instance-card/interface.ts index c8e2de584e..f40b942259 100644 --- a/web/src/pages/user-setting/setting-model/instance-card/interface.ts +++ b/web/src/pages/user-setting/setting-model/instance-card/interface.ts @@ -39,9 +39,11 @@ export interface ProviderInstanceCardProps { * Called after a draft instance's *name* has been persisted via * `addProviderInstance` (with just `instance_name`). The parent should * remove this draft from its visible list; the freshly invalidated - * `providerInstances` query will surface the persisted card. + * `providerInstances` query will surface the persisted card. The + * saved `instanceName` is passed so the parent can keep the newly + * persisted card expanded. */ - onNameSaved?: () => void; + onNameSaved?: (instanceName: string) => void; /** * Called when the user deletes a draft instance. * For drafts this is equivalent to onCancel; for saved instances diff --git a/web/src/pages/user-setting/setting-model/instance-card/somark-instance-card.tsx b/web/src/pages/user-setting/setting-model/instance-card/somark-instance-card.tsx index 84f56c59f6..aa3758b792 100644 --- a/web/src/pages/user-setting/setting-model/instance-card/somark-instance-card.tsx +++ b/web/src/pages/user-setting/setting-model/instance-card/somark-instance-card.tsx @@ -104,7 +104,7 @@ interface SoMarkInstanceCardProps { instance: IProviderInstance; isDraft?: boolean; onSaved?: (values: Record) => void | Promise; - onNameSaved?: () => void; + onNameSaved?: (instanceName: string) => void; onDelete?: () => void; /** * When true, this card starts expanded and fetches its instance @@ -355,7 +355,7 @@ export function SoMarkInstanceCard({ instance_name: trimmed, } as any); if (ret?.code === 0) { - onNameSaved?.(); + onNameSaved?.(trimmed); } }, [draftName, addProviderInstance, providerName, onNameSaved]);