pi-multikey 1.8.1 → 1.10.0

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 CHANGED
@@ -29,7 +29,7 @@ pi install /path/to/multikey
29
29
  /multikey → Add pool… → Preset: B.AI → paste keys one per line (blank line to finish)
30
30
  ```
31
31
 
32
- After picking the preset, the endpoint, compat, and all 4 model definitions are wired up automatically. Models are available directly as `bai/<model-id>`, e.g. `bai/hy3`.
32
+ After picking the preset, the endpoint, compat, and all 3 model definitions are wired up automatically. Models are available directly as `bai/<model-id>`, e.g. `bai/hy3`.
33
33
 
34
34
  ## Presets
35
35
 
@@ -40,7 +40,6 @@ Built-in presets decouple "model settings" from "keys". The data comes from b.ai
40
40
  | hy3 | 256K / 128K | text | off · low · high |
41
41
  | mimo-v2.5 | 1M / 128K | text+image | off · high (official: low/medium/high behave identically) |
42
42
  | qwen3.8-flash | 1M / 131K | text+image | off · low · medium · xhigh |
43
- | glm-5.3-flash | 1M / 131K | text+image | low · high · max (always thinks, no off) |
44
43
 
45
44
  > Why `null` must be explicit: pi's `getSupportedThinkingLevels` treats `mapped === null` as unsupported and hides that level, but **omitting** it is treated as supported and the level name is sent to the API verbatim; `xhigh` / `max` additionally require an explicit non-null value to be usable.
46
45
 
package/README.zh.md CHANGED
@@ -27,7 +27,7 @@ pi install /path/to/multikey
27
27
  /multikey → Add pool… → Preset: B.AI → 逐行粘贴 key(一行一个,留空结束)
28
28
  ```
29
29
 
30
- 选 preset 后 endpoint、compat、4 个模型的全部设定自动就位,模型通过
30
+ 选 preset 后 endpoint、compat、3 个模型的全部设定自动就位,模型通过
31
31
  `bai/<model-id>` 直接可用,例如 `bai/hy3`。
32
32
 
33
33
  ## Presets
@@ -41,7 +41,6 @@ DeepSeek / Tencent / 小米官方文档,并对每个 thinking 档位做过实
41
41
  | hy3 | 256K / 128K | text | off · low · high |
42
42
  | mimo-v2.5 | 1M / 128K | text+image | off · high(官方:low/medium/high 行为相同) |
43
43
  | qwen3.8-flash | 1M / 131K | text+image | off · low · medium · xhigh |
44
- | glm-5.3-flash | 1M / 131K | text+image | low · high · max(始终思考,无 off) |
45
44
 
46
45
  > 为什么必须显式写 `null`:pi 的 `getSupportedThinkingLevels` 把 `mapped === null`
47
46
  > 视为不支持并隐藏该档,但**省略**会被当作支持并把档名原样发给 API;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-multikey",
3
- "version": "1.8.1",
3
+ "version": "1.10.0",
4
4
  "description": "One pi provider backed by many API keys: automatic 429 rotation, per-request key leases for concurrent subagents, and a /multikey management TUI",
5
5
  "keywords": [
6
6
  "pi-package",
package/presets.ts CHANGED
@@ -57,7 +57,7 @@ export const PRESETS: Preset[] = [
57
57
  {
58
58
  id: "b-ai",
59
59
  name: "B.AI",
60
- description: "api.b.ai — Hunyuan Hy3, MiMo V2.5, Qwen3.8, GLM 5.3 (4 models)",
60
+ description: "api.b.ai — Hunyuan Hy3, MiMo V2.5, Qwen3.8 (3 models)",
61
61
  defaultPoolId: "bai",
62
62
  baseUrl: "https://api.b.ai/v1",
63
63
  api: "openai-completions",
@@ -96,17 +96,6 @@ export const PRESETS: Preset[] = [
96
96
  maxTokens: 131_072,
97
97
  thinkingLevelMap: levels({ off: "none", low: "low", medium: "medium", xhigh: "xhigh" }),
98
98
  },
99
- {
100
- // docs.b.ai/llmservice/models/glm-5-3-flash — always thinks (off unsupported);
101
- // reasoning_effort: low/high/max, default max.
102
- id: "glm-5.3-flash",
103
- name: "GLM 5.3 Flash",
104
- reasoning: true,
105
- input: ["text", "image"],
106
- contextWindow: 1_000_000,
107
- maxTokens: 131_072,
108
- thinkingLevelMap: levels({ low: "low", high: "high", max: "max" }),
109
- },
110
99
  ],
111
100
  },
112
101
  {
@@ -199,7 +188,7 @@ export const PRESETS: Preset[] = [
199
188
  id: "cline-free",
200
189
  name: "Cline Free",
201
190
  description:
202
- "api.cline.bot — Cline account free tier: DeepSeek V4 Flash, Longcat 2.0, Laguna S 2.1, GLM 5.2 (daily per-model quota, lineup rotates)",
191
+ "api.cline.bot — Cline account free tier: DeepSeek V4 Flash, Longcat 2.0, Laguna S 2.1, GLM 5.3, Solar Pro 4, Muse Spark 1.3 (daily per-model quota, lineup rotates)",
203
192
  defaultPoolId: "cline",
204
193
  baseUrl: "https://api.cline.bot/api/v1",
205
194
  api: "openai-completions",
@@ -226,16 +215,39 @@ export const PRESETS: Preset[] = [
226
215
  name: "Laguna S 2.1 (Free)",
227
216
  reasoning: true,
228
217
  input: ["text"],
229
- // Poolside doesn't publish the window; safe default, tune if needed.
230
- contextWindow: 128_000,
231
- maxTokens: 16_384,
218
+ // Window/output measured from the live free tier (tuned in multikey.json).
219
+ contextWindow: 262_144,
220
+ maxTokens: 32_768,
221
+ },
222
+ {
223
+ // z-ai/glm-5.2:free retired from the Cline lineup (id answers "model not found");
224
+ // succeeded by glm-5.3-flash. Always-on reasoning, no effort tiers; vision input.
225
+ id: "z-ai/glm-5.3-flash",
226
+ name: "GLM 5.3 (Free)",
227
+ reasoning: true,
228
+ input: ["text", "image"],
229
+ contextWindow: 1_048_576,
230
+ maxTokens: 128_000,
232
231
  },
233
232
  {
234
- id: "z-ai/glm-5.2:free",
235
- name: "GLM 5.2 (Free)",
233
+ id: "upstage/solar-pro4",
234
+ name: "Upstage Solar Pro 4",
236
235
  reasoning: true,
237
236
  input: ["text"],
238
- contextWindow: 200_000,
237
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
238
+ contextWindow: 524_000,
239
+ maxTokens: 16_384,
240
+ },
241
+ {
242
+ // Same Meta model as OpenCode Zen's muse-spark-1.3-contributor-free, served
243
+ // through Cline's chat-completions endpoint (no Responses API / session
244
+ // affinity needed). Always-on reasoning; text + image input.
245
+ id: "meta/muse-spark-1.3-contributor",
246
+ name: "Meta Muse Spark 1.3 Contributor",
247
+ reasoning: true,
248
+ input: ["text", "image"],
249
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
250
+ contextWindow: 1_048_576,
239
251
  maxTokens: 131_072,
240
252
  },
241
253
  ],
package/tui.ts CHANGED
@@ -267,7 +267,9 @@ export async function pickMany(
267
267
  if (v.length === 0) {
268
268
  add(theme.fg("warning", " No matches."));
269
269
  } else {
270
- for (let i = 0; i < Math.min(v.length, maxVisible); i++) {
270
+ const start = Math.max(0, Math.min(cursor - Math.floor(maxVisible / 2), Math.max(0, v.length - maxVisible)));
271
+ const end = Math.min(v.length, start + maxVisible);
272
+ for (let i = start; i < end; i++) {
271
273
  const item = v[i]!;
272
274
  const active = i === cursor;
273
275
  const check = selected.has(item.value) ? theme.fg("accent", "✓") : " ";