mirror of
https://gitcode.com/JianFeeeee/HomeAgent.git
synced 2026-10-04 00:03:59 +00:00
gui: renderChat 增加防护与日志; log:r 改 invoke; 修 SSE 流式丢失气泡; chat 布局 overflow 修复
This commit is contained in:
@ -364,6 +364,7 @@ function doWebuiLogin(baseUrl, username, password, extraCookie) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ipcMain.on('log:r', (_e, m) => { log('[r] ' + m); });
|
ipcMain.on('log:r', (_e, m) => { log('[r] ' + m); });
|
||||||
|
ipcMain.handle('log:r', (_e, m) => { log('[r] ' + m); return true; });
|
||||||
|
|
||||||
ipcMain.handle('webui:setAuth', async (_, { url, cookie, headers, username, password }) => {
|
ipcMain.handle('webui:setAuth', async (_, { url, cookie, headers, username, password }) => {
|
||||||
const resp = { ok: true, error: '' };
|
const resp = { ok: true, error: '' };
|
||||||
|
|||||||
@ -20,7 +20,7 @@ contextBridge.exposeInMainWorld('homeagent', {
|
|||||||
setAuth: (url, cookie, headers, username, password) => ipcRenderer.invoke('webui:setAuth', { url, cookie, headers, username, password }),
|
setAuth: (url, cookie, headers, username, password) => ipcRenderer.invoke('webui:setAuth', { url, cookie, headers, username, password }),
|
||||||
openLogin: (url, username, password) => ipcRenderer.invoke('webui:openLogin', { url, username, password }),
|
openLogin: (url, username, password) => ipcRenderer.invoke('webui:openLogin', { url, username, password }),
|
||||||
onLoginResult: (cb) => ipcRenderer.on('webui:login-result', (_e, d) => cb(d)),
|
onLoginResult: (cb) => ipcRenderer.on('webui:login-result', (_e, d) => cb(d)),
|
||||||
cacheBg: (src) => ipcRenderer.invoke('bg:cache', { src }),
|
|
||||||
log: (m) => ipcRenderer.send('log:r', m),
|
|
||||||
},
|
},
|
||||||
|
cacheBg: (src) => ipcRenderer.invoke('bg:cache', { src }),
|
||||||
|
log: (m) => ipcRenderer.invoke('log:r', m),
|
||||||
});
|
});
|
||||||
|
|||||||
@ -664,6 +664,18 @@ function renderChat() {
|
|||||||
msgsEl.innerHTML = html;
|
msgsEl.innerHTML = html;
|
||||||
if (state.chatStick !== false) { try { msgsEl.scrollTo({ top: msgsEl.scrollHeight, behavior: 'smooth' }) } catch(e) { msgsEl.scrollTop = msgsEl.scrollHeight } }
|
if (state.chatStick !== false) { try { msgsEl.scrollTo({ top: msgsEl.scrollHeight, behavior: 'smooth' }) } catch(e) { msgsEl.scrollTop = msgsEl.scrollHeight } }
|
||||||
updateChatBadge();
|
updateChatBadge();
|
||||||
|
if (window.homeagent && window.homeagent.log) {
|
||||||
|
window.homeagent.log('render: msgs=' + msgs.length + ' sig=' + sig.slice(0, 60)
|
||||||
|
+ ' last=' + (lastM ? lastM.role + '/C=' + String(lastM.content || '').length + '/T=' + ((lastM.tool_calls || []).length) : 'none')
|
||||||
|
+ ' roles=' + msgs.map(function(m){ return m.role + (m.content ? '#' + String(m.content).length : '') + (m.source ? '@' + m.source : '') + (m.tool_calls && m.tool_calls.length ? 'T' + m.tool_calls.length : '') }).join(','));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function guardedRenderChat() {
|
||||||
|
try { renderChat() } catch (e) {
|
||||||
|
if (window.homeagent && window.homeagent.log) window.homeagent.log('renderChat ERROR: ' + e.message + ' stack=' + (e.stack || '').split('\n').slice(0, 2).join(';'));
|
||||||
|
console.error('renderChat error', e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateChatBadge() {
|
function updateChatBadge() {
|
||||||
@ -673,7 +685,7 @@ function updateChatBadge() {
|
|||||||
badge.style.display = 'none';
|
badge.style.display = 'none';
|
||||||
}
|
}
|
||||||
|
|
||||||
function rerenderChat() { renderChat(); renderChatStarmap(); renderTerminals(); renderCmdHistory() }
|
function rerenderChat() { guardedRenderChat(); renderChatStarmap(); renderTerminals(); renderCmdHistory() }
|
||||||
|
|
||||||
function toggleToolCall(el) {
|
function toggleToolCall(el) {
|
||||||
var d = el.querySelector('.tc-detail');
|
var d = el.querySelector('.tc-detail');
|
||||||
@ -1104,7 +1116,7 @@ function switchChatPanel(tab, el) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function loadChatHistory() {
|
async function loadChatHistory() {
|
||||||
try { var data = await api('/chat/history'); if (data && data.messages) state.messages = data.messages } catch(e) {}
|
try { var data = await api('/chat/history'); if (data && data.messages) { state.messages = data.messages; if (window.homeagent && window.homeagent.log) window.homeagent.log('history: loaded ' + data.messages.length); } else if (window.homeagent && window.homeagent.log) { window.homeagent.log('history: no messages field'); } } catch(e) { if (window.homeagent && window.homeagent.log) window.homeagent.log('history: error ' + e.message) }
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadTerminals() {
|
async function loadTerminals() {
|
||||||
@ -2311,7 +2323,6 @@ async function connectFetchSSE(url) {
|
|||||||
last.content += (p.content || '');
|
last.content += (p.content || '');
|
||||||
rerenderChatIfActive(); return;
|
rerenderChatIfActive(); return;
|
||||||
}
|
}
|
||||||
if (last && last.role === 'assistant' && last._final && !last.source) { return; }
|
|
||||||
state.messages.push({ role: 'assistant', content: p.content || '', _streaming: true, _grow: true });
|
state.messages.push({ role: 'assistant', content: p.content || '', _streaming: true, _grow: true });
|
||||||
rerenderChatIfActive();
|
rerenderChatIfActive();
|
||||||
} else if (type === 'reasoning') {
|
} else if (type === 'reasoning') {
|
||||||
|
|||||||
@ -497,15 +497,15 @@ code { font-family: var(--font-mono); font-size: 12px; color: var(--pre-color) }
|
|||||||
.empty-state p { font-size: 14px; margin-bottom: 8px }
|
.empty-state p { font-size: 14px; margin-bottom: 8px }
|
||||||
|
|
||||||
/* ===== Chat (对话主页) ===== */
|
/* ===== Chat (对话主页) ===== */
|
||||||
.chat-layout { display: flex; flex-direction: column; gap: 12px; height: 100%; min-height: 60vh }
|
.chat-layout { display: flex; flex-direction: column; gap: 12px; height: 100%; min-height: 0 }
|
||||||
.chat-tabs { display: flex; gap: 4px; flex-wrap: wrap; border-bottom: 1px solid var(--border-color); padding-bottom: 10px }
|
.chat-tabs { display: flex; gap: 4px; flex-wrap: wrap; border-bottom: 1px solid var(--border-color); padding-bottom: 10px }
|
||||||
.chat-tabs span { padding: 6px 14px; font-size: 13px; cursor: pointer; color: var(--text-muted); border-radius: var(--radius-pill); border: 1px solid transparent; transition: all .15s }
|
.chat-tabs span { padding: 6px 14px; font-size: 13px; cursor: pointer; color: var(--text-muted); border-radius: var(--radius-pill); border: 1px solid transparent; transition: all .15s }
|
||||||
.chat-tabs span:hover { color: var(--text-primary); background: var(--bg-hover) }
|
.chat-tabs span:hover { color: var(--text-primary); background: var(--bg-hover) }
|
||||||
.chat-tabs span.active { color: var(--accent); background: var(--accent-bg); border-color: color-mix(in srgb, var(--accent) 35%, transparent) }
|
.chat-tabs span.active { color: var(--accent); background: var(--accent-bg); border-color: color-mix(in srgb, var(--accent) 35%, transparent) }
|
||||||
.chat-panel { display: none; flex: 1; min-height: 0; flex-direction: column }
|
.chat-panel { display: none; flex: 1; min-height: 0; flex-direction: column; overflow: hidden }
|
||||||
.chat-panel.active { display: flex }
|
.chat-panel.active { display: flex }
|
||||||
.chat-main { flex: 1; min-width: 0; min-height: 0; display: flex; flex-direction: column }
|
.chat-main { flex: 1; min-width: 0; min-height: 0; display: flex; flex-direction: column }
|
||||||
.chat-main .card { flex: 1; display: flex; flex-direction: column; margin-bottom: 0; min-height: 0; background: transparent; border: none; box-shadow: none; backdrop-filter: none; padding: 0 }
|
.chat-main .card { flex: 1; display: flex; flex-direction: column; margin-bottom: 0; min-height: 0; background: transparent; border: none; box-shadow: none; backdrop-filter: none; padding: 0; overflow: hidden }
|
||||||
.chat-main .card h2 { flex-shrink: 0 }
|
.chat-main .card h2 { flex-shrink: 0 }
|
||||||
.chat-messages { flex: 1; overflow-y: auto; padding: 18px 18px 26px; margin-bottom: 0; display: flex; flex-direction: column; gap: 6px; min-height: 0 }
|
.chat-messages { flex: 1; overflow-y: auto; padding: 18px 18px 26px; margin-bottom: 0; display: flex; flex-direction: column; gap: 6px; min-height: 0 }
|
||||||
.msg { display: flex; gap: 8px; margin-bottom: 2px; align-items: flex-start; max-width: 100% }
|
.msg { display: flex; gap: 8px; margin-bottom: 2px; align-items: flex-start; max-width: 100% }
|
||||||
|
|||||||
Reference in New Issue
Block a user