pi-ccswitch-auto-switch 0.3.4 → 0.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/README.zh-CN.md +4 -4
- package/index.ts +1 -1
- package/package.json +1 -1
- package/runner.mjs +19 -5
package/README.md
CHANGED
|
@@ -38,7 +38,7 @@ All knobs below are optional and have sensible defaults:
|
|
|
38
38
|
| Setting | Scope | Default | Notes |
|
|
39
39
|
| --- | --- | --- | --- |
|
|
40
40
|
| `PI_CODING_AGENT_DIR` | Extension state | `~/.pi/agent` | Where health state, logs, and failure reports are stored. Only relevant if you relocated your Pi agent directory; the extension follows Pi's own convention. |
|
|
41
|
-
| `PI_BIN` | Headless runner only | `pi` on `PATH` | Must point to the real `pi` executable
|
|
41
|
+
| `PI_BIN` | Headless runner only | `pi` on `PATH` | Must point to the real `pi` executable. Legacy self-references to `pi-ccswitch-run` or `ccswitch-run` are ignored with a warning and fall back to `pi`; other invalid commands remain configuration errors. |
|
|
42
42
|
| Model scope (`/model` etc.) | Failover candidates | Full registry | When Pi has an active model scope, failover only considers models inside that scope; otherwise the full registry is used. The status bar shows which source is active. |
|
|
43
43
|
| `baseUrl` metadata | Endpoint isolation | provider key | Endpoint-level platform isolation groups models by `baseUrl` (provided by CC Switch `3.20+`). Without it, isolation degrades to provider-level grouping, which still works. |
|
|
44
44
|
|
|
@@ -93,7 +93,7 @@ cd ~/.pi/agent/npm && npm install pi-ccswitch-auto-switch@latest
|
|
|
93
93
|
pi-ccswitch-run --no-tools --no-context-files @prompt.md "Summarize the attached text"
|
|
94
94
|
```
|
|
95
95
|
|
|
96
|
-
The runner starts one `pi --mode rpc --no-session --no-extensions --extension <this package>/index.ts` process, so only CCSwitch is loaded. `PI_BIN` may point to the real Pi executable
|
|
96
|
+
The runner starts one `pi --mode rpc --no-session --no-extensions --extension <this package>/index.ts` process, so only CCSwitch is loaded. `PI_BIN` may point to the real Pi executable. For migration safety, an old `PI_BIN=pi-ccswitch-run` or `PI_BIN=ccswitch-run` value emits a warning and falls back to `pi` on `PATH` instead of recursing or terminating every downstream job. Arbitrary commands are still rejected. The default deadline is ten minutes and can be changed with `--timeout-ms`.
|
|
97
97
|
|
|
98
98
|
Exit codes are `0` for success, `1` when candidates are exhausted, `2` for invocation/RPC configuration failures, `124` for timeout, and `130`/`143` for interruption. Text `@files` are supported in the first release; images and stdin input are intentionally not.
|
|
99
99
|
|
|
@@ -121,10 +121,10 @@ Examples:
|
|
|
121
121
|
## Status bar
|
|
122
122
|
|
|
123
123
|
```text
|
|
124
|
-
CCS v0.3.
|
|
124
|
+
CCS v0.3.5 ✓70/131 · ⏳61 · ⛔0 · 🔄3 · provider/model-id
|
|
125
125
|
```
|
|
126
126
|
|
|
127
|
-
- `v0.3.
|
|
127
|
+
- `v0.3.5`: the installed CCSwitch extension version.
|
|
128
128
|
- `✓70/131`: 70 healthy models out of 131 unique `provider/model` combinations in Pi's effective scope. Duplicate scoped entries are counted once.
|
|
129
129
|
- `⏳61`: 61 models are currently affected by automatic model, provider, or endpoint cooldowns. One provider breaker can account for many affected models.
|
|
130
130
|
- `⛔0`: no manually disabled models.
|
package/README.zh-CN.md
CHANGED
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
| 设置项 | 作用域 | 默认值 | 说明 |
|
|
37
37
|
| --- | --- | --- | --- |
|
|
38
38
|
| `PI_CODING_AGENT_DIR` | 扩展状态 | `~/.pi/agent` | 健康状态、日志与失败报告的存放目录;仅在你迁移了 Pi agent 目录时需要,插件跟随 Pi 自身约定。 |
|
|
39
|
-
| `PI_BIN` | 仅 headless runner | `PATH` 中的 `pi` | 必须指向真实 `pi`
|
|
39
|
+
| `PI_BIN` | 仅 headless runner | `PATH` 中的 `pi` | 必须指向真实 `pi` 可执行文件。历史自引用值 `pi-ccswitch-run` 或 `ccswitch-run` 会警告并降级到 `pi`;其他非法命令仍按配置错误处理。 |
|
|
40
40
|
| 模型 scope(`/model` 等) | 故障转移候选 | 全量注册表 | Pi 启用了 model scope 时,只在 scope 内模型间切换;否则使用全量注册表。状态栏会显示当前数据源。 |
|
|
41
41
|
| `baseUrl` 元数据 | 端点隔离 | provider key | 端点级平台隔离按 `baseUrl` 分组模型(由 CC Switch `3.20+` 提供);缺失时退化为 provider 级分组,仍然可用。 |
|
|
42
42
|
|
|
@@ -89,7 +89,7 @@ cd ~/.pi/agent/npm && npm install pi-ccswitch-auto-switch@latest
|
|
|
89
89
|
pi-ccswitch-run --no-tools --no-context-files @prompt.md "请总结附件"
|
|
90
90
|
```
|
|
91
91
|
|
|
92
|
-
runner 内部只显式加载本扩展并启动一次 Pi RPC;`PI_BIN`
|
|
92
|
+
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`。首版只支持文本 `@文件`,不支持图片和 stdin。
|
|
93
93
|
|
|
94
94
|
正常使用 CC Switch 配置 Provider 即可;本插件不会修改 Pi 模型设置或 CC Switch 数据。
|
|
95
95
|
|
|
@@ -109,10 +109,10 @@ runner 内部只显式加载本扩展并启动一次 Pi RPC;`PI_BIN` 只能指
|
|
|
109
109
|
## 状态栏
|
|
110
110
|
|
|
111
111
|
```text
|
|
112
|
-
CCS v0.3.
|
|
112
|
+
CCS v0.3.5 ✓70/131 · ⏳61 · ⛔0 · 🔄3 · provider/model-id
|
|
113
113
|
```
|
|
114
114
|
|
|
115
|
-
- `v0.3.
|
|
115
|
+
- `v0.3.5`:当前安装的 CCSwitch 扩展版本。
|
|
116
116
|
- `✓70/131`:Pi 有效范围内共有 131 个去重后的 `provider/model` 组合,其中 70 个健康;重复的 scope 条目只计一次。
|
|
117
117
|
- `⏳61`:有 61 个模型正受模型、Provider 或端点自动冷却影响;一条 Provider 熔断记录可能同时影响许多模型。
|
|
118
118
|
- `⛔0`:没有被手动禁用的模型。
|
package/index.ts
CHANGED
|
@@ -13,7 +13,7 @@ const STREAM_IDLE_TIMEOUT = 120_000
|
|
|
13
13
|
const MAX_ATTEMPTS = 5
|
|
14
14
|
const ROUND_LIMIT = 8 * 60_000
|
|
15
15
|
const RPC_PROTOCOL_VERSION = 1
|
|
16
|
-
const EXTENSION_VERSION = '0.3.
|
|
16
|
+
const EXTENSION_VERSION = '0.3.5'
|
|
17
17
|
// 同端点(BaseURL 相同)连续失败达到该次数即隔离该端点,避免同一个平台的多个模型逐个试错耗尽本轮切换
|
|
18
18
|
const ENDPOINT_FAIL_THRESHOLD = 3
|
|
19
19
|
|
package/package.json
CHANGED
package/runner.mjs
CHANGED
|
@@ -7,7 +7,7 @@ import { spawn } from 'node:child_process'
|
|
|
7
7
|
import { access, readFile, stat } from 'node:fs/promises'
|
|
8
8
|
import { existsSync } from 'node:fs'
|
|
9
9
|
import { fileURLToPath } from 'node:url'
|
|
10
|
-
import {
|
|
10
|
+
import { delimiter, dirname, extname, isAbsolute, join, resolve } from 'node:path'
|
|
11
11
|
|
|
12
12
|
export const EXIT = Object.freeze({ SUCCESS: 0, EXHAUSTED: 1, CONFIG: 2, TIMEOUT: 124, INTERRUPTED: 130, TERMINATED: 143 })
|
|
13
13
|
export const DEFAULT_TIMEOUT_MS = 600_000
|
|
@@ -87,9 +87,24 @@ export function buildMessage(fileText, prompt) {
|
|
|
87
87
|
return fileText ? `${fileText}\n${prompt}` : prompt
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
+
const LEGACY_RUNNER_STEMS = new Set(['pi-ccswitch-run', 'ccswitch-run'])
|
|
91
|
+
|
|
92
|
+
function executableStem(value) {
|
|
93
|
+
return String(value).split(/[\\/]/).pop().toLowerCase().replace(/\.(cmd|exe|bat)$/, '')
|
|
94
|
+
}
|
|
95
|
+
|
|
90
96
|
function validPiBinary(value) {
|
|
91
|
-
|
|
92
|
-
|
|
97
|
+
return executableStem(value) === 'pi'
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export function selectPiBinary(configured, warn = () => {}) {
|
|
101
|
+
if (!configured) return 'pi'
|
|
102
|
+
if (validPiBinary(configured)) return configured
|
|
103
|
+
if (LEGACY_RUNNER_STEMS.has(executableStem(configured))) {
|
|
104
|
+
warn("PI_BIN points to a legacy runner wrapper; ignoring it and falling back to 'pi' on PATH")
|
|
105
|
+
return 'pi'
|
|
106
|
+
}
|
|
107
|
+
throw new Error('PI_BIN must name the real pi executable, not an arbitrary command')
|
|
93
108
|
}
|
|
94
109
|
|
|
95
110
|
async function resolveWindowsShim(command) {
|
|
@@ -115,8 +130,7 @@ async function resolveWindowsShim(command) {
|
|
|
115
130
|
|
|
116
131
|
async function resolvePiCommand() {
|
|
117
132
|
const configured = String(process.env.PI_BIN || '').trim()
|
|
118
|
-
|
|
119
|
-
const command = configured || 'pi'
|
|
133
|
+
const command = selectPiBinary(configured, message => process.stderr.write(`pi-ccswitch-run: warning: ${message}\n`))
|
|
120
134
|
if (process.platform === 'win32') return resolveWindowsShim(command)
|
|
121
135
|
return { command, prefix: [] }
|
|
122
136
|
}
|