diff --git a/.memory/worklog.json b/.memory/worklog.json index be85846..a8df40a 100644 --- a/.memory/worklog.json +++ b/.memory/worklog.json @@ -1,12 +1,5 @@ { "entries": [ - { - "files_changed": 1, - "hash": "a94dc90", - "message": "auto-save 2026-05-10 09:37 (~1)", - "ts": "2026-05-10T09:37:59+08:00", - "type": "commit" - }, { "files_changed": 1, "message": "Codex 会话活跃 · 最近命令:codex · 分支 master · 1 项未提交变更 · 最近提交:auto-save 2026-05-10 09:37 (~1)", @@ -3268,6 +3261,13 @@ "type": "session-heartbeat", "message": "Codex 会话活跃 · 最近命令:codex · 分支 master · 1 项未提交变更 · 最近提交:auto-save 2026-05-11 18:23 (~1)", "files_changed": 1 + }, + { + "ts": "2026-05-11T18:29:22+08:00", + "type": "commit", + "message": "auto-save 2026-05-11 18:29 (~2)", + "hash": "111dbfe", + "files_changed": 2 } ] } diff --git a/RULES.md b/RULES.md index 4d270c6..1640e10 100644 --- a/RULES.md +++ b/RULES.md @@ -14,13 +14,14 @@ - 飞书事件回调(`cli_a97764e101b95be9`):https://hermes.kang-kang.com/feishu/events/cli_a97764e101b95be9 - 飞书主动通知:https://hermes.kang-kang.com/feishu/notify - 飞书机器人列表:https://hermes.kang-kang.com/feishu/apps(展示 App ID / 回调地址,不含 Secret / Token) -- 爱马仕前端「集成 → 飞书集成」可自助添加 / 更新 / 删除飞书机器人;Secret / Token 只写入服务器 `/etc/hermes-feishu-bridge.env` +- 爱马仕前端「网关 → 飞书集成」可自助添加 / 更新 / 删除飞书机器人;Secret / Token 只写入服务器 `/etc/hermes-feishu-bridge.env` - 飞书事件消息回复默认走 Feishu `im/v1/messages/{message_id}/reply`;主动通知仍走 `/feishu/notify` -- 爱马仕前端「仪表盘」同步了上游 Hermes 的快捷入口板块,个人版展示主站、API、飞书机器人列表、文档/解析入口 -- 爱马仕前端「仪表盘」活动热力图已重做为带摘要、月份标尺、紧凑格子和细分色阶的活动卡片 +- 爱马仕前端「工作区」同步了上游 Hermes 的快捷入口板块,个人版展示主站、API、飞书机器人列表、文档/解析入口 +- 爱马仕前端「工作区」活动热力图已重做为带摘要、月份标尺、紧凑格子和细分色阶的活动卡片 - 爱马仕前端「设置 → 连接」可自助维护 API 地址 / API Key 并测试连接;「对话 → 存周报」和「设置 → 周报记录」会在本地保存任务描述、上下文片段和最终周报 -- 爱马仕前端「模型」可维护 AI 模型 Profiles、Provider、Base URL 和 LXC 内 `/opt/hermes-agent/config.yaml` 的 `model` 块,保存后重启 Docker `hermes-agent` -- 爱马仕前端「工具集 → MCP 工具接入」可维护 LXC 内 `/opt/hermes-agent/config.yaml` 的 `mcp_servers` 块,保存后重启 Docker `hermes-agent` +- 爱马仕前端「模型」可维护 AI 模型 Profiles,用于给不同 Agent 绑定不同模型、Provider、Base URL 和服务器端 Key 引用 +- 爱马仕前端「提供商」可维护 LXC 内 `/opt/hermes-agent/config.yaml` 的 `model` 块,保存后重启 Docker `hermes-agent` +- 爱马仕前端「工具 → MCP 工具接入」可维护 LXC 内 `/opt/hermes-agent/config.yaml` 的 `mcp_servers` 块,保存后重启 Docker `hermes-agent` - 飞书、模型、MCP、共享 Agent/Profile 等 `/feishu/*` 管理接口复用网页登录 cookie,并在前端 401 时走 `/_auth/verify` 静默续期 - 当前前端不再启用 Service Worker 静态壳缓存;`sw.js` 仅用于清理旧 `hermes-ui-*` 缓存并注销旧注册 - 文档 / 解析:https://styles.kang-kang.com diff --git a/src/app.js b/src/app.js index 70bbd58..a409d4b 100644 --- a/src/app.js +++ b/src/app.js @@ -110,7 +110,7 @@ document.addEventListener("DOMContentLoaded", () => { safeBoot("绑定导航", bindTabs); safeBoot("绑定对话", bindChat); safeBoot("绑定搜索", bindSearch); - safeBoot("绑定 Skill Studio", bindStudio); + safeBoot("绑定技能库", bindStudio); safeBoot("渲染侧栏", renderSidebar); safeBoot("渲染对话", renderChat); safeBoot("渲染智能体", renderAgents); @@ -223,7 +223,7 @@ function updateModelDisplay(modelValue, providerValue = "") { const statSub = document.getElementById("statModelSub"); const aboutModel = document.getElementById("aboutModelValue"); if (stat) stat.textContent = label; - if (statSub) statSub.textContent = provider ? "Provider: " + provider : "Provider 以设置为准"; + if (statSub) statSub.textContent = provider ? "Provider: " + provider : "Provider 以提供商页为准"; if (aboutModel) aboutModel.textContent = provider ? model + " · " + provider : model; } @@ -626,9 +626,19 @@ function bindTabs() { function restoreActiveTab() { const saved = localStorage.getItem(LS_TAB); if (!saved) return; - if (!document.querySelector(`.side-item[data-tab="${CSS.escape(saved)}"]`)) return; - if (!document.getElementById("tab-" + saved)) return; - switchTab(saved, { persist: false }); + const aliases = { + research: "sessions", + agent: "agents", + dashboard: "office", + studio: "skills", + cron: "schedules", + integrations: "gateway", + }; + let next = aliases[saved] || saved; + if (!document.querySelector(`.side-item[data-tab="${CSS.escape(next)}"]`) || !document.getElementById("tab-" + next)) { + next = "chat"; + } + switchTab(next, { persist: false }); } let _dashboardDirty = true; function markDashboardDirty() { _dashboardDirty = true; } @@ -638,29 +648,35 @@ function switchTab(name, options = {}) { document.querySelectorAll(".side-item").forEach(t => t.classList.toggle("active", t.dataset.tab === name)); document.querySelectorAll(".tab-panel").forEach(p => p.classList.toggle("active", p.id === "tab-" + name)); if (name === "chat") setTimeout(() => document.getElementById("chatInput")?.focus(), 50); - if (name === "studio") { + if (name === "sessions") { + renderSessionsPanel(); + refreshMemory(); + } + if (name === "skills") { renderStudioLibrary(); renderStudioCanvas(); } - if (name === "cron") refreshCron(); - if (name === "memory") refreshMemory(); + if (name === "schedules") refreshCron(); + if (name === "soul") refreshMemory(); if (name === "models") { renderModelProfiles(); refreshUiConfig().catch((error) => { setSharedConfigStatus("共享配置读取失败: " + (error.message || error), true); }); + } + if (name === "providers") { refreshHermesConfig(); } if (name === "tools") { refreshTools(); refreshHermesConfig(); } - if (name === "integrations") refreshFeishuApps(); + if (name === "gateway") refreshFeishuApps(); if (name === "settings") { renderWeeklyReports(); } if (name === "runs") setTimeout(() => document.getElementById("runPrompt")?.focus(), 50); - if (name === "dashboard" && _dashboardDirty) { + if (name === "office" && _dashboardDirty) { // 推迟到下一帧,避免阻塞切换动画 requestAnimationFrame(() => { refreshDashboard(); @@ -2103,7 +2119,7 @@ function renderDashStats() { if (avatarEl) avatarEl.textContent = a.emoji || "🤖"; } else { setText("stTopAgent", "还未使用智能体"); - setText("stTopAgentSub", "去 Agent 面板创建一个开始对话"); + setText("stTopAgentSub", "去档案面板创建一个开始对话"); if (avatarEl) avatarEl.textContent = "—"; } } @@ -2204,7 +2220,7 @@ function renderHeatmap() { // 窗口尺寸变化时重新渲染热力图 window.addEventListener("resize", () => { - if (document.getElementById("tab-dashboard")?.classList.contains("active")) { + if (document.getElementById("tab-office")?.classList.contains("active")) { renderHeatmap(); } }); @@ -4227,22 +4243,62 @@ function handleRunEvent(evt) { addRunEvent(shortType, body, cls); } -// ========== Memory (真实 Hermes SOUL.md + sessions 快照) ========== +// ========== Sessions / Soul / Memory ========== +function renderSessionsPanel() { + const list = document.getElementById("localSessionsList"); + if (!list) return; + const ids = sortedConvoIds(); + list.innerHTML = ""; + if (!ids.length) { + list.innerHTML = '
Hermes 后端 SOUL.md + 会话历史快照 · 每分钟自动同步
通过 SOUL.md 定义 Agent 的人格、语气和长期指令。
Hermes 在不同会话之间沉淀的偏好、事实和可检索上下文。
+配置 LLM Provider、运行模型、Base URL 和服务器端 API Key 引用。
+POST /v1/chat/completions (SSE 流式)GET /hermes-skills/ autoindex JSONGET/POST/PATCH/DELETE /api/jobsGET /memory/SOUL.md + /memory/sessions.json + /memory/sessions/{id}.jsonGET /memory/tools.txthermes tools list 输出每分钟刷新/memory/sessions.json + /memory/sessions/{id}.jsonGET /v1/models + localStorage 聚合GET/PUT /feishu/shared-configGET/PUT /feishu/hermes-config 的 model 块GET /hermes-skills/ autoindex JSONGET /memory/SOUL.mdGET /memory/sessions.json 入口聚合GET /memory/tools.txt + GET/PUT /feishu/hermes-config 的 mcp_servers 块hermes tools list + MCP 配置GET/POST/PATCH/DELETE /api/jobsGET/POST/DELETE /feishu/appsPOST /v1/runs + EventSource /v1/runs/{id}/eventsGET /v1/models + localStorage 聚合不是真的在后端运行编排,而是前端组装复合 system prompt:
Agent.stages.pre → 阶段一 · 前置(理解目标)
Agent.stages.exec → 阶段二 · 执行(工具调用 / 生成)
@@ -928,47 +1026,39 @@ git push # Gitea kangwan/hermes-glass-ui-personal
爱马仕能帮你深度调研、解读文档、调用工具。
+查看本地对话和 Hermes 后端同步的会话快照,可导入继续聊。
+用量、系统状态、快捷入口和实时日志。
+集中查看运行状态、快捷入口、活动热力图和工作节奏。
统一管理飞书、微信、WhatsApp、Telegram、Discord 等外部消息入口。