import type { WebPermissionConfig, WebPermissionContext, PermissionCheckResult, PermissionDecision, PermissionContext, } from '../types.js'; import type { PermissionChecker } from './base.js'; // 默认 Web 权限配置 const DEFAULT_CONFIG: WebPermissionConfig = { default: 'ask', // 默认需要确认 allowAdvancedSearch: true, allowedTopics: [], // 空数组表示允许所有主题 }; /** * Web 搜索权限检查器 * 控制网络搜索操作的权限 */ export class WebPermissionChecker implements PermissionChecker { readonly name = 'web'; private config: WebPermissionConfig; private askCallback?: (ctx: PermissionContext) => Promise; private sessionPermissions = new Map(); constructor() { this.config = { ...DEFAULT_CONFIG }; } /** * 设置权限询问回调 */ setAskCallback(callback: (ctx: PermissionContext) => Promise): void { this.askCallback = callback; } /** * 检查 Web 搜索权限 */ async checkWebPermission(ctx: WebPermissionContext): Promise { const { query, searchDepth, topic } = ctx; // 1. 检查深度搜索权限 if (searchDepth === 'advanced' && !this.config.allowAdvancedSearch) { return { allowed: false, action: 'deny', reason: '不允许深度搜索', }; } // 2. 检查主题限制 if (this.config.allowedTopics.length > 0 && topic) { if (!this.config.allowedTopics.includes(topic)) { return { allowed: false, action: 'deny', reason: `不允许搜索主题: ${topic}`, }; } } // 3. 检查会话级别的临时权限 const sessionKey = `web_search`; const sessionPerm = this.sessionPermissions.get(sessionKey); if (sessionPerm === 'allow') { return { allowed: true, action: 'allow', reason: '本次会话已允许网络搜索', }; } if (sessionPerm === 'deny') { return { allowed: false, action: 'deny', reason: '本次会话已拒绝网络搜索', }; } // 4. 根据默认策略处理 const action = this.config.default; if (action === 'allow') { return { allowed: true, action: 'allow', reason: '默认允许网络搜索', }; } if (action === 'deny') { return { allowed: false, action: 'deny', reason: '默认拒绝网络搜索', }; } // action === 'ask' if (!this.askCallback) { return { allowed: false, action: 'ask', needsConfirmation: true, reason: `搜索: ${query}`, }; } // 调用回调询问用户 const decision = await this.askCallback({ command: `web_search: ${query}`, workdir: process.cwd(), }); if (decision.remember) { this.sessionPermissions.set(sessionKey, decision.allow ? 'allow' : 'deny'); } return { allowed: decision.allow, action: decision.allow ? 'allow' : 'deny', reason: decision.allow ? '用户允许' : '用户拒绝', }; } /** * 实现 PermissionChecker 接口的 check 方法 * 从通用 PermissionContext 中提取 Web 搜索信息 */ async check(ctx: PermissionContext): Promise { // 从 command 中提取搜索查询 const query = ctx.command.replace(/^web_search:\s*/, ''); return this.checkWebPermission({ query }); } /** * 清除会话权限 */ clearSessionPermissions(): void { this.sessionPermissions.clear(); } /** * 获取当前配置 */ getConfig(): WebPermissionConfig { return { ...this.config }; } /** * 更新配置 */ setConfig(config: Partial): void { this.config = { ...this.config, ...config }; } }