From 60152fb4438ff5a9bbabc25e7fc5fa7d062f8e4a Mon Sep 17 00:00:00 2001 From: thzxx Date: Tue, 7 Apr 2026 01:42:56 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E6=B8=85=E7=90=86=E6=B8=B2?= =?UTF-8?q?=E6=9F=93=E8=BF=9B=E7=A8=8B=E5=85=A8=E9=83=A8=2058=20=E5=A4=84?= =?UTF-8?q?=20console.log/warn/error?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 所有错误日志统一走 logService(logError/logWarn/logInfo) - 无 logService 的地方补上对应调用 - 纯调试 trace 直接删除(桌面应用看不到 console) - ollama.ts 流式解析错误改为静默跳过(非关键) - 执行日志面板信息量不变 --- src/renderer/api/ollama.ts | 7 +----- src/renderer/components/chat-area.ts | 3 ++- src/renderer/components/input-area.ts | 13 +++++------ src/renderer/components/kb-modal.ts | 12 ++++------ src/renderer/components/model-bar.ts | 2 -- src/renderer/components/settings-modal.ts | 2 -- src/renderer/db/chat-db.ts | 2 -- src/renderer/main.ts | 15 ++++-------- src/renderer/services/agent-engine.ts | 28 +++-------------------- src/renderer/services/memory-manager.ts | 2 -- src/renderer/services/tool-registry.ts | 7 +++--- src/renderer/services/vector-store.ts | 1 - src/renderer/state/state.ts | 2 -- src/renderer/utils/sanitizer.ts | 1 - 14 files changed, 24 insertions(+), 73 deletions(-) diff --git a/src/renderer/api/ollama.ts b/src/renderer/api/ollama.ts index 834727c..8a1b44d 100644 --- a/src/renderer/api/ollama.ts +++ b/src/renderer/api/ollama.ts @@ -89,9 +89,7 @@ export class OllamaAPI { fetchOptions.signal = abortController.signal; } - console.log('[OllamaAPI] chatStream 请求:', `${this.baseUrl}/api/chat`, 'messages:', params.messages.length, 'tools:', params.tools?.length || 0); const response = await this._request('/api/chat', fetchOptions); - console.log('[OllamaAPI] chatStream 响应状态:', response.status); const reader = response.body!.getReader(); const decoder = new TextDecoder(); let buffer = ''; @@ -105,7 +103,6 @@ export class OllamaAPI { while (true) { const { done, value } = await reader.read(); if (done) { - console.log('[OllamaAPI] 流读取结束 (reader done)'); break; } @@ -119,12 +116,10 @@ export class OllamaAPI { const chunk: OllamaStreamChunk = JSON.parse(line); if (onChunk) onChunk(chunk); if (chunk.done) { - console.log('[OllamaAPI] 收到 done:true, eval_count:', chunk.eval_count); reader.cancel(); return; } - } catch (err) { - console.warn('[OllamaAPI] 流式数据解析警告:', (err as Error).message); + } catch { } } } diff --git a/src/renderer/components/chat-area.ts b/src/renderer/components/chat-area.ts index 30ed2aa..d8d76af 100644 --- a/src/renderer/components/chat-area.ts +++ b/src/renderer/components/chat-area.ts @@ -3,6 +3,7 @@ */ import { state, KEYS } from '../state/state.js'; +import { logError } from '../services/log-service.js'; import { marked } from '../utils/marked-config.js'; import { escapeHtml, formatTime } from '../utils/utils.js'; import type { ChatSession, ChatMessage, ToolCallRecord } from '../types.js'; @@ -396,7 +397,7 @@ async function nativeSaveFile(defaultName: string, content: string): Promise { pendingImages.push({ name, base64 }); logInfo(`图片已添加: ${name}`, formatSize(binary.length)); } catch (err) { - console.error('[InputArea] 图片读取失败:', err); + logError('图片读取失败', (err as Error).message); appendSystemMessage(`❌ 读取 ${name} 失败`); } } @@ -201,7 +201,7 @@ async function handleTextFilePaths(paths: string[]): Promise { logInfo(`文件已添加: ${name}`, formatSize(size)); renderFilePreviews(); } catch (err) { - console.error('[InputArea] 文件读取失败:', err); + logError('文件读取失败', (err as Error).message); appendSystemMessage(`❌ 读取 ${name} 失败`); } } @@ -445,7 +445,7 @@ export async function sendMessage(): Promise { appendSystemMessage('🧠 知识库未检索到相关内容,使用通用知识回答', 'rag-status'); } } catch (ragErr) { - console.error('[RAG] 检索失败:', ragErr); + logError('RAG 检索失败', (ragErr as Error).message); appendSystemMessage(`🧠 知识库检索失败: ${(ragErr as Error).message}`, 'rag-status'); } } @@ -520,9 +520,9 @@ export async function sendMessage(): Promise { currentSession2.title ).then(count => { if (count > 0) { - console.log(`[Memory] 自动提取了 ${count} 条记忆`); + logInfo(`自动提取了 ${count} 条记忆`); } - }).catch(err => console.warn('[Memory] 提取失败:', err)); + }).catch(err => logError('记忆提取失败', (err as Error).message)); } } } catch (err) { @@ -728,7 +728,6 @@ async function sendMessageWithAgentLoop(text: string, currentSession: ChatSessio } }); } catch (err) { - console.error('[AgentLoop] 错误:', err); logError('Agent Loop 错误', (err as Error).message); if ((err as Error).name === 'AbortError') { @@ -793,6 +792,6 @@ async function saveCurrentSession(): Promise { try { await db.saveSession(currentSession); } catch (err) { - console.error('[InputArea] 保存会话失败:', err); + logError('保存会话失败', (err as Error).message); } } diff --git a/src/renderer/components/kb-modal.ts b/src/renderer/components/kb-modal.ts index c282947..f51f317 100644 --- a/src/renderer/components/kb-modal.ts +++ b/src/renderer/components/kb-modal.ts @@ -12,7 +12,7 @@ import { formatSize, escapeHtml, truncate } from '../utils/utils.js'; import { showToast } from './toast.js'; import { showConfirm } from './prompt-modal.js'; import { OllamaAPI } from '../api/ollama.js'; -import { logRAG, logError } from '../services/log-service.js'; +import { logRAG, logError, logWarn } from '../services/log-service.js'; import type { VectorCollection, SearchResult } from '../types.js'; let kbModalEl: HTMLElement; @@ -85,7 +85,7 @@ export async function performRagRetrieval(query: string): Promise<{ context: str if (!context) return null; return { context, results, ragPrompt: buildRagSystemPrompt(context) }; } catch (err) { - console.warn('[KB] RAG 检索失败:', err); + logWarn('RAG 检索失败', (err as Error).message); return null; } } @@ -267,10 +267,8 @@ async function handleDocUpload(paths: string[]): Promise { logRAG(`文档上传: ${name}`, `${kbResult.chunkCount} 个分块`); successCount++; } catch (err) { - console.error('[KB] 文档处理失败:', err); - const fileName = filePath.split(/[/\\]/).pop() || filePath; - showToast(`${fileName} 处理失败: ${(err as Error).message}`, 'error'); - logError(`RAG 文档处理失败: ${fileName}`, (err as Error).message); + logError(`RAG 文档处理失败: ${name}`, (err as Error).message); + showToast(`${name} 处理失败: ${(err as Error).message}`, 'error'); failCount++; } } @@ -322,6 +320,6 @@ async function populateEmbedModels(): Promise { select.innerHTML = ''; } } catch (err) { - console.warn('[KB] 加载模型列表失败:', err); + logWarn('加载嵌入模型列表失败', (err as Error).message); } } diff --git a/src/renderer/components/model-bar.ts b/src/renderer/components/model-bar.ts index 737a2ff..7a7d30d 100644 --- a/src/renderer/components/model-bar.ts +++ b/src/renderer/components/model-bar.ts @@ -90,7 +90,6 @@ export async function loadModels(): Promise { filterEmbedModels(data.models); } catch (err) { - console.error('[ModelBar] 加载模型失败:', err); logError('加载模型列表失败', (err as Error).message); modelSelectEl.innerHTML = ''; badgeThinkEl.style.display = 'none'; badgeVisionEl.style.display = 'none'; @@ -169,7 +168,6 @@ async function checkModelCapability(modelName: string): Promise { logDebug(`能力检测: ${modelName}`, capabilities.join(', ')); applyCapability(modelName, caps); } catch (err) { - console.warn('[ModelBar] 获取模型能力失败:', err); logWarn(`能力检测失败: ${modelName}`, (err as Error).message); const fallback = { think: false, vision: false, tools: false, completion: true }; modelCapabilityCache.set(modelName, fallback); diff --git a/src/renderer/components/settings-modal.ts b/src/renderer/components/settings-modal.ts index 8c40c1a..4135f42 100644 --- a/src/renderer/components/settings-modal.ts +++ b/src/renderer/components/settings-modal.ts @@ -232,7 +232,6 @@ async function exportAllSessions(): Promise { showToast(`已导出 ${sessions.length} 个会话(已加密)`, 'success'); logSuccess(`导出完成: ${sessions.length} 个会话`); } catch (err) { - console.error('[Settings] 导出失败:', err); showToast(`导出失败: ${(err as Error).message}`, 'error'); logError('导出失败', (err as Error).message); } @@ -276,7 +275,6 @@ async function importSessions(filePath: string): Promise { showToast(`导入完成:${result.imported} 个会话${result.skipped > 0 ? `,跳过 ${result.skipped} 个` : ''}`, 'success', 4000); logSuccess(`导入完成: ${result.imported} 个, 跳过 ${result.skipped} 个`); } catch (err) { - console.error('[Settings] 导入失败:', err); showToast(`导入失败: ${(err as Error).message}`, 'error'); logError('导入失败', (err as Error).message); } diff --git a/src/renderer/db/chat-db.ts b/src/renderer/db/chat-db.ts index 76a8e7f..b25081e 100644 --- a/src/renderer/db/chat-db.ts +++ b/src/renderer/db/chat-db.ts @@ -19,12 +19,10 @@ export class ChatDB { return new Promise((resolve, reject) => { const request = indexedDB.open(this.dbName, this.version); request.onerror = () => { - console.error('[ChatDB] 数据库打开失败:', request.error); reject(request.error); }; request.onsuccess = () => { this.db = request.result; - console.log('[ChatDB] 数据库已连接'); resolve(); }; request.onupgradeneeded = (event) => { diff --git a/src/renderer/main.ts b/src/renderer/main.ts index 1225d41..2b6efbc 100644 --- a/src/renderer/main.ts +++ b/src/renderer/main.ts @@ -26,7 +26,7 @@ import { setToolEnabled } from './services/tool-registry.js'; import { initToolConfirmModal } from './components/tool-confirm-modal.js'; import { initMemoryPanel } from './components/memory-panel.js'; import { initLogPanel } from './services/log-service.js'; -import { logInfo, logSuccess, logError, logDebug, logInit } from './services/log-service.js'; +import { logInfo, logSuccess, logError, logDebug, logInit, logWarn } from './services/log-service.js'; import type { ChatSession } from './types.js'; function initHelpModal(): void { @@ -51,8 +51,6 @@ function setupDesktopIntegration(): void { logInit('桌面集成...'); - console.log('[Desktop Integration] 初始化桌面集成...'); - bridge.onMenuAction((action: string) => { logInfo(`菜单操作: ${action}`); switch (action) { @@ -87,12 +85,9 @@ function setupDesktopIntegration(): void { } }); - console.log('[Desktop Integration] 桌面集成完成 ✓'); logSuccess('桌面集成完成'); } -console.log('[Metona] TypeScript + Electron v3.0.0 ' + new Date().toISOString()); - function createNewSession(): ChatSession { const selectedModel = (document.querySelector('#modelSelect') as HTMLSelectElement)?.value || ''; const defaultModel = selectedModel || state.get('_defaultModel', ''); @@ -121,7 +116,7 @@ async function startNewSession(): Promise { await api.chat({ model, messages: [], keep_alive: 0 } as any); logDebug('释放旧模型显存'); } catch (e) { - console.warn('[App] 释放显存失败:', e); + logWarn('释放显存失败', (e as Error).message); } } @@ -248,10 +243,8 @@ async function init(): Promise { (document.querySelector('#chatInput') as HTMLElement)?.focus(); - console.log('[App] 初始化完成'); logSuccess('应用初始化完成'); } catch (err) { - console.error('[App] 初始化失败:', err); logError('初始化失败', (err as Error).message); if (!api!) { api = new OllamaAPI(); @@ -290,12 +283,12 @@ function bindGlobalEvents(): void { }); window.addEventListener('error', (e) => { - console.error('[App] 未捕获错误:', e.error || e.message); + logError('未捕获错误', (e.error as Error)?.message || e.message); showToast(`发生错误: ${e.message}`, 'error', 5000); }); window.addEventListener('unhandledrejection', (e) => { - console.error('[App] 未处理 Promise 拒绝:', e.reason); + logError('未处理 Promise 拒绝', (e.reason as Error)?.message || String(e.reason)); const msg = e.reason?.message || String(e.reason); showToast(`操作失败: ${msg}`, 'error', 5000); }); diff --git a/src/renderer/services/agent-engine.ts b/src/renderer/services/agent-engine.ts index 243a55a..aecb1c6 100644 --- a/src/renderer/services/agent-engine.ts +++ b/src/renderer/services/agent-engine.ts @@ -53,7 +53,6 @@ export async function runAgentLoop( // 检查模型是否支持 Tool Calling const modelSupportsTools = state.get('modelSupportsTools', false); if (!modelSupportsTools) { - console.warn(`[AgentEngine] 模型 ${model} 未声明 tools 能力,Agent Loop 可能不稳定`); logWarn(`模型 ${model} 不支持 Tool Calling`, 'Agent Loop 可能不稳定'); } @@ -108,7 +107,6 @@ export async function runAgentLoop( // 全局超时检查 if (Date.now() - loopStartTime > MAX_LOOP_TIME) { - console.warn('[AgentEngine] 达到最大运行时间(5分钟),自动停止'); logWarn('Agent Loop 达到最大运行时间(5分钟),自动停止'); callbacks.onDone(content || '(达到最大运行时间限制)', allToolRecords); return; @@ -122,7 +120,6 @@ export async function runAgentLoop( } logAgentLoop(loopCount, MAX_LOOPS); - console.log(`[AgentEngine] ===== Loop #${loopCount} 开始, messages: ${messages.length}, tools: ${useTools} =====`); let thinking = ''; content = ''; @@ -133,7 +130,6 @@ export async function runAgentLoop( try { // 带超时保护的流式调用 - console.log('[AgentEngine] 开始流式调用, model:', model, 'think:', state.get('thinkEnabled', false)); await Promise.race([ api.chatStream( { @@ -188,7 +184,6 @@ export async function runAgentLoop( ) ]); } catch (err) { - console.error('[AgentEngine] 流式调用错误:', (err as Error).message, 'aborted:', abortController.signal.aborted); if (abortController.signal.aborted) { logInfo('流式调用已中止'); if (content || thinking) { @@ -203,7 +198,6 @@ export async function runAgentLoop( } // 超时错误 — 保留已生成的内容 if ((err as Error).message.includes('超时')) { - console.warn('[AgentEngine] 流式调用超时:', (err as Error).message); logError('流式调用超时(2分钟无数据)', (err as Error).message); if (content || thinking) { messages.push({ @@ -231,7 +225,6 @@ export async function runAgentLoop( messages.push(assistantMsg); logModelResponse(content.length, toolCalls.length); - console.log('[AgentEngine] 流式完成, toolCalls:', toolCalls.length, 'content:', content.length); if (toolCalls.length === 0) { logInfo('无工具调用,Agent Loop 结束'); @@ -239,27 +232,20 @@ export async function runAgentLoop( return; } - console.log('[AgentEngine] 开始处理工具调用:', toolCalls.map(c => c.function.name)); - for (const call of toolCalls) { // 检查是否已中止 if (abortController.signal.aborted) { - console.log('[AgentEngine] Abort 信号已设置,退出'); callbacks.onDone(content, allToolRecords.length > 0 ? allToolRecords : undefined); return; } callbacks.onToolCallStart(call); logToolStart(call.function.name, JSON.stringify(call.function.arguments)); - console.log('[AgentEngine] 工具调用:', call.function.name, call.function.arguments); if (needsConfirmation(call.function.name)) { - console.log('[AgentEngine] 需要确认,弹出确认框:', call.function.name); const confirmed = await callbacks.onConfirmTool(call); - console.log('[AgentEngine] 用户确认结果:', confirmed, 'abort:', abortController.signal.aborted); // 确认后再次检查是否已中止 if (abortController.signal.aborted) { - console.log('[AgentEngine] 确认后 Abort 信号已设置,退出'); callbacks.onDone(content, allToolRecords.length > 0 ? allToolRecords : undefined); return; } @@ -286,16 +272,11 @@ export async function runAgentLoop( try { // 工具执行超时保护 - console.log('[AgentEngine] 执行工具:', call.function.name); logInfo(`执行工具: ${call.function.name}`, JSON.stringify(call.function.arguments)); const result = await Promise.race([ - executeTool(call.function.name, call.function.arguments).then(r => { - console.log('[AgentEngine] executeTool resolve:', call.function.name, r); - return r; - }).catch(err => { - console.error('[AgentEngine] executeTool reject:', call.function.name, err); - return { success: false, error: err?.message || String(err) } as ToolResult; - }), + executeTool(call.function.name, call.function.arguments).catch(err => + ({ success: false, error: err?.message || String(err) }) as ToolResult + ), new Promise((_, reject) => setTimeout(() => reject(new Error('工具执行超时(30秒)')), TOOL_EXEC_TIMEOUT) ) @@ -309,18 +290,15 @@ export async function runAgentLoop( }; allToolRecords.push(record); - console.log('[AgentEngine] 工具结果:', call.function.name, result.success, result); messages.push({ role: 'tool', tool_name: call.function.name, content: JSON.stringify(result) }); - console.log('[AgentEngine] 当前 messages 数量:', messages.length); callbacks.onToolCallResult(call.function.name, result, call); logToolResult(call.function.name, result.success, result.success ? undefined : result.error); } catch (err) { const errorMsg = (err as Error).message; - console.error(`[AgentEngine] 工具执行失败 (${call.function.name}):`, errorMsg); logError(`工具执行失败: ${call.function.name}`, errorMsg); const record: ToolCallRecord = { name: call.function.name, diff --git a/src/renderer/services/memory-manager.ts b/src/renderer/services/memory-manager.ts index b94ad99..43b28e2 100644 --- a/src/renderer/services/memory-manager.ts +++ b/src/renderer/services/memory-manager.ts @@ -41,7 +41,6 @@ export async function initMemoryManager(): Promise { memoryCache = await db.getAllMemories(); state.set('memoryEntries', memoryCache); - console.log(`[Memory] 初始化完成,加载 ${memoryCache.length} 条记忆`); logMemory(`初始化完成, 加载 ${memoryCache.length} 条`); } @@ -323,7 +322,6 @@ ${conversationText.slice(0, 4000)} if (count > 0) logMemory(`自动提取 ${count} 条`); return count; } catch (err) { - console.warn('[Memory] 自动提取失败:', err); logWarn('记忆自动提取失败', (err as Error).message); return 0; } diff --git a/src/renderer/services/tool-registry.ts b/src/renderer/services/tool-registry.ts index 73b8c51..7e3e350 100644 --- a/src/renderer/services/tool-registry.ts +++ b/src/renderer/services/tool-registry.ts @@ -4,7 +4,7 @@ */ import type { ToolDefinition, ToolResult } from '../types.js'; -import { logToolResult, logError } from './log-service.js'; +import { logToolStart, logToolResult, logError } from './log-service.js'; export const TOOL_DEFINITIONS: ToolDefinition[] = [ { @@ -159,7 +159,7 @@ export async function executeTool(toolName: string, args: Record reject(new Error(`工具 ${toolName} IPC 超时(25秒)`)), 25000) ) ]); - console.log('[ToolRegistry] 执行完成:', toolName, result); + logToolResult(toolName, result.success, result.success ? undefined : result.error); return result; } catch (err) { logError(`工具异常: ${toolName}`, (err as Error).message); - console.error('[ToolRegistry] 执行异常:', toolName, err); return { success: false, error: (err as Error).message }; } } diff --git a/src/renderer/services/vector-store.ts b/src/renderer/services/vector-store.ts index c482773..a416220 100644 --- a/src/renderer/services/vector-store.ts +++ b/src/renderer/services/vector-store.ts @@ -230,7 +230,6 @@ export class VectorStore { return saved; } - console.log(`[VectorStore] 构建 IVF 索引: ${colId} (${vectors.length} 向量)`); const index = this._buildIVFIndex(vectors); index.collectionId = colId; index.version = this._indexVersion(vectors); diff --git a/src/renderer/state/state.ts b/src/renderer/state/state.ts index 7bf6348..7a072cf 100644 --- a/src/renderer/state/state.ts +++ b/src/renderer/state/state.ts @@ -65,7 +65,6 @@ class AppState { } const old = this._state[key]; if (old == null || typeof old !== 'object') { - console.warn(`[State] setIn 失败: ${key} 不是对象`); return; } const newRoot = Array.isArray(old) ? [...(old as unknown[])] : { ...(old as Record) }; @@ -111,7 +110,6 @@ class AppState { if (!this._listeners.has(key)) return; for (const cb of this._listeners.get(key)!) { try { cb(value, old); } catch (e) { - console.error(`[State] 监听器错误 (${key}):`, e); } } } diff --git a/src/renderer/utils/sanitizer.ts b/src/renderer/utils/sanitizer.ts index e5fa47c..7d0666d 100644 --- a/src/renderer/utils/sanitizer.ts +++ b/src/renderer/utils/sanitizer.ts @@ -68,7 +68,6 @@ export function sanitize(html: string): string { return root.innerHTML; } catch (e) { - console.warn('[Sanitizer] 净化失败:', e); return html; } }