插件 Scheduler 请支持 opt-in 接收全 priority 层候选(先业务池过滤再套 CPA priority/weight)

Author: FlameMidaCreated Sep 17, 2026Updated Sep 17, 2026
LabelsFixed

场景

CPA 上有一批上游凭据(认证文件 / AI Providers),各自配置了 priorityweight。多个客户端 key 共用这一池子,但每个 key 只被允许使用其中一部分渠道(例如 key A 只能走订阅 1、2;key B 只能走订阅 3)。

这是插件 model-mapper-plus 的「渠道定向」:在 scheduler.pick 里把候选限制到该 key 绑定的供应商 ∪ 凭据,交集为空则 429,绝不改用池外凭据

管理员期望的调度是:

  1. 看这个 key 当前真正能用的渠道(绑定集合 ∩ 当前就绪);
  2. 只在这个子集上套 CPA 已有的调度规则:更高 priority 优先;同一层内按 weight 做平滑加权;weight≤0 不接流量。

也就是:priority/weight 的作用域是「这个 key 拥有的渠道」,而不是「全实例所有凭据」。

用途

  • 多租户 / 多 key 共用一台 CPA 时,每个 key 锁定自己的上游,避免打到别人的订阅。
  • 锁定之后,仍然希望沿用 CPA 管理页里已经配好的 priority、weight,不必在插件里再做一套优先级配置。
  • 某 key 的渠道全部在冷却时,行为应是「该 key 暂时不可用」(429),而不是悄悄用池外更高优先级的凭据顶上。

当前限制(问题本身)

宿主在调用插件 scheduler.pick 之前,已经按 全局 最高 priority 裁掉一层,只把这一层放进 Candidates

因此会出现:

  • key A 绑定的是 priority=5 的凭据 F1(本身 active);
  • 池外有一条 priority=10 的凭据 F2(不属于 A);
  • 宿主只把 F2 交给插件 → 插件过滤后池空 → A 收到 429;
  • F1 从未进入 Candidates,插件无法选它。

routing.strategy(round-robin / weighted-round-robin / fill-first)只决定最高层内部怎么挑,不能关掉这层预过滤。

v7.3.3 的 availableAuthsForRouteModelAcrossPriorities 把全层候选给了 SessionAffinity 内建选择器,插件路径拿到的仍是最高层。

插件侧也无法自救:不能选择不在 Candidates 里的 AuthID;DelegateBuiltin 会在宿主全量分片上重挑,会破坏「不许用池外凭据」。把全部凭据 priority 拉平可以避开裁层,但会抹掉 CPA 的 priority 信号,插件也就没法再分层。

以上在 SDK v7.2.119v7.2.159v7.3.3 上行为一致;SchedulerPickRequest / SchedulerAuthCandidate 没有新字段能要到全层候选。

建议(宿主侧)

请让插件 Scheduler 可以拿到「各 priority 层里当前可用」的凭据(cooldown / 不可用的仍排除;PriorityAttributes["weight"] 继续透传)。插件自己做:业务池过滤 → 按 Priority 取最高层 → 层内按 weight 调度。

兼容上希望 opt-in(注册能力或等价声明)。现有插件多半默认「Candidates 已经是最高层」;若无开关直接改成全层,它们可能误选低优先级凭据。

Source: router-for-me/CLIProxyAPI