feat: Unified Embedding Pool with auto-discovery

Architecture refactoring for multi-provider rotation:

Backend:
- Add EmbeddingPoolConfig type with autoDiscover support
- Implement discoverProvidersForModel() for auto-aggregation
- Add GET/PUT /api/litellm-api/embedding-pool endpoints
- Add GET /api/litellm-api/embedding-pool/discover/:model preview
- Convert ccw-litellm status check to async with 5-min cache
- Maintain backward compatibility with legacy rotation config

Frontend:
- Add "Embedding Pool" tab in API Settings
- Auto-discover providers when target model selected
- Show provider/key count with include/exclude controls
- Increase sidebar width (280px → 320px)
- Add sync result feedback on save

Other:
- Remove worker count limits (was max=32)
- Add i18n translations (EN/CN)
- Update .gitignore for .mcp.json

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
catlog22
2025-12-25 16:06:49 +08:00
parent 4e6ee2db25
commit a1413dd1b3
10 changed files with 882 additions and 43 deletions

View File

@@ -19,6 +19,7 @@ const i18n = {
'common.delete': 'Delete',
'common.cancel': 'Cancel',
'common.save': 'Save',
'common.include': 'Include',
'common.close': 'Close',
'common.loading': 'Loading...',
'common.error': 'Error',
@@ -28,6 +29,8 @@ const i18n = {
'common.retry': 'Retry',
'common.refresh': 'Refresh',
'common.minutes': 'minutes',
'common.enabled': 'Enabled',
'common.disabled': 'Disabled',
// Header
'header.project': 'Project:',
@@ -267,7 +270,7 @@ const i18n = {
'codexlens.embeddingModel': 'Embedding Model',
'codexlens.modelHint': 'Select embedding model for vector search (models with ✓ are installed)',
'codexlens.concurrency': 'API Concurrency',
'codexlens.concurrencyHint': 'Number of parallel API calls (1-32). Higher values speed up indexing but may hit rate limits.',
'codexlens.concurrencyHint': 'Number of parallel API calls. Higher values speed up indexing but may hit rate limits.',
'codexlens.concurrencyCustom': 'Custom',
'codexlens.rotation': 'Multi-Provider Rotation',
'codexlens.rotationDesc': 'Aggregate multiple API providers and keys for parallel embedding generation',
@@ -289,6 +292,8 @@ const i18n = {
'codexlens.selectKeys': 'Select Keys',
'codexlens.configureRotation': 'Configure Rotation',
'codexlens.rotationSaved': 'Rotation config saved successfully',
'codexlens.endpointsSynced': 'endpoints synced to CodexLens',
'codexlens.syncFailed': 'Sync failed',
'codexlens.rotationDeleted': 'Rotation config deleted',
'codexlens.totalEndpoints': 'Total Endpoints',
'codexlens.fullIndex': 'Full',
@@ -312,6 +317,9 @@ const i18n = {
'codexlens.runSearch': 'Run Search',
'codexlens.results': 'Results',
'codexlens.resultsCount': 'results',
'codexlens.resultLimit': 'Limit',
'codexlens.contentLength': 'Content Length',
'codexlens.extraFiles': 'Extra Files',
'codexlens.saveConfig': 'Save Configuration',
'codexlens.searching': 'Searching...',
'codexlens.searchCompleted': 'Search completed',
@@ -1470,6 +1478,20 @@ const i18n = {
'apiSettings.endpointDeleted': 'Endpoint deleted successfully',
'apiSettings.cacheCleared': 'Cache cleared successfully',
'apiSettings.cacheSettingsUpdated': 'Cache settings updated',
'apiSettings.embeddingPool': 'Embedding Pool',
'apiSettings.embeddingPoolDesc': 'Auto-rotate between providers with same model',
'apiSettings.targetModel': 'Target Model',
'apiSettings.discoveredProviders': 'Discovered Providers',
'apiSettings.autoDiscover': 'Auto-discover providers',
'apiSettings.excludeProvider': 'Exclude',
'apiSettings.defaultCooldown': 'Cooldown (seconds)',
'apiSettings.defaultConcurrent': 'Concurrent per key',
'apiSettings.poolEnabled': 'Enable Embedding Pool',
'apiSettings.noProvidersFound': 'No providers found for this model',
'apiSettings.poolSaved': 'Embedding pool config saved',
'apiSettings.strategy': 'Strategy',
'apiSettings.providerKeys': 'keys',
'apiSettings.selectTargetModel': 'Select target model',
'apiSettings.confirmDeleteProvider': 'Are you sure you want to delete this provider?',
'apiSettings.confirmDeleteEndpoint': 'Are you sure you want to delete this endpoint?',
'apiSettings.confirmClearCache': 'Are you sure you want to clear the cache?',
@@ -1703,6 +1725,7 @@ const i18n = {
'common.delete': '删除',
'common.cancel': '取消',
'common.save': '保存',
'common.include': '包含',
'common.close': '关闭',
'common.loading': '加载中...',
'common.error': '错误',
@@ -1712,6 +1735,8 @@ const i18n = {
'common.retry': '重试',
'common.refresh': '刷新',
'common.minutes': '分钟',
'common.enabled': '已启用',
'common.disabled': '已禁用',
// Header
'header.project': '项目:',
@@ -1951,7 +1976,7 @@ const i18n = {
'codexlens.embeddingModel': '嵌入模型',
'codexlens.modelHint': '选择向量搜索的嵌入模型(带 ✓ 的已安装)',
'codexlens.concurrency': 'API 并发数',
'codexlens.concurrencyHint': '并行 API 调用数量1-32。较高的值可加速索引但可能触发速率限制。',
'codexlens.concurrencyHint': '并行 API 调用数量。较高的值可加速索引但可能触发速率限制。',
'codexlens.concurrencyCustom': '自定义',
'codexlens.rotation': '多供应商轮训',
'codexlens.rotationDesc': '聚合多个 API 供应商和密钥进行并行嵌入生成',
@@ -1973,6 +1998,8 @@ const i18n = {
'codexlens.selectKeys': '选择密钥',
'codexlens.configureRotation': '配置轮训',
'codexlens.rotationSaved': '轮训配置保存成功',
'codexlens.endpointsSynced': '个端点已同步到 CodexLens',
'codexlens.syncFailed': '同步失败',
'codexlens.rotationDeleted': '轮训配置已删除',
'codexlens.totalEndpoints': '总端点数',
'codexlens.fullIndex': '全部',
@@ -1996,6 +2023,9 @@ const i18n = {
'codexlens.runSearch': '运行搜索',
'codexlens.results': '结果',
'codexlens.resultsCount': '个结果',
'codexlens.resultLimit': '数量限制',
'codexlens.contentLength': '内容长度',
'codexlens.extraFiles': '额外文件',
'codexlens.saveConfig': '保存配置',
'codexlens.searching': '搜索中...',
'codexlens.searchCompleted': '搜索完成',
@@ -3163,6 +3193,20 @@ const i18n = {
'apiSettings.endpointDeleted': '端点删除成功',
'apiSettings.cacheCleared': '缓存清除成功',
'apiSettings.cacheSettingsUpdated': '缓存设置已更新',
'apiSettings.embeddingPool': '高可用嵌入',
'apiSettings.embeddingPoolDesc': '自动轮训相同模型的供应商',
'apiSettings.targetModel': '目标模型',
'apiSettings.discoveredProviders': '发现的供应商',
'apiSettings.autoDiscover': '自动发现供应商',
'apiSettings.excludeProvider': '排除',
'apiSettings.defaultCooldown': '冷却时间(秒)',
'apiSettings.defaultConcurrent': '每密钥并发数',
'apiSettings.poolEnabled': '启用嵌入池',
'apiSettings.noProvidersFound': '未找到提供此模型的供应商',
'apiSettings.poolSaved': '嵌入池配置已保存',
'apiSettings.strategy': '策略',
'apiSettings.providerKeys': '密钥',
'apiSettings.selectTargetModel': '选择目标模型',
'apiSettings.confirmDeleteProvider': '确定要删除此提供商吗?',
'apiSettings.confirmDeleteEndpoint': '确定要删除此端点吗?',
'apiSettings.confirmClearCache': '确定要清除缓存吗?',