/ src / hooks / useMainLoopModel.ts
useMainLoopModel.ts
 1  import { useEffect, useReducer } from 'react'
 2  import { onGrowthBookRefresh } from '../services/analytics/growthbook.js'
 3  import { useAppState } from '../state/AppState.js'
 4  import {
 5    getDefaultMainLoopModelSetting,
 6    type ModelName,
 7    parseUserSpecifiedModel,
 8  } from '../utils/model/model.js'
 9  
10  // The value of the selector is a full model name that can be used directly in
11  // API calls. Use this over getMainLoopModel() when the component needs to
12  // update upon a model config change.
13  export function useMainLoopModel(): ModelName {
14    const mainLoopModel = useAppState(s => s.mainLoopModel)
15    const mainLoopModelForSession = useAppState(s => s.mainLoopModelForSession)
16  
17    // parseUserSpecifiedModel reads tengu_ant_model_override via
18    // _CACHED_MAY_BE_STALE (in resolveAntModel). Until GB init completes,
19    // that's the stale disk cache; after, it's the in-memory remoteEval map.
20    // AppState doesn't change when GB init finishes, so we subscribe to the
21    // refresh signal and force a re-render to re-resolve with fresh values.
22    // Without this, the alias resolution is frozen until something else
23    // happens to re-render the component — the API would sample one model
24    // while /model (which also re-resolves) displays another.
25    const [, forceRerender] = useReducer(x => x + 1, 0)
26    useEffect(() => onGrowthBookRefresh(forceRerender), [])
27  
28    const model = parseUserSpecifiedModel(
29      mainLoopModelForSession ??
30        mainLoopModel ??
31        getDefaultMainLoopModelSetting(),
32    )
33    return model
34  }