feat: 新增节点优先级配置,支持多候选模型按优先级路由 - #697
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 431d96a8eb
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
|
||
| // 0. 优先级分层:priority 越小越优先,未配置默认 Infinity | ||
| // 使用 1e16 作为每个优先级层的间隔,确保低优先级节点不会因其他因子超越高优先级节点 | ||
| const priorityScore = (config.priority ?? Infinity) * 1e16; |
There was a problem hiding this comment.
Use a finite score for nodes without priority
Existing provider-pool configurations, and new nodes whose optional priority field is left blank, have no priority, so this expression makes every healthy node's score Infinity. In _doSelectProvider, all such scores compare equal and the UUID tie-breaker repeatedly selects the same node, disabling the existing LRU/load balancing behavior for the default configuration. Use a finite lowest-priority tier so the remaining score components can still order nodes within that tier.
Useful? React with 👍 / 👎.
| return CONFIG.customModels.filter(m => | ||
| // m.provider === targetProvider && | ||
| (m.id === targetModelId || m.alias === targetModelId) |
There was a problem hiding this comment.
Preserve the explicit provider prefix when collecting routes
When a request uses an explicit model such as atlascloud:gpt-4o, the prefix is parsed into targetProvider but then ignored by this filter. If several custom models share the gpt-4o alias—as in the supplied example—the priority comparison can route that explicitly prefixed request through qiniu, fenno, or another provider instead of atlascloud. Keep the m.provider === targetProvider constraint for prefixed model IDs.
Useful? React with 👍 / 👎.
| const healthyProviders = availableProviders.filter(p => | ||
| p.config.isHealthy && !p.config.isDisabled && !p.config.needsRefresh | ||
| ); |
There was a problem hiding this comment.
Recover scheduled nodes before evaluating custom routes
For a custom-model candidate whose target node was marked unhealthy with scheduledRecoveryTime, this method filters the node out without invoking _checkAndRecoverScheduledProviders, unlike both selectProvider and the new hasHealthyProviderForModel. Once the cooldown expires, alias requests still skip that target and never reach selection, so it may remain unusable indefinitely when scheduled health checks are disabled and no unrelated traffic selects that provider type. Run scheduled recovery before constructing healthyProviders.
Useful? React with 👍 / 👎.
| // 0. 优先级分层:priority 越小越优先,未配置默认 Infinity | ||
| // 使用 1e16 作为每个优先级层的间隔,确保低优先级节点不会因其他因子超越高优先级节点 | ||
| const priorityScore = (config.priority ?? Infinity) * 1e16; |
There was a problem hiding this comment.
Skip queue-full nodes before applying priority tiers
With configured tiers, the fixed 1e17 score returned for a queue-full node can beat an idle lower-priority node: for example, a full priority-1 node scores 1e17, while an idle priority-10 node scores slightly above 1e17 after its base score is added. acquireSlot therefore selects the full node and throws 429 even though the lower-priority node has capacity, regressing the prior concurrency fallback behavior. Exclude full nodes or ensure their sentinel score sorts after every usable priority tier.
Useful? React with 👍 / 👎.
功能:新增节点优先级配置,支持多候选模型按优先级路由
背景
当
customModels中配置了多个modelId/alias相同的模型映射(例如多个供应商提供同一个模型),或同一模型既在customModels中配置又被当前 Provider 直接支持时,原先只能取第一个匹配的配置,无法按节点健康状态和优先级智能选择最优路径。变更内容
1. 多候选模型路由引擎
src/utils/common.js-handleContentGenerationRequest重写模型选择逻辑:收集所有匹配的customModel候选 + 当前 Provider 直接支持,按节点优先级排序,选最优路径;所有候选不可用时兜底到直接支持src/providers/provider-models.js- 新增getAllCustomModelConfigs()返回所有匹配的自定义模型配置(而非仅第一个)2. 节点优先级评分
src/providers/provider-pool-manager.js-_calculateNodeScore()引入priority作为首要排序因子(priority * 1e16),确保低优先级节点不会因其他因子(使用次数、负载等)被误选hasHealthyProviderForModel()- 只读检查指定 Provider 是否有健康节点支持某模型getBestPriorityForModel()- 获取指定 Provider 下支持某模型的健康节点中最高优先级3. 配置与 UI
configs/provider_pools.json.example- 示例配置添加priority字段static/app/modal.js- 新增/编辑 Provider 表单增加「优先级」输入框,可选填,留空视为最低优先级static/app/utils.js- 注册priority字段标签static/app/i18n.js- 中英文翻译添加modal.provider.priority条目使用方式
在
provider_pools.json的节点配置中添加priority字段,数值越小优先级越高(如priority: 1高于priority: 10)。未配置的节点默认最低优先级。