pi-ccswitch-auto-switch 0.3.6 → 0.3.7
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 +1 -1
- package/README.zh-CN.md +1 -1
- package/index.ts +5 -6
- package/package.json +1 -1
- package/runner.mjs +1 -1
package/README.md
CHANGED
|
@@ -130,7 +130,7 @@ CCS v0.3.5 ✓70/131 · ⏳61 · ⛔0 · 🔄3 · provider/model-id
|
|
|
130
130
|
- `⛔0`: no manually disabled models.
|
|
131
131
|
- `🔄3`: **本次 pi session 成功切换的模型次数**(衡量扩展有效程度)。`/new`、`/fork`、`/resume` 等新 session 开始时归零;但**失败记录与冷却状态不重置**(它们是物理事实,跨 session 保留)。累计切换数(`state.switches`)与最近 20 条切换日志会持久化到状态文件,可在 `/ccswitch` 面板和 `/ccswitch-test` 中查看。
|
|
132
132
|
- `provider/model-id`: 当前实际生效的模型(`provider/id`,切换后立即更新,长名自动截断)。
|
|
133
|
-
- During a switch, `CCS ↻2
|
|
133
|
+
- During a switch, `CCS ↻2 provider/model` means this is the second switch attempt of the current round. Attempts are only bounded by the round time window, not a fixed count; a round fails only once every candidate has been tried.
|
|
134
134
|
|
|
135
135
|
四个状态(健康/冷却/禁用/切换)即使为 0 也始终显示,便于确认扩展处于监控中。All-healthy still shows zero counters, e.g. `CCS ✓131/131 · ⏳0 · ⛔0 · 🔄0 · provider/model-id`. Use `/ccswitch` or `/ccswitch-test` to see Pi's raw scope entry count, the deduplicated model count, affected model counts, and the underlying breaker-record count.
|
|
136
136
|
|
package/README.zh-CN.md
CHANGED
|
@@ -118,7 +118,7 @@ CCS v0.3.5 ✓70/131 · ⏳61 · ⛔0 · 🔄3 · provider/model-id
|
|
|
118
118
|
- `⛔0`:没有被手动禁用的模型。
|
|
119
119
|
- `🔄3`:**本次 pi session 成功切换的模型次数**(衡量扩展有效程度,0 时也显示图标)。`/new`、`/fork`、`/resume` 等新 session 开始时归零;但**失败记录与冷却状态不重置**(它们是物理事实,跨 session 保留)。累计切换数(`state.switches`)与最近 20 条切换日志会持久化到状态文件,可在 `/ccswitch` 面板和 `/ccswitch-test` 中查看。
|
|
120
120
|
- `provider/model-id`:当前实际生效的模型(`provider/id`,切换后立即更新,长名自动截断)。
|
|
121
|
-
- 切换中出现 `CCS ↻2
|
|
121
|
+
- 切换中出现 `CCS ↻2 provider/model`,表示这是本轮的第 2 次切换尝试。切换次数只受本轮时间窗口限制,不再有固定次数上限;只有当所有候选都尝试过仍无可用模型时才会判定本轮失败。
|
|
122
122
|
|
|
123
123
|
四个状态(健康/冷却/禁用/切换)即使为 0 也始终显示,便于确认扩展处于监控中;全部健康时仍显示零计数,例如 `CCS ✓131/131 · ⏳0 · ⛔0 · 🔄0 · provider/model-id`。通过 `/ccswitch` 或 `/ccswitch-test` 可同时查看 Pi 原始 scope 条目数、去重模型数、受影响模型数、底层熔断记录数、本 session 切换数与累计切换数。
|
|
124
124
|
|
package/index.ts
CHANGED
|
@@ -10,7 +10,6 @@ import { HealthStore, endpointKey, modelKey, type HealthState } from './health.t
|
|
|
10
10
|
|
|
11
11
|
const FIRST_RESPONSE_TIMEOUT = 90_000
|
|
12
12
|
const STREAM_IDLE_TIMEOUT = 120_000
|
|
13
|
-
const MAX_ATTEMPTS = 5
|
|
14
13
|
const ROUND_LIMIT = 8 * 60_000
|
|
15
14
|
const RPC_PROTOCOL_VERSION = 1
|
|
16
15
|
const EXTENSION_VERSION = '0.3.6'
|
|
@@ -41,7 +40,7 @@ interface Round {
|
|
|
41
40
|
endpointFails?: EndpointFailTracker
|
|
42
41
|
/** 本轮内容审查故障转移中必须避开的模型系列(包含持久化学到的约束)。 */
|
|
43
42
|
avoidFamilies?: Set<string>
|
|
44
|
-
/** 本轮内最后一次成功切换的时间;用于刷新 ROUND_LIMIT
|
|
43
|
+
/** 本轮内最后一次成功切换的时间;用于刷新 ROUND_LIMIT 窗口,避免供应商内部重试耗时导致误判“超过本轮时间限制” */
|
|
45
44
|
lastSwitchAt?: number
|
|
46
45
|
}
|
|
47
46
|
|
|
@@ -104,7 +103,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
104
103
|
const activeModel = round?.model ?? ctx.model
|
|
105
104
|
// 恒显完整状态:健康/总数 · 冷却 · 禁用 · 本session切换 · 当前模型(均为 0 时也显示,便于确认扩展在监控中)
|
|
106
105
|
const prefix = `CCS v${EXTENSION_VERSION}`
|
|
107
|
-
const plain = round?.phase === 'switching' ? `${prefix} ↻${round.attempts}
|
|
106
|
+
const plain = round?.phase === 'switching' ? `${prefix} ↻${round.attempts} ${modelTag(round.model)}` :
|
|
108
107
|
round?.phase === 'exhausted' ? `${prefix} ⏸切换停止 ${modelTag(round.model ?? ctx.model)}` :
|
|
109
108
|
`${prefix} ✓${counts.healthy}/${counts.total} · ⏳${counts.cooling} · ⛔${counts.disabled}${switchSuffix()} · ${modelTag(activeModel)}`
|
|
110
109
|
const theme = ctx.ui.theme
|
|
@@ -246,7 +245,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
246
245
|
if (!round || !round.observation || !round.model || !canRetry(ctx)) return
|
|
247
246
|
// 窗口从上一次成功切换(或本轮开始)起算:供应商内部重试耗时不应消耗整轮限额
|
|
248
247
|
const windowStart = Math.max(round.startedAt, round.lastSwitchAt ?? 0)
|
|
249
|
-
if (
|
|
248
|
+
if (Date.now() - windowStart >= ROUND_LIMIT) return exhaust(ctx, '超过本轮时间限制')
|
|
250
249
|
const classification = classifyFailure(round.observation)
|
|
251
250
|
if (round.observation.aborted && !round.observation.watchdog) { round.phase = 'idle'; clearWatchdog(); status(ctx); return }
|
|
252
251
|
round.phase = 'switching'
|
|
@@ -294,14 +293,14 @@ export default function (pi: ExtensionAPI) {
|
|
|
294
293
|
}
|
|
295
294
|
round.model = next
|
|
296
295
|
round.phase = 'redispatching'
|
|
297
|
-
// 刷新本轮切换时间窗:成功切换后重新起算 ROUND_LIMIT
|
|
296
|
+
// 刷新本轮切换时间窗:成功切换后重新起算 ROUND_LIMIT,避免长重试轮被误判为“超过时间限制”
|
|
298
297
|
round.lastSwitchAt = Date.now()
|
|
299
298
|
// 本次 session 成功切换计数 + 持久化累计/日志(衡量扩展有效程度)
|
|
300
299
|
sessionSwitches += 1
|
|
301
300
|
const fromKey = key(previousModel ?? ctx.model)
|
|
302
301
|
health.recordSwitch(fromKey ?? '', modelKey(next), classification.kind)
|
|
303
302
|
await health.flush()
|
|
304
|
-
notify(ctx, `CCSwitch:已切换至 ${modelKey(next)}
|
|
303
|
+
notify(ctx, `CCSwitch:已切换至 ${modelKey(next)}(第${round.attempts}次切换)`, 'info')
|
|
305
304
|
// 触发 TUI 底栏/界面重绘:appendEntry 会发出 entry_appended 事件进入 session.subscribe 流,
|
|
306
305
|
// interactive-mode 收到后执行 footer.invalidate() + requestRender(),footer 从 session.state.model 重新读取,
|
|
307
306
|
// 从而让右下角模型名同步显示新模型(setModel 只改 state,不直接触发 footer 刷新)。
|
package/package.json
CHANGED
package/runner.mjs
CHANGED
|
@@ -189,7 +189,7 @@ export async function run(options, runtime = {}) {
|
|
|
189
189
|
if (entry.data?.protocolVersion !== 1) return
|
|
190
190
|
if (entry.type === 'ccswitch-switch') {
|
|
191
191
|
retryPending = true
|
|
192
|
-
log(`switch ${entry.data.from || '?'} → ${entry.data.to || '?'} (${entry.data.attempts ?? '?'}
|
|
192
|
+
log(`switch ${entry.data.from || '?'} → ${entry.data.to || '?'} (${entry.data.attempts ?? '?'})`)
|
|
193
193
|
} else if (entry.type === 'ccswitch-complete') {
|
|
194
194
|
terminal = { kind: 'complete', data: entry.data }
|
|
195
195
|
} else if (entry.type === 'ccswitch-exhausted') {
|