From d44d0f61e4026da35c0d1a4acb87ba71ed6cd599 Mon Sep 17 00:00:00 2001 From: Clawd Date: Sun, 1 Mar 2026 08:31:52 -0800 Subject: 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) --- renderer/src/components/settings/ModelSettings.tsx | 94 ++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 renderer/src/components/settings/ModelSettings.tsx (limited to 'renderer/src/components/settings') diff --git a/renderer/src/components/settings/ModelSettings.tsx b/renderer/src/components/settings/ModelSettings.tsx new file mode 100644 index 0000000..ecfc12c --- /dev/null +++ b/renderer/src/components/settings/ModelSettings.tsx @@ -0,0 +1,94 @@ +import React, { useState, useEffect } from "react"; + +const api = window.api; + +export function ModelSettings() { + // null = not yet loaded from DB + const [model, setModel] = useState(null); + const [draft, setDraft] = useState(""); + const [saveStatus, setSaveStatus] = useState<"idle" | "saved">("idle"); + + useEffect(() => { + api.getSettings(["model"]).then((settings) => { + const saved = settings["model"] ?? ""; + setModel(saved); + setDraft(saved); + }); + }, []); + + const handleSave = async () => { + const trimmed = draft.trim(); + if (trimmed) { + await api.setSetting("model", trimmed); + setModel(trimmed); + } else { + await api.deleteSetting("model"); + setModel(""); + } + setSaveStatus("saved"); + setTimeout(() => setSaveStatus("idle"), 1500); + }; + + const handleReset = async () => { + await api.deleteSetting("model"); + setModel(""); + setDraft(""); + setSaveStatus("saved"); + setTimeout(() => setSaveStatus("idle"), 1500); + }; + + if (model === null) { + return ( +
+ Loading... +
+ ); + } + + const isDirty = draft.trim() !== model; + + return ( +
+
Model
+
+ Claude model to use for all phases. Leave blank to use the SDK's + default model. Takes effect on the next message sent in any session. +
+ +
+ { + setDraft(e.target.value); + setSaveStatus("idle"); + }} + onKeyDown={(e) => { + if (e.key === "Enter") handleSave(); + }} + spellCheck={false} + /> +
+ +
+ {model && ( + + )} + + {model && ( + custom + )} +
+
+ ); +} -- cgit v1.2.3