aboutsummaryrefslogtreecommitdiffstats
path: root/renderer/src/App.tsx
diff options
context:
space:
mode:
authorClawd <ai@clawd.bot>2026-03-01 08:31:52 -0800
committerClawd <ai@clawd.bot>2026-03-01 08:31:52 -0800
commitd44d0f61e4026da35c0d1a4acb87ba71ed6cd599 (patch)
tree4d3eb7c1db6d71e25634848078ad1cfde57bad6d /renderer/src/App.tsx
parentafdf3d57cb7ae4cbf0a519d1b53872f151ecba87 (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.tsx15
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 && (