@bacnh85/pi-sub 0.1.32 → 0.1.35
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/CHANGELOG.md +27 -3
- package/README.md +8 -0
- package/extensions/index.ts +33 -11
- package/package.json +5 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,12 +1,30 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.35 (2026-09-05)
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- **`zai-anthropic` provider usage tracking** — GLM through the Anthropic-compatible endpoint (`api.z.ai/api/anthropic`, registered by pi-model-tools) now shows the same quota footer as `zai`/`zai-coding-cn`: 5-hour/weekly windows, MCP monthly allowance, and model/tool breakdowns, keyed by the auth.json `zai-anthropic` credential, labeled `Z.ai (Anthropic)`.
|
|
8
|
+
|
|
9
|
+
## 0.1.34 (2026-09-05)
|
|
10
|
+
|
|
11
|
+
- Widen Pi SDK peer range to `>=0.80.8 <0.86.0` for Pi 0.85.0 compatibility (no breaking changes; peer cap widening only).
|
|
12
|
+
|
|
13
|
+
## 0.1.33 (2026-08-29)
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- `/sub` argument completion offers `refresh`.
|
|
18
|
+
|
|
1
19
|
## 0.1.32 (2026-08-22)
|
|
2
20
|
|
|
3
21
|
- **DeepSeek via OmniRoute now shows the real USD balance** (e.g. `M:$18.25`)
|
|
4
22
|
instead of the misleading aggregate windows (R:100%/5H W:0%/2D). Credit-based
|
|
5
23
|
upstreams report "Unavailable" session/weekly in the usage text; pi-sub now
|
|
6
24
|
recognizes that shape and fetches `credits_usd` from the management usage
|
|
7
|
-
API
|
|
8
|
-
|
|
9
|
-
endpoint display (no aggregate leak).
|
|
25
|
+
API — grant the router key the `manage` scope in the OmniRoute dashboard
|
|
26
|
+
(done), or set `ROUTER_MGMT_TOKEN`. Without it, the footer degrades to the
|
|
27
|
+
clean endpoint display (no aggregate leak).
|
|
10
28
|
- The plain-retry fallback (drop `?provider=`) now fires only on "No cached
|
|
11
29
|
usage data" (wrong/unknown slug), not on "Unavailable" windows.
|
|
12
30
|
- pi-sub now reads `.env.local`/`.env` (cwd then `~/.pi/agent`) for its own
|
|
@@ -66,6 +84,12 @@
|
|
|
66
84
|
|
|
67
85
|
# Changelog
|
|
68
86
|
|
|
87
|
+
## 0.1.33 (2026-08-29)
|
|
88
|
+
|
|
89
|
+
### Added
|
|
90
|
+
|
|
91
|
+
- `/sub` argument completion offers `refresh`.
|
|
92
|
+
|
|
69
93
|
## 0.1.29 (2026-08-15)
|
|
70
94
|
|
|
71
95
|
### Features
|
package/README.md
CHANGED
|
@@ -51,6 +51,14 @@ The built-in `zai-coding-cn` provider targets the domestic BigModel endpoint (`o
|
|
|
51
51
|
(Z.ai (CN) key#1a2b3c4d) R:55%/2H W:80%/3D 42 tok/s
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
+
### Z.ai via Anthropic endpoint
|
|
55
|
+
|
|
56
|
+
The `zai-anthropic` provider (registered by pi-model-tools, GLM through `api.z.ai/api/anthropic`) is tracked the same way — same api.z.ai quota monitor as the international `zai` provider, keyed by the auth.json `zai-anthropic` credential, labeled `Z.ai (Anthropic)`:
|
|
57
|
+
|
|
58
|
+
```text
|
|
59
|
+
(Z.ai (Anthropic) key#1a2b3c4d) R:55%/2H W:80%/3D 42 tok/s
|
|
60
|
+
```
|
|
61
|
+
|
|
54
62
|
### Router (pi-router — formerly 9router)
|
|
55
63
|
|
|
56
64
|
For **OmniRoute** instances the footer shows real usage: `GET <origin>/api/usage/om-usage`
|
package/extensions/index.ts
CHANGED
|
@@ -38,6 +38,13 @@ const ZAI_PROVIDER = "zai";
|
|
|
38
38
|
const ZAI_USAGE_URL = "https://api.z.ai/api/monitor/usage/quota/limit";
|
|
39
39
|
const ZAI_CODING_CN_PROVIDER = "zai-coding-cn";
|
|
40
40
|
const ZAI_CODING_CN_USAGE_URL = "https://open.bigmodel.cn/api/monitor/usage/quota/limit";
|
|
41
|
+
// GLM via the Anthropic-compatible endpoint (pi-model-tools `zai-anthropic`
|
|
42
|
+
// provider). Same api.z.ai host and quota monitor as the `zai` provider.
|
|
43
|
+
// ponytail: usage URL is fixed to api.z.ai — if ZAI_ANTHROPIC_BASE_URL is
|
|
44
|
+
// overridden to BigModel/zcode-plan, quota still reads from api.z.ai (correct
|
|
45
|
+
// for the z.ai coding-plan key; BigModel-plan keys should use zai-coding-cn).
|
|
46
|
+
const ZAI_ANTHROPIC_PROVIDER = "zai-anthropic";
|
|
47
|
+
const ZAI_ANTHROPIC_USAGE_URL = ZAI_USAGE_URL;
|
|
41
48
|
const ROUTER_PROVIDER = "router";
|
|
42
49
|
const LEGACY_9ROUTER_PROVIDER = "9router";
|
|
43
50
|
// pi-router (formerly pi-9router): URL lives in settings.json `router.baseUrl`
|
|
@@ -142,6 +149,10 @@ function isZaiCodingCnModel(model: ModelLike): boolean {
|
|
|
142
149
|
return (model?.provider?.toLowerCase() ?? "") === ZAI_CODING_CN_PROVIDER;
|
|
143
150
|
}
|
|
144
151
|
|
|
152
|
+
function isZaiAnthropicModel(model: ModelLike): boolean {
|
|
153
|
+
return (model?.provider?.toLowerCase() ?? "") === ZAI_ANTHROPIC_PROVIDER;
|
|
154
|
+
}
|
|
155
|
+
|
|
145
156
|
function isRouterModel(model: ModelLike, provider: string = ROUTER_PROVIDER): boolean {
|
|
146
157
|
return (model?.provider?.toLowerCase() ?? "") === provider;
|
|
147
158
|
}
|
|
@@ -362,11 +373,13 @@ function routerOrigin(baseUrl: string): string {
|
|
|
362
373
|
return baseUrl.replace(/\/v1\/?$/, "");
|
|
363
374
|
}
|
|
364
375
|
|
|
365
|
-
/** OmniRoute management
|
|
366
|
-
*
|
|
367
|
-
*
|
|
368
|
-
|
|
369
|
-
|
|
376
|
+
/** OmniRoute management credential (manage-scope key or oma_ CLI token) from
|
|
377
|
+
* env — optional override. The router key itself works when it holds the
|
|
378
|
+
* `manage` scope (API Keys dashboard), which unlocks
|
|
379
|
+
* /api/usage/<connectionId> carrying the raw USD balance for credit-based
|
|
380
|
+
* upstreams (deepseek) that the key-authable endpoints normalize away. */
|
|
381
|
+
function readRouterMgmtToken(apiKey: string | undefined): string | undefined {
|
|
382
|
+
return process.env.ROUTER_MGMT_TOKEN || process.env.OMNIROUTE_MGMT_TOKEN || apiKey;
|
|
370
383
|
}
|
|
371
384
|
|
|
372
385
|
/** Parse OmniRoute's `/api/usage/om-usage` plain-text report into windows.
|
|
@@ -667,15 +680,15 @@ interface RouterCredits {
|
|
|
667
680
|
|
|
668
681
|
/** Fetch the raw USD balance for credit-based upstreams (deepseek: `credits_usd`)
|
|
669
682
|
* via OmniRoute's management usage API. Only called when the key-authable
|
|
670
|
-
* om-usage text reports no usable windows —
|
|
671
|
-
*
|
|
672
|
-
*
|
|
673
|
-
* /api/usage/<id
|
|
683
|
+
* om-usage text reports no usable windows — that surface normalizes credits
|
|
684
|
+
* to meaningless percentages. Needs the router key to hold the `manage`
|
|
685
|
+
* scope (or ROUTER_MGMT_TOKEN as override). Connection discovery comes from
|
|
686
|
+
* /api/v1/me/status (key-authable); the balance from /api/usage/<id>. */
|
|
674
687
|
async function fetchRouterCredits(provider: string | undefined, w: ReturnType<typeof parseOmniUsageText>): Promise<RouterCredits | undefined> {
|
|
675
688
|
if (!provider || w.session || w.providerWeekly) return undefined;
|
|
676
689
|
const cfg = readRouterConfig();
|
|
677
690
|
const apiKey = readRouterApiKey();
|
|
678
|
-
const mgmtToken = readRouterMgmtToken();
|
|
691
|
+
const mgmtToken = readRouterMgmtToken(apiKey);
|
|
679
692
|
if (!cfg || !apiKey || !mgmtToken) return undefined;
|
|
680
693
|
const origin = routerOrigin(cfg.baseUrl);
|
|
681
694
|
try {
|
|
@@ -989,11 +1002,14 @@ function zaiUsageAdapter(providerId: string, usageUrl: string, displayName: stri
|
|
|
989
1002
|
return { fetchUsage };
|
|
990
1003
|
}
|
|
991
1004
|
|
|
992
|
-
|
|
1005
|
+
// Exported for the adapter-wiring regression test (provider-id string ↔
|
|
1006
|
+
// adapter id ↔ usage URL are exactly what a typo silently breaks).
|
|
1007
|
+
export function supportedAdapter(model: ModelLike): SubscriptionProviderAdapter | undefined {
|
|
993
1008
|
if (isCodexModel(model)) return { id: CODEX_PROVIDER, displayName: "Codex", fetchUsage: fetchCodexUsage };
|
|
994
1009
|
if (isOpenCodeGoModel(model)) return { id: OPC_PROVIDER, displayName: "OpenCode Go", fetchUsage: fetchOpenCodeGoUsage };
|
|
995
1010
|
if (isZaiModel(model)) return { id: ZAI_PROVIDER, displayName: "Z.ai", ...zaiUsageAdapter(ZAI_PROVIDER, ZAI_USAGE_URL, "Z.ai") };
|
|
996
1011
|
if (isZaiCodingCnModel(model)) return { id: ZAI_CODING_CN_PROVIDER, displayName: "Z.ai (CN)", ...zaiUsageAdapter(ZAI_CODING_CN_PROVIDER, ZAI_CODING_CN_USAGE_URL, "Z.ai (CN)") };
|
|
1012
|
+
if (isZaiAnthropicModel(model)) return { id: ZAI_ANTHROPIC_PROVIDER, displayName: "Z.ai (Anthropic)", ...zaiUsageAdapter(ZAI_ANTHROPIC_PROVIDER, ZAI_ANTHROPIC_USAGE_URL, "Z.ai (Anthropic)") };
|
|
997
1013
|
if (isRouterModel(model)) {
|
|
998
1014
|
const prefix = routerUpstreamPrefix(model);
|
|
999
1015
|
return {
|
|
@@ -1293,6 +1309,12 @@ export default function (pi: ExtensionAPI) {
|
|
|
1293
1309
|
|
|
1294
1310
|
pi.registerCommand("sub", {
|
|
1295
1311
|
description: "Show subscription usage for the current supported model provider (use /sub refresh to force refresh).",
|
|
1312
|
+
getArgumentCompletions: (prefix) => {
|
|
1313
|
+
const items = ["refresh"]
|
|
1314
|
+
.filter((k) => k.startsWith(String(prefix || "").trim().toLowerCase()))
|
|
1315
|
+
.map((k) => ({ value: k, label: k, description: "force refresh" }));
|
|
1316
|
+
return items.length > 0 ? items : null;
|
|
1317
|
+
},
|
|
1296
1318
|
handler: async (args, ctx) => {
|
|
1297
1319
|
updateActiveAdapter(ctx, state, ctx.model);
|
|
1298
1320
|
const command = args.trim().toLowerCase();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bacnh85/pi-sub",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.35",
|
|
4
4
|
"description": "Pi extension showing subscription usage for supported model providers.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -39,6 +39,9 @@
|
|
|
39
39
|
"node": ">=20.3.0"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
|
-
"@earendil-works/pi-coding-agent": ">=0.80.8 <0.
|
|
42
|
+
"@earendil-works/pi-coding-agent": ">=0.80.8 <0.86.0"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@earendil-works/pi-server": "^0.85.1"
|
|
43
46
|
}
|
|
44
47
|
}
|