diff --git a/src/engines/hermes/pages/chat.js b/src/engines/hermes/pages/chat.js
index ac8811f..c5e2696 100644
--- a/src/engines/hermes/pages/chat.js
+++ b/src/engines/hermes/pages/chat.js
@@ -780,7 +780,7 @@ export function render() {
if (hermesInstalled === false) {
return `
@@ -789,7 +789,7 @@ export function render() {
if (!gwOnline) {
return `
diff --git a/src/engines/hermes/pages/env-editor.js b/src/engines/hermes/pages/env-editor.js
index b369c19..91b1672 100644
--- a/src/engines/hermes/pages/env-editor.js
+++ b/src/engines/hermes/pages/env-editor.js
@@ -9,6 +9,7 @@
*/
import { api } from '../../../lib/tauri-api.js'
import { toast } from '../../../components/toast.js'
+import { showConfirm } from '../../../components/modal.js'
import { humanizeError } from '../../../lib/humanize-error.js'
// NOTE: i18n keys for this page are not yet wired up in src/locales; using
@@ -254,7 +255,12 @@ export function render() {
}
})
rowEl.querySelector('.env-delete-btn')?.addEventListener('click', async () => {
- if (!confirm(`确定删除 ${row.key} 吗?`)) return
+ const ok = await showConfirm({
+ message: `确定删除 ${row.key} 吗?`,
+ confirmText: '删除',
+ variant: 'danger',
+ })
+ if (!ok) return
try {
await api.hermesEnvDelete(row.key)
rows.splice(idx, 1)
diff --git a/src/engines/hermes/pages/gateways.js b/src/engines/hermes/pages/gateways.js
index 7ef1fbb..476c4bd 100644
--- a/src/engines/hermes/pages/gateways.js
+++ b/src/engines/hermes/pages/gateways.js
@@ -18,6 +18,7 @@ import { api } from '../../../lib/tauri-api.js'
import { toast } from '../../../components/toast.js'
import { showModal, showConfirm } from '../../../components/modal.js'
import { humanizeError } from '../../../lib/humanize-error.js'
+import { svgIcon } from '../lib/svg-icons.js'
function escHtml(s) {
return String(s ?? '').replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"')
@@ -52,7 +53,7 @@ export function render() {
${error ? `${escHtml(error)}
` : ''}
${(!loading && !error && !gateways.length) ? `
-
⚙️
+
${svgIcon('settings', { size: 32 })}
${escHtml(t('engine.hermesGatewaysEmpty'))}
${escHtml(t('engine.hermesGatewaysEmptyHint'))}
` : ''}
@@ -123,7 +124,8 @@ export function render() {
profiles = arr.map(p => (typeof p === 'string' ? p : (p.name || ''))).filter(Boolean)
if (!profiles.includes('default')) profiles.unshift('default')
} catch (e) {
- error = String(e?.message || e)
+ // 保留 Error 对象、给 humanizeError 输出友好提示
+ error = humanizeError(e, t('engine.hermesGatewaysLoadFailed') || 'Load failed')
} finally {
loading = false
draw()
diff --git a/src/engines/hermes/pages/memory.js b/src/engines/hermes/pages/memory.js
index 656e635..45a2f1d 100644
--- a/src/engines/hermes/pages/memory.js
+++ b/src/engines/hermes/pages/memory.js
@@ -12,7 +12,7 @@
import { t } from '../../../lib/i18n.js'
import { api } from '../../../lib/tauri-api.js'
import { toast } from '../../../components/toast.js'
-import { showContentModal } from '../../../components/modal.js'
+import { showContentModal, showConfirm } from '../../../components/modal.js'
import { humanizeError } from '../../../lib/humanize-error.js'
function escHtml(s) {
@@ -135,13 +135,20 @@ export function render() {
const ta = overlay.querySelector('#hm-mem-modal-textarea')
const cancelBtn = overlay.querySelector('[data-action="cancel"]')
const saveBtn = overlay.querySelector('#hm-mem-modal-save')
- const closeWithConfirm = () => {
+ const closeWithConfirm = async () => {
if (!editing) {
overlay.remove()
return
}
const dirty = editing.buffer !== (data[editing.key] || '')
- if (dirty && !confirm(t('engine.memoryUnsaved'))) return
+ if (dirty) {
+ const ok = await showConfirm({
+ message: t('engine.memoryUnsaved'),
+ confirmText: t('common.confirm') || 'OK',
+ variant: 'danger',
+ })
+ if (!ok) return
+ }
editing = null
overlay.remove()
}
@@ -183,10 +190,17 @@ export function render() {
})
}
- function cancelEdit() {
+ async function cancelEdit() {
if (!editing) return
const dirty = editing.buffer !== (data[editing.key] || '')
- if (dirty && !confirm(t('engine.memoryUnsaved'))) return
+ if (dirty) {
+ const ok = await showConfirm({
+ message: t('engine.memoryUnsaved'),
+ confirmText: t('common.confirm') || 'OK',
+ variant: 'danger',
+ })
+ if (!ok) return
+ }
editing = null
document.querySelector('.hm-mem-modal-overlay')?.remove()
draw()
diff --git a/src/engines/hermes/pages/setup.js b/src/engines/hermes/pages/setup.js
index 5ae91cd..a24e660 100644
--- a/src/engines/hermes/pages/setup.js
+++ b/src/engines/hermes/pages/setup.js
@@ -5,6 +5,7 @@
*/
import { t } from '../../../lib/i18n.js'
import { api, invalidate, isTauriRuntime } from '../../../lib/tauri-api.js'
+import { toast } from '../../../components/toast.js'
import { getActiveEngine } from '../../../lib/engine-manager.js'
import {
loadHermesProviders,
@@ -611,7 +612,7 @@ export function render() {
const provider = matched?.id || 'custom'
if (!apiKey) {
- alert('请输入 API Key')
+ toast(t('engine.installCustomEmpty') || '请输入 API Key', 'warning')
return
}
try {
@@ -619,7 +620,8 @@ export function render() {
phase = 'gateway'
await refreshHermes()
} catch (e) {
- alert(`配置保存失败: ${e}`)
+ const msg = String(e?.message || e).replace(/^Error:\s*/, '')
+ toast(`${t('engine.configSaveFailed') || '配置保存失败'}: ${msg}`, 'error')
}
}
@@ -640,7 +642,7 @@ export function render() {
errEl.textContent = msg || t('engine.gatewayStartFailed')
errEl.style.display = 'block'
} else {
- alert(msg || t('engine.gatewayStartFailed'))
+ toast(msg || t('engine.gatewayStartFailed'), 'error')
}
} finally {
gwStarting = false