/** * 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; } export interface PreToolHook { beforeExecute(toolCall: MetonaToolCall, sessionId: string): Promise; } /** 权限校验钩子 — 集成 PolicyEngine */ export class PermissionCheckHook implements PreToolHook { constructor(private policyEngine: PolicyEngine) {} async beforeExecute(toolCall: MetonaToolCall, _sessionId: string): Promise { 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(); constructor(private maxCallsPerMinute: number = 20) {} async beforeExecute(toolCall: MetonaToolCall, _sessionId: string): Promise { 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 }; } }