diff options
| author | Clawd <ai@clawd.bot> | 2026-03-01 08:31:52 -0800 |
|---|---|---|
| committer | Clawd <ai@clawd.bot> | 2026-03-01 08:31:52 -0800 |
| commit | d44d0f61e4026da35c0d1a4acb87ba71ed6cd599 (patch) | |
| tree | 4d3eb7c1db6d71e25634848078ad1cfde57bad6d /renderer/src/App.tsx | |
| parent | afdf3d57cb7ae4cbf0a519d1b53872f151ecba87 (diff) | |
feat(settings): add configurable model selection
- Add Model settings section with free-text input for model override
- Pass configured model through to SDK query() calls
- Display active model badge in ActionBar next to token usage
- Seed model state from DB on mount, update from system:init events
- Empty/unset value uses SDK default (no breaking change)
Diffstat (limited to 'renderer/src/App.tsx')
| -rw-r--r-- | renderer/src/App.tsx | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/renderer/src/App.tsx b/renderer/src/App.tsx index 36d3a82..b2cd168 100644 --- a/renderer/src/App.tsx +++ b/renderer/src/App.tsx | |||
| @@ -59,6 +59,7 @@ export function App() { | |||
| 59 | }); | 59 | }); |
| 60 | const [error, setError] = useState<string | null>(null); | 60 | const [error, setError] = useState<string | null>(null); |
| 61 | const [showSettings, setShowSettings] = useState(false); | 61 | const [showSettings, setShowSettings] = useState(false); |
| 62 | const [activeModel, setActiveModel] = useState<string | null>(null); | ||
| 62 | 63 | ||
| 63 | const [theme, setTheme] = useState<Theme>( | 64 | const [theme, setTheme] = useState<Theme>( |
| 64 | () => (localStorage.getItem("cf-theme") as Theme) ?? "dark" | 65 | () => (localStorage.getItem("cf-theme") as Theme) ?? "dark" |
| @@ -147,9 +148,14 @@ export function App() { | |||
| 147 | return () => window.removeEventListener("keydown", handleKeyDown); | 148 | return () => window.removeEventListener("keydown", handleKeyDown); |
| 148 | }, [selectedSession, isLoading]); | 149 | }, [selectedSession, isLoading]); |
| 149 | 150 | ||
| 150 | // Load projects on mount | 151 | // Load projects and initial model setting on mount |
| 151 | useEffect(() => { | 152 | useEffect(() => { |
| 152 | api.listProjects().then(setProjects); | 153 | api.listProjects().then(setProjects); |
| 154 | // Seed the model badge from the DB so it shows before any query fires. | ||
| 155 | // system:init will overwrite this with the SDK-resolved name once a query runs. | ||
| 156 | api.getSettings(["model"]).then((s) => { | ||
| 157 | if (s["model"]) setActiveModel(s["model"]); | ||
| 158 | }); | ||
| 153 | }, []); | 159 | }, []); |
| 154 | 160 | ||
| 155 | // Load sessions when project changes | 161 | // Load sessions when project changes |
| @@ -209,6 +215,12 @@ export function App() { | |||
| 209 | ); | 215 | ); |
| 210 | } | 216 | } |
| 211 | 217 | ||
| 218 | // ── Model resolved by SDK ──────────────────────────────────────── | ||
| 219 | // SDKSystemMessage (subtype "init") contains the actual model in use. | ||
| 220 | if (msg.type === "system" && msg.subtype === "init") { | ||
| 221 | setActiveModel((msg as { model?: string }).model ?? null); | ||
| 222 | } | ||
| 223 | |||
| 212 | // ── Result (success or error) ──────────────────────────────────── | 224 | // ── Result (success or error) ──────────────────────────────────── |
| 213 | // Always clear loading state on any result subtype so error results | 225 | // Always clear loading state on any result subtype so error results |
| 214 | // don't leave the UI stuck in the loading/thinking state. | 226 | // don't leave the UI stuck in the loading/thinking state. |
| @@ -498,6 +510,7 @@ export function App() { | |||
| 498 | } | 510 | } |
| 499 | }} | 511 | }} |
| 500 | disabled={!selectedSession} | 512 | disabled={!selectedSession} |
| 513 | modelName={activeModel} | ||
| 501 | /> | 514 | /> |
| 502 | 515 | ||
| 503 | {showSettings && ( | 516 | {showSettings && ( |
