11import type { ReactNode } from "react" ;
2- import React , { createContext , useContext } from "react" ;
2+ import React , { createContext , useContext , useMemo } from "react" ;
33import type { ThinkingLevel } from "@/common/types/thinking" ;
4- import { usePersistedState , readPersistedState } from "@/browser/hooks/usePersistedState" ;
4+ import { usePersistedState } from "@/browser/hooks/usePersistedState" ;
55import { getThinkingLevelByModelKey , getModelKey } from "@/common/constants/storage" ;
66import { getDefaultModel } from "@/browser/hooks/useModelsFromSettings" ;
77import { migrateGatewayModel } from "@/browser/hooks/useGatewayModels" ;
@@ -20,37 +20,37 @@ interface ThinkingProviderProps {
2020}
2121
2222/**
23- * Reads the current model from localStorage for the given scope.
24- * Returns canonical model format (after gateway migration).
23+ * Hook to get the model key for the current scope.
2524 */
26- function getScopedModel ( workspaceId ?: string , projectPath ?: string ) : string {
27- const defaultModel = getDefaultModel ( ) ;
28- // Use workspace-scoped model key if available, otherwise project-scoped
29- const modelKey = workspaceId
25+ function useModelKey ( workspaceId ?: string , projectPath ?: string ) : string | null {
26+ return workspaceId
3027 ? getModelKey ( workspaceId )
3128 : projectPath
3229 ? getModelKey ( `__project__/${ projectPath } ` )
3330 : null ;
34-
35- if ( ! modelKey ) {
36- return defaultModel ;
37- }
38-
39- const rawModel = readPersistedState < string > ( modelKey , defaultModel ) ;
40- // Normalize to canonical format (e.g., strip legacy gateway prefix)
41- return migrateGatewayModel ( rawModel || defaultModel ) ;
4231}
4332
4433export const ThinkingProvider : React . FC < ThinkingProviderProps > = ( {
4534 workspaceId,
4635 projectPath,
4736 children,
4837} ) => {
49- // Read current model from localStorage (non-reactive, re-reads on each render)
50- const modelString = getScopedModel ( workspaceId , projectPath ) ;
51- const key = getThinkingLevelByModelKey ( modelString ) ;
38+ const defaultModel = getDefaultModel ( ) ;
39+ const modelKey = useModelKey ( workspaceId , projectPath ) ;
40+
41+ // Subscribe to model changes so we update thinking level when model changes
42+ const [ rawModel ] = usePersistedState < string > ( modelKey ?? "model:__unused__" , defaultModel , {
43+ listener : true ,
44+ } ) ;
45+
46+ // Derive the thinking level key from the current model
47+ const thinkingKey = useMemo ( ( ) => {
48+ const model = migrateGatewayModel ( rawModel || defaultModel ) ;
49+ return getThinkingLevelByModelKey ( model ) ;
50+ } , [ rawModel , defaultModel ] ) ;
51+
5252 const [ thinkingLevel , setThinkingLevel ] = usePersistedState < ThinkingLevel > (
53- key ,
53+ thinkingKey ,
5454 "off" ,
5555 { listener : true } // Listen for changes from command palette and other sources
5656 ) ;
0 commit comments