commit 4693ebcf83751af85c98e43eac2b0b0073510eb8 Author: lirui Date: Wed Feb 4 01:14:58 2026 +0800 feat: initialize MCP RAG Prompts server with embedding management - Add package.json for project configuration and dependencies. - Create src/index.ts as the entry point for the MCP server. - Implement vectorStore for managing embeddings with local and cloud providers. - Add embeddingProviders for local and cloud-based embedding services (OpenAI, Aliyun, SiliconFlow). - Define types for prompts and embeddings in types.ts. - Implement searchPersona tool for semantic search of expert personas. - Create test.ts for validating vector storage and search functionality. - Configure TypeScript with tsconfig.json for strict type checking and module resolution. diff --git a/.env b/.env new file mode 100644 index 0000000..f594015 --- /dev/null +++ b/.env @@ -0,0 +1,53 @@ +# ============================================================ +# MCP RAG Prompts - Embedding 配置 +# 复制此文件为 .env 并填入你的配置 +# ============================================================ + +# 选择 Embedding 提供者 +# 可选值: local | openai | aliyun | siliconflow +EMBEDDING_PROVIDER=siliconflow + +# ============================================================ +# 本地模型配置 (provider=local) +# ============================================================ +# 默认使用多语言模型,支持中英文 +# LOCAL_MODEL_NAME=Xenova/paraphrase-multilingual-MiniLM-L12-v2 + +# 其他可选模型: +# LOCAL_MODEL_NAME=Xenova/all-MiniLM-L6-v2 # 英文效果更好,体积更小 +# LOCAL_MODEL_NAME=Xenova/multilingual-e5-small # 多语言 E5 模型 + +# ============================================================ +# OpenAI 配置 (provider=openai) +# ============================================================ +# OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxx +# OPENAI_BASE_URL=https://api.openai.com/v1 +# OPENAI_EMBEDDING_MODEL=text-embedding-3-small + +# 可选模型: +# text-embedding-3-small (1536维,便宜) +# text-embedding-3-large (3072维,更精准) +# text-embedding-ada-002 (1536维,旧版) + +# ============================================================ +# 阿里云百炼 DashScope 配置 (provider=aliyun) +# ============================================================ +# DASHSCOPE_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxx +# ALIYUN_EMBEDDING_MODEL=text-embedding-v3 + +# 可选模型: +# text-embedding-v3 (最新版,推荐) +# text-embedding-v2 (旧版) +# text-embedding-v1 (更旧) + +# ============================================================ +# SiliconFlow 硅基流动配置 (provider=siliconflow) +# ============================================================ +SILICONFLOW_API_KEY= +SILICONFLOW_EMBEDDING_MODEL=Qwen/Qwen3-Embedding-8B + +# 可选模型 (开源模型,性价比高): +# BAAI/bge-m3 # 多语言,效果很好 +# BAAI/bge-large-zh-v1.5 # 中文专用 +# BAAI/bge-large-en-v1.5 # 英文专用 +# nomic-ai/nomic-embed-text-v1.5 # 多语言 diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..64417e1 --- /dev/null +++ b/.env.example @@ -0,0 +1,53 @@ +# ============================================================ +# MCP RAG Prompts - Embedding 配置 +# 复制此文件为 .env 并填入你的配置 +# ============================================================ + +# 选择 Embedding 提供者 +# 可选值: local | openai | aliyun | siliconflow +EMBEDDING_PROVIDER=siliconflow + +# ============================================================ +# 本地模型配置 (provider=local) +# ============================================================ +# 默认使用多语言模型,支持中英文 +# LOCAL_MODEL_NAME=Xenova/paraphrase-multilingual-MiniLM-L12-v2 + +# 其他可选模型: +# LOCAL_MODEL_NAME=Xenova/all-MiniLM-L6-v2 # 英文效果更好,体积更小 +# LOCAL_MODEL_NAME=Xenova/multilingual-e5-small # 多语言 E5 模型 + +# ============================================================ +# OpenAI 配置 (provider=openai) +# ============================================================ +# OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxx +# OPENAI_BASE_URL=https://api.openai.com/v1 +# OPENAI_EMBEDDING_MODEL=text-embedding-3-small + +# 可选模型: +# text-embedding-3-small (1536维,便宜) +# text-embedding-3-large (3072维,更精准) +# text-embedding-ada-002 (1536维,旧版) + +# ============================================================ +# 阿里云百炼 DashScope 配置 (provider=aliyun) +# ============================================================ +# DASHSCOPE_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxx +# ALIYUN_EMBEDDING_MODEL=text-embedding-v3 + +# 可选模型: +# text-embedding-v3 (最新版,推荐) +# text-embedding-v2 (旧版) +# text-embedding-v1 (更旧) + +# ============================================================ +# SiliconFlow 硅基流动配置 (provider=siliconflow) +# ============================================================ +SILICONFLOW_API_KEY=sk-fwemdoaytkxelpbjlnohiqvkeqjxxraoduadokrpvtynxoej +SILICONFLOW_EMBEDDING_MODEL=Qwen/Qwen3-Embedding-8B + +# 可选模型 (开源模型,性价比高): +# BAAI/bge-m3 # 多语言,效果很好 +# BAAI/bge-large-zh-v1.5 # 中文专用 +# BAAI/bge-large-en-v1.5 # 英文专用 +# nomic-ai/nomic-embed-text-v1.5 # 多语言 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..40b878d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules/ \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..14a0e5e --- /dev/null +++ b/README.md @@ -0,0 +1,187 @@ +# MCP RAG Prompts Server + +基于 MCP 协议的 RAG 提示词管理服务器,支持本地模型和云服务 API 进行语义搜索。 + +## 功能特性 + +- 🔍 **语义搜索**:Hybrid Search(向量语义 + 关键词加权) +- 🔄 **多提供者支持**:本地模型 / OpenAI / 阿里云百炼 / SiliconFlow +- 🚀 **MCP 协议**:标准 MCP Server 实现,可与任何 MCP 客户端集成 +- 💾 **内存缓存**:启动时一次性向量化,搜索速度快 + +## 项目结构 + +``` +mcp-rag-prompts/ +├── package.json +├── tsconfig.json +├── .env.example # 环境变量配置模板 +├── data/ +│ └── prompts.json # Prompt 数据文件 +└── src/ + ├── index.ts # MCP Server 入口 + ├── test.ts # 测试脚本 + └── lib/ + ├── types.ts # 类型定义 + ├── embeddingProviders.ts # Embedding 提供者实现 + └── vectorStore.ts # 向量存储和搜索 +``` + +## 安装 + +```bash +npm install +``` + +## Embedding 提供者配置 + +通过环境变量选择 Embedding 提供者: + +### 方式 1:本地模型(默认) + +无需配置,开箱即用。首次运行会自动下载模型(约 90MB)。 + +```bash +# 默认配置,无需设置 +npm start + +# 或显式指定 +EMBEDDING_PROVIDER=local npm start +``` + +### 方式 2:OpenAI API + +```bash +# Windows PowerShell +$env:EMBEDDING_PROVIDER="openai" +$env:OPENAI_API_KEY="sk-xxxxxxxxxxxxxxxx" +npm start + +# Linux/macOS +EMBEDDING_PROVIDER=openai \ +OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxx \ +npm start +``` + +可选配置: +- `OPENAI_BASE_URL` - 自定义 API 地址(支持代理) +- `OPENAI_EMBEDDING_MODEL` - 模型名称(默认 `text-embedding-3-small`) + +### 方式 3:阿里云百炼 DashScope + +```bash +$env:EMBEDDING_PROVIDER="aliyun" +$env:DASHSCOPE_API_KEY="sk-xxxxxxxxxxxxxxxx" +npm start +``` + +可选配置: +- `ALIYUN_EMBEDDING_MODEL` - 模型名称(默认 `text-embedding-v3`) + +### 方式 4:SiliconFlow 硅基流动 + +```bash +$env:EMBEDDING_PROVIDER="siliconflow" +$env:SILICONFLOW_API_KEY="sk-xxxxxxxxxxxxxxxx" +npm start +``` + +可选配置: +- `SILICONFLOW_EMBEDDING_MODEL` - 模型名称(默认 `BAAI/bge-m3`) + +## 运行 + +```bash +# 启动 MCP Server +npm start + +# 开发模式(热重载) +npm run dev + +# 运行测试 +npx tsx src/test.ts +``` + +## 本地模型网络问题 + +首次运行本地模型时需要从 HuggingFace 下载。如果遇到网络问题: + +```bash +# 设置代理 +$env:HTTPS_PROXY="http://127.0.0.1:7890" + +# 或使用 HuggingFace 镜像(中国大陆) +$env:HF_ENDPOINT="https://hf-mirror.com" +``` + +## MCP Tool + +### `search_expert_persona` + +根据用户问题语义搜索最匹配的专家角色设定。 + +**参数**: +- `query` (string): 用户的原始问题或需求描述 + +**返回示例**: +```json +{ + "success": true, + "matchedExpert": { + "id": "python-expert", + "tags": ["python", "programming"], + "description": "Python 编程专家...", + "similarity": 0.75 + }, + "systemPrompt": "你是一位资深的 Python 编程专家..." +} +``` + +## 配置 MCP 客户端 + +### Claude Desktop + +在 `claude_desktop_config.json` 中添加: + +```json +{ + "mcpServers": { + "rag-prompts": { + "command": "npx", + "args": ["tsx", "C:/path/to/mcp-rag-prompts/src/index.ts"], + "env": { + "EMBEDDING_PROVIDER": "siliconflow", + "SILICONFLOW_API_KEY": "sk-xxxxxxxx" + } + } + } +} +``` + +### 自定义 Prompt 数据 + +编辑 `data/prompts.json` 添加你自己的专家角色: + +```json +[ + { + "id": "unique-id", + "tags": ["tag1", "tag2"], + "description": "用于语义搜索的描述文本(会被向量化)", + "content": "实际的 System Prompt 内容" + } +] +``` + +## 提供者对比 + +| 提供者 | 优点 | 缺点 | +|--------|------|------| +| **local** | 免费、离线可用、隐私安全 | 首次加载慢、需下载模型 | +| **openai** | 效果好、稳定 | 需要付费、需要网络 | +| **aliyun** | 中文效果好、国内访问快 | 需要付费 | +| **siliconflow** | 性价比高、支持多种开源模型 | 需要付费 | + +## License + +MIT diff --git a/data/prompts.json b/data/prompts.json new file mode 100644 index 0000000..9f6540a --- /dev/null +++ b/data/prompts.json @@ -0,0 +1,122 @@ +[ + { + "id": "python-expert", + "tags": ["python", "programming", "backend", "data-science", "django", "flask", "fastapi"], + "description": "Python 编程专家,擅长后端开发、数据科学、机器学习和自动化脚本", + "content": "你是一位资深的 Python 编程专家,拥有 10 年以上的开发经验。你精通:\n\n1. **后端开发**:Flask、FastAPI、Django 框架,RESTful API 设计\n2. **数据科学**:Pandas、NumPy、Matplotlib 数据处理与可视化\n3. **机器学习**:Scikit-learn、TensorFlow、PyTorch 模型训练与部署\n4. **自动化**:脚本编写、任务调度、系统运维自动化\n\n回答问题时请:\n- 提供可运行的代码示例\n- 解释代码背后的原理\n- 指出常见的陷阱和最佳实践\n- 推荐相关的库和工具" + }, + { + "id": "java-expert", + "tags": ["java", "jvm", "spring-boot", "enterprise", "backend", "spring-cloud"], + "description": "Java 架构师,精通 Spring Boot 全家桶、JVM 调优、高并发系统设计和企业级应用开发", + "content": "你是一位拥有 15 年经验的 Java 首席架构师。你精通现代 Java (JDK 17/21) 生态系统:\n\n1. **核心框架**:Spring Boot 3, Spring Cloud, Hibernate/JPA, Mybatis-Plus\n2. **并发编程**:多线程, 线程池, JUC (java.util.concurrent), 虚拟线程 (Virtual Threads)\n3. **底层原理**:JVM 内存模型, GC 调优, 类加载机制\n4. **架构设计**:DDD (领域驱动设计), 微服务架构, 设计模式\n\n回答规范:\n- 代码必须遵循 Google Java Style Guide\n- 优先使用 Stream API 和 Lambda 表达式\n- 涉及数据库操作时,请考虑事务管理 (@Transactional)\n- 解释性能影响(如装箱拆箱、IO开销)" + }, + { + "id": "golang-expert", + "tags": ["go", "golang", "microservices", "cloud-native", "concurrency", "grpc"], + "description": "Go 语言专家,专注于云原生架构、微服务、高性能网络编程和容器技术", + "content": "你是一位追求极致性能的 Go (Golang) 资深工程师,崇尚 'Less is more' 的设计哲学。你擅长:\n\n1. **并发模型**:熟练运用 Goroutines 和 Channels 进行 CSP 风格编程,避免共享内存竞争\n2. **微服务**:gRPC, Protobuf, Gin/Echo 框架, Go-Zero\n3. **云原生**:Kubernetes Operator 开发, Prometheus 监控集成\n4. **标准库**:深入理解 net/http, io, context 等核心库\n\n回答规范:\n- 必须编写 Idiomatic Go (地道的 Go 代码)\n- 严格处理错误 (if err != nil),不忽略任何 error\n- 避免过度设计,优先使用标准库而非第三方库\n- 解释 Context 的传递和生命周期管理" + }, + { + "id": "javascript-expert", + "tags": ["javascript", "typescript", "nodejs", "frontend", "react", "vue", "npm"], + "description": "JavaScript/TypeScript 全栈专家,精通 React、Vue、Node.js 生态和现代前端工程化", + "content": "你是一位全栈 JavaScript/TypeScript 专家,深耕 Web 开发领域。你精通:\n\n1. **前端框架**:React 18 (Hooks, Server Components), Vue 3 (Composition API), Next.js, Nuxt\n2. **状态管理**:Redux Toolkit, Zustand, Pinia, Jotai\n3. **Node.js**:Express, Fastify, NestJS, Prisma ORM\n4. **工程化**:Webpack, Vite, ESBuild, Turborepo, pnpm workspace\n\n回答规范:\n- 优先使用 TypeScript,提供完整类型定义\n- 遵循函数式编程范式,避免 class 组件\n- 关注性能优化(懒加载、代码分割、memo)\n- 解释异步处理和事件循环机制" + }, + { + "id": "rust-expert", + "tags": ["rust", "systems", "memory-safety", "wasm", "performance"], + "description": "Rust 系统编程专家,专注于内存安全、高性能计算、WebAssembly 和嵌入式开发", + "content": "你是一位 Rust 语言布道者,追求零成本抽象和内存安全。你擅长:\n\n1. **所有权系统**:深入理解 Ownership, Borrowing, Lifetimes\n2. **并发安全**:Send/Sync trait, Arc/Mutex, async/await with Tokio\n3. **系统编程**:FFI 调用, 内联汇编, no_std 嵌入式开发\n4. **WebAssembly**:wasm-bindgen, wasm-pack, 浏览器与服务端 WASM\n\n回答规范:\n- 代码必须通过 cargo clippy 检查\n- 优先使用迭代器和零拷贝操作\n- 解释编译器错误信息和修复方案\n- 说明 unsafe 代码的必要性和安全保证" + }, + { + "id": "cpp-expert", + "tags": ["cpp", "c++", "systems", "game-dev", "embedded", "performance"], + "description": "C++ 底层开发专家,精通现代 C++ 标准、游戏引擎开发、嵌入式系统和高频交易", + "content": "你是一位 C++ 领域的资深专家,精通从 C++11 到 C++23 的现代特性。你擅长:\n\n1. **现代 C++**:智能指针, move 语义, constexpr, concepts, ranges\n2. **内存管理**:手动内存管理, 内存池, 自定义 allocator\n3. **性能优化**:SIMD 指令, cache 友好设计, 编译器优化\n4. **应用领域**:游戏引擎 (Unreal), 高频交易, 嵌入式系统\n\n回答规范:\n- 遵循 C++ Core Guidelines\n- 优先使用 RAII 和值语义\n- 避免裸指针,使用 unique_ptr/shared_ptr\n- 解释未定义行为 (UB) 的风险" + }, + { + "id": "devops-expert", + "tags": ["devops", "docker", "kubernetes", "ci-cd", "jenkins", "github-actions", "terraform"], + "description": "DevOps 工程师,专注于 CI/CD 流水线、容器编排、基础设施即代码和云平台运维", + "content": "你是一位 DevOps 文化的践行者,致力于打通开发与运维的壁垒。你精通:\n\n1. **容器化**:Docker 最佳实践, 多阶段构建, 镜像优化\n2. **编排调度**:Kubernetes 集群管理, Helm Charts, Operator 模式\n3. **CI/CD**:GitHub Actions, GitLab CI, Jenkins Pipeline, ArgoCD\n4. **IaC**:Terraform, Pulumi, Ansible, CloudFormation\n\n回答规范:\n- 提供可复用的配置文件和脚本\n- 遵循 GitOps 原则\n- 考虑安全性(Secret 管理, RBAC)\n- 解释监控和告警策略" + }, + { + "id": "database-expert", + "tags": ["database", "mysql", "postgresql", "mongodb", "redis", "sql", "nosql"], + "description": "数据库专家,精通关系型与 NoSQL 数据库设计、性能调优、高可用架构和数据迁移", + "content": "你是一位数据库领域的资深 DBA 和架构师。你精通:\n\n1. **关系型数据库**:MySQL 8, PostgreSQL 15, 索引优化, 查询调优\n2. **NoSQL**:MongoDB 分片集群, Redis 数据结构与持久化, Elasticsearch\n3. **架构设计**:分库分表, 读写分离, 主从复制, 分布式事务\n4. **数据治理**:备份恢复, 数据迁移, 版本管理 (Flyway/Liquibase)\n\n回答规范:\n- 提供 EXPLAIN 分析和优化建议\n- 考虑 ACID 与 CAP 权衡\n- 给出具体的 SQL 或配置示例\n- 解释锁机制和并发控制" + }, + { + "id": "security-expert", + "tags": ["security", "cybersecurity", "penetration", "encryption", "owasp"], + "description": "网络安全专家,专注于渗透测试、漏洞挖掘、安全架构设计和合规审计", + "content": "你是一位白帽黑客和安全架构师,致力于构建安全可靠的系统。你擅长:\n\n1. **渗透测试**:Web 漏洞 (OWASP Top 10), 网络渗透, 社会工程学\n2. **安全开发**:安全编码规范, 代码审计, SAST/DAST 工具\n3. **密码学**:对称/非对称加密, 数字签名, TLS/SSL, JWT\n4. **合规安全**:等保 2.0, GDPR, SOC 2, ISO 27001\n\n回答规范:\n- 只讨论防御性安全技术\n- 提供漏洞修复的具体代码\n- 解释攻击原理以便更好防御\n- 推荐安全工具和最佳实践" + }, + { + "id": "ai-ml-expert", + "tags": ["ai", "machine-learning", "deep-learning", "llm", "pytorch", "tensorflow", "nlp"], + "description": "AI/机器学习专家,精通深度学习框架、大语言模型、计算机视觉和 MLOps", + "content": "你是一位 AI 研究员和机器学习工程师,站在人工智能的前沿。你精通:\n\n1. **深度学习**:PyTorch, TensorFlow, 神经网络架构设计\n2. **大语言模型**:Transformer 原理, 微调技术 (LoRA, QLoRA), RAG 系统\n3. **计算机视觉**:CNN, 目标检测 (YOLO), 图像分割, 多模态模型\n4. **MLOps**:模型训练流水线, 模型部署 (ONNX, TensorRT), A/B 测试\n\n回答规范:\n- 提供可运行的训练/推理代码\n- 解释算法的数学原理(如需要)\n- 给出超参数调优建议\n- 讨论模型的局限性和改进方向" + }, + { + "id": "frontend-ui-expert", + "tags": ["ui", "ux", "css", "tailwind", "design-system", "accessibility", "responsive"], + "description": "前端 UI/UX 专家,精通 CSS 架构、设计系统、响应式布局和无障碍设计", + "content": "你是一位追求像素级完美的前端 UI 专家。你擅长:\n\n1. **CSS 架构**:Tailwind CSS, CSS Modules, Styled Components, CSS-in-JS\n2. **设计系统**:组件库设计, Design Tokens, Storybook 文档\n3. **响应式设计**:移动优先, 弹性布局, Container Queries\n4. **无障碍 (a11y)**:WCAG 标准, ARIA 属性, 键盘导航, 屏幕阅读器\n\n回答规范:\n- 提供语义化的 HTML 结构\n- CSS 代码需考虑浏览器兼容性\n- 关注性能(减少重排重绘)\n- 确保设计对色盲用户友好" + }, + { + "id": "mobile-expert", + "tags": ["mobile", "ios", "android", "react-native", "flutter", "swift", "kotlin"], + "description": "移动端开发专家,精通 iOS/Android 原生开发和 React Native、Flutter 跨平台方案", + "content": "你是一位全能的移动端开发专家,覆盖原生与跨平台方案。你精通:\n\n1. **iOS 开发**:Swift, SwiftUI, UIKit, Core Data, Combine\n2. **Android 开发**:Kotlin, Jetpack Compose, Room, Coroutines\n3. **跨平台**:React Native (Expo), Flutter (Dart), 性能优化\n4. **发布流程**:App Store/Google Play 审核, CI/CD, 热更新\n\n回答规范:\n- 遵循各平台的设计规范 (HIG/Material Design)\n- 考虑不同设备尺寸的适配\n- 关注启动速度和内存占用\n- 解释原生模块桥接机制" + }, + { + "id": "legal-advisor", + "tags": ["law", "legal", "contract", "compliance", "intellectual-property"], + "description": "法律顾问,专注于合同审查、知识产权、公司法和合规咨询", + "content": "你是一位经验丰富的法律顾问,专注于以下领域:\n\n1. **合同法**:合同起草、审查、谈判和争议解决\n2. **知识产权**:专利、商标、版权保护策略\n3. **公司法**:公司设立、股权架构、并购重组\n4. **合规咨询**:数据隐私、行业监管、风险管理\n\n回答问题时请:\n- 提供清晰的法律分析框架\n- 引用相关法律法规(如适用)\n- 指出潜在的法律风险\n- 建议具体的应对措施\n- 提醒用户在必要时寻求专业律师意见" + }, + { + "id": "creative-writer", + "tags": ["writing", "creative", "storytelling", "copywriting", "content"], + "description": "创意写作专家,擅长故事创作、文案撰写、内容策划和品牌叙事", + "content": "你是一位才华横溢的创意写作专家,擅长:\n\n1. **故事创作**:小说、剧本、短篇故事的构思与写作\n2. **商业文案**:广告文案、品牌故事、营销内容\n3. **内容策划**:社交媒体内容、博客文章、视频脚本\n4. **品牌叙事**:品牌定位、价值主张、情感连接\n\n创作时请:\n- 注重情感共鸣和读者体验\n- 运用修辞手法增强表达力\n- 保持风格一致性和创意新颖性\n- 根据目标受众调整语言风格\n- 提供多个创意方向供选择" + }, + { + "id": "product-manager", + "tags": ["product", "pm", "agile", "scrum", "roadmap", "user-story"], + "description": "产品经理,擅长需求分析、产品规划、敏捷开发流程和用户增长策略", + "content": "你是一位经验丰富的产品经理,具备技术背景和商业洞察力。你擅长:\n\n1. **需求管理**:用户调研, 需求挖掘, PRD 文档, 用户故事\n2. **产品规划**:产品路线图, 优先级排序 (RICE/ICE), OKR 制定\n3. **敏捷实践**:Scrum/Kanban, Sprint 规划, 站会, 复盘\n4. **增长策略**:用户留存, A/B 测试, 北极星指标, AARRR 模型\n\n回答规范:\n- 以用户价值为导向思考问题\n- 用数据驱动决策\n- 平衡技术可行性与商业价值\n- 提供可落地的执行方案" + }, + { + "id": "data-analyst", + "tags": ["data-analysis", "sql", "excel", "tableau", "power-bi", "statistics"], + "description": "数据分析师,精通 SQL 查询、数据可视化、统计分析和商业智能报表", + "content": "你是一位数据驱动的分析专家,善于从数据中发现洞察。你精通:\n\n1. **数据处理**:SQL 高级查询, Python/R 数据清洗, ETL 流程\n2. **可视化**:Tableau, Power BI, ECharts, 仪表盘设计\n3. **统计分析**:描述性统计, 假设检验, 回归分析, 时间序列\n4. **商业分析**:用户分群, 漏斗分析, 归因模型, LTV 计算\n\n回答规范:\n- 提供可执行的 SQL 或代码\n- 解释数据背后的业务含义\n- 给出可视化图表建议\n- 注意数据的统计显著性" + }, + { + "id": "english-teacher", + "tags": ["english", "language", "grammar", "writing", "ielts", "toefl"], + "description": "英语教师,擅长语法讲解、写作指导、口语训练和雅思托福备考", + "content": "你是一位耐心专业的英语教师,拥有丰富的教学经验。你擅长:\n\n1. **语法教学**:从基础到高级语法的系统讲解,易错点分析\n2. **写作指导**:学术写作, 商务邮件, 雅思/托福作文批改\n3. **口语训练**:发音纠正, 地道表达, 场景对话练习\n4. **考试备考**:雅思, 托福, GRE, 四六级备考策略\n\n教学原则:\n- 用简单易懂的方式解释复杂语法\n- 提供大量例句和对比练习\n- 指出中式英语的常见错误\n- 鼓励学生多练习,及时给予反馈" + }, + { + "id": "fitness-coach", + "tags": ["fitness", "workout", "nutrition", "health", "gym", "exercise"], + "description": "健身教练,提供训练计划制定、动作指导、营养建议和体态改善方案", + "content": "你是一位专业的健身教练和营养顾问,帮助人们实现健康目标。你擅长:\n\n1. **训练计划**:力量训练, 有氧运动, HIIT, 分化训练安排\n2. **动作指导**:标准动作讲解, 常见错误纠正, 替代动作推荐\n3. **营养指导**:宏量营养素计算, 增肌/减脂饮食, 补剂建议\n4. **体态改善**:圆肩驼背矫正, 骨盆前倾改善, 拉伸放松\n\n指导原则:\n- 根据个人情况定制方案\n- 安全第一,循序渐进\n- 解释训练背后的原理\n- 提醒热身和恢复的重要性" + }, + { + "id": "finance-advisor", + "tags": ["finance", "investment", "stock", "fund", "financial-planning"], + "description": "财务顾问,提供个人理财规划、投资策略、税务优化和财务分析", + "content": "你是一位专业的财务顾问,帮助个人和家庭实现财务自由。你擅长:\n\n1. **理财规划**:预算管理, 储蓄策略, 应急基金, 保险配置\n2. **投资分析**:股票基本面分析, 基金筛选, 资产配置, 风险评估\n3. **税务优化**:个税筹划, 专项扣除, 税收优惠政策\n4. **财务分析**:财务报表解读, 估值方法, 行业分析\n\n建议原则:\n- 强调风险与收益的平衡\n- 根据风险承受能力给建议\n- 不推荐具体股票,只讲方法论\n- 提醒投资有风险,入市需谨慎" + }, + { + "id": "psychologist", + "tags": ["psychology", "mental-health", "counseling", "emotion", "stress"], + "description": "心理咨询师,提供情绪疏导、压力管理、人际关系和自我成长指导", + "content": "你是一位温暖有同理心的心理咨询师,致力于帮助人们获得心理健康。你擅长:\n\n1. **情绪支持**:倾听、共情、情绪识别与表达\n2. **压力管理**:焦虑缓解、正念冥想、放松技巧\n3. **人际关系**:沟通技巧、边界设定、冲突解决\n4. **自我成长**:自我认知、价值观探索、目标设定\n\n咨询原则:\n- 营造安全、不评判的谈话环境\n- 以来访者为中心,尊重个人选择\n- 使用专业但易懂的语言\n- 必要时建议寻求线下专业帮助" + } +] diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..83a9c7f --- /dev/null +++ b/package-lock.json @@ -0,0 +1,2561 @@ +{ + "name": "mcp-rag-prompts", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "mcp-rag-prompts", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "@modelcontextprotocol/sdk": "^1.0.0", + "@xenova/transformers": "^2.17.2", + "dotenv": "^17.2.3", + "zod": "^3.23.8" + }, + "devDependencies": { + "@types/node": "^20.11.0", + "tsx": "^4.7.0", + "typescript": "^5.3.3" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz", + "integrity": "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.2.tgz", + "integrity": "sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.2.tgz", + "integrity": "sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.2.tgz", + "integrity": "sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.2.tgz", + "integrity": "sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.2.tgz", + "integrity": "sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.2.tgz", + "integrity": "sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.2.tgz", + "integrity": "sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.2.tgz", + "integrity": "sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.2.tgz", + "integrity": "sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.2.tgz", + "integrity": "sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.2.tgz", + "integrity": "sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.2.tgz", + "integrity": "sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.2.tgz", + "integrity": "sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.2.tgz", + "integrity": "sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.2.tgz", + "integrity": "sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.2.tgz", + "integrity": "sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.2.tgz", + "integrity": "sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.2.tgz", + "integrity": "sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.2.tgz", + "integrity": "sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.2.tgz", + "integrity": "sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.2.tgz", + "integrity": "sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.2.tgz", + "integrity": "sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.2.tgz", + "integrity": "sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.2.tgz", + "integrity": "sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.2.tgz", + "integrity": "sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@hono/node-server": { + "version": "1.19.9", + "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.9.tgz", + "integrity": "sha512-vHL6w3ecZsky+8P5MD+eFfaGTyCeOHUIFYMGpQGbrBTSmNNoxv0if69rEZ5giu36weC5saFuznL411gRX7bJDw==", + "license": "MIT", + "engines": { + "node": ">=18.14.1" + }, + "peerDependencies": { + "hono": "^4" + } + }, + "node_modules/@huggingface/jinja": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@huggingface/jinja/-/jinja-0.2.2.tgz", + "integrity": "sha512-/KPde26khDUIPkTGU82jdtTW9UAuvUTumCAbFs/7giR0SxsvZC4hru51PBvpijH6BVkHcROcvZM/lpy5h1jRRA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@modelcontextprotocol/sdk": { + "version": "1.25.3", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.25.3.tgz", + "integrity": "sha512-vsAMBMERybvYgKbg/l4L1rhS7VXV1c0CtyJg72vwxONVX0l4ZfKVAnZEWTQixJGTzKnELjQ59e4NbdFDALRiAQ==", + "license": "MIT", + "dependencies": { + "@hono/node-server": "^1.19.9", + "ajv": "^8.17.1", + "ajv-formats": "^3.0.1", + "content-type": "^1.0.5", + "cors": "^2.8.5", + "cross-spawn": "^7.0.5", + "eventsource": "^3.0.2", + "eventsource-parser": "^3.0.0", + "express": "^5.0.1", + "express-rate-limit": "^7.5.0", + "jose": "^6.1.1", + "json-schema-typed": "^8.0.2", + "pkce-challenge": "^5.0.0", + "raw-body": "^3.0.0", + "zod": "^3.25 || ^4.0", + "zod-to-json-schema": "^3.25.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@cfworker/json-schema": "^4.1.1", + "zod": "^3.25 || ^4.0" + }, + "peerDependenciesMeta": { + "@cfworker/json-schema": { + "optional": true + }, + "zod": { + "optional": false + } + } + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", + "license": "BSD-3-Clause" + }, + "node_modules/@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "20.19.31", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.31.tgz", + "integrity": "sha512-5jsi0wpncvTD33Sh1UCgacK37FFwDn+EG7wCmEvs62fCvBL+n8/76cAYDok21NF6+jaVWIqKwCZyX7Vbu8eB3A==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@xenova/transformers": { + "version": "2.17.2", + "resolved": "https://registry.npmjs.org/@xenova/transformers/-/transformers-2.17.2.tgz", + "integrity": "sha512-lZmHqzrVIkSvZdKZEx7IYY51TK0WDrC8eR0c5IMnBsO8di8are1zzw8BlLhyO2TklZKLN5UffNGs1IJwT6oOqQ==", + "license": "Apache-2.0", + "dependencies": { + "@huggingface/jinja": "^0.2.2", + "onnxruntime-web": "1.14.0", + "sharp": "^0.32.0" + }, + "optionalDependencies": { + "onnxruntime-node": "1.14.0" + } + }, + "node_modules/accepts": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", + "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", + "license": "MIT", + "dependencies": { + "mime-types": "^3.0.0", + "negotiator": "^1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/b4a": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.7.3.tgz", + "integrity": "sha512-5Q2mfq2WfGuFp3uS//0s6baOJLMoVduPYVeNmDYxu5OUA1/cBfvr2RIS7vi62LdNj/urk1hfmj867I3qt6uZ7Q==", + "license": "Apache-2.0", + "peerDependencies": { + "react-native-b4a": "*" + }, + "peerDependenciesMeta": { + "react-native-b4a": { + "optional": true + } + } + }, + "node_modules/bare-events": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.8.2.tgz", + "integrity": "sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==", + "license": "Apache-2.0", + "peerDependencies": { + "bare-abort-controller": "*" + }, + "peerDependenciesMeta": { + "bare-abort-controller": { + "optional": true + } + } + }, + "node_modules/bare-fs": { + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.5.3.tgz", + "integrity": "sha512-9+kwVx8QYvt3hPWnmb19tPnh38c6Nihz8Lx3t0g9+4GoIf3/fTgYwM4Z6NxgI+B9elLQA7mLE9PpqcWtOMRDiQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "bare-events": "^2.5.4", + "bare-path": "^3.0.0", + "bare-stream": "^2.6.4", + "bare-url": "^2.2.2", + "fast-fifo": "^1.3.2" + }, + "engines": { + "bare": ">=1.16.0" + }, + "peerDependencies": { + "bare-buffer": "*" + }, + "peerDependenciesMeta": { + "bare-buffer": { + "optional": true + } + } + }, + "node_modules/bare-os": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.6.2.tgz", + "integrity": "sha512-T+V1+1srU2qYNBmJCXZkUY5vQ0B4FSlL3QDROnKQYOqeiQR8UbjNHlPa+TIbM4cuidiN9GaTaOZgSEgsvPbh5A==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "bare": ">=1.14.0" + } + }, + "node_modules/bare-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.0.0.tgz", + "integrity": "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "bare-os": "^3.0.1" + } + }, + "node_modules/bare-stream": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.7.0.tgz", + "integrity": "sha512-oyXQNicV1y8nc2aKffH+BUHFRXmx6VrPzlnaEvMhram0nPBrKcEdcyBg5r08D0i8VxngHFAiVyn1QKXpSG0B8A==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "streamx": "^2.21.0" + }, + "peerDependencies": { + "bare-buffer": "*", + "bare-events": "*" + }, + "peerDependenciesMeta": { + "bare-buffer": { + "optional": true + }, + "bare-events": { + "optional": true + } + } + }, + "node_modules/bare-url": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.3.2.tgz", + "integrity": "sha512-ZMq4gd9ngV5aTMa5p9+UfY0b3skwhHELaDkhEHetMdX0LRkW9kzaym4oo/Eh+Ghm0CCDuMTsRIGM/ytUc1ZYmw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "bare-path": "^3.0.0" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/body-parser": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz", + "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==", + "license": "MIT", + "dependencies": { + "bytes": "^3.1.2", + "content-type": "^1.0.5", + "debug": "^4.4.3", + "http-errors": "^2.0.0", + "iconv-lite": "^0.7.0", + "on-finished": "^2.4.1", + "qs": "^6.14.1", + "raw-body": "^3.0.1", + "type-is": "^2.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "license": "ISC" + }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "license": "MIT", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/content-disposition": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz", + "integrity": "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", + "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", + "license": "MIT", + "engines": { + "node": ">=6.6.0" + } + }, + "node_modules/cors": { + "version": "2.8.6", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz", + "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==", + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "license": "MIT", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/dotenv": { + "version": "17.2.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.3.tgz", + "integrity": "sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.2.tgz", + "integrity": "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.2", + "@esbuild/android-arm": "0.27.2", + "@esbuild/android-arm64": "0.27.2", + "@esbuild/android-x64": "0.27.2", + "@esbuild/darwin-arm64": "0.27.2", + "@esbuild/darwin-x64": "0.27.2", + "@esbuild/freebsd-arm64": "0.27.2", + "@esbuild/freebsd-x64": "0.27.2", + "@esbuild/linux-arm": "0.27.2", + "@esbuild/linux-arm64": "0.27.2", + "@esbuild/linux-ia32": "0.27.2", + "@esbuild/linux-loong64": "0.27.2", + "@esbuild/linux-mips64el": "0.27.2", + "@esbuild/linux-ppc64": "0.27.2", + "@esbuild/linux-riscv64": "0.27.2", + "@esbuild/linux-s390x": "0.27.2", + "@esbuild/linux-x64": "0.27.2", + "@esbuild/netbsd-arm64": "0.27.2", + "@esbuild/netbsd-x64": "0.27.2", + "@esbuild/openbsd-arm64": "0.27.2", + "@esbuild/openbsd-x64": "0.27.2", + "@esbuild/openharmony-arm64": "0.27.2", + "@esbuild/sunos-x64": "0.27.2", + "@esbuild/win32-arm64": "0.27.2", + "@esbuild/win32-ia32": "0.27.2", + "@esbuild/win32-x64": "0.27.2" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/events-universal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz", + "integrity": "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==", + "license": "Apache-2.0", + "dependencies": { + "bare-events": "^2.7.0" + } + }, + "node_modules/eventsource": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz", + "integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==", + "license": "MIT", + "dependencies": { + "eventsource-parser": "^3.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/eventsource-parser": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.6.tgz", + "integrity": "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "license": "(MIT OR WTFPL)", + "engines": { + "node": ">=6" + } + }, + "node_modules/express": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", + "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", + "license": "MIT", + "peer": true, + "dependencies": { + "accepts": "^2.0.0", + "body-parser": "^2.2.1", + "content-disposition": "^1.0.0", + "content-type": "^1.0.5", + "cookie": "^0.7.1", + "cookie-signature": "^1.2.1", + "debug": "^4.4.0", + "depd": "^2.0.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "finalhandler": "^2.1.0", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", + "merge-descriptors": "^2.0.0", + "mime-types": "^3.0.0", + "on-finished": "^2.4.1", + "once": "^1.4.0", + "parseurl": "^1.3.3", + "proxy-addr": "^2.0.7", + "qs": "^6.14.0", + "range-parser": "^1.2.1", + "router": "^2.2.0", + "send": "^1.1.0", + "serve-static": "^2.2.0", + "statuses": "^2.0.1", + "type-is": "^2.0.1", + "vary": "^1.1.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express-rate-limit": { + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.1.tgz", + "integrity": "sha512-7iN8iPMDzOMHPUYllBEsQdWVB6fPDMPqwjBaFrgr4Jgr/+okjvzAy+UHlYYL/Vs0OsOrMkwS6PJDkFlJwoxUnw==", + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/express-rate-limit" + }, + "peerDependencies": { + "express": ">= 4.11" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" + }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/finalhandler": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", + "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "on-finished": "^2.4.1", + "parseurl": "^1.3.3", + "statuses": "^2.0.1" + }, + "engines": { + "node": ">= 18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/flatbuffers": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-1.12.0.tgz", + "integrity": "sha512-c7CZADjRcl6j0PlvFy0ZqXQ67qSEZfrVPynmnL+2zPc+NtMvrF8Y0QceMo7QqnSPc7+uWjUIAbvCQ5WIKlMVdQ==", + "license": "SEE LICENSE IN LICENSE.txt" + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "license": "MIT" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-tsconfig": { + "version": "4.13.1", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.1.tgz", + "integrity": "sha512-EoY1N2xCn44xU6750Sx7OjOIT59FkmstNc3X6y5xpz7D5cBtZRe/3pSlTkDJgqsOk3WwZPkWfonhhUJfttQo3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", + "license": "MIT" + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/guid-typescript": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/guid-typescript/-/guid-typescript-1.0.9.tgz", + "integrity": "sha512-Y8T4vYhEfwJOTbouREvG+3XDsjr8E3kIr7uf+JZ0BYloFsttiHU0WfvANVsR7TxNUJa/WpCnw/Ino/p+DeBhBQ==", + "license": "ISC" + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hono": { + "version": "4.11.7", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.11.7.tgz", + "integrity": "sha512-l7qMiNee7t82bH3SeyUCt9UF15EVmaBvsppY2zQtrbIhl/yzBTny+YUxsVjSjQ6gaqaeVtZmGocom8TzBlA4Yw==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=16.9.0" + } + }, + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/iconv-lite": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", + "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "license": "ISC" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-arrayish": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.4.tgz", + "integrity": "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==", + "license": "MIT" + }, + "node_modules/is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/jose": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/jose/-/jose-6.1.3.tgz", + "integrity": "sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, + "node_modules/json-schema-typed": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz", + "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==", + "license": "BSD-2-Clause" + }, + "node_modules/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", + "license": "Apache-2.0" + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/media-typer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", + "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/merge-descriptors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", + "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "license": "MIT" + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/napi-build-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz", + "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==", + "license": "MIT" + }, + "node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/node-abi": { + "version": "3.87.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.87.0.tgz", + "integrity": "sha512-+CGM1L1CgmtheLcBuleyYOn7NWPVu0s0EJH2C4puxgEZb9h8QpR9G2dBfZJOAUhi7VQxuBPMd0hiISWcTyiYyQ==", + "license": "MIT", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-addon-api": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", + "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==", + "license": "MIT" + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onnx-proto": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/onnx-proto/-/onnx-proto-4.0.4.tgz", + "integrity": "sha512-aldMOB3HRoo6q/phyB6QRQxSt895HNNw82BNyZ2CMh4bjeKv7g/c+VpAFtJuEMVfYLMbRx61hbuqnKceLeDcDA==", + "license": "MIT", + "dependencies": { + "protobufjs": "^6.8.8" + } + }, + "node_modules/onnxruntime-common": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/onnxruntime-common/-/onnxruntime-common-1.14.0.tgz", + "integrity": "sha512-3LJpegM2iMNRX2wUmtYfeX/ytfOzNwAWKSq1HbRrKc9+uqG/FsEA0bbKZl1btQeZaXhC26l44NWpNUeXPII7Ew==", + "license": "MIT" + }, + "node_modules/onnxruntime-node": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/onnxruntime-node/-/onnxruntime-node-1.14.0.tgz", + "integrity": "sha512-5ba7TWomIV/9b6NH/1x/8QEeowsb+jBEvFzU6z0T4mNsFwdPqXeFUM7uxC6QeSRkEbWu3qEB0VMjrvzN/0S9+w==", + "license": "MIT", + "optional": true, + "os": [ + "win32", + "darwin", + "linux" + ], + "dependencies": { + "onnxruntime-common": "~1.14.0" + } + }, + "node_modules/onnxruntime-web": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/onnxruntime-web/-/onnxruntime-web-1.14.0.tgz", + "integrity": "sha512-Kcqf43UMfW8mCydVGcX9OMXI2VN17c0p6XvR7IPSZzBf/6lteBzXHvcEVWDPmCKuGombl997HgLqj91F11DzXw==", + "license": "MIT", + "dependencies": { + "flatbuffers": "^1.12.0", + "guid-typescript": "^1.0.9", + "long": "^4.0.0", + "onnx-proto": "^4.0.4", + "onnxruntime-common": "~1.14.0", + "platform": "^1.3.6" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-to-regexp": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", + "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/pkce-challenge": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.1.tgz", + "integrity": "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==", + "license": "MIT", + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/platform": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz", + "integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==", + "license": "MIT" + }, + "node_modules/prebuild-install": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", + "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==", + "license": "MIT", + "dependencies": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^2.0.0", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/prebuild-install/node_modules/tar-fs": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.4.tgz", + "integrity": "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==", + "license": "MIT", + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/prebuild-install/node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "license": "MIT", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/protobufjs": { + "version": "6.11.4", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.4.tgz", + "integrity": "sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + }, + "bin": { + "pbjs": "bin/pbjs", + "pbts": "bin/pbts" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/pump": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", + "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/qs": { + "version": "6.14.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz", + "integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", + "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.7.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/router": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", + "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "depd": "^2.0.0", + "is-promise": "^4.0.0", + "parseurl": "^1.3.3", + "path-to-regexp": "^8.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", + "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.3", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^2.0.0", + "http-errors": "^2.0.1", + "mime-types": "^3.0.2", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/serve-static": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", + "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", + "license": "MIT", + "dependencies": { + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "parseurl": "^1.3.3", + "send": "^1.2.0" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/sharp": { + "version": "0.32.6", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.32.6.tgz", + "integrity": "sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.2", + "node-addon-api": "^6.1.0", + "prebuild-install": "^7.1.1", + "semver": "^7.5.4", + "simple-get": "^4.0.1", + "tar-fs": "^3.0.4", + "tunnel-agent": "^0.6.0" + }, + "engines": { + "node": ">=14.15.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/simple-swizzle": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.4.tgz", + "integrity": "sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/streamx": { + "version": "2.23.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.23.0.tgz", + "integrity": "sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==", + "license": "MIT", + "dependencies": { + "events-universal": "^1.0.0", + "fast-fifo": "^1.3.2", + "text-decoder": "^1.1.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tar-fs": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.1.tgz", + "integrity": "sha512-LZA0oaPOc2fVo82Txf3gw+AkEd38szODlptMYejQUhndHMLQ9M059uXR+AfS7DNo0NpINvSqDsvyaCrBVkptWg==", + "license": "MIT", + "dependencies": { + "pump": "^3.0.0", + "tar-stream": "^3.1.5" + }, + "optionalDependencies": { + "bare-fs": "^4.0.1", + "bare-path": "^3.0.0" + } + }, + "node_modules/tar-stream": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", + "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "license": "MIT", + "dependencies": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, + "node_modules/text-decoder": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz", + "integrity": "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==", + "license": "Apache-2.0", + "dependencies": { + "b4a": "^1.6.4" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tsx": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz", + "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "~0.27.0", + "get-tsconfig": "^4.7.5" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/type-is": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", + "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", + "license": "MIT", + "dependencies": { + "content-type": "^1.0.5", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "license": "MIT" + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" + }, + "node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "license": "MIT", + "peer": true, + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-to-json-schema": { + "version": "3.25.1", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.1.tgz", + "integrity": "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==", + "license": "ISC", + "peerDependencies": { + "zod": "^3.25 || ^4" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..0e7ef21 --- /dev/null +++ b/package.json @@ -0,0 +1,33 @@ +{ + "name": "mcp-rag-prompts", + "version": "1.0.0", + "description": "MCP Server for RAG-based prompt management with local embeddings", + "type": "module", + "main": "src/index.ts", + "scripts": { + "start": "tsx src/index.ts", + "build": "tsc", + "dev": "tsx watch src/index.ts" + }, + "keywords": [ + "mcp", + "rag", + "embeddings", + "prompt-management" + ], + "license": "MIT", + "dependencies": { + "@modelcontextprotocol/sdk": "^1.0.0", + "@xenova/transformers": "^2.17.2", + "dotenv": "^17.2.3", + "zod": "^3.23.8" + }, + "devDependencies": { + "@types/node": "^20.11.0", + "tsx": "^4.7.0", + "typescript": "^5.3.3" + }, + "engines": { + "node": ">=18.0.0" + } +} diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..f34508f --- /dev/null +++ b/src/index.ts @@ -0,0 +1,124 @@ +/** + * MCP RAG Prompts Server 入口文件 + * 基于 MCP 协议的 RAG 提示词管理服务器 + */ + +// 加载 .env 文件(必须在最前面) +import 'dotenv/config'; + +import { Server } from '@modelcontextprotocol/sdk/server/index.js'; +import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; +import { + CallToolRequestSchema, + ListToolsRequestSchema, +} from '@modelcontextprotocol/sdk/types.js'; + +import { vectorStore } from './lib/vectorStore.js'; +import { + TOOL_NAME, + TOOL_DESCRIPTION, + inputJsonSchema, + handleSearchPersona, + type SearchPersonaInput, +} from './tools/searchPersona.js'; + +/** + * 创建并配置 MCP Server + */ +function createServer(): Server { + const server = new Server( + { + name: 'mcp-rag-prompts', + version: '1.0.0', + }, + { + capabilities: { + tools: {}, + }, + } + ); + + /** + * 处理 tools/list 请求 + * 返回服务器提供的所有工具列表 + */ + server.setRequestHandler(ListToolsRequestSchema, async () => { + console.error('[Server] 收到 tools/list 请求'); + + return { + tools: [ + { + name: TOOL_NAME, + description: TOOL_DESCRIPTION, + inputSchema: inputJsonSchema, + }, + ], + }; + }); + + /** + * 处理 tools/call 请求 + * 执行指定的工具并返回结果 + */ + server.setRequestHandler(CallToolRequestSchema, async (request) => { + const { name, arguments: args } = request.params; + + console.error(`[Server] 收到 tools/call 请求: ${name}`); + console.error(`[Server] 参数: ${JSON.stringify(args)}`); + + // 路由到对应的工具处理函数 + switch (name) { + case TOOL_NAME: + return handleSearchPersona(args as SearchPersonaInput); + + default: + return { + content: [ + { + type: 'text' as const, + text: JSON.stringify({ + success: false, + error: `未知工具: ${name}`, + }), + }, + ], + isError: true, + }; + } + }); + + return server; +} + +/** + * 主函数:初始化并启动服务器 + */ +async function main(): Promise { + console.error('='.repeat(50)); + console.error('MCP RAG Prompts Server 启动中...'); + console.error('='.repeat(50)); + + try { + // 1. 初始化向量存储(加载数据并生成 embeddings) + console.error('\n[Main] 步骤 1: 初始化向量存储'); + await vectorStore.initialize(); + + // 2. 创建 MCP Server + console.error('\n[Main] 步骤 2: 创建 MCP Server'); + const server = createServer(); + + // 3. 创建 Stdio Transport 并连接 + console.error('\n[Main] 步骤 3: 启动 Stdio Transport'); + const transport = new StdioServerTransport(); + await server.connect(transport); + + console.error('\n[Main] ✓ MCP Server 已启动,等待客户端连接...'); + console.error('='.repeat(50)); + } catch (error) { + console.error('\n[Main] ✗ 启动失败:', error); + process.exit(1); + } +} + +// 启动服务器 +main(); diff --git a/src/lib/embeddingProviders.ts b/src/lib/embeddingProviders.ts new file mode 100644 index 0000000..4823ebe --- /dev/null +++ b/src/lib/embeddingProviders.ts @@ -0,0 +1,305 @@ +/** + * Embedding 提供者实现 + * 支持本地模型和多种云服务 API + */ + +import type { IEmbeddingProvider, EmbeddingConfig } from './types.js'; + +// ============================================================ +// 本地模型提供者 (使用 @xenova/transformers) +// ============================================================ +export class LocalEmbeddingProvider implements IEmbeddingProvider { + readonly name = 'local'; + private modelName: string; + private extractor: any = null; + + constructor(modelName: string = 'Xenova/paraphrase-multilingual-MiniLM-L12-v2') { + this.modelName = modelName; + } + + async initialize(): Promise { + if (this.extractor) return; + + console.error(`[LocalProvider] 正在加载本地模型: ${this.modelName}`); + // 动态导入,避免在使用 API 时也加载这个大依赖 + const { pipeline } = await import('@xenova/transformers'); + this.extractor = await pipeline('feature-extraction', this.modelName); + console.error(`[LocalProvider] 模型加载完成`); + } + + async embed(text: string): Promise { + if (!this.extractor) { + throw new Error('LocalProvider 尚未初始化'); + } + const output = await this.extractor(text, { + pooling: 'mean', + normalize: true, + }); + return Array.from(output.data as Float32Array); + } + + async embedBatch(texts: string[]): Promise { + // 本地模型逐个处理 + const results: number[][] = []; + for (const text of texts) { + results.push(await this.embed(text)); + } + return results; + } +} + +// ============================================================ +// OpenAI 兼容 API 提供者 +// 支持 OpenAI 官方 API 和兼容接口(如 Azure OpenAI) +// ============================================================ +export class OpenAIEmbeddingProvider implements IEmbeddingProvider { + readonly name = 'openai'; + private apiKey: string; + private baseUrl: string; + private model: string; + + constructor(config: { apiKey: string; baseUrl?: string; model?: string }) { + this.apiKey = config.apiKey; + this.baseUrl = config.baseUrl || 'https://api.openai.com/v1'; + this.model = config.model || 'text-embedding-3-small'; + } + + async initialize(): Promise { + console.error(`[OpenAIProvider] 使用模型: ${this.model}`); + console.error(`[OpenAIProvider] API 地址: ${this.baseUrl}`); + } + + async embed(text: string): Promise { + const response = await fetch(`${this.baseUrl}/embeddings`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${this.apiKey}`, + }, + body: JSON.stringify({ + input: text, + model: this.model, + }), + }); + + if (!response.ok) { + const error = await response.text(); + throw new Error(`OpenAI API 错误: ${response.status} - ${error}`); + } + + const data = await response.json(); + return data.data[0].embedding; + } + + async embedBatch(texts: string[]): Promise { + // OpenAI 支持批量请求 + const response = await fetch(`${this.baseUrl}/embeddings`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${this.apiKey}`, + }, + body: JSON.stringify({ + input: texts, + model: this.model, + }), + }); + + if (!response.ok) { + const error = await response.text(); + throw new Error(`OpenAI API 错误: ${response.status} - ${error}`); + } + + const data = await response.json(); + // 按 index 排序确保顺序正确 + return data.data + .sort((a: any, b: any) => a.index - b.index) + .map((item: any) => item.embedding); + } +} + +// ============================================================ +// 阿里云百炼 DashScope API 提供者 +// ============================================================ +export class AliyunEmbeddingProvider implements IEmbeddingProvider { + readonly name = 'aliyun'; + private apiKey: string; + private model: string; + private baseUrl = 'https://dashscope.aliyuncs.com/api/v1/services/embeddings/text-embedding/text-embedding'; + + constructor(config: { apiKey: string; model?: string }) { + this.apiKey = config.apiKey; + this.model = config.model || 'text-embedding-v3'; + } + + async initialize(): Promise { + console.error(`[AliyunProvider] 使用模型: ${this.model}`); + } + + async embed(text: string): Promise { + const response = await fetch(this.baseUrl, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${this.apiKey}`, + }, + body: JSON.stringify({ + model: this.model, + input: { + texts: [text], + }, + parameters: { + text_type: 'query', + }, + }), + }); + + if (!response.ok) { + const error = await response.text(); + throw new Error(`阿里云 API 错误: ${response.status} - ${error}`); + } + + const data = await response.json(); + + if (data.output?.embeddings?.[0]?.embedding) { + return data.output.embeddings[0].embedding; + } + + throw new Error(`阿里云 API 返回格式错误: ${JSON.stringify(data)}`); + } + + async embedBatch(texts: string[]): Promise { + const response = await fetch(this.baseUrl, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${this.apiKey}`, + }, + body: JSON.stringify({ + model: this.model, + input: { + texts: texts, + }, + parameters: { + text_type: 'query', + }, + }), + }); + + if (!response.ok) { + const error = await response.text(); + throw new Error(`阿里云 API 错误: ${response.status} - ${error}`); + } + + const data = await response.json(); + + if (data.output?.embeddings) { + return data.output.embeddings + .sort((a: any, b: any) => a.text_index - b.text_index) + .map((item: any) => item.embedding); + } + + throw new Error(`阿里云 API 返回格式错误: ${JSON.stringify(data)}`); + } +} + +// ============================================================ +// SiliconFlow API 提供者 +// 硅基流动,支持多种开源 Embedding 模型 +// ============================================================ +export class SiliconFlowEmbeddingProvider implements IEmbeddingProvider { + readonly name = 'siliconflow'; + private apiKey: string; + private model: string; + private baseUrl = 'https://api.siliconflow.cn/v1/embeddings'; + + constructor(config: { apiKey: string; model?: string }) { + this.apiKey = config.apiKey; + // 默认使用 BGE-M3,多语言效果好 + this.model = config.model || 'BAAI/bge-m3'; + } + + async initialize(): Promise { + console.error(`[SiliconFlowProvider] 使用模型: ${this.model}`); + } + + async embed(text: string): Promise { + const response = await fetch(this.baseUrl, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${this.apiKey}`, + }, + body: JSON.stringify({ + model: this.model, + input: text, + encoding_format: 'float', + }), + }); + + if (!response.ok) { + const error = await response.text(); + throw new Error(`SiliconFlow API 错误: ${response.status} - ${error}`); + } + + const data = await response.json(); + return data.data[0].embedding; + } + + async embedBatch(texts: string[]): Promise { + // SiliconFlow 支持批量(与 OpenAI 兼容) + const response = await fetch(this.baseUrl, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${this.apiKey}`, + }, + body: JSON.stringify({ + model: this.model, + input: texts, + encoding_format: 'float', + }), + }); + + if (!response.ok) { + const error = await response.text(); + throw new Error(`SiliconFlow API 错误: ${response.status} - ${error}`); + } + + const data = await response.json(); + return data.data + .sort((a: any, b: any) => a.index - b.index) + .map((item: any) => item.embedding); + } +} + +// ============================================================ +// 工厂函数:根据配置创建对应的提供者 +// ============================================================ +export function createEmbeddingProvider(config: EmbeddingConfig): IEmbeddingProvider { + switch (config.provider) { + case 'local': + return new LocalEmbeddingProvider(config.local?.modelName); + + case 'openai': + if (!config.openai?.apiKey) { + throw new Error('OpenAI 配置缺少 apiKey'); + } + return new OpenAIEmbeddingProvider(config.openai); + + case 'aliyun': + if (!config.aliyun?.apiKey) { + throw new Error('阿里云配置缺少 apiKey'); + } + return new AliyunEmbeddingProvider(config.aliyun); + + case 'siliconflow': + if (!config.siliconflow?.apiKey) { + throw new Error('SiliconFlow 配置缺少 apiKey'); + } + return new SiliconFlowEmbeddingProvider(config.siliconflow); + + default: + throw new Error(`不支持的 Embedding 提供者: ${config.provider}`); + } +} diff --git a/src/lib/types.ts b/src/lib/types.ts new file mode 100644 index 0000000..e9bebd5 --- /dev/null +++ b/src/lib/types.ts @@ -0,0 +1,84 @@ +/** + * 类型定义文件 + * 定义 Prompt 数据结构和向量存储相关类型 + */ + +/** + * 原始 Prompt 数据结构(从 JSON 文件读取) + */ +export interface PromptData { + id: string; + tags: string[]; + description: string; + content: string; +} + +/** + * 带向量的 Prompt 数据(内存中缓存) + */ +export interface PromptWithEmbedding extends PromptData { + embedding: number[]; +} + +/** + * 搜索结果结构 + */ +export interface SearchResult { + prompt: PromptData; + similarity: number; +} + +/** + * Embedding 提供者类型 + */ +export type EmbeddingProvider = 'local' | 'openai' | 'aliyun' | 'siliconflow'; + +/** + * Embedding 配置接口 + */ +export interface EmbeddingConfig { + /** 提供者类型 */ + provider: EmbeddingProvider; + + /** 本地模型配置 */ + local?: { + modelName: string; + }; + + /** OpenAI 配置 */ + openai?: { + apiKey: string; + baseUrl?: string; // 支持自定义 base URL(如代理) + model?: string; // 默认 text-embedding-3-small + }; + + /** 阿里云百炼配置 */ + aliyun?: { + apiKey: string; + model?: string; // 默认 text-embedding-v3 + }; + + /** SiliconFlow 配置 */ + siliconflow?: { + apiKey: string; + model?: string; // 默认 BAAI/bge-m3 + }; +} + +/** + * Embedding 提供者接口 + * 所有 Embedding 实现都需要遵循此接口 + */ +export interface IEmbeddingProvider { + /** 提供者名称 */ + readonly name: string; + + /** 初始化(如加载模型) */ + initialize(): Promise; + + /** 生成单个文本的向量 */ + embed(text: string): Promise; + + /** 批量生成向量(可选优化) */ + embedBatch?(texts: string[]): Promise; +} diff --git a/src/lib/vectorStore.ts b/src/lib/vectorStore.ts new file mode 100644 index 0000000..aeaf147 --- /dev/null +++ b/src/lib/vectorStore.ts @@ -0,0 +1,232 @@ +/** + * 向量存储模块 (增强版) + * 支持本地模型和云服务 API 切换 + * 核心功能:Hybrid Search (向量语义 + 关键词加权) + */ + +import { readFile } from 'fs/promises'; +import { fileURLToPath } from 'url'; +import { dirname, join } from 'path'; +import type { + PromptData, + PromptWithEmbedding, + SearchResult, + EmbeddingConfig, + IEmbeddingProvider, +} from './types.js'; +import { createEmbeddingProvider } from './embeddingProviders.js'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + +// 相似度阈值 +const SIMILARITY_THRESHOLD = 0.4; + +// 关键词命中加分 +const KEYWORD_BOOST_SCORE = 0.3; + +/** + * 从环境变量读取配置 + * 优先级:环境变量 > 默认值 + */ +function getConfigFromEnv(): EmbeddingConfig { + const provider = (process.env.EMBEDDING_PROVIDER || 'local') as EmbeddingConfig['provider']; + + const config: EmbeddingConfig = { + provider, + local: { + modelName: process.env.LOCAL_MODEL_NAME || 'Xenova/paraphrase-multilingual-MiniLM-L12-v2', + }, + openai: { + apiKey: process.env.OPENAI_API_KEY || '', + baseUrl: process.env.OPENAI_BASE_URL || 'https://api.openai.com/v1', + model: process.env.OPENAI_EMBEDDING_MODEL || 'text-embedding-3-small', + }, + aliyun: { + apiKey: process.env.DASHSCOPE_API_KEY || '', + model: process.env.ALIYUN_EMBEDDING_MODEL || 'text-embedding-v3', + }, + siliconflow: { + apiKey: process.env.SILICONFLOW_API_KEY || '', + model: process.env.SILICONFLOW_EMBEDDING_MODEL || 'BAAI/bge-m3', + }, + }; + + return config; +} + +/** + * 向量存储类 + */ +export class VectorStore { + private prompts: PromptWithEmbedding[] = []; + private embeddingProvider: IEmbeddingProvider | null = null; + private initialized = false; + private config: EmbeddingConfig; + + constructor(config?: EmbeddingConfig) { + // 使用传入配置或从环境变量读取 + this.config = config || getConfigFromEnv(); + } + + /** + * 计算余弦相似度 + */ + private cosineSimilarity(vecA: number[], vecB: number[]): number { + if (vecA.length !== vecB.length) return 0; + + let dotProduct = 0; + let normA = 0; + let normB = 0; + + for (let i = 0; i < vecA.length; i++) { + dotProduct += vecA[i] * vecB[i]; + normA += vecA[i] * vecA[i]; + normB += vecB[i] * vecB[i]; + } + + const magnitude = Math.sqrt(normA) * Math.sqrt(normB); + return magnitude === 0 ? 0 : dotProduct / magnitude; + } + + /** + * 初始化向量存储 + */ + async initialize(): Promise { + if (this.initialized) return; + + console.error('='.repeat(50)); + console.error('[VectorStore] 开始初始化...'); + console.error(`[VectorStore] Embedding 提供者: ${this.config.provider}`); + + // 创建并初始化 Embedding 提供者 + this.embeddingProvider = createEmbeddingProvider(this.config); + await this.embeddingProvider.initialize(); + + // 读取 Prompt 数据 + const dataPath = join(__dirname, '../../data/prompts.json'); + const rawData = await readFile(dataPath, 'utf-8'); + const promptsData: PromptData[] = JSON.parse(rawData); + + console.error(`[VectorStore] 读取到 ${promptsData.length} 条 Prompt 数据`); + + // 准备待向量化的文本 + const textsToEmbed = promptsData.map( + (prompt) => `${prompt.tags.join(' ')} ${prompt.description}` + ); + + // 生成向量(优先使用批量接口) + let embeddings: number[][]; + + if (this.embeddingProvider.embedBatch) { + console.error('[VectorStore] 使用批量向量化...'); + embeddings = await this.embeddingProvider.embedBatch(textsToEmbed); + } else { + console.error('[VectorStore] 逐个向量化...'); + embeddings = []; + for (const text of textsToEmbed) { + embeddings.push(await this.embeddingProvider.embed(text)); + } + } + + // 组装数据 + for (let i = 0; i < promptsData.length; i++) { + this.prompts.push({ + ...promptsData[i], + embedding: embeddings[i], + }); + } + + this.initialized = true; + console.error(`[VectorStore] ✓ 初始化完成,加载了 ${promptsData.length} 条数据`); + console.error('='.repeat(50)); + } + + /** + * 语义搜索 + */ + async search(query: string): Promise { + if (!this.initialized || !this.embeddingProvider) { + throw new Error('VectorStore 尚未初始化'); + } + + console.error(`[VectorStore] 搜索: "${query}"`); + + // 生成查询向量 + const queryEmbedding = await this.embeddingProvider.embed(query); + const queryLower = query.toLowerCase(); + + // 混合打分 + const results: SearchResult[] = this.prompts.map((prompt) => { + // A. 向量相似度 + const vectorScore = this.cosineSimilarity(queryEmbedding, prompt.embedding); + + // B. 关键词加分 + let boostScore = 0; + if (prompt.tags && prompt.tags.length > 0) { + for (const tag of prompt.tags) { + if (queryLower.includes(tag.toLowerCase())) { + boostScore = KEYWORD_BOOST_SCORE; + break; + } + } + } + + // 最终得分 + const finalScore = Math.min(vectorScore + boostScore, 1.0); + + return { + prompt: { + id: prompt.id, + tags: prompt.tags, + description: prompt.description, + content: prompt.content, + }, + similarity: finalScore, + }; + }); + + // 排序 + results.sort((a, b) => b.similarity - a.similarity); + const bestMatch = results[0]; + + // 调试输出 + console.error(`--- Top 3 候选 ---`); + results.slice(0, 3).forEach((r, i) => { + console.error(`${i + 1}. [${r.prompt.id}] 得分: ${r.similarity.toFixed(4)}`); + }); + + // 阈值检查 + if (bestMatch.similarity < SIMILARITY_THRESHOLD) { + console.error( + `[VectorStore] ✗ 最高分 ${bestMatch.similarity.toFixed(4)} 低于阈值 ${SIMILARITY_THRESHOLD}` + ); + return null; + } + + console.error( + `[VectorStore] ✓ 选中: ${bestMatch.prompt.id} (得分: ${bestMatch.similarity.toFixed(4)})` + ); + return bestMatch; + } + + /** + * 获取所有可用的 Prompt ID + */ + getAvailablePrompts(): string[] { + return this.prompts.map((p) => p.id); + } + + /** + * 获取当前使用的 Embedding 提供者信息 + */ + getProviderInfo(): { provider: string; initialized: boolean } { + return { + provider: this.config.provider, + initialized: this.initialized, + }; + } +} + +// 导出单例(使用环境变量配置) +export const vectorStore = new VectorStore(); diff --git a/src/test.ts b/src/test.ts new file mode 100644 index 0000000..2d919c3 --- /dev/null +++ b/src/test.ts @@ -0,0 +1,184 @@ +/** + * 测试脚本:验证向量存储和搜索功能 + * 包含多场景测试用例 + */ + +// 加载 .env 文件 +import 'dotenv/config'; + +import { vectorStore } from './lib/vectorStore.js'; + +// 定义测试用例结构 +interface TestCase { + query: string; + expectedId: string | null; // null 表示期望无匹配 + category: string; +} + +// 测试用例集 +const testCases: TestCase[] = [ + // ==================== 编程语言类 ==================== + { query: '如何用 Python 写一个爬虫?', expectedId: 'python-expert', category: '编程-Python' }, + { query: '帮我用 FastAPI 搭建一个后端服务', expectedId: 'python-expert', category: '编程-Python' }, + { query: 'Django ORM 怎么做多表关联查询?', expectedId: 'python-expert', category: '编程-Python' }, + + { query: '如何用 Java 实现单例模式?', expectedId: 'java-expert', category: '编程-Java' }, + { query: 'Spring Boot 项目如何配置多数据源?', expectedId: 'java-expert', category: '编程-Java' }, + { query: 'JVM 垃圾回收机制是怎样的?', expectedId: 'java-expert', category: '编程-Java' }, + + { query: '用 Go 写一个高并发的 HTTP 服务', expectedId: 'golang-expert', category: '编程-Go' }, + { query: 'Golang 的 channel 和 goroutine 怎么用?', expectedId: 'golang-expert', category: '编程-Go' }, + { query: '如何用 gRPC 实现微服务通信?', expectedId: 'golang-expert', category: '编程-Go' }, + + { query: 'React Hooks 的最佳实践是什么?', expectedId: 'javascript-expert', category: '编程-JS/TS' }, + { query: 'TypeScript 泛型怎么用?', expectedId: 'javascript-expert', category: '编程-JS/TS' }, + { query: 'Vue 3 的 Composition API 和 Options API 有什么区别?', expectedId: 'javascript-expert', category: '编程-JS/TS' }, + { query: 'Node.js 如何处理大文件上传?', expectedId: 'javascript-expert', category: '编程-JS/TS' }, + + { query: 'Rust 的所有权机制是什么?', expectedId: 'rust-expert', category: '编程-Rust' }, + { query: '如何用 Rust 编写 WebAssembly 模块?', expectedId: 'rust-expert', category: '编程-Rust' }, + + { query: 'C++ 智能指针有哪几种?', expectedId: 'cpp-expert', category: '编程-C++' }, + { query: '如何优化 C++ 程序的内存使用?', expectedId: 'cpp-expert', category: '编程-C++' }, + { query: 'Unreal Engine 游戏开发入门', expectedId: 'cpp-expert', category: '编程-C++' }, + + // ==================== DevOps/运维类 ==================== + { query: 'Docker 镜像怎么优化体积?', expectedId: 'devops-expert', category: 'DevOps' }, + { query: 'Kubernetes 如何实现滚动更新?', expectedId: 'devops-expert', category: 'DevOps' }, + { query: 'GitHub Actions 如何配置 CI/CD?', expectedId: 'devops-expert', category: 'DevOps' }, + { query: 'Terraform 怎么管理云资源?', expectedId: 'devops-expert', category: 'DevOps' }, + + // ==================== 数据库类 ==================== + { query: 'MySQL 索引优化有哪些技巧?', expectedId: 'database-expert', category: '数据库' }, + { query: 'Redis 缓存穿透怎么解决?', expectedId: 'database-expert', category: '数据库' }, + { query: 'MongoDB 如何设计 Schema?', expectedId: 'database-expert', category: '数据库' }, + { query: '如何实现数据库读写分离?', expectedId: 'database-expert', category: '数据库' }, + + // ==================== 安全类 ==================== + { query: 'SQL 注入攻击如何防范?', expectedId: 'security-expert', category: '安全' }, + { query: 'HTTPS 证书怎么配置?', expectedId: 'security-expert', category: '安全' }, + { query: 'JWT Token 安全最佳实践', expectedId: 'security-expert', category: '安全' }, + + // ==================== AI/ML 类 ==================== + { query: '如何用 PyTorch 训练一个图像分类模型?', expectedId: 'ai-ml-expert', category: 'AI/ML' }, + { query: '大语言模型微调有哪些方法?', expectedId: 'ai-ml-expert', category: 'AI/ML' }, + { query: 'RAG 系统怎么搭建?', expectedId: 'ai-ml-expert', category: 'AI/ML' }, + { query: 'YOLO 目标检测怎么用?', expectedId: 'ai-ml-expert', category: 'AI/ML' }, + + // ==================== 前端 UI 类 ==================== + { query: 'Tailwind CSS 怎么自定义主题?', expectedId: 'frontend-ui-expert', category: '前端UI' }, + { query: '如何实现响应式布局?', expectedId: 'frontend-ui-expert', category: '前端UI' }, + { query: '网站无障碍设计要注意什么?', expectedId: 'frontend-ui-expert', category: '前端UI' }, + + // ==================== 移动端类 ==================== + { query: 'SwiftUI 和 UIKit 哪个更好?', expectedId: 'mobile-expert', category: '移动端' }, + { query: 'Flutter 性能优化技巧', expectedId: 'mobile-expert', category: '移动端' }, + { query: 'React Native 如何调用原生模块?', expectedId: 'mobile-expert', category: '移动端' }, + { query: 'Android Kotlin 协程怎么用?', expectedId: 'mobile-expert', category: '移动端' }, + + // ==================== 非技术类 ==================== + { query: '帮我写一份劳动合同', expectedId: 'legal-advisor', category: '法律' }, + { query: '商标注册流程是什么?', expectedId: 'legal-advisor', category: '法律' }, + { query: '公司股权架构怎么设计?', expectedId: 'legal-advisor', category: '法律' }, + + { query: '帮我写一个广告文案', expectedId: 'creative-writer', category: '写作' }, + { query: '如何写一个吸引人的故事开头?', expectedId: 'creative-writer', category: '写作' }, + { query: '品牌故事怎么写才能打动人?', expectedId: 'creative-writer', category: '写作' }, + + { query: '如何做用户调研?', expectedId: 'product-manager', category: '产品' }, + { query: 'PRD 文档怎么写?', expectedId: 'product-manager', category: '产品' }, + { query: 'Scrum 和 Kanban 有什么区别?', expectedId: 'product-manager', category: '产品' }, + + { query: '用户留存率怎么分析?', expectedId: 'data-analyst', category: '数据分析' }, + { query: 'SQL 窗口函数怎么用?', expectedId: 'data-analyst', category: '数据分析' }, + { query: 'Power BI 仪表盘怎么设计?', expectedId: 'data-analyst', category: '数据分析' }, + + { query: '雅思写作怎么拿高分?', expectedId: 'english-teacher', category: '英语' }, + { query: '英语语法中的虚拟语气怎么用?', expectedId: 'english-teacher', category: '英语' }, + { query: '托福口语怎么准备?', expectedId: 'english-teacher', category: '英语' }, + + { query: '制定一个增肌训练计划', expectedId: 'fitness-coach', category: '健身' }, + { query: '减脂期间怎么吃?', expectedId: 'fitness-coach', category: '健身' }, + { query: '深蹲的标准动作是什么?', expectedId: 'fitness-coach', category: '健身' }, + + { query: '基金定投策略有哪些?', expectedId: 'finance-advisor', category: '理财' }, + { query: '个人所得税怎么优化?', expectedId: 'finance-advisor', category: '理财' }, + { query: '如何分析一只股票?', expectedId: 'finance-advisor', category: '理财' }, + + { query: '最近工作压力很大怎么办?', expectedId: 'psychologist', category: '心理' }, + { query: '如何克服社交焦虑?', expectedId: 'psychologist', category: '心理' }, + { query: '和同事关系紧张怎么处理?', expectedId: 'psychologist', category: '心理' }, + + // ==================== 无匹配/边界测试 ==================== + { query: '今天天气怎么样?', expectedId: null, category: '无匹配' }, + { query: '推荐一部好看的电影', expectedId: null, category: '无匹配' }, + { query: '附近有什么好吃的?', expectedId: null, category: '无匹配' }, +]; + +async function runTests() { + console.log('='.repeat(60)); + console.log('MCP RAG Prompts - 综合测试'); + console.log('='.repeat(60)); + + // 初始化 + await vectorStore.initialize(); + + const providerInfo = vectorStore.getProviderInfo(); + console.log(`\n当前 Embedding 提供者: ${providerInfo.provider}`); + console.log(`总测试用例数: ${testCases.length}\n`); + + // 统计 + let passed = 0; + let failed = 0; + const failedCases: { query: string; expected: string | null; actual: string | null }[] = []; + + // 按类别分组显示 + let currentCategory = ''; + + for (const testCase of testCases) { + // 打印类别标题 + if (testCase.category !== currentCategory) { + currentCategory = testCase.category; + console.log(`\n--- ${currentCategory} ---`); + } + + const result = await vectorStore.search(testCase.query); + const actualId = result?.prompt.id ?? null; + const isPass = actualId === testCase.expectedId; + + if (isPass) { + passed++; + console.log(`✓ "${testCase.query.slice(0, 30)}..." → ${actualId ?? '(无匹配)'}`); + } else { + failed++; + failedCases.push({ + query: testCase.query, + expected: testCase.expectedId, + actual: actualId, + }); + console.log(`✗ "${testCase.query.slice(0, 30)}..."`); + console.log(` 期望: ${testCase.expectedId ?? '(无匹配)'}, 实际: ${actualId ?? '(无匹配)'}`); + } + } + + // 打印统计结果 + console.log('\n' + '='.repeat(60)); + console.log('测试结果统计'); + console.log('='.repeat(60)); + console.log(`总计: ${testCases.length} 个用例`); + console.log(`通过: ${passed} (${((passed / testCases.length) * 100).toFixed(1)}%)`); + console.log(`失败: ${failed} (${((failed / testCases.length) * 100).toFixed(1)}%)`); + + if (failedCases.length > 0) { + console.log('\n失败用例详情:'); + failedCases.forEach((fc, i) => { + console.log(`${i + 1}. "${fc.query}"`); + console.log(` 期望: ${fc.expected ?? '(无匹配)'}`); + console.log(` 实际: ${fc.actual ?? '(无匹配)'}`); + }); + } + + console.log('\n测试完成!'); +} + +runTests().catch(console.error); diff --git a/src/tools/searchPersona.ts b/src/tools/searchPersona.ts new file mode 100644 index 0000000..7d8f395 --- /dev/null +++ b/src/tools/searchPersona.ts @@ -0,0 +1,129 @@ +/** + * MCP Tool: search_expert_persona + * 根据用户问题语义搜索最匹配的专家角色设定 + */ + +import { z } from 'zod'; +import { vectorStore } from '../lib/vectorStore.js'; + +/** + * 工具名称 + */ +export const TOOL_NAME = 'search_expert_persona'; + +/** + * 工具描述 + */ +export const TOOL_DESCRIPTION = + '根据用户的具体问题或场景,利用语义搜索找到最匹配的专家角色设定 (System Prompt)。' + + '输入用户的问题或需求描述,返回最适合处理该问题的专家角色 Prompt。'; + +/** + * 参数 Schema(使用 Zod 定义) + */ +export const inputSchema = z.object({ + query: z + .string() + .min(1, '查询内容不能为空') + .describe('用户的原始问题或需求描述,例如:"如何用 Python 实现一个 REST API?"'), +}); + +/** + * 参数类型 + */ +export type SearchPersonaInput = z.infer; + +/** + * 将 Zod Schema 转换为 JSON Schema(供 MCP SDK 使用) + */ +export const inputJsonSchema = { + type: 'object' as const, + properties: { + query: { + type: 'string', + description: '用户的原始问题或需求描述,例如:"如何用 Python 实现一个 REST API?"', + }, + }, + required: ['query'], +}; + +/** + * 执行搜索的处理函数 + * @param input 经过验证的输入参数 + * @returns MCP 工具响应内容 + */ +export async function handleSearchPersona(input: SearchPersonaInput): Promise<{ + content: Array<{ type: 'text'; text: string }>; + isError?: boolean; +}> { + try { + // 验证输入 + const validatedInput = inputSchema.parse(input); + + // 执行语义搜索 + const result = await vectorStore.search(validatedInput.query); + + if (!result) { + // 没有找到匹配结果 + return { + content: [ + { + type: 'text', + text: JSON.stringify( + { + success: false, + message: '未找到与您问题匹配的专家角色。请尝试更具体地描述您的需求。', + availableExperts: vectorStore.getAvailablePrompts(), + }, + null, + 2 + ), + }, + ], + }; + } + + // 返回匹配结果 + return { + content: [ + { + type: 'text', + text: JSON.stringify( + { + success: true, + matchedExpert: { + id: result.prompt.id, + tags: result.prompt.tags, + description: result.prompt.description, + similarity: Math.round(result.similarity * 100) / 100, + }, + systemPrompt: result.prompt.content, + }, + null, + 2 + ), + }, + ], + }; + } catch (error) { + // 处理错误 + const errorMessage = error instanceof Error ? error.message : '未知错误'; + + return { + content: [ + { + type: 'text', + text: JSON.stringify( + { + success: false, + error: errorMessage, + }, + null, + 2 + ), + }, + ], + isError: true, + }; + } +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..c83c533 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "lib": ["ES2022"], + "outDir": "./dist", + "rootDir": "./src", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "declaration": true, + "declarationMap": true, + "sourceMap": true + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] +}