import type { ToolMetadata, ToolSearchResult } from './types.js'; /** * 分词函数,支持中英文 */ function tokenize(text: string): string[] { return text .toLowerCase() .split(/[\s,,、_\-]+/) .filter((t) => t.length > 0); } /** * 计算工具与查询的匹配分数 */ function calculateScore(queryTerms: string[], tool: ToolMetadata): number { let score = 0; const nameLower = tool.name.toLowerCase(); const descLower = tool.description.toLowerCase(); const keywordsLower = tool.keywords.map((k) => k.toLowerCase()); for (const term of queryTerms) { // 名称精确匹配 (最高分) if (nameLower === term) { score += 10; } // 名称包含匹配 else if (nameLower.includes(term)) { score += 5; } // 关键词精确匹配 if (keywordsLower.includes(term)) { score += 8; } // 关键词包含匹配 else if (keywordsLower.some((k) => k.includes(term) || term.includes(k))) { score += 3; } // 描述包含匹配 if (descLower.includes(term)) { score += 2; } } return score; } /** * 搜索工具 * @param query 搜索查询 * @param allTools 所有工具的元数据 * @param limit 返回结果数量限制 * @returns 匹配的工具列表(按分数排序) */ export function searchTools( query: string, allTools: ToolMetadata[], limit: number = 5 ): ToolSearchResult[] { const queryTerms = tokenize(query); if (queryTerms.length === 0) { return []; } const results = allTools // 只搜索延迟加载的工具 .filter((tool) => tool.deferLoading) .map((tool) => ({ name: tool.name, description: tool.description, category: tool.category, score: calculateScore(queryTerms, tool), })) .filter((r) => r.score > 0) .sort((a, b) => b.score - a.score) .slice(0, limit); return results; }