diff --git a/src/renderer/components/chat-area.ts b/src/renderer/components/chat-area.ts index 50017d4..f80b6ef 100644 --- a/src/renderer/components/chat-area.ts +++ b/src/renderer/components/chat-area.ts @@ -157,6 +157,32 @@ export function appendMessageDOM(msg: ChatMessage, index: number): void { contentHtml = contentHtml.replace('
', ''); } + // ── 工具调用历史记录(可折叠)── + if (msg.role === 'assistant' && msg.toolCalls && msg.toolCalls.length > 0) { + const tcCount = msg.toolCalls.length; + const successCount = msg.toolCalls.filter(t => t.status === 'success').length; + const errorCount = msg.toolCalls.filter(t => t.status === 'error').length; + const summary = msg.toolCalls.map(t => { + const names: Record = { + read_file: 'read_file', write_file: 'write_file', list_directory: 'list_directory', + search_files: 'search_files', run_command: 'run_command', web_fetch: 'web_fetch', + web_search: 'web_search', git: 'git', browser_open: 'browser_open', + memory_search: 'memory_search', memory_add: 'memory_add', spawn_task: 'spawn_task', + }; + return names[t.name] || t.name; + }).slice(0, 5).join(', ') + (tcCount > 5 ? ` +${tcCount - 5}` : ''); + + contentHtml += `
+
+ + 🔧 ${tcCount} 个工具调用(✅${successCount} ❌${errorCount}) +
+
+ ${msg.toolCalls.map(tc => renderToolCallCard(tc)).join('')} +
+
`; + } + const stats: string[] = []; const statClasses: string[] = []; if (msg.timestamp) { stats.push(formatTime(msg.timestamp)); statClasses.push(''); } diff --git a/src/renderer/styles/style.css b/src/renderer/styles/style.css index afa5765..d6af97f 100644 --- a/src/renderer/styles/style.css +++ b/src/renderer/styles/style.css @@ -2092,6 +2092,78 @@ html, body { color: var(--critical); } +/* ── 聊天区域工具调用历史(可折叠)── */ +.tool-calls-history { + margin: 8px 0; + border: 1px solid var(--border-default); + border-radius: var(--radius-md); + overflow: hidden; + background: var(--bg-layer); +} + +.tool-calls-toggle { + display: flex; + align-items: center; + gap: 6px; + padding: 8px 12px; + cursor: pointer; + user-select: none; + font-size: 12px; + color: var(--text-secondary); + transition: background 0.15s; +} + +.tool-calls-toggle:hover { + background: var(--bg-hover); +} + +.tool-calls-chevron { + font-size: 10px; + transition: transform 0.2s; + color: var(--text-tertiary); +} + +.tool-calls-history.expanded .tool-calls-chevron { + transform: rotate(90deg); +} + +.tool-calls-summary { + font-family: var(--font); + font-weight: 500; +} + +.tool-calls-list { + display: none; + padding: 0 8px 8px; +} + +.tool-calls-history.expanded .tool-calls-list { + display: block; +} + +.tool-calls-list .tool-call-card { + margin: 6px 0; + font-size: 12px; +} + +.tool-calls-list .tool-call-header { + padding: 6px 10px; +} + +.tool-calls-list .tool-call-params { + padding: 4px 10px; +} + +.tool-calls-list .tool-call-result { + padding: 6px 10px; + max-height: 200px; +} + +.tool-calls-list .tool-result-content { + font-size: 11px; + max-height: 150px; +} + /* 状态颜色 */ .tool-call-pending { border-color: rgba(212, 160, 60, 0.3);