omp packages

pi-ccswitch-auto-switch0.3.16

Provider-first automatic model failover extension for Pi and CC Switch

errorje Published 11 days ago MIT ~1.5K downloads/mo

Untested on omp

This is a pi package. No one has reported whether it works on omp yet. If you try it, add your result below.

Did it work for you?

Result

One report per person. A new report replaces your old one.

Reports 0

No reports yet.

Readme

Pi CCSwitch 自动故障转移

推荐项目: Magpie,适合统一管理多个 AI Agent 的模型、账号和路由。

English: README.md

当 CC Switch 管理 Pi 的 Provider 时,为 Pi 提供更稳健的模型自动故障转移。

它只观察 Pi 的真实请求,保存脱敏健康记录;仅在 TUI/RPC 交互会话中,才会把失败请求平滑切到健康模型。额度耗尽、凭据失效或限流等 Provider 级问题会直接熔断整个 Provider,不会连续尝试同一 Provider 下的多个兄弟模型。

功能

  • 以 Pi 的有效模型注册表为准,不读取 CC Switch 数据库、Pi 认证文件或 API Key。
  • 对认证、额度、账单和限流实施 Provider 优先熔断。
  • 对 DNS、连接、服务端和流中断实施端点熔断。
  • 模型不存在或参数不兼容时仅隔离该模型。
  • Pi 本地程序分块文件缺失时停止本轮切换并提示完整重启,不计入模型、Provider 或端点健康,也不触发平台隔离。
  • 内容审查失败会学习模型系列约束(例如 glm-4.5、GLM-4.6 同属 glm),在本轮内容审查故障转移中避开整个受限系列。该约束仅保存在当前扩展实例的内存中,不写入共享健康状态;当前实例的 session_start 只清除自身约束,因为新 session 处理的任务不一定涉及审查内容,模型系列恢复可用,直到本 session 再次观察到内容审查拒绝。
  • 候选模型先经过健康、故障域、审查系列、输入模态和上下文窗口硬过滤,再按跨 Provider、模型等价性、能力兼容和历史稳定性排序。
  • 首响应 90 秒、流式停滞 120 秒看门狗。
  • 指数退避、Retry-After 支持和跨进程 half-open 单探针租约。
  • 原子持久化状态、错误脱敏和有上限的日志。
  • Pi 紧凑状态栏与健康管理面板。
  • --print / JSON 非交互运行只监控和记录,不会注入可能与进程退出竞争的新请求。
  • pi-ccswitch-run 使用单个 Pi RPC 会话完成无头自动故障转移,只输出最终成功模型的回答。

要求

  • Pi 0.84.4 或更高版本。
  • 建议使用 CC Switch 3.20+,其已支持原生维护 Pi 模型配置。
  • 本地开发和测试需要 Node.js 22.19+;Pi 运行插件本身不需要额外安装 Node。

配置

插件不需要任何用户配置:它只观察 Pi 的真实请求,读取 Pi 已暴露的模型元数据;从不读取 CC Switch 数据库、Pi 认证文件、API Key、Cookie 或 .env 文件,也从不写入 Pi 模型设置或 CC Switch 数据。

以下开关全部可选,且有合理默认值:

设置项 作用域 默认值 说明
PI_CODING_AGENT_DIR 扩展状态 ~/.pi/agent 健康状态、日志与失败报告的存放目录;仅在你迁移了 Pi agent 目录时需要,插件跟随 Pi 自身约定。
PI_BIN 仅 headless runner PATH 中的 pi 必须指向真实 pi 可执行文件。历史自引用值 pi-ccswitch-run 或 ccswitch-run 会警告并降级到 pi;其他非法命令仍按配置错误处理。
CCSWITCH_ROUND_LIMIT_MS 故障转移 480000(8 分钟) 本轮故障转移的时间限制(毫秒)。窗口从本轮开始或最后一次成功切换起算;超过后停止切换并报告已试模型及最后错误。
模型 scope(/model 等) 故障转移候选 全量注册表 Pi 启用了 model scope 时,只在 scope 内模型间切换;否则使用全量注册表。状态栏会显示当前数据源。
baseUrl 元数据 端点隔离 provider key 端点级平台隔离按 baseUrl 分组模型(由 CC Switch 3.20+ 提供);缺失时退化为 provider 级分组,仍然可用。

安装

通过 Pi Package 安装(推荐)

pi install git:github.com/JunyWuuuu91/pi-ccswitch-auto-switch

该命令在 macOS、Linux 和安装了 Git 的 Windows 上均可使用。npm 版本发布后,也可以执行:

pi install npm:pi-ccswitch-auto-switch

安装或更新本扩展后重启 Pi,或执行 /reload。后续更新 Git 版本可执行 pi update --extensions。

更新 Pi 本体后,应完整退出并重新启动 Pi,再恢复原会话。/reload 只在现有进程中重载扩展和资源。如果旧进程仍引用已被替换的 Pi 程序分块文件,报出 Cannot find module .../pi-coding-agent/dist/bundle/chunks/...,CCSwitch 会停止本轮切换并提示重启 Pi。这类本地加载错误不计入模型、Provider 或端点冷却,也不累计到“失败 3 次隔离平台”的阈值。

无头自动化调用

pi-ccswitch-run(runner.mjs)是独立于 Pi 扩展的 headless 调用入口:它启动一个 pi --mode rpc 会话,把一次请求自动切换到健康模型后只返回最终成功结果。它不在 pi install 的扩展加载路径里自动暴露给下游项目,需要单独安装。

在消费方项目内安装(推荐,保证 require.resolve 可解析)

pi install git:... 只把扩展装进 Pi 全局目录(~/.pi/agent/...),不会把它放进下游项目的 node_modules 解析路径。因此消费方代码里 require.resolve('pi-ccswitch-auto-switch/runner.mjs') 需要把本包安装进自己的项目依赖:

# 在消费方项目目录内执行
npm i github:JunyWuuuu91/pi-ccswitch-auto-switch
# 或从 npm registry 安装最新版
npm i pi-ccswitch-auto-switch@latest

安装后 require.resolve('pi-ccswitch-auto-switch/runner.mjs') 会命中项目自身 node_modules,bin pi-ccswitch-run 也可直接调用。

版本锁定警告(0.x caret 陷阱)

npm 对 ^0.1.6 的 caret 语义只匹配 0.1.x,不会自动升到含 runner.mjs 的 0.3.x。如果机器上 ~/.pi/agent/npm/node_modules/pi-ccswitch-auto-switch 仍停留在 0.1.6(该版本无 runner.mjs、无 pi-ccswitch-run bin),重复执行 pi install 也不会升级。请手动升级 npm 侧版本:

cd ~/.pi/agent/npm && npm install pi-ccswitch-auto-switch@latest

升级后确认 ~/.pi/agent/npm/node_modules/pi-ccswitch-auto-switch/runner.mjs 存在。也可以在扩展内执行 /ccswitch-doctor 检查 runner.mjs 是否可解析。

运行方式

pi-ccswitch-run --no-tools --no-context-files @prompt.md "请总结附件"

runner 内部只显式加载本扩展并启动一次 Pi RPC;PI_BIN 应指定内部真实 pi。为兼容旧配置,PI_BIN=pi-ccswitch-run 或 PI_BIN=ccswitch-run 会输出警告并降级到 PATH 中的 pi,避免递归和长驻消费方连续失败;其他任意命令仍会被拒绝。默认总超时为 10 分钟,可用 --timeout-ms 调整。退出码:成功 0、候选耗尽 1、参数/RPC 配置错误 2、超时 124、中断 130/143。支持文本及 PNG/JPEG/GIF/WebP @文件,按签名识别图片并传入 RPC images;损坏/不支持的图片及其他二进制附件明确拒绝。单附件上限 20 MiB,最多 20 张图片;不支持 stdin。

正常使用 CC Switch 配置 Provider 即可;本插件不会修改 Pi 模型设置或 CC Switch 数据。

命令

命令 作用
/ccswitch 或 /ccswitch status 打开健康面板。
/ccswitch help 在 Pi 内显示命令帮助。
/ccswitch refresh 刷新 Pi 模型注册表和状态栏。
/ccswitch reactivate <provider/model|all> 解除熔断,下一次真实请求验证恢复情况;保留历史。
/ccswitch disable <provider/model> 手动排除模型。
/ccswitch reset <provider/model|all> 确认后删除相应健康历史;all 同时清除已学习的审查约束。
/ccswitch-test 仅检查候选发现,不切换模型。
/ccswitch-doctor 诊断 runner.mjs 可解析性和安装情况。

状态栏

CCS v0.3.5 ✓70/131 · ⏳61 · ⛔0 · 🔄3 · provider/model-id
  • v0.3.5:当前安装的 CCSwitch 扩展版本。
  • ✓70/131:Pi 有效范围内共有 131 个去重后的 provider/model 组合,其中 70 个健康;重复的 scope 条目只计一次。
  • ⏳61:有 61 个模型正受模型、Provider 或端点自动冷却影响;一条 Provider 熔断记录可能同时影响许多模型。
  • ⛔0:没有被手动禁用的模型。
  • 🔄3:本次 pi session 成功切换的模型次数(衡量扩展有效程度,0 时也显示图标)。/new、/fork、/resume 等新 session 开始时归零;但失败记录与冷却状态不重置(它们是物理事实,跨 session 保留)。累计切换数(state.switches)与最近 20 条切换日志会持久化到状态文件,可在 /ccswitch 面板和 /ccswitch-test 中查看。
  • provider/model-id:当前实际生效的模型(provider/id,切换后立即更新,长名自动截断)。
  • 切换中出现 CCS ↻2 provider/model,表示这是本轮的第 2 次切换尝试。切换次数只受本轮时间窗口限制,不再有固定次数上限;只有当所有候选都尝试过仍无可用模型时才会判定本轮失败。

四个状态(健康/冷却/禁用/切换)即使为 0 也始终显示,便于确认扩展处于监控中;全部健康时仍显示零计数,例如 CCS ✓131/131 · ⏳0 · ⛔0 · 🔄0 · provider/model-id。通过 /ccswitch 或 /ccswitch-test 可同时查看 Pi 原始 scope 条目数、去重模型数、受影响模型数、底层熔断记录数、本 session 切换数与累计切换数。

切换成功后扩展还会通过 appendEntry 向会话注入一条 ccswitch-switch custom entry(不参与 LLM 上下文),触发 TUI 底栏重绘——这样 Pi 右下角的模型名显示也会同步为切换后的模型。RPC 模式还会发出协议版本为 1 的 ccswitch-complete 或 ccswitch-exhausted 终态 entry,供 runner 判定最终结果。

故障转移逻辑

插件会先等待 Pi 内置重试结束和会话恢复 idle,再进行切换。新的用户输入会使旧轮次的待切换任务失效,从而避免重复发送。

失败类型 熔断范围 初始冷却
401、403、额度或账单问题 Provider 30 分钟
429 Provider 配额/余额正文(如 AccountQuotaExceeded)→ 30 分钟;否则优先使用 Retry-After,无则 5 分钟
DNS、网络、408、5xx、流中断 端点 2 分钟
404、模型不存在、参数不兼容 模型 15 分钟
内容审查/敏感拦截 当前模型 + 模型系列约束 模型冷却 2 分钟;系列约束按 session 隔离(session_start 时清除)
上下文溢出 仅本轮 无

冷却时间会指数增长但有上限。发生内容审查时,插件只在审查故障转移链中避开已标记系列,普通限流、网络或模型配置故障仍可选择这些模型。上下文溢出时只会选择上下文窗口更大的模型;带图片的请求只选择显式声明支持 image 的模型。无法归类的异常按单模型故障处理并正常切换。用户主动取消是唯一不会触发故障转移的异常终止;看门狗取消会记录为超时。

模态预检(OCR / 图片请求自动切换多模态模型)

Pi 在把请求发给 Provider 时,会根据当前模型的 input 能力静默处理图片:如果模型不支持图片(input 不含 image,即非多模态模型),Pi 会把图片替换成一段文本提示 (image omitted: model does not support images) 再发送——请求不会报错,因此普通的“失败后切换”永远不会触发,模型只会回答“看不到图片”,OCR 结果拿不到。

插件因此在发送前主动预检,不等失败:

  • 用户输入带图片时(input 事件含 images),如果当前模型不支持图片,立即切换到健康的多模态候选(input 明确含 image)再处理,图片被保留;
  • 工具执行返回图片时(如 read 工具读取图片文件,工具结果含 image content),同样在下一轮 LLM 调用前切到多模态模型,确保图片不被剥除;
  • 候选只选明确声明支持图片的模型(input 含 image);元数据缺失的模型不冒险选择;
  • 图片能力要求贯穿整个故障转移轮次,包括重试验证阶段工具返回图片以及此后的再次切换;
  • 切换原因记为 modality,计入本 session 切换数与累计切换;
  • 如果没有可用的多模态候选,RPC 图片输入会返回 exhausted 终态并在发出剥图请求前停止;交互式 TUI 保持原有通知行为。

模态预检只在 TUI/RPC 交互模式下生效(与故障转移一致);print/json 模式只监控不切换。

数据与隐私

健康状态保存在 Pi agent 目录的 ccswitch-auto-switch-state.json。其中只有计数、时间、冷却信息和脱敏/截断的错误摘要;模型系列审查约束只保存在 session 内存中;插件不会访问凭据、Authorization 请求头、CC Switch 数据库或 Pi 的 auth.json。

开发

状态 schema 3 兼容加载 schema 2 的健康记录,将原有累计数保留为共同基线;每个写入实例独立计数,合并时不丢增量、不重复累计。旧版本无法读取 schema 3,新进程中的代码无法修复仍在运行的旧代码。**禁止 schema-2 与 schema-3 版本共用同一目录混跑。**升级时必须依次:① 退出所有使用同一 PI_CODING_AGENT_DIR 的旧 Pi 进程并停止相关定时 runner;② 在进程停止后备份 ccswitch-auto-switch-state.json;③ 升级使用该目录的所有安装;④ 仅启动升级后的进程。当前版本遇到不支持的 schema,或已观察到 schema 3 后又读到 schema 2 时,会拒绝写入、保留原文件,并在 ccswitch-auto-switch.log 记录原因。这不能撤销旧代码已经造成的破坏,因此必须执行上述停机升级步骤。人工启用/禁用按本地单调时间戳选择较新操作;时间戳完全相同时保守保留禁用(旧记录缺字段时也如此)。reset 标记阻止旧快照恢复已清除的记录。计数元数据随实际记录失败或切换的实例数增长。

npm install
npm run typecheck
npm test

TypeScript 已显式列为开发依赖。npm test 开启 Node 原生 TypeScript 类型剥离,在 Node 22.19+ 上运行 health、integration、logic、runner 全部测试。测试使用 Node 内置测试运行器,覆盖失败分类矩阵、系列级审查避让、Provider 优先选择、输入兼容、冷却、状态持久化以及 Windows 路径。

可选任务复杂度

--task-complexity auto 根据任务指令、输入文字长度和图片数量估计推理强度:短文本使用 low;结构化摘要或图片使用 medium;至少 20,000 个字符、4 张图片或跨来源综合分析使用 high。也可显式指定 low|medium|high。这是确定性的任务估计,不是模型质量排名。

默认沿用 Pi 当前模型;需要健康或视觉候选时由 CCSwitch 切换。Pi 会按模型能力限制推理强度。显式 --thinking 优先;省略 --task-complexity 时保留现有推理行为。runner 不写入全局设置。

RPC 图片请求没有可选的视觉模型时返回 exhausted 终态,避免发送丢失图片的请求。交互式 TUI 行为保持不变。超过 1.5 MiB base64 的大图会通过已安装 Pi 的图片处理功能压缩后传入 RPC,保留原图;处理失败时明确报错。

许可证

MIT