@@ -10,22 +10,25 @@ import { TopBar } from "./ui/TopBar";
1010import { useChatStore } from "@/features/chat/stores/chatStore" ;
1111import {
1212 type ChatSession ,
13- hasSessionStarted ,
1413 useChatSessionStore ,
1514} from "@/features/chat/stores/chatSessionStore" ;
1615import { useAgentStore } from "@/features/agents/stores/agentStore" ;
1716import { useProjectStore } from "@/features/projects/stores/projectStore" ;
1817import { findExistingDraft } from "@/features/chat/lib/newChat" ;
1918import { DEFAULT_CHAT_TITLE } from "@/features/chat/lib/sessionTitle" ;
2019import { useAppStartup } from "./hooks/useAppStartup" ;
20+ import { useHomeSessionStateSync } from "./hooks/useHomeSessionStateSync" ;
21+ import { loadStoredHomeSessionId } from "./lib/homeSessionStorage" ;
22+ import { resolveSupportedSessionModelPreference } from "./lib/resolveSupportedSessionModelPreference" ;
2123import { AppShellContent } from "./ui/AppShellContent" ;
22- import { acpPrepareSession } from "@/shared/api/acp" ;
24+ import { acpPrepareSession , acpSetModel } from "@/shared/api/acp" ;
2325import {
2426 clearReplayBuffer ,
2527 getAndDeleteReplayBuffer ,
2628} from "@/features/chat/hooks/replayBuffer" ;
2729import { resolveSessionCwd } from "@/features/projects/lib/sessionCwdSelection" ;
2830import { perfLog } from "@/shared/lib/perfLog" ;
31+ import { useProviderInventoryStore } from "@/features/providers/stores/providerInventoryStore" ;
2932
3033export type AppView =
3134 | "home"
@@ -40,34 +43,6 @@ const SIDEBAR_MIN_WIDTH = 180;
4043const SIDEBAR_MAX_WIDTH = 380 ;
4144const SIDEBAR_SNAP_COLLAPSE_THRESHOLD = 100 ;
4245const SIDEBAR_COLLAPSED_WIDTH = 48 ;
43- const HOME_SESSION_STORAGE_KEY = "goose:home-session-id" ;
44-
45- function loadStoredHomeSessionId ( ) : string | null {
46- if ( typeof window === "undefined" ) {
47- return null ;
48- }
49- try {
50- return window . localStorage . getItem ( HOME_SESSION_STORAGE_KEY ) ;
51- } catch {
52- return null ;
53- }
54- }
55-
56- function persistHomeSessionId ( sessionId : string | null ) : void {
57- if ( typeof window === "undefined" ) {
58- return ;
59- }
60- try {
61- if ( sessionId ) {
62- window . localStorage . setItem ( HOME_SESSION_STORAGE_KEY , sessionId ) ;
63- return ;
64- }
65- window . localStorage . removeItem ( HOME_SESSION_STORAGE_KEY ) ;
66- } catch {
67- // localStorage may be unavailable
68- }
69- }
70-
7146export function AppShell ( { children } : { children ?: React . ReactNode } ) {
7247 const [ sidebarCollapsed , setSidebarCollapsed ] = useState ( false ) ;
7348 const [ sidebarWidth , setSidebarWidth ] = useState ( SIDEBAR_DEFAULT_WIDTH ) ;
@@ -90,6 +65,7 @@ export function AppShell({ children }: { children?: React.ReactNode }) {
9065 const sessionStore = useChatSessionStore ( ) ;
9166 const agentStore = useAgentStore ( ) ;
9267 const projectStore = useProjectStore ( ) ;
68+ const providerInventoryEntries = useProviderInventoryStore ( ( s ) => s . entries ) ;
9369
9470 const pendingProjectCreatedRef = useRef < ( ( projectId : string ) => void ) | null > (
9571 null ,
@@ -173,37 +149,14 @@ export function AppShell({ children }: { children?: React.ReactNode }) {
173149 ? sessionStore . getSession ( homeSessionId )
174150 : undefined ;
175151
176- useEffect ( ( ) => {
177- if (
178- ! homeSessionId ||
179- ! sessionStore . hasHydratedSessions ||
180- sessionStore . isLoading
181- ) {
182- return ;
183- }
184- if (
185- ! homeSession ||
186- homeSession . archivedAt ||
187- hasSessionStarted (
188- homeSession ,
189- chatStore . messagesBySession [ homeSession . id ] ,
190- )
191- ) {
192- setHomeSessionId ( null ) ;
193- }
194- } , [
195- chatStore . messagesBySession ,
196- homeSession ,
197- homeSession ?. archivedAt ,
198- homeSession ?. messageCount ,
152+ useHomeSessionStateSync ( {
199153 homeSessionId,
200- sessionStore . hasHydratedSessions ,
201- sessionStore . isLoading ,
202- ] ) ;
203-
204- useEffect ( ( ) => {
205- persistHomeSessionId ( homeSessionId ) ;
206- } , [ homeSessionId ] ) ;
154+ homeSession,
155+ messagesBySession : chatStore . messagesBySession ,
156+ hasHydratedSessions : sessionStore . hasHydratedSessions ,
157+ isLoading : sessionStore . isLoading ,
158+ setHomeSessionId,
159+ } ) ;
207160
208161 const ensureHomeSession = useCallback ( async ( ) => {
209162 if ( ! sessionStore . hasHydratedSessions || sessionStore . isLoading ) {
@@ -220,6 +173,11 @@ export function AppShell({ children }: { children?: React.ReactNode }) {
220173 ! homeSession . archivedAt &&
221174 homeSession . messageCount === 0
222175 ) {
176+ const sessionModelPreference =
177+ await resolveSupportedSessionModelPreference (
178+ agentStore . selectedProvider ?? "goose" ,
179+ providerInventoryEntries ,
180+ ) ;
223181 const project = homeSession . projectId
224182 ? ( projectStore . projects . find (
225183 ( candidate ) => candidate . id === homeSession . projectId ,
@@ -228,20 +186,42 @@ export function AppShell({ children }: { children?: React.ReactNode }) {
228186 const workingDir = await resolveSessionCwd ( project ) ;
229187 await acpPrepareSession (
230188 homeSession . id ,
231- homeSession . providerId ?? agentStore . selectedProvider ?? "goose" ,
189+ sessionModelPreference . providerId ,
232190 workingDir ,
233191 {
234192 personaId : homeSession . personaId ,
235193 } ,
236194 ) ;
195+ const shouldClearHomeModel =
196+ sessionModelPreference . providerId !== homeSession . providerId ||
197+ ! sessionModelPreference . modelId ;
198+ sessionStore . updateSession ( homeSession . id , {
199+ providerId : sessionModelPreference . providerId ,
200+ modelId : shouldClearHomeModel ? undefined : homeSession . modelId ,
201+ modelName : shouldClearHomeModel ? undefined : homeSession . modelName ,
202+ } ) ;
203+ if ( sessionModelPreference . modelId ) {
204+ await acpSetModel ( homeSession . id , sessionModelPreference . modelId ) ;
205+ sessionStore . updateSession ( homeSession . id , {
206+ modelId : sessionModelPreference . modelId ,
207+ modelName : sessionModelPreference . modelName ,
208+ } ) ;
209+ }
237210 return homeSession ;
238211 }
239212
240213 const workingDir = await resolveSessionCwd ( null ) ;
214+ const sessionModelPreference =
215+ await resolveSupportedSessionModelPreference (
216+ agentStore . selectedProvider ?? "goose" ,
217+ providerInventoryEntries ,
218+ ) ;
241219 const session = await sessionStore . createSession ( {
242220 title : DEFAULT_CHAT_TITLE ,
243- providerId : agentStore . selectedProvider ?? "goose" ,
221+ providerId : sessionModelPreference . providerId ,
244222 workingDir,
223+ modelId : sessionModelPreference . modelId ,
224+ modelName : sessionModelPreference . modelName ,
245225 } ) ;
246226 setHomeSessionId ( session . id ) ;
247227 return session ;
@@ -258,6 +238,7 @@ export function AppShell({ children }: { children?: React.ReactNode }) {
258238 } , [
259239 agentStore . selectedProvider ,
260240 homeSession ,
241+ providerInventoryEntries ,
261242 projectStore . projects ,
262243 sessionStore . hasHydratedSessions ,
263244 sessionStore ,
@@ -282,7 +263,12 @@ export function AppShell({ children }: { children?: React.ReactNode }) {
282263 const agentId = agentStore . activeAgentId ?? undefined ;
283264 const providerId =
284265 project ?. preferredProvider ?? agentStore . selectedProvider ?? "goose" ;
285- const modelId = project ?. preferredModel ?? undefined ;
266+ const sessionModelPreference =
267+ await resolveSupportedSessionModelPreference (
268+ providerId ,
269+ providerInventoryEntries ,
270+ project ?. preferredModel ?? undefined ,
271+ ) ;
286272 const sessionState = useChatSessionStore . getState ( ) ;
287273 const chatState = useChatStore . getState ( ) ;
288274 const existingDraft = findExistingDraft ( {
@@ -311,10 +297,10 @@ export function AppShell({ children }: { children?: React.ReactNode }) {
311297 title,
312298 projectId : project ?. id ,
313299 agentId,
314- providerId,
300+ providerId : sessionModelPreference . providerId ,
315301 workingDir,
316- modelId,
317- modelName : modelId ,
302+ modelId : sessionModelPreference . modelId ,
303+ modelName : sessionModelPreference . modelName ,
318304 } ) ;
319305 sessionStore . setActiveSession ( session . id ) ;
320306 setActiveView ( "chat" ) ;
@@ -328,6 +314,7 @@ export function AppShell({ children }: { children?: React.ReactNode }) {
328314 agentStore . activeAgentId ,
329315 agentStore . selectedProvider ,
330316 chatStore ,
317+ providerInventoryEntries ,
331318 sessionStore ,
332319 ] ,
333320 ) ;
0 commit comments