feat: 重构为 Monorepo 架构并实现 HTTP Server
架构变更: - 采用 pnpm workspaces 实现 Monorepo 结构 - 将现有代码迁移到 packages/core - 新增 packages/server HTTP 服务层 Server 功能: - REST API: 会话管理、工具管理、配置管理 - WebSocket: 实时双向通信支持 - SSE: 服务端事件推送 - Hono + Bun 作为运行时 API 端点: - GET/POST /api/sessions - 会话 CRUD - GET/POST /api/sessions/:id/messages - 消息管理 - GET /api/sessions/:id/events - SSE 事件流 - WS /api/ws/:sessionId - WebSocket 连接 - GET/POST /api/tools - 工具管理 - GET/PUT /api/config - 配置管理
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
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;
|
||||
}
|
||||
Reference in New Issue
Block a user