feat: MetonaAI Desktop 初始项目
- Electron + React + TypeScript 架构 - 三栏布局: Sidebar | ChatPanel | DetailPanel - 9 个内置工具 (文件系统/网络/记忆/命令) - SQLite 持久化 (better-sqlite3) - MUI 暗色/亮色主题系统 - Agent Loop ReAct 状态机引擎 - DeepSeek / Agnes AI / Ollama Provider 适配器 - MCP 协议集成 - 系统托盘 + 全局快捷键 - Tailwind CSS v4 + Tailwind Merge - 修复: Sidebar 缺失 TextField 导入导致黑屏
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* Post-Tool Hooks — 工具执行后钩子
|
||||
*
|
||||
* 用途:结果验证、审计日志写入、记忆触发、错误恢复建议。
|
||||
*
|
||||
* @see docs/生产级通用 AI Agent 智能体桌面应用:完整设计与构建指南.html — 第五章
|
||||
*/
|
||||
|
||||
import type { MetonaToolCall, MetonaToolResult } from '../types';
|
||||
import type { AuditService } from '../../services/audit.service';
|
||||
import type { MemoryManager } from '../memory/manager';
|
||||
|
||||
export interface PostToolHook {
|
||||
afterExecute(toolCall: MetonaToolCall, result: MetonaToolResult, sessionId: string): Promise<void>;
|
||||
}
|
||||
|
||||
/** 审计日志钩子 */
|
||||
export class AuditLogHook implements PostToolHook {
|
||||
constructor(private auditService: AuditService) {}
|
||||
|
||||
async afterExecute(toolCall: MetonaToolCall, result: MetonaToolResult, sessionId: string): Promise<void> {
|
||||
this.auditService.logToolCall({
|
||||
sessionId,
|
||||
iteration: toolCall.iteration,
|
||||
toolName: toolCall.name,
|
||||
args: toolCall.args,
|
||||
outcome: result.success ? 'success' : 'error',
|
||||
result: result.result,
|
||||
error: result.error,
|
||||
durationMs: result.durationMs,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/** 记忆触发钩子 */
|
||||
export class MemoryTriggerHook implements PostToolHook {
|
||||
private memorableTools = ['web_search', 'read_file', 'memory_search'];
|
||||
|
||||
constructor(private memoryManager: MemoryManager) {}
|
||||
|
||||
async afterExecute(toolCall: MetonaToolCall, result: MetonaToolResult, sessionId: string): Promise<void> {
|
||||
if (this.memorableTools.includes(toolCall.name) && result.success) {
|
||||
const content = typeof result.result === 'string' ? result.result : JSON.stringify(result.result);
|
||||
this.memoryManager.store({
|
||||
type: 'episodic',
|
||||
content: `Tool ${toolCall.name} returned: ${content.slice(0, 500)}`,
|
||||
source: 'tool_result',
|
||||
sessionId,
|
||||
importance: 0.6,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user