UNPKG

autosnippet

Version:

Extract code patterns into a knowledge base for AI coding assistants

162 lines (161 loc) 7.55 kB
/** * evolution-tools.ts — Evolution Agent 专用工具 * * 三个提案驱动的决策工具,供 Evolution Agent 在 rescan 时对现有 Recipe 做出明确决策: * - propose_evolution: 附加进化提案(代码已变但知识仍有价值) * - confirm_deprecation: 确认 Recipe 应被废弃(加速 deprecate 流程) * - skip_evolution: 显式跳过进化决策(仍然有效或信息不足) * * @module agent/tools/evolution-tools */ // ────────────────────────────────────────────────────────── // propose_evolution — 为现有 Recipe 附加进化提案 // ────────────────────────────────────────────────────────── export const proposeEvolution = { name: 'propose_evolution', description: '为现有 Recipe 附加进化提案(代码已变化但知识仍有价值时使用,不创建新 Recipe)', parameters: { type: 'object', properties: { recipeId: { type: 'string', description: '目标 Recipe ID' }, type: { type: 'string', enum: ['enhance', 'correction'], description: '提案类型: enhance=增强补充(代码迁移/扩展), correction=纠正错误(代码变更导致描述不准确)', }, description: { type: 'string', description: '描述发生了什么变化、为什么需要更新(人类可读)', }, evidence: { type: 'object', description: '代码验证证据', properties: { sourceStatus: { type: 'string', enum: ['exists', 'moved', 'modified', 'deleted'], description: '源文件状态: exists=存在但内容变化, moved=迁移到新位置, modified=签名/结构变化, deleted=已删除但有替代', }, currentCode: { type: 'string', description: '当前实际代码片段(验证时读到的)', }, newLocation: { type: 'string', description: '新文件路径(仅 moved 时填写)', }, suggestedChanges: { type: 'string', description: '建议对 Recipe 做出的具体更新', }, }, required: ['sourceStatus', 'suggestedChanges'], }, confidence: { type: 'number', description: '置信度 0.0-1.0(基于代码验证的确定程度)', }, }, required: ['recipeId', 'type', 'description', 'evidence', 'confidence'], }, handler: async (params, ctx) => { const { recipeId, type, description, evidence, confidence } = params; // 通过 ProposalRepository 创建提案 const proposalRepo = ctx.container.get('proposalRepository'); if (!proposalRepo) { return { status: 'error', message: 'ProposalRepository not available', recipeId, }; } const proposal = proposalRepo.create({ type, targetRecipeId: recipeId, relatedRecipeIds: [], confidence: Math.max(0, Math.min(1, confidence)), source: 'decay-scan', description, evidence: [ { sourceStatus: evidence.sourceStatus, currentCode: evidence.currentCode, newLocation: evidence.newLocation, suggestedChanges: evidence.suggestedChanges, verifiedBy: 'evolution-agent', verifiedAt: Date.now(), }, ], }); if (!proposal) { return { status: 'error', message: 'Failed to create proposal (target recipe may not exist or duplicate proposal)', recipeId, }; } return { status: 'proposed', proposalId: proposal.id, recipeId, type, expiresAt: proposal.expiresAt, }; }, }; // ────────────────────────────────────────────────────────── // confirm_deprecation — 确认 Recipe 应被废弃 // ────────────────────────────────────────────────────────── export const confirmDeprecation = { name: 'confirm_deprecation', description: '确认一个衰退 Recipe 应被废弃(加速废弃流程,跳过观察窗口)', parameters: { type: 'object', properties: { recipeId: { type: 'string', description: '要废弃的 Recipe ID' }, reason: { type: 'string', description: '废弃原因(人类可读)' }, }, required: ['recipeId', 'reason'], }, handler: async (params, ctx) => { const { recipeId, reason } = params; // 1. 通过 knowledgeService 将 lifecycle 转为 deprecated const knowledgeService = ctx.container.get('knowledgeService'); const result = knowledgeService.deprecate(recipeId, reason, { userId: 'evolution-agent' }); // 2. 尝试解决关联的 deprecate proposal(status → executed) try { const proposalRepo = ctx.container.get('proposalRepository'); if (proposalRepo) { const existing = proposalRepo.findByTarget(recipeId); for (const p of existing) { if (p.type === 'deprecate') { proposalRepo.markExecuted(p.id, `Evolution Agent confirmed deprecation: ${reason}`, 'evolution-agent'); } } } } catch { // ProposalRepository 不可用时静默失败 } return { status: 'deprecated', recipeId, reason, result }; }, }; // ────────────────────────────────────────────────────────── // skip_evolution — 显式跳过进化决策 // ────────────────────────────────────────────────────────── export const skipEvolution = { name: 'skip_evolution', description: '显式跳过一个 Recipe 的进化决策(信息不足或不紧急,交给时限机制处理)', parameters: { type: 'object', properties: { recipeId: { type: 'string', description: '跳过的 Recipe ID' }, reason: { type: 'string', description: '跳过原因' }, }, required: ['recipeId', 'reason'], }, handler: async (params, _ctx) => { // 不修改 proposal 状态,仅记录决策 return { status: 'skipped', recipeId: params.recipeId, reason: params.reason }; }, };