From 90322e1c4fff96b26bd27456784b5757455da941 Mon Sep 17 00:00:00 2001 From: kang Date: Mon, 11 May 2026 17:10:40 +0800 Subject: [PATCH] auto-save 2026-05-11 17:10 (~3) --- .memory/worklog.json | 26 ++++++++++++------------- server/feishu_bridge.py | 1 + src/app.js | 42 +++++++++++++++++++++++++++++++++++------ 3 files changed, 50 insertions(+), 19 deletions(-) diff --git a/.memory/worklog.json b/.memory/worklog.json index 5ecb7cf..5ecae3f 100644 --- a/.memory/worklog.json +++ b/.memory/worklog.json @@ -1,18 +1,5 @@ { "entries": [ - { - "files_changed": 1, - "message": "Codex 会话活跃 · 最近命令:codex · 分支 master · 1 项未提交变更 · 最近提交:auto-save 2026-05-10 08:27 (~1)", - "ts": "2026-05-10T00:28:58Z", - "type": "session-heartbeat" - }, - { - "files_changed": 1, - "hash": "4466051", - "message": "auto-save 2026-05-10 08:33 (~1)", - "ts": "2026-05-10T08:33:14+08:00", - "type": "commit" - }, { "files_changed": 1, "message": "Codex 会话活跃 · 最近命令:codex · 分支 master · 1 项未提交变更 · 最近提交:auto-save 2026-05-10 08:33 (~1)", @@ -3263,6 +3250,19 @@ "message": "auto-save 2026-05-11 16:59 (~3)", "hash": "7a150ae", "files_changed": 3 + }, + { + "ts": "2026-05-11T17:04:53+08:00", + "type": "commit", + "message": "auto-save 2026-05-11 17:04 (~4)", + "hash": "60c44cf", + "files_changed": 4 + }, + { + "ts": "2026-05-11T09:06:29Z", + "type": "session-heartbeat", + "message": "Codex 会话活跃 · 最近命令:codex · 分支 master · 2 项未提交变更 · 最近提交:auto-save 2026-05-11 17:04 (~4)", + "files_changed": 2 } ] } diff --git a/server/feishu_bridge.py b/server/feishu_bridge.py index 5758084..6660b09 100644 --- a/server/feishu_bridge.py +++ b/server/feishu_bridge.py @@ -625,6 +625,7 @@ def validate_hermes_config_payload(body: dict[str, Any], current: dict[str, Any] or body.get("model_default") or current_model.get("default") or current_model.get("model") + or Config.hermes_model or "" ).strip() provider = str( diff --git a/src/app.js b/src/app.js index 4432a62..48b53f8 100644 --- a/src/app.js +++ b/src/app.js @@ -11,6 +11,7 @@ const LS_CUSTOM_SKILLS = "hermes-ui-custom-skills-v1"; const LS_FLOWS = "hermes-ui-flows-v1"; const LS_TAB = "hermes-ui-active-tab-v1"; const LS_WEEKLY_REPORTS = "hermes-ui-weekly-reports-v1"; +const LS_MODEL_PROFILES = "hermes-ui-model-profiles-v1"; const UI_CONFIG_ENDPOINT = "/feishu/ui-config"; const DEFAULT_MODEL_ID = "google/gemini-3.1-pro-preview"; const LEGACY_DEFAULT_MODEL_ID = "gemini-3-pro-preview"; @@ -113,6 +114,10 @@ document.addEventListener("DOMContentLoaded", () => { safeBoot("渲染侧栏", renderSidebar); safeBoot("渲染对话", renderChat); safeBoot("渲染智能体", renderAgents); + safeBoot("初始化模型 Profiles", () => { + state.modelProfiles = normalizeModelProfiles(state.modelProfiles); + renderModelProfiles(); + }); safeBoot("恢复页面", restoreActiveTab); refreshUiConfig({ migrateLocalAgents: true }).catch((error) => { console.warn("[ui-config] fallback to local config", error); @@ -168,6 +173,12 @@ function loadSettings() { if (sm) sm.checked = state.stream; } } catch (e) {} + try { + const rawProfiles = localStorage.getItem(LS_MODEL_PROFILES); + if (rawProfiles) state.modelProfiles = normalizeModelProfiles(JSON.parse(rawProfiles)); + } catch (e) { + state.modelProfiles = []; + } syncModelPick(state.model); } function saveSettings(options = {}) { @@ -226,6 +237,10 @@ function syncModelPick(modelValue, providerValue = "") { updateModelDisplay(model, providerValue); } +function saveModelProfilesToLS() { + localStorage.setItem(LS_MODEL_PROFILES, JSON.stringify(normalizeModelProfiles(state.modelProfiles))); +} + function makeId(prefix) { return prefix + "_" + Date.now().toString(36) + Math.random().toString(36).slice(2, 6); } @@ -327,6 +342,7 @@ function upsertRuntimeModelProfile(model) { next, ...state.modelProfiles.filter(profile => profile.id !== next.id).map(profile => ({ ...profile, isDefault: false })), ]); + saveModelProfilesToLS(); syncModelOptionsFromProfiles(); renderModelProfiles(); } @@ -594,6 +610,10 @@ function switchTab(name, options = {}) { if (name === "integrations") refreshFeishuApps(); if (name === "settings") { renderWeeklyReports(); + renderModelProfiles(); + refreshUiConfig().catch((error) => { + setSharedConfigStatus("共享配置读取失败: " + (error.message || error), true); + }); refreshHermesConfig(); } if (name === "runs") setTimeout(() => document.getElementById("runPrompt")?.focus(), 50); @@ -976,6 +996,7 @@ async function saveSharedConfig(options = {}) { if (!res.ok || data.code !== 0) throw new Error(data.msg || ("HTTP " + res.status)); const saved = data.config || config; state.modelProfiles = normalizeModelProfiles(saved.modelProfiles); + saveModelProfilesToLS(); state.sharedConfigLoaded = true; state.sharedConfigAvailable = true; syncModelOptionsFromProfiles(); @@ -1007,6 +1028,7 @@ async function refreshUiConfig(options = {}) { const config = await fetchUiConfig(); const profiles = normalizeModelProfiles(config.modelProfiles); state.modelProfiles = profiles; + saveModelProfilesToLS(); state.sharedConfigLoaded = true; state.sharedConfigAvailable = true; syncModelOptionsFromProfiles(); @@ -1052,6 +1074,7 @@ function modelProfileCard(profile) { function renderModelProfiles() { state.modelProfiles = normalizeModelProfiles(state.modelProfiles); + saveModelProfilesToLS(); const list = document.getElementById("modelProfilesList"); if (list) { list.innerHTML = state.modelProfiles.map(modelProfileCard).join(""); @@ -1142,6 +1165,7 @@ async function saveModelProfile() { } state.modelProfiles.push(next); state.modelProfiles = normalizeModelProfiles(state.modelProfiles); + saveModelProfilesToLS(); syncModelOptionsFromProfiles(); renderModelProfiles(); clearModelProfileForm(); @@ -1161,6 +1185,7 @@ async function makeModelProfileDefault(id) { ...item, isDefault: item.id === id, }))); + saveModelProfilesToLS(); syncModelOptionsFromProfiles(); renderModelProfiles(); try { @@ -1193,6 +1218,7 @@ async function deleteModelProfile(id) { if (agent.modelProfileId === id) agent.modelProfileId = ""; } state.modelProfiles = normalizeModelProfiles(state.modelProfiles); + saveModelProfilesToLS(); syncModelOptionsFromProfiles(); renderModelProfiles(); renderAgents(); @@ -1271,14 +1297,15 @@ async function saveMcpConfig() { mcp_servers_yaml: mcpServersYaml, restart: true, }); - const savedModel = saved.model || snapshotModelOrFields(); - if (savedModel.default) syncModelPick(savedModel.default, savedModel.provider || model.provider || ""); + const fallbackModel = snapshotModelOrFields(); + const savedModel = saved.model || fallbackModel; + if (savedModel.default) syncModelPick(savedModel.default, savedModel.provider || fallbackModel.provider || ""); document.getElementById("mcpServersYaml").value = saved.mcp_servers_yaml || ""; _hermesConfigSnapshot = { model: { - default: savedModel.default || model.default, - provider: savedModel.provider || model.provider, - base_url: savedModel.base_url || model.base_url, + default: savedModel.default || fallbackModel.default, + provider: savedModel.provider || fallbackModel.provider, + base_url: savedModel.base_url || fallbackModel.base_url, }, mcp_servers_yaml: saved.mcp_servers_yaml || "", }; @@ -4368,7 +4395,10 @@ function importData(event) { saveWeeklyReports(); } if (data.agents) state.agents = data.agents; - if (Array.isArray(data.modelProfiles)) state.modelProfiles = normalizeModelProfiles(data.modelProfiles); + if (Array.isArray(data.modelProfiles)) { + state.modelProfiles = normalizeModelProfiles(data.modelProfiles); + saveModelProfilesToLS(); + } if (data.customSkills) { state.customSkills = data.customSkills; saveCustomSkillsToLS(); } if (data.flows) { state.flows = data.flows; saveFlowsToLS(); } if (data.settings) {