Files
clawpanel/src/engines/hermes/index.js
晴天 2de05d9ca6 fix: Hermes setup 完成后自动更新引擎状态并跳转仪表盘
- detectHermesStatus 每次调用前清除 check_hermes 缓存,确保拿到最新数据
- setup 向导检测到已安装+Gateway 运行中时,自动调用 engine.detect() 更新 _ready
- refreshHermes 同样清缓存+自动跳转,覆盖安装/配置/启动后的刷新场景
- 修复 sidebar 停留在"初始设置"的问题
2026-04-13 04:28:18 +08:00

127 lines
3.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Hermes Agent 引擎
*/
import { t } from '../../lib/i18n.js'
import { api, invalidate } from '../../lib/tauri-api.js'
// Hermes 状态
let _ready = false
let _running = false
let _listeners = []
let _pollTimer = null
async function detectHermesStatus() {
try {
invalidate('check_hermes')
const info = await api.checkHermes()
_ready = !!info?.installed && !!info?.configExists
_running = !!info?.gatewayRunning
} catch (_) {
_ready = false
_running = false
}
_listeners.forEach(fn => { try { fn({ ready: _ready, running: _running }) } catch (_) {} })
return _ready
}
function startPoll() {
if (_pollTimer) return
_pollTimer = setInterval(detectHermesStatus, 15000)
}
function stopPoll() {
if (_pollTimer) { clearInterval(_pollTimer); _pollTimer = null }
}
export default {
id: 'hermes',
name: 'Hermes Agent',
description: 'Hermes AI Agent with tool-calling capabilities',
icon: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="16" height="16"><path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"/></svg>',
async detect() {
await detectHermesStatus()
return { installed: _ready, ready: _ready }
},
async boot() {
await detectHermesStatus()
startPoll()
},
cleanup() {
stopPoll()
},
getNavItems() {
// 未就绪时显示 Setup 菜单
if (!_ready) {
return [{
section: '',
items: [
{ route: '/h/setup', label: t('sidebar.setup'), icon: 'setup' },
{ route: '/assistant', label: t('sidebar.assistant'), icon: 'assistant' },
]
}, {
section: '',
items: [
{ route: '/settings', label: t('sidebar.settings'), icon: 'settings' },
{ route: '/about', label: t('sidebar.about'), icon: 'about' },
]
}]
}
// 就绪后显示完整菜单
// 仅展示已开发的页面stub 页面暂时隐藏
return [{
section: t('sidebar.sectionMonitor'),
items: [
{ route: '/h/dashboard', label: t('sidebar.dashboard'), icon: 'dashboard' },
{ route: '/assistant', label: t('sidebar.assistant'), icon: 'assistant' },
{ route: '/h/chat', label: t('sidebar.chat'), icon: 'chat' },
]
}, {
section: '',
items: [
{ route: '/settings', label: t('sidebar.settings'), icon: 'settings' },
{ route: '/about', label: t('sidebar.about'), icon: 'about' },
]
}]
},
getRoutes() {
return [
// Hermes 专属页面(/h/ 前缀)— Phase 2 实现
{ path: '/h/setup', loader: () => import('./pages/setup.js') },
{ path: '/h/dashboard', loader: () => import('./pages/dashboard.js') },
{ path: '/h/chat', loader: () => import('./pages/chat.js') },
{ path: '/h/services', loader: () => import('./pages/services.js') },
{ path: '/h/config', loader: () => import('./pages/config.js') },
{ path: '/h/channels', loader: () => import('./pages/channels.js') },
{ path: '/h/cron', loader: () => import('./pages/cron.js') },
{ path: '/h/skills', loader: () => import('./pages/skills.js') },
// 共用页面(引擎无关)
{ path: '/assistant', loader: () => import('../../pages/assistant.js') },
{ path: '/settings', loader: () => import('../../pages/settings.js') },
{ path: '/about', loader: () => import('../../pages/about.js') },
]
},
getSetupRoute() { return '/h/setup' },
getDefaultRoute() { return '/h/dashboard' },
isReady() { return _ready },
isGatewayRunning() { return _running },
isGatewayForeign() { return false },
onStateChange(fn) {
_listeners.push(fn)
return () => { _listeners = _listeners.filter(cb => cb !== fn) }
},
onReadyChange(fn) {
_listeners.push(fn)
return () => { _listeners = _listeners.filter(cb => cb !== fn) }
},
isFeatureAvailable() { return true },
}