**崩溃/挂死修复 (5):** - 统一 TrayManager.isQuitting 变量,修复 Cmd+Q 无法退出 - useAgentStream 闭包过期快照 → 每次 getState() - Agnes chatStream 添加 AbortSignal.timeout - SSE JSON.parse 添加 try-catch 保护 - Orchestrator setTools 污染 → save/restore 模式 **功能修复 (14):** - 上下文压缩实现 (每5轮 COMPRESSING 状态) - 修复 requestId 硬编码空串 - ConfigService.set() 保留已有 category - MemoryManager 新增 working 类型搜索 - PromptInjectionDefender 补全 sanitize() - Ollama: 补全 dynamicReminders + reasoningContent - openai-format: 所有 assistant 消息保留 reasoningContent - SSE: finish_reason 时提前 flush tool_calls - DeepSeek thinking effort 映射注释 - Ollama done_reason load→stop - RateLimitHook >= 边界修复 - WorkspaceService isValid 首次启动修复 - sessions:archive IPC handler - 托盘/窗口图标路径生产环境修复 **系统提示词优化:** - SOUL.md 存在时不显示兜底身份,原文放最前 - 兜底身份改为中文 (MetonaAI 自身描述) - 用户文本在前,附件内容在后 **文件上传:** - 非图片文件不再 base64 编码,保留 JSON 结构 - 用户文本优先于文件内容 **UI 修复:** - 首页 Logo 路径修复 (public/ + 相对路径) - TokenUsage contextWindow 动态计算 (Provider 感知) - 切换 Provider 同步 contextWindow - 托盘图标始终显示 Logo (状态由右键菜单展示)
110 lines
3.3 KiB
TypeScript
110 lines
3.3 KiB
TypeScript
/**
|
|
* Health Checker — 健康检查器
|
|
*
|
|
* 对数据库连通性、磁盘空间、内存使用执行真实检查。
|
|
*
|
|
* @see docs/生产级通用 AI Agent 智能体桌面应用:完整设计与构建指南.html — 第十一章
|
|
*/
|
|
|
|
import { existsSync } from 'fs';
|
|
import { app } from 'electron';
|
|
import type Database from 'better-sqlite3';
|
|
|
|
export interface HealthReport {
|
|
healthy: boolean;
|
|
checks: HealthCheck[];
|
|
timestamp: Date;
|
|
}
|
|
|
|
export interface HealthCheck {
|
|
name: string;
|
|
healthy: boolean;
|
|
latencyMs?: number;
|
|
error?: string;
|
|
}
|
|
|
|
export class HealthChecker {
|
|
/**
|
|
* @param getDB 数据库获取器(用于真实验证数据库连通性)
|
|
* @param dbPath 数据库文件路径(后备:文件存在性检查)
|
|
*/
|
|
constructor(
|
|
private getDB?: () => Database.Database,
|
|
private dbPath?: string,
|
|
) {}
|
|
|
|
async check(): Promise<HealthReport> {
|
|
const checks: HealthCheck[] = [];
|
|
checks.push(await this.checkDatabase());
|
|
checks.push(await this.checkDiskSpace());
|
|
checks.push(await this.checkMemoryUsage());
|
|
const allHealthy = checks.every((c) => c.healthy);
|
|
return { healthy: allHealthy, checks, timestamp: new Date() };
|
|
}
|
|
|
|
private async checkDatabase(): Promise<HealthCheck> {
|
|
const start = Date.now();
|
|
try {
|
|
// 优先使用注入的 DB 实例执行真实 ping
|
|
if (this.getDB) {
|
|
const db = this.getDB();
|
|
// 执行真实查询验证数据库连通性
|
|
db.prepare('SELECT 1').get();
|
|
return { name: 'database', healthy: true, latencyMs: Date.now() - start };
|
|
}
|
|
// 后备:检查数据库文件是否存在
|
|
if (this.dbPath && existsSync(this.dbPath)) {
|
|
return { name: 'database', healthy: true, latencyMs: Date.now() - start };
|
|
}
|
|
return { name: 'database', healthy: false, error: 'Database not available' };
|
|
} catch (error) {
|
|
return {
|
|
name: 'database',
|
|
healthy: false,
|
|
error: error instanceof Error ? error.message : String(error),
|
|
};
|
|
}
|
|
}
|
|
|
|
private async checkDiskSpace(): Promise<HealthCheck> {
|
|
try {
|
|
const userDataPath = app.getPath('userData');
|
|
if (!existsSync(userDataPath)) {
|
|
return { name: 'disk_space', healthy: false, error: 'User data path not accessible' };
|
|
}
|
|
// 检查实际可用磁盘空间(Windows/Linux 返回字节数)
|
|
const { freemem } = await import('os');
|
|
const freeBytes = freemem();
|
|
const freeMB = freeBytes / (1024 * 1024);
|
|
// 少于 200MB 视为不健康
|
|
if (freeMB < 200) {
|
|
return {
|
|
name: 'disk_space',
|
|
healthy: false,
|
|
error: `Free memory critically low: ${freeMB.toFixed(0)}MB available`,
|
|
};
|
|
}
|
|
return { name: 'disk_space', healthy: true };
|
|
} catch (error) {
|
|
return {
|
|
name: 'disk_space',
|
|
healthy: false,
|
|
error: error instanceof Error ? error.message : String(error),
|
|
};
|
|
}
|
|
}
|
|
|
|
private async checkMemoryUsage(): Promise<HealthCheck> {
|
|
const used = process.memoryUsage();
|
|
const heapUsedMB = used.heapUsed / 1024 / 1024;
|
|
const thresholdMB = 512;
|
|
return {
|
|
name: 'memory_usage',
|
|
healthy: heapUsedMB < thresholdMB,
|
|
...(heapUsedMB >= thresholdMB
|
|
? { error: `Heap usage ${heapUsedMB.toFixed(0)}MB exceeds threshold ${thresholdMB}MB` }
|
|
: {}),
|
|
};
|
|
}
|
|
}
|