Skip to main content
Glama
freefish1218

MCP HuggingFetch

by freefish1218
suggestions.js13.2 kB
/** * 智能建议生成模块 - 根据查询结果生成有用的建议 */ const { PRESET_PATTERNS } = require('./patterns'); /** * 建议生成器类 */ class SuggestionGenerator { constructor() { // 常见模型类型和对应的关键文件 this.modelTypes = { transformers: { keywords: ['pytorch_model.bin', 'model.safetensors', 'config.json'], description: 'Transformers模型' }, diffusers: { keywords: ['model_index.json', 'unet/diffusion_pytorch_model.bin'], description: 'Diffusion模型' }, gguf: { keywords: ['.gguf', '.ggml'], description: 'GGUF/GGML量化模型' }, onnx: { keywords: ['.onnx'], description: 'ONNX模型' }, tensorflow: { keywords: ['saved_model.pb', '.h5', '.tflite'], description: 'TensorFlow模型' } }; // 文件大小建议阈值 this.sizeThresholds = { small: 100 * 1024 * 1024, // 100MB medium: 1024 * 1024 * 1024, // 1GB large: 5 * 1024 * 1024 * 1024, // 5GB huge: 20 * 1024 * 1024 * 1024 // 20GB }; } /** * 生成建议 */ generateSuggestions(context) { const suggestions = []; // 根据不同的上下文生成建议 if (context.error) { suggestions.push(...this.generateErrorSuggestions(context.error)); } if (context.files && context.files.length > 0) { suggestions.push(...this.generateFileSuggestions(context.files, context.options)); } if (context.stats) { suggestions.push(...this.generateStatsSuggestions(context.stats)); } if (context.download) { suggestions.push(...this.generateDownloadSuggestions(context.download)); } // 去重并排序 return this.formatSuggestions(suggestions); } /** * 错误相关建议 */ generateErrorSuggestions(error) { const suggestions = []; if (error.code === 'NOT_FOUND') { suggestions.push({ type: 'error', priority: 1, text: '检查仓库ID格式是否正确(格式:owner/repo)', command: null }); suggestions.push({ type: 'error', priority: 2, text: '确认仓库是否存在且为公开仓库', command: null }); } if (error.code === 'RATE_LIMIT') { suggestions.push({ type: 'warning', priority: 1, text: '使用认证令牌以获得更高的速率限制', command: 'export HF_TOKEN=your_token_here' }); suggestions.push({ type: 'info', priority: 2, text: '考虑使用缓存或减少请求频率', command: null }); } if (error.code === 'NETWORK_ERROR') { suggestions.push({ type: 'error', priority: 1, text: '检查网络连接和防火墙设置', command: null }); suggestions.push({ type: 'info', priority: 2, text: '如在中国大陆,可能需要配置代理', command: 'export HTTPS_PROXY=your_proxy_here' }); } if (error.code === 'UNAUTHORIZED') { suggestions.push({ type: 'error', priority: 1, text: '认证失败,请检查访问权限', command: null }); suggestions.push({ type: 'info', priority: 2, text: '如果是私有仓库,请提供有效的访问令牌', command: 'export HF_TOKEN=your_token_here' }); } if (error.code === 'FORBIDDEN') { suggestions.push({ type: 'error', priority: 1, text: '权限不足,无法访问该资源', command: null }); suggestions.push({ type: 'info', priority: 2, text: '确认token具有所需权限', command: null }); } return suggestions; } /** * 文件相关建议 */ generateFileSuggestions(files, options = {}) { const suggestions = []; // 分析文件类型 const fileTypes = this.analyzeFileTypes(files); const modelType = this.detectModelType(files); // 模型类型建议 if (modelType) { suggestions.push({ type: 'info', priority: 1, text: `检测到${this.modelTypes[modelType].description}`, details: this.getModelSpecificSuggestions(modelType, files) }); } // 文件过滤建议 if (!options.pattern && !options.allow_patterns && files.length > 100) { suggestions.push({ type: 'tip', priority: 2, text: '文件数量较多,建议使用pattern参数过滤', command: '使用 pattern: "*.safetensors" 只下载模型文件' }); } // 大文件建议 const largeFiles = files.filter(f => f.size > this.sizeThresholds.large); if (largeFiles.length > 0) { suggestions.push({ type: 'warning', priority: 1, text: `发现 ${largeFiles.length} 个大文件(>5GB)`, details: '建议:使用断点续传、增加超时时间、考虑分批下载' }); } // 文件类型分布建议 if (fileTypes.models > 0 && fileTypes.configs > 0) { suggestions.push({ type: 'info', priority: 3, text: '完整的模型仓库,包含模型文件和配置', details: `模型文件: ${fileTypes.models}个, 配置文件: ${fileTypes.configs}个` }); } // 空仓库建议 if (files.length === 0) { suggestions.push({ type: 'warning', priority: 1, text: '仓库为空或没有匹配的文件', details: options.pattern ? '尝试调整pattern参数' : '检查仓库内容' }); } return suggestions; } /** * 统计相关建议 */ generateStatsSuggestions(stats) { const suggestions = []; if (stats.truncated) { suggestions.push({ type: 'info', priority: 2, text: `结果被截断,仅显示前 ${stats.returned_files || stats.fileCount} 个文件`, command: '增加 max_files 参数以获取更多文件' }); } if (stats.total_size > this.sizeThresholds.huge) { const sizeGB = Math.round(stats.total_size / 1024 / 1024 / 1024); suggestions.push({ type: 'warning', priority: 1, text: `仓库总大小超过 ${sizeGB}GB`, details: '建议:仔细选择需要下载的文件,使用pattern过滤' }); } if (stats.directory_count > 10 && stats.depth > 3) { suggestions.push({ type: 'info', priority: 3, text: '仓库结构复杂,目录层级较深', command: '可使用 max_depth 参数限制扫描深度' }); } return suggestions; } /** * 下载相关建议 */ generateDownloadSuggestions(download) { const suggestions = []; // 下载速度建议 if (download.speed && download.speed < 1024 * 100) { // 小于100KB/s suggestions.push({ type: 'warning', priority: 2, text: '下载速度较慢', details: '建议:检查网络连接、使用更近的镜像、或在网络状况好时下载' }); } // 断点续传建议 if (download.resumable) { suggestions.push({ type: 'info', priority: 3, text: '支持断点续传', details: '如果下载中断,可以继续之前的进度' }); } // 并发下载建议 if (download.fileCount > 10) { suggestions.push({ type: 'tip', priority: 2, text: `正在下载 ${download.fileCount} 个文件`, details: '已启用并发下载以提高效率' }); } // 磁盘空间建议 if (download.requiredSpace > download.availableSpace * 0.9) { suggestions.push({ type: 'error', priority: 1, text: '磁盘空间可能不足', details: `需要 ${this.formatSize(download.requiredSpace)},可用 ${this.formatSize(download.availableSpace)}` }); } return suggestions; } /** * 分析文件类型分布 */ analyzeFileTypes(files) { const types = { models: 0, configs: 0, docs: 0, code: 0, data: 0, other: 0 }; files.forEach(file => { const path = typeof file === 'string' ? file : file.path; if (this.matchesPattern(path, PRESET_PATTERNS.models)) { types.models++; } else if (this.matchesPattern(path, PRESET_PATTERNS.configs)) { types.configs++; } else if (this.matchesPattern(path, PRESET_PATTERNS.docs)) { types.docs++; } else if (this.matchesPattern(path, PRESET_PATTERNS.code)) { types.code++; } else if (this.matchesPattern(path, PRESET_PATTERNS.data)) { types.data++; } else { types.other++; } }); return types; } /** * 检测模型类型 */ detectModelType(files) { const filePaths = files.map(f => typeof f === 'string' ? f : f.path); for (const [type, info] of Object.entries(this.modelTypes)) { const hasKeywords = info.keywords.some(keyword => filePaths.some(path => path.includes(keyword)) ); if (hasKeywords) { return type; } } return null; } /** * 获取模型特定建议 */ getModelSpecificSuggestions(modelType, files) { const suggestions = []; switch (modelType) { case 'transformers': suggestions.push('使用 transformers 库加载: from transformers import AutoModel'); suggestions.push('确保下载 config.json 和 tokenizer 文件'); break; case 'diffusers': suggestions.push('使用 diffusers 库加载: from diffusers import DiffusionPipeline'); suggestions.push('需要下载所有子目录(unet, vae, text_encoder等)'); break; case 'gguf': suggestions.push('适用于 llama.cpp、Ollama 等工具'); suggestions.push('选择合适的量化版本(Q4_K_M, Q5_K_M等)'); break; case 'onnx': suggestions.push('使用 ONNX Runtime 加载'); suggestions.push('跨平台部署的好选择'); break; case 'tensorflow': suggestions.push('使用 TensorFlow 加载'); suggestions.push('注意 TF1.x 和 TF2.x 的兼容性'); break; } return suggestions.join('\n'); } /** * 格式化建议 */ formatSuggestions(suggestions) { // 去重 const unique = []; const seen = new Set(); suggestions.forEach(suggestion => { const key = `${suggestion.type}-${suggestion.text}`; if (!seen.has(key)) { seen.add(key); unique.push(suggestion); } }); // 按优先级排序 unique.sort((a, b) => (a.priority || 999) - (b.priority || 999)); // 格式化输出 return unique.map(suggestion => this.formatSingleSuggestion(suggestion)); } /** * 格式化单个建议 */ formatSingleSuggestion(suggestion) { const icons = { error: '❌', warning: '⚠️', info: 'ℹ️', tip: '💡', success: '✅' }; let formatted = `${icons[suggestion.type] || '•'} ${suggestion.text}`; if (suggestion.details) { formatted += `\n ${suggestion.details}`; } if (suggestion.command) { formatted += `\n 命令: ${suggestion.command}`; } return formatted; } /** * 辅助方法:匹配模式 */ matchesPattern(path, patterns) { return patterns.some(pattern => { if (pattern.startsWith('*')) { return path.endsWith(pattern.slice(1)); } return path.includes(pattern); }); } /** * 辅助方法:格式化文件大小 */ formatSize(bytes) { const units = ['B', 'KB', 'MB', 'GB', 'TB']; let size = bytes; let unitIndex = 0; while (size >= 1024 && unitIndex < units.length - 1) { size /= 1024; unitIndex++; } return `${Math.round(size * 100) / 100} ${units[unitIndex]}`; } /** * 生成命令行建议 */ generateCommandSuggestions(context) { const commands = []; if (context.needsAuth) { commands.push({ description: '设置HuggingFace令牌', command: 'export HF_TOKEN=your_token_here' }); } if (context.pattern) { commands.push({ description: '只下载模型文件', command: '--pattern "*.safetensors"' }); commands.push({ description: '排除大文件', command: '--ignore-patterns "*.bin"' }); } if (context.largeRepo) { commands.push({ description: '限制下载文件数量', command: '--max-files 10' }); commands.push({ description: '限制扫描深度', command: '--max-depth 2' }); } return commands; } } /** * 创建建议生成器实例 */ function createSuggestionGenerator() { return new SuggestionGenerator(); } /** * 快速生成建议 */ function quickSuggestions(context) { const generator = new SuggestionGenerator(); return generator.generateSuggestions(context); } module.exports = { SuggestionGenerator, createSuggestionGenerator, quickSuggestions };

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/freefish1218/mcp-huggingfetch'

If you have feedback or need assistance with the MCP directory API, please join our Discord server