UNPKG

autosnippet

Version:

Extract code patterns into a knowledge base for AI coding assistants

253 lines (252 loc) 11.9 kB
/** * query.js — 查询类工具 (6) * * 3. search_recipes 搜索知识库 Recipe * 2. search_candidates 搜索候选项 * 3. get_recipe_detail 获取 Recipe 详情 * 4. get_project_stats 获取项目统计 * 5. search_knowledge RAG 语义搜索 * 6. get_related_recipes 知识图谱关联查询 */ // ──────────────────────────────────────────────────────────── // 3. search_recipes // ──────────────────────────────────────────────────────────── export const searchRecipes = { name: 'search_recipes', description: '搜索知识库中的 Recipe(代码片段/最佳实践/架构模式)。支持关键词搜索和按分类/语言/类型筛选。', parameters: { type: 'object', properties: { keyword: { type: 'string', description: '搜索关键词' }, category: { type: 'string', description: '分类过滤 (View/Service/Tool/Model/Network/Storage/UI/Utility)', }, language: { type: 'string', description: '编程语言过滤 (swift/objectivec/typescript 等)' }, knowledgeType: { type: 'string', description: '知识类型过滤 (code-standard/code-pattern/architecture/best-practice 等)', }, limit: { type: 'number', description: '返回数量上限,默认 10' }, }, }, handler: async (params, ctx) => { const { keyword, category, language, knowledgeType, limit = 10 } = params; if (keyword) { // 使用 SearchEngine(BM25 + SQL LIKE 降级),消除与 KnowledgeService.search 的双路径 try { const searchEngine = ctx.container.get('searchEngine'); const result = await searchEngine.search(keyword, { mode: 'keyword', limit, }); const items = result?.items || []; return { items, total: items.length }; } catch { // SearchEngine 不可用,降级到 KnowledgeService const knowledgeService = ctx.container.get('knowledgeService'); return knowledgeService.search(keyword, { page: 1, pageSize: limit }); } } const knowledgeService = ctx.container.get('knowledgeService'); const filters = { lifecycle: 'active' }; if (category) { filters.category = category; } if (language) { filters.language = language; } if (knowledgeType) { filters.knowledgeType = knowledgeType; } return knowledgeService.list(filters, { page: 1, pageSize: limit }); }, }; // ──────────────────────────────────────────────────────────── // 2. search_candidates // ──────────────────────────────────────────────────────────── export const searchCandidates = { name: 'search_candidates', description: '搜索或列出候选项(待审核的代码片段)。支持关键词搜索和按状态/语言/分类筛选。', parameters: { type: 'object', properties: { keyword: { type: 'string', description: '搜索关键词' }, status: { type: 'string', description: '状态过滤 (pending/approved/rejected/applied)' }, language: { type: 'string', description: '编程语言过滤' }, category: { type: 'string', description: '分类过滤' }, limit: { type: 'number', description: '返回数量上限,默认 10' }, }, }, handler: async (params, ctx) => { const { keyword, status, language, category, limit = 10 } = params; if (keyword) { // 使用 SearchEngine(BM25 + SQL LIKE 降级),消除与 KnowledgeService.search 的双路径 try { const searchEngine = ctx.container.get('searchEngine'); const result = await searchEngine.search(keyword, { mode: 'keyword', limit, }); const items = result?.items || []; return { items, total: items.length }; } catch { // SearchEngine 不可用,降级到 KnowledgeService const knowledgeService = ctx.container.get('knowledgeService'); return knowledgeService.search(keyword, { page: 1, pageSize: limit }); } } const knowledgeService = ctx.container.get('knowledgeService'); // V3: status 映射为 lifecycle const filters = {}; if (status) { filters.lifecycle = status; } if (language) { filters.language = language; } if (category) { filters.category = category; } return knowledgeService.list(filters, { page: 1, pageSize: limit }); }, }; // ──────────────────────────────────────────────────────────── // 3. get_recipe_detail // ──────────────────────────────────────────────────────────── export const getRecipeDetail = { name: 'get_recipe_detail', description: '获取单个 Recipe 的完整详情(代码、摘要、使用指南、关系等)。', parameters: { type: 'object', properties: { recipeId: { type: 'string', description: 'Recipe ID' }, }, required: ['recipeId'], }, handler: async (params, ctx) => { const knowledgeService = ctx.container.get('knowledgeService'); try { const entry = await knowledgeService.get(params.recipeId); return typeof entry.toJSON === 'function' ? entry.toJSON() : entry; } catch { return { error: `Knowledge entry '${params.recipeId}' not found` }; } }, }; // ──────────────────────────────────────────────────────────── // 4. get_project_stats // ──────────────────────────────────────────────────────────── export const getProjectStats = { name: 'get_project_stats', description: '获取项目知识库的整体统计:Recipe 数量/分类分布、候选项数量/状态分布、知识图谱节点/边数。', parameters: { type: 'object', properties: {} }, handler: async (_params, ctx) => { const knowledgeService = ctx.container.get('knowledgeService'); const stats = await knowledgeService.getStats(); // 尝试获取知识图谱统计 let graphStats = null; try { const kgService = ctx.container.get('knowledgeGraphService'); graphStats = kgService.getStats(); } catch { /* KG not available */ } return { knowledge: stats, knowledgeGraph: graphStats, }; }, }; // ──────────────────────────────────────────────────────────── // 5. search_knowledge // ──────────────────────────────────────────────────────────── export const searchKnowledge = { name: 'search_knowledge', description: 'RAG 知识库语义搜索 — 结合向量检索和关键词检索,返回与查询最相关的知识片段。', parameters: { type: 'object', properties: { query: { type: 'string', description: '搜索查询' }, topK: { type: 'number', description: '返回结果数,默认 5' }, }, required: ['query'], }, handler: async (params, ctx) => { const { query, topK = 5 } = params; // 优先使用 SearchEngine(有 BM25 + 向量搜索 + Ranking Pipeline) try { const searchEngine = ctx.container.get('searchEngine'); const results = await searchEngine.search(query, { limit: topK, mode: 'auto', rank: true, }); const items = results?.items || (Array.isArray(results) ? results : []); if (items.length > 0) { const enriched = items.slice(0, topK).map((r, i) => ({ ...r, reasoning: { whyRelevant: r.score != null ? `匹配分 ${(r.score * 100).toFixed(0)}%${r.matchType ? ` (${r.matchType})` : ''}` : '语义相关', rank: i + 1, }, })); const topScore = enriched[0]?.score ?? 0; return { source: 'searchEngine', results: enriched, _meta: { confidence: topScore > 0.7 ? 'high' : topScore > 0.3 ? 'medium' : 'low', hint: topScore < 0.3 ? '匹配度较低,结果可能不够相关。建议尝试更具体的查询词。' : null, }, }; } } catch { /* SearchEngine not available */ } return { source: 'none', results: [], message: 'No search engine available', _meta: { confidence: 'none', hint: '搜索引擎不可用。请确认向量索引已构建(rebuild_index)。', }, }; }, }; // ──────────────────────────────────────────────────────────── // 6. get_related_recipes // ──────────────────────────────────────────────────────────── export const getRelatedRecipes = { name: 'get_related_recipes', description: '通过知识图谱查询某个 Recipe 的关联 Recipe(requires/extends/enforces 等关系)。', parameters: { type: 'object', properties: { recipeId: { type: 'string', description: 'Recipe ID' }, relation: { type: 'string', description: '关系类型过滤 (requires/extends/enforces/depends_on/inherits/implements/calls/prerequisite),不传则返回全部关系', }, }, required: ['recipeId'], }, handler: async (params, ctx) => { const kgService = ctx.container.get('knowledgeGraphService'); const { recipeId, relation } = params; if (relation) { const edges = kgService.getRelated(recipeId, 'recipe', relation); return { recipeId, relation, edges }; } const edges = kgService.getEdges(recipeId, 'recipe', 'both'); return { recipeId, ...edges }; }, };