- 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 导入导致黑屏
54 lines
1.7 KiB
TypeScript
54 lines
1.7 KiB
TypeScript
/**
|
|
* Pre-Tool Hooks — 工具执行前钩子
|
|
*
|
|
* @see docs/生产级通用 AI Agent 智能体桌面应用:完整设计与构建指南.html — 第五章
|
|
*/
|
|
|
|
import type { MetonaToolCall } from '../types';
|
|
import type { PolicyEngine } from '../sandbox/permissions';
|
|
|
|
export interface HookResult {
|
|
blocked: boolean;
|
|
reason?: string;
|
|
modifiedArgs?: Record<string, unknown>;
|
|
}
|
|
|
|
export interface PreToolHook {
|
|
beforeExecute(toolCall: MetonaToolCall, sessionId: string): Promise<HookResult>;
|
|
}
|
|
|
|
/** 权限校验钩子 — 集成 PolicyEngine */
|
|
export class PermissionCheckHook implements PreToolHook {
|
|
constructor(private policyEngine: PolicyEngine) {}
|
|
|
|
async beforeExecute(toolCall: MetonaToolCall, _sessionId: string): Promise<HookResult> {
|
|
const result = this.policyEngine.checkAuthorization(toolCall.name, toolCall.args);
|
|
if (!result.authorized) {
|
|
return { blocked: true, reason: result.reason };
|
|
}
|
|
return { blocked: false };
|
|
}
|
|
}
|
|
|
|
/** 速率限制钩子 */
|
|
export class RateLimitHook implements PreToolHook {
|
|
private callCounts = new Map<string, { count: number; resetTime: number }>();
|
|
|
|
constructor(private maxCallsPerMinute: number = 20) {}
|
|
|
|
async beforeExecute(toolCall: MetonaToolCall, _sessionId: string): Promise<HookResult> {
|
|
const key = toolCall.name;
|
|
const now = Date.now();
|
|
const entry = this.callCounts.get(key);
|
|
if (entry && entry.resetTime > now) {
|
|
if (entry.count >= this.maxCallsPerMinute) {
|
|
return { blocked: true, reason: `Rate limit exceeded for tool "${toolCall.name}"` };
|
|
}
|
|
entry.count++;
|
|
} else {
|
|
this.callCounts.set(key, { count: 1, resetTime: now + 60_000 });
|
|
}
|
|
return { blocked: false };
|
|
}
|
|
}
|