feat(web): cloud chat-model selector in Settings
Pick which OpenAI model answers on the Cloud backend (gpt-4o / -mini / 4.1 / 4.1-mini / o4-mini, or Default). Persisted in localStorage, sent as `model` in the chat request; respond() applies it only on the cloud backend (local/mi50 keep their fixed models). Reachable from desktop + mobile via Settings. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+9
-2
@@ -113,14 +113,21 @@ def build_messages(session_id: str, user_msg: str) -> list[Message]:
|
|||||||
return messages
|
return messages
|
||||||
|
|
||||||
|
|
||||||
def respond(session_id: str, user_msg: str, backend: Backend = "cloud") -> str:
|
def respond(session_id: str, user_msg: str, backend: Backend = "cloud",
|
||||||
"""Produce Lyra's reply to a single user message and persist the exchange."""
|
model_override: str | None = None) -> str:
|
||||||
|
"""Produce Lyra's reply to a single user message and persist the exchange.
|
||||||
|
|
||||||
|
`model_override` (from the UI's cloud-model picker) only applies on the cloud
|
||||||
|
backend; local/mi50 keep their own configured models.
|
||||||
|
"""
|
||||||
cfg = config.load()
|
cfg = config.load()
|
||||||
# Live chat uses the stronger chat_model on cloud (bulk consolidation keeps
|
# Live chat uses the stronger chat_model on cloud (bulk consolidation keeps
|
||||||
# cloud_model). local/mi50 use their own configured model.
|
# cloud_model). local/mi50 use their own configured model.
|
||||||
model = {"local": cfg.local_model, "cloud": cfg.chat_model, "mi50": cfg.mi50_model}.get(
|
model = {"local": cfg.local_model, "cloud": cfg.chat_model, "mi50": cfg.mi50_model}.get(
|
||||||
backend, backend
|
backend, backend
|
||||||
)
|
)
|
||||||
|
if model_override and backend == "cloud":
|
||||||
|
model = model_override
|
||||||
logbus.log(
|
logbus.log(
|
||||||
"info", "chat request", session=session_id, backend=backend,
|
"info", "chat request", session=session_id, backend=backend,
|
||||||
model=model, embed=cfg.embed_backend,
|
model=model, embed=cfg.embed_backend,
|
||||||
|
|||||||
+2
-1
@@ -92,9 +92,10 @@ def create_app() -> FastAPI:
|
|||||||
backend = _backend_for(body.get("backend"))
|
backend = _backend_for(body.get("backend"))
|
||||||
user_msg = _last_user_message(body.get("messages", []))
|
user_msg = _last_user_message(body.get("messages", []))
|
||||||
|
|
||||||
|
model_override = body.get("model") or None
|
||||||
memory.ensure_session(session_id)
|
memory.ensure_session(session_id)
|
||||||
try:
|
try:
|
||||||
reply = await asyncio.to_thread(chat.respond, session_id, user_msg, backend)
|
reply = await asyncio.to_thread(chat.respond, session_id, user_msg, backend, model_override)
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
logbus.log("error", "chat failed", session=session_id, error=str(exc))
|
logbus.log("error", "chat failed", session=session_id, error=str(exc))
|
||||||
reply = f"[error] {exc}"
|
reply = f"[error] {exc}"
|
||||||
|
|||||||
@@ -143,6 +143,19 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="settings-section" style="margin-top: 24px;">
|
||||||
|
<h4>Chat Model (Cloud)</h4>
|
||||||
|
<p class="settings-desc">Which OpenAI model answers on the Cloud backend. Tools (poker, equity, journaling) require Cloud.</p>
|
||||||
|
<select id="cloudModel">
|
||||||
|
<option value="">Default (gpt-4o)</option>
|
||||||
|
<option value="gpt-4o">gpt-4o — best persona</option>
|
||||||
|
<option value="gpt-4o-mini">gpt-4o-mini — cheap/fast</option>
|
||||||
|
<option value="gpt-4.1">gpt-4.1</option>
|
||||||
|
<option value="gpt-4.1-mini">gpt-4.1-mini</option>
|
||||||
|
<option value="o4-mini">o4-mini — reasoning</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="settings-section" style="margin-top: 24px;">
|
<div class="settings-section" style="margin-top: 24px;">
|
||||||
<h4>Session Management</h4>
|
<h4>Session Management</h4>
|
||||||
<p class="settings-desc">Manage your saved chat sessions:</p>
|
<p class="settings-desc">Manage your saved chat sessions:</p>
|
||||||
@@ -283,6 +296,12 @@
|
|||||||
body.backend = backend;
|
body.backend = backend;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cloud chat-model override (ignored server-side unless backend is cloud)
|
||||||
|
const cloudModel = localStorage.getItem("cloudModel");
|
||||||
|
if (cloudModel) {
|
||||||
|
body.model = cloudModel;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const resp = await fetch(API_URL, {
|
const resp = await fetch(API_URL, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
@@ -571,6 +590,10 @@
|
|||||||
const initialRadio = document.querySelector(`input[name="backend"][value="${savedBackend}"]`);
|
const initialRadio = document.querySelector(`input[name="backend"][value="${savedBackend}"]`);
|
||||||
if (initialRadio) initialRadio.checked = true;
|
if (initialRadio) initialRadio.checked = true;
|
||||||
|
|
||||||
|
// Restore saved cloud-model choice
|
||||||
|
const savedModelSel = document.getElementById("cloudModel");
|
||||||
|
if (savedModelSel) savedModelSel.value = localStorage.getItem("cloudModel") || "";
|
||||||
|
|
||||||
// Session management functions
|
// Session management functions
|
||||||
async function loadSessionList() {
|
async function loadSessionList() {
|
||||||
try {
|
try {
|
||||||
@@ -679,7 +702,11 @@
|
|||||||
const backendValue = selectedRadio ? selectedRadio.value : "local";
|
const backendValue = selectedRadio ? selectedRadio.value : "local";
|
||||||
|
|
||||||
localStorage.setItem("standardModeBackend", backendValue);
|
localStorage.setItem("standardModeBackend", backendValue);
|
||||||
addMessage("system", `Backend changed to: ${backendValue}`);
|
const modelSel = document.getElementById("cloudModel");
|
||||||
|
const modelValue = modelSel ? modelSel.value : "";
|
||||||
|
localStorage.setItem("cloudModel", modelValue);
|
||||||
|
const modelLabel = modelValue || "default (gpt-4o)";
|
||||||
|
addMessage("system", `Backend: ${backendValue} · cloud model: ${modelLabel}`);
|
||||||
hideModal();
|
hideModal();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user