diff --git a/src/engines/hermes/pages/chat.js b/src/engines/hermes/pages/chat.js
index a3fcc84..946598e 100644
--- a/src/engines/hermes/pages/chat.js
+++ b/src/engines/hermes/pages/chat.js
@@ -14,7 +14,7 @@
* State lives in `chat-store.js`; this module only does DOM + events.
*/
import { t } from '../../../lib/i18n.js'
-import { api } from '../../../lib/tauri-api.js'
+import { api, invalidate } from '../../../lib/tauri-api.js'
import { toast } from '../../../components/toast.js'
import { showConfirm } from '../../../components/modal.js'
import { getChatStore, getSourceLabel } from '../lib/chat-store.js'
@@ -277,6 +277,8 @@ export function render() {
let showSlash = false
let slashFilter = ''
let gwOnline = false
+ // null = 仍在加载首次 check,先不显示 banner 防首屏闪烁
+ let hermesInstalled = null
let currentModel = ''
const mobileQuery = window.matchMedia('(max-width: 720px)')
@@ -305,11 +307,19 @@ export function render() {
// --- initial session load + model meta ---
store.loadSessions().then(() => draw())
store.loadProfiles().then(() => draw()).catch(() => {})
+ // 强制刷新安装/Gateway 状态缓存,避免用户刚在仪表盘启动 Gateway 后
+ // 进聊天页看到 30s 过期的「未启动」误判。
+ invalidate('check_hermes')
api.checkHermes().then(info => {
+ hermesInstalled = !!info?.installed
gwOnline = !!info?.gatewayRunning
currentModel = info?.model || ''
draw()
- }).catch(() => {})
+ }).catch(() => {
+ hermesInstalled = false
+ gwOnline = false
+ draw()
+ })
// ----------------------------------------------------------- subscription
@@ -676,8 +686,8 @@ export function render() {
${ICONS.stop}
`
: ``}
@@ -732,6 +742,31 @@ export function render() {
`
}
+ // 健康状态 banner:未装/未启动 → 在输入区上方显示一条警告 + 「去仪表盘」按钮。
+ // 首次 fetch 完成前返回空字符串,避免首屏闪烁。
+ function renderHealthBanner() {
+ if (hermesInstalled === null) return ''
+ if (hermesInstalled === false) {
+ return `
+
+ `
+ }
+ if (!gwOnline) {
+ return `
+
+ `
+ }
+ return ''
+ }
+
// ----------------------------------------------------------- draw
function draw() {
@@ -750,6 +785,7 @@ export function render() {
${renderSidebar()}
${renderHeader()}
+ ${renderHealthBanner()}
${renderMessages()}
diff --git a/src/engines/hermes/style/hermes.css b/src/engines/hermes/style/hermes.css
index dd16b40..8ea93ff 100644
--- a/src/engines/hermes/style/hermes.css
+++ b/src/engines/hermes/style/hermes.css
@@ -4577,6 +4577,50 @@ body[data-active-engine="hermes"][data-theme="dark"] {
margin-left: 2px;
}
+/* ---- Health banner (install / gateway readiness) ---- */
+[data-engine="hermes"] .hm-chat-health-banner {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ padding: 10px 28px;
+ font-size: 13px;
+ border-bottom: 1px solid var(--hm-border);
+ flex-shrink: 0;
+}
+[data-engine="hermes"] .hm-chat-health-banner.is-error {
+ background: var(--hm-error-soft);
+ color: var(--hm-error);
+}
+[data-engine="hermes"] .hm-chat-health-banner.is-warn {
+ background: var(--hm-warn-soft);
+ color: var(--hm-warn);
+}
+[data-engine="hermes"] .hm-chat-health-icon {
+ font-size: 14px;
+ line-height: 1;
+ flex-shrink: 0;
+}
+[data-engine="hermes"] .hm-chat-health-msg {
+ flex: 1;
+ line-height: 1.5;
+}
+[data-engine="hermes"] .hm-chat-health-action {
+ flex-shrink: 0;
+ padding: 4px 12px;
+ border-radius: 999px;
+ color: inherit;
+ text-decoration: none;
+ font-weight: 500;
+ font-size: 12px;
+ border: 1px solid currentColor;
+ background: transparent;
+ transition: background 0.16s ease, color 0.16s ease;
+}
+[data-engine="hermes"] .hm-chat-health-action:hover {
+ background: currentColor;
+ color: var(--hm-surface-0);
+}
+
/* ---- Messages area ---- */
[data-engine="hermes"] .hm-chat-messages {
flex: 1;
diff --git a/src/locales/modules/engine.js b/src/locales/modules/engine.js
index c85ae82..b2ae4e9 100644
--- a/src/locales/modules/engine.js
+++ b/src/locales/modules/engine.js
@@ -293,6 +293,18 @@ export default {
// Short labels for the header pill — full sentence lives in the tooltip
chatGatewayOfflineShort: _('离线', 'Offline', '離線'),
chatGatewayOnlineShort: _('在线', 'Online', '線上'),
+ // 健康检查 banner(聊天页顶部)
+ chatHealthInstallMissing: _(
+ '未检测到 Hermes Agent 安装。请在仪表盘完成安装后再开始对话。',
+ 'Hermes Agent is not installed. Please complete installation on the dashboard before chatting.',
+ '未偵測到 Hermes Agent 安裝。請在儀表板完成安裝後再開始對話。'
+ ),
+ chatHealthGatewayDown: _(
+ 'Hermes Gateway 未启动,无法发送消息。请在仪表盘启动 Gateway。',
+ 'Hermes Gateway is not running, messages cannot be sent. Please start the Gateway on the dashboard.',
+ 'Hermes Gateway 未啟動,無法發送訊息。請在儀表板啟動 Gateway。'
+ ),
+ chatHealthGoDashboard: _('去仪表盘', 'Open Dashboard', '去儀表板'),
chatWelcome: _('你好!我是 Hermes Agent,有什么可以帮你的?', 'Hello! I\'m Hermes Agent, how can I help?', '你好!我是 Hermes Agent,有什麼可以幫你的?'),
chatEmptyHint: _('开始一段对话吧', 'Start a conversation', '開始一段對話吧'),
chatEmptyTitle: _('和 Hermes Agent 对话', 'Talk to Hermes Agent', '和 Hermes Agent 對話'),