fix: dashboard null crash, chat layout, markdown escaping, gzip, gateway banner delay

feat: hosted agent with auto-stop, context compression, visual sliders
feat: auto-reload gateway after config save (debounced 3s)
style: toast solid bg, chat input enlargement, hosted agent panel CSS
chore: fix dev.ps1 encoding, engagement share text
This commit is contained in:
晴天
2026-03-18 15:02:04 +08:00
parent 08031b9dca
commit 7764a32799
11 changed files with 757 additions and 41 deletions

View File

@@ -25,7 +25,7 @@ function highlightCode(code, lang) {
.replace(/\b(\d+\.?\d*)\b/g, `${S}0${E}$1${S}c${E}`)
.replace(/(\/\/.*$|#.*$)/gm, `${S}1${E}$1${S}c${E}`)
.replace(/(\/\*[\s\S]*?\*\/)/g, `${S}1${E}$1${S}c${E}`)
.replace(/("(?:[^&]|&(?!quot;))*?"|'(?:[^&]|&(?!#x27;))*?'|`[^`]*`)/g,
.replace(/("(?:[^&]|&(?!quot;))*?"|'[^'\n]*'|`[^`]*`)/g,
`${S}2${E}$1${S}c${E}`)
.replace(/\b([A-Z][a-zA-Z0-9_]*)\b/g, (m, w) =>
KEYWORDS.has(w) ? m : `${S}3${E}${w}${S}c${E}`)
@@ -43,7 +43,6 @@ function escapeHtml(str) {
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#x27;')
}
// 预加载 Tauri convertFileSrc
@@ -150,7 +149,8 @@ function inlineFormat(text) {
.replace(/(?<!\w)_(.+?)_(?!\w)/g, '<em>$1</em>')
.replace(/!\[([^\]]*)\]\(([^)]+)\)/g, (_, alt, src) => {
const safeSrc = resolveImageSrc(src.trim())
return `<img src="${safeSrc}" alt="${alt}" class="msg-img" onerror="this.onerror=null;this.style.display='none';this.insertAdjacentHTML('afterend','<span style=\\'color:var(--text-tertiary);font-size:12px\\'>[图片无法加载: ${escapeHtml(src)}]</span>')" />`
const escapedSrc = escapeHtml(src).replace(/\\/g, '&#x5c;')
return `<img src="${safeSrc}" alt="${alt}" class="msg-img" onerror="this.onerror=null;this.style.display='none';this.insertAdjacentHTML('afterend','<span style=\\'color:var(--text-tertiary);font-size:12px\\'>[图片无法加载: ${escapedSrc}]</span>')" />`
})
.replace(/\[([^\]]+)\]\(([^)]+)\)/g, (_, label, url) => {
const safe = /^https?:|^mailto:/i.test(url.trim()) ? url : '#'

View File

@@ -156,6 +156,13 @@ export async function checkBackendHealth() {
}
}
// 配置保存后防抖重载 Gateway3 秒内多次写入只触发一次重载)
let _reloadTimer = null
function _debouncedReloadGateway() {
clearTimeout(_reloadTimer)
_reloadTimer = setTimeout(() => { invoke('reload_gateway').catch(() => {}) }, 3000)
}
// 导出 API
export const api = {
// 服务管理(状态用短缓存,操作不缓存)
@@ -169,7 +176,7 @@ export const api = {
getVersionInfo: () => cachedInvoke('get_version_info', {}, 30000),
getStatusSummary: () => cachedInvoke('get_status_summary', {}, 60000),
readOpenclawConfig: () => cachedInvoke('read_openclaw_config'),
writeOpenclawConfig: (config) => { invalidate('read_openclaw_config'); return invoke('write_openclaw_config', { config }) },
writeOpenclawConfig: (config) => { invalidate('read_openclaw_config'); return invoke('write_openclaw_config', { config }).then(r => { _debouncedReloadGateway(); return r }) },
readMcpConfig: () => cachedInvoke('read_mcp_config'),
writeMcpConfig: (config) => { invalidate('read_mcp_config'); return invoke('write_mcp_config', { config }) },
reloadGateway: () => invoke('reload_gateway'),