@howaboua/opencode-usage-plugin 0.1.4 → 0.1.6
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 +83 -30
- package/dist/providers/index.d.ts +1 -0
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +3 -0
- package/dist/providers/proxy/fetch.js +2 -2
- package/dist/providers/proxy/format.d.ts +2 -1
- package/dist/providers/proxy/format.d.ts.map +1 -1
- package/dist/providers/proxy/format.js +11 -21
- package/dist/providers/proxy/index.d.ts +6 -0
- package/dist/providers/proxy/index.d.ts.map +1 -1
- package/dist/providers/proxy/index.js +90 -28
- package/dist/providers/proxy/types.d.ts +1 -0
- package/dist/providers/proxy/types.d.ts.map +1 -1
- package/dist/providers/zai/fetch.d.ts +32 -0
- package/dist/providers/zai/fetch.d.ts.map +1 -0
- package/dist/providers/zai/fetch.js +40 -0
- package/dist/providers/zai/index.d.ts +7 -0
- package/dist/providers/zai/index.d.ts.map +1 -0
- package/dist/providers/zai/index.js +39 -0
- package/dist/providers/zai/types.d.ts +61 -0
- package/dist/providers/zai/types.d.ts.map +1 -0
- package/dist/providers/zai/types.js +4 -0
- package/dist/types.d.ts +30 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/ui/formatters/proxy.d.ts.map +1 -1
- package/dist/ui/formatters/proxy.js +10 -4
- package/dist/ui/formatters/shared.d.ts.map +1 -1
- package/dist/ui/formatters/shared.js +20 -12
- package/dist/ui/formatters/zai.d.ts +6 -0
- package/dist/ui/formatters/zai.d.ts.map +1 -0
- package/dist/ui/formatters/zai.js +29 -0
- package/dist/ui/status.d.ts.map +1 -1
- package/dist/ui/status.js +3 -0
- package/dist/usage/config.d.ts.map +1 -1
- package/dist/usage/config.js +17 -3
- package/dist/usage/fetch.d.ts.map +1 -1
- package/dist/usage/fetch.js +5 -2
- package/dist/usage/registry.d.ts +4 -0
- package/dist/usage/registry.d.ts.map +1 -1
- package/dist/usage/registry.js +8 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -25,6 +25,75 @@ Add to your `opencode.json`:
|
|
|
25
25
|
|
|
26
26
|
OpenCode installs dependencies automatically on next launch.
|
|
27
27
|
|
|
28
|
+
## Configuration
|
|
29
|
+
|
|
30
|
+
The plugin creates a default config file on first run at:
|
|
31
|
+
|
|
32
|
+
**Linux/macOS**: `~/.config/opencode/usage-config.jsonc`
|
|
33
|
+
**Windows**: `%APPDATA%\opencode\usage-config.jsonc`
|
|
34
|
+
|
|
35
|
+
```jsonc
|
|
36
|
+
{
|
|
37
|
+
// REQUIRED: Proxy server endpoint (default: "http://localhost:8000")
|
|
38
|
+
// Leave empty ONLY if you don't use the proxy
|
|
39
|
+
"endpoint": "http://localhost:8000",
|
|
40
|
+
|
|
41
|
+
// REQUIRED: API key for proxy auth (default: "VerysecretKey")
|
|
42
|
+
// Leave empty if your proxy doesn't require authentication
|
|
43
|
+
"apiKey": "VerysecretKey",
|
|
44
|
+
|
|
45
|
+
// Optional: Request timeout in milliseconds (default: 10000)
|
|
46
|
+
"timeout": 10000,
|
|
47
|
+
|
|
48
|
+
// Optional: Show/hide providers in /usage output
|
|
49
|
+
"providers": {
|
|
50
|
+
"openai": true,
|
|
51
|
+
"proxy": true,
|
|
52
|
+
"copilot": true
|
|
53
|
+
},
|
|
54
|
+
|
|
55
|
+
// Model group display configuration (optional)
|
|
56
|
+
"modelGroups": {
|
|
57
|
+
// Show all model groups from proxy (default: true)
|
|
58
|
+
// When true: auto-discovers all groups, uses displayNames as overrides
|
|
59
|
+
// When false: only shows groups listed in displayNames (whitelist mode)
|
|
60
|
+
"showAll": true,
|
|
61
|
+
|
|
62
|
+
// Override display names for specific groups (optional)
|
|
63
|
+
// Groups not listed here use their original name from the proxy
|
|
64
|
+
"displayNames": {
|
|
65
|
+
"g3-pro": "Gemini Pro",
|
|
66
|
+
"g3-flash": "Gemini Flash",
|
|
67
|
+
"claude": "Claude"
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
> **⚠️ Important**: If using the Mirrowel Proxy, both `endpoint` and `apiKey` must be set. The proxy defaults to `endpoint: http://localhost:8000` and `apiKey: VerysecretKey`. If you changed these during your proxy setup, you MUST update your config file to match.
|
|
74
|
+
|
|
75
|
+
### Model Group Configuration
|
|
76
|
+
|
|
77
|
+
The `modelGroups` section controls how quota groups are displayed:
|
|
78
|
+
|
|
79
|
+
| `showAll` | `displayNames` | Behavior |
|
|
80
|
+
|-----------|----------------|----------|
|
|
81
|
+
| `true` (default) | empty/missing | Show all groups with original names |
|
|
82
|
+
| `true` | provided | Show all groups, apply display name overrides |
|
|
83
|
+
| `false` | provided | Only show groups in displayNames (whitelist mode) |
|
|
84
|
+
| `false` | empty/missing | Shows no groups (all filtered out) |
|
|
85
|
+
| missing section | — | Legacy behavior (hardcoded group whitelist) |
|
|
86
|
+
|
|
87
|
+
If missing, the plugin creates a default template on first run.
|
|
88
|
+
|
|
89
|
+
### Copilot auth
|
|
90
|
+
|
|
91
|
+
Copilot is detected from either of these locations:
|
|
92
|
+
|
|
93
|
+
- `~/.local/share/opencode/copilot-usage-token.json`
|
|
94
|
+
- `~/.local/share/opencode/auth.json` with a `github-copilot` entry
|
|
95
|
+
- `~/.config/opencode/copilot-quota-token.json` (optional override)
|
|
96
|
+
|
|
28
97
|
## Usage
|
|
29
98
|
|
|
30
99
|
### Check all providers
|
|
@@ -55,38 +124,22 @@ OpenCode installs dependencies automatically on next launch.
|
|
|
55
124
|
| **Mirrowel Proxy** | Local `/v1/quota-stats` endpoint |
|
|
56
125
|
| **GitHub Copilot** | GitHub internal usage APIs |
|
|
57
126
|
|
|
58
|
-
##
|
|
59
|
-
|
|
60
|
-
Optional config at `~/.config/opencode/usage-config.jsonc`:
|
|
61
|
-
|
|
62
|
-
```jsonc
|
|
63
|
-
{
|
|
64
|
-
// Proxy server endpoint
|
|
65
|
-
"endpoint": "http://localhost:8000",
|
|
66
|
-
|
|
67
|
-
// API key for proxy auth
|
|
68
|
-
"apiKey": "your-key",
|
|
69
|
-
|
|
70
|
-
// Request timeout (ms)
|
|
71
|
-
"timeout": 10000,
|
|
72
|
-
|
|
73
|
-
// Show/hide providers in /usage output
|
|
74
|
-
"providers": {
|
|
75
|
-
"openai": true,
|
|
76
|
-
"proxy": true,
|
|
77
|
-
"copilot": true
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
```
|
|
127
|
+
## Troubleshooting
|
|
81
128
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
129
|
+
**Proxy shows "not configured" error**
|
|
130
|
+
- Ensure `endpoint` and `apiKey` are set in `usage-config.jsonc`
|
|
131
|
+
- Default values: `endpoint: http://localhost:8000`, `apiKey: VerysecretKey`
|
|
132
|
+
- If you changed these during proxy setup, update your config file to match
|
|
133
|
+
- Verify your proxy is running at the specified endpoint
|
|
85
134
|
|
|
86
|
-
|
|
135
|
+
**Missing provider data**
|
|
136
|
+
- Use `providers: { ... }` in config to disable unused providers
|
|
137
|
+
- For Codex: Ensure you have valid auth tokens
|
|
138
|
+
- For Copilot: Check token file locations in Configuration section above
|
|
87
139
|
|
|
88
|
-
|
|
89
|
-
-
|
|
90
|
-
-
|
|
140
|
+
**Config file not found**
|
|
141
|
+
- The plugin auto-creates `usage-config.jsonc` on first run
|
|
142
|
+
- Check the path in Configuration section above
|
|
143
|
+
- Manually create the file if needed
|
|
91
144
|
|
|
92
145
|
See `AGENTS.md` for internal architecture.
|
|
@@ -3,5 +3,6 @@ export declare const providers: Record<string, UsageProvider<unknown>>;
|
|
|
3
3
|
export { CodexProvider } from "./codex";
|
|
4
4
|
export { ProxyProvider } from "./proxy";
|
|
5
5
|
export { CopilotProvider } from "./copilot";
|
|
6
|
+
export { ZaiProvider } from "./zai";
|
|
6
7
|
export type { UsageProvider } from "./base";
|
|
7
8
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAA;AAM3C,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,OAAO,CAAC,CAK5D,CAAA;AAED,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AACvC,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AACnC,YAAY,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAA"}
|
package/dist/providers/index.js
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { CodexProvider } from "./codex";
|
|
2
2
|
import { ProxyProvider } from "./proxy";
|
|
3
3
|
import { CopilotProvider } from "./copilot";
|
|
4
|
+
import { ZaiProvider } from "./zai";
|
|
4
5
|
export const providers = {
|
|
5
6
|
[CodexProvider.id]: CodexProvider,
|
|
6
7
|
[ProxyProvider.id]: ProxyProvider,
|
|
7
8
|
[CopilotProvider.id]: CopilotProvider,
|
|
9
|
+
[ZaiProvider.id]: ZaiProvider,
|
|
8
10
|
};
|
|
9
11
|
export { CodexProvider } from "./codex";
|
|
10
12
|
export { ProxyProvider } from "./proxy";
|
|
11
13
|
export { CopilotProvider } from "./copilot";
|
|
14
|
+
export { ZaiProvider } from "./zai";
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
export async function fetchProxyLimits(config) {
|
|
5
5
|
const { endpoint, apiKey, timeout = 10000 } = config;
|
|
6
6
|
if (!endpoint) {
|
|
7
|
-
throw new Error("Proxy endpoint not configured");
|
|
7
|
+
throw new Error("Proxy endpoint not configured. Set 'endpoint' in ~/.config/opencode/usage-config.jsonc (Windows: %APPDATA%\\opencode\\usage-config.jsonc)\n\nDefault: http://localhost:8000\nIf you changed this during proxy setup, update your config.");
|
|
8
8
|
}
|
|
9
9
|
const headers = {
|
|
10
10
|
"Content-Type": "application/json",
|
|
@@ -23,7 +23,7 @@ export async function fetchProxyLimits(config) {
|
|
|
23
23
|
signal: controller.signal,
|
|
24
24
|
});
|
|
25
25
|
if (!response.ok) {
|
|
26
|
-
throw new Error(`HTTP ${response.status}:
|
|
26
|
+
throw new Error(`Proxy request failed: HTTP ${response.status}. Check your usage-config.jsonc:\n\n - Default endpoint: http://localhost:8000\n - Default apiKey: VerysecretKey\n\nIf you changed these during proxy setup, you MUST update your config file to match.`);
|
|
27
27
|
}
|
|
28
28
|
return (await response.json());
|
|
29
29
|
}
|
|
@@ -2,5 +2,6 @@
|
|
|
2
2
|
* Display formatting utilities for proxy limits.
|
|
3
3
|
*/
|
|
4
4
|
import type { ProxyResponse } from "./types";
|
|
5
|
-
|
|
5
|
+
import type { UsageConfig } from "../../types";
|
|
6
|
+
export declare function formatProxyLimits(data: ProxyResponse, config: UsageConfig | null): string;
|
|
6
7
|
//# sourceMappingURL=format.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../../src/providers/proxy/format.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAA8B,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../../src/providers/proxy/format.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAA8B,MAAM,SAAS,CAAA;AACxE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AA0G9C,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,WAAW,GAAG,IAAI,GAAG,MAAM,CAqCzF"}
|
|
@@ -1,22 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Display formatting utilities for proxy limits.
|
|
3
3
|
*/
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
"g3-pro": "g3-pro",
|
|
7
|
-
"g3-flash": "g3-flash",
|
|
8
|
-
"g25-flash": "25-flash",
|
|
9
|
-
"g25-lite": "25-lite",
|
|
10
|
-
"pro": "g3-pro",
|
|
11
|
-
"3-flash": "g3-flash",
|
|
12
|
-
"25-flash": "25-flash",
|
|
13
|
-
"25-lite": "25-lite"
|
|
14
|
-
};
|
|
15
|
-
const GROUP_ORDER = ["claude", "g3-pro", "g3-flash", "25-flash", "25-lite"];
|
|
16
|
-
function sortGroupNames(groups) {
|
|
4
|
+
import { resolveDisplayName } from "./index";
|
|
5
|
+
function sortGroupNames(groups, groupOrder) {
|
|
17
6
|
return Array.from(groups.keys()).sort((a, b) => {
|
|
18
|
-
const aIndex =
|
|
19
|
-
const bIndex =
|
|
7
|
+
const aIndex = groupOrder.indexOf(a);
|
|
8
|
+
const bIndex = groupOrder.indexOf(b);
|
|
20
9
|
if (aIndex !== -1 && bIndex !== -1)
|
|
21
10
|
return aIndex - bIndex;
|
|
22
11
|
if (aIndex !== -1)
|
|
@@ -59,7 +48,7 @@ function formatResetTime(isoString) {
|
|
|
59
48
|
return "";
|
|
60
49
|
}
|
|
61
50
|
}
|
|
62
|
-
function aggregateCredentialsByTier(credentials) {
|
|
51
|
+
function aggregateCredentialsByTier(credentials, config) {
|
|
63
52
|
const result = {
|
|
64
53
|
paid: new Map(),
|
|
65
54
|
free: new Map(),
|
|
@@ -68,9 +57,9 @@ function aggregateCredentialsByTier(credentials) {
|
|
|
68
57
|
const tier = normalizeTier(cred.tier);
|
|
69
58
|
const groupUsage = cred.group_usage ?? {};
|
|
70
59
|
for (const [name, groupData] of Object.entries(groupUsage)) {
|
|
71
|
-
|
|
60
|
+
const mappedName = resolveDisplayName(name, config);
|
|
61
|
+
if (mappedName === null)
|
|
72
62
|
continue;
|
|
73
|
-
const mappedName = GROUP_MAPPING[name];
|
|
74
63
|
const windows = groupData.windows || {};
|
|
75
64
|
let bestWindow = null;
|
|
76
65
|
const windowPriority = ["daily", "5h", "1h", "15m"];
|
|
@@ -107,8 +96,9 @@ function aggregateCredentialsByTier(credentials) {
|
|
|
107
96
|
}
|
|
108
97
|
return result;
|
|
109
98
|
}
|
|
110
|
-
export function formatProxyLimits(data) {
|
|
99
|
+
export function formatProxyLimits(data, config) {
|
|
111
100
|
const lines = [];
|
|
101
|
+
const groupOrder = ["claude", "g3-pro", "g3-flash", "25-flash", "25-lite"];
|
|
112
102
|
lines.push("[Google] Mirrowel Proxy");
|
|
113
103
|
lines.push("");
|
|
114
104
|
if (!data.providers || Object.keys(data.providers).length === 0) {
|
|
@@ -118,13 +108,13 @@ export function formatProxyLimits(data) {
|
|
|
118
108
|
for (const [providerName, provider] of Object.entries(data.providers)) {
|
|
119
109
|
lines.push(`${providerName}:`);
|
|
120
110
|
const credentialsArray = Object.values(provider.credentials ?? {});
|
|
121
|
-
const tierData = aggregateCredentialsByTier(credentialsArray);
|
|
111
|
+
const tierData = aggregateCredentialsByTier(credentialsArray, config);
|
|
122
112
|
for (const [tierName, quotas] of Object.entries(tierData)) {
|
|
123
113
|
if (quotas.size === 0)
|
|
124
114
|
continue;
|
|
125
115
|
const tierLabel = tierName === "paid" ? "Paid" : "Free";
|
|
126
116
|
lines.push(` ${tierLabel}:`);
|
|
127
|
-
const sortedNames = sortGroupNames(quotas);
|
|
117
|
+
const sortedNames = sortGroupNames(quotas, groupOrder);
|
|
128
118
|
for (const groupName of sortedNames) {
|
|
129
119
|
const quota = quotas.get(groupName);
|
|
130
120
|
const remainingPct = quota.max > 0 ? (quota.remaining / quota.max) * 100 : 0;
|
|
@@ -3,8 +3,14 @@
|
|
|
3
3
|
* Fetches quota stats from a local/remote proxy server.
|
|
4
4
|
*/
|
|
5
5
|
import type { UsageProvider } from "../base";
|
|
6
|
+
import type { UsageConfig } from "../../types";
|
|
6
7
|
export type { ProxyResponse } from "./types";
|
|
7
8
|
export { fetchProxyLimits } from "./fetch";
|
|
8
9
|
export { formatProxyLimits } from "./format";
|
|
10
|
+
/**
|
|
11
|
+
* Resolve the display name for a model group based on config.
|
|
12
|
+
* Returns null if the group should be filtered out.
|
|
13
|
+
*/
|
|
14
|
+
export declare function resolveDisplayName(groupName: string, config: UsageConfig | null): string | null;
|
|
9
15
|
export declare const ProxyProvider: UsageProvider<void>;
|
|
10
16
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/providers/proxy/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/providers/proxy/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAC5C,OAAO,KAAK,EAAgF,WAAW,EAAE,MAAM,aAAa,CAAA;AAK5H,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAA;AA4B5C;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,WAAW,GAAG,IAAI,GACzB,MAAM,GAAG,IAAI,CAoBf;AAyND,eAAO,MAAM,aAAa,EAAE,aAAa,CAAC,IAAI,CAwB7C,CAAA"}
|
|
@@ -6,7 +6,8 @@ import { loadUsageConfig } from "../../usage/config";
|
|
|
6
6
|
import { fetchProxyLimits } from "./fetch";
|
|
7
7
|
export { fetchProxyLimits } from "./fetch";
|
|
8
8
|
export { formatProxyLimits } from "./format";
|
|
9
|
-
|
|
9
|
+
/** Default mapping for backward compatibility when no modelGroups config is present */
|
|
10
|
+
const DEFAULT_GROUP_MAPPING = {
|
|
10
11
|
"claude": "claude",
|
|
11
12
|
"g3-pro": "g3-pro",
|
|
12
13
|
"g3-flash": "g3-flash",
|
|
@@ -31,6 +32,29 @@ function sortQuotaGroups(groups) {
|
|
|
31
32
|
return a.name.localeCompare(b.name);
|
|
32
33
|
});
|
|
33
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* Resolve the display name for a model group based on config.
|
|
37
|
+
* Returns null if the group should be filtered out.
|
|
38
|
+
*/
|
|
39
|
+
export function resolveDisplayName(groupName, config) {
|
|
40
|
+
const modelGroupsConfig = config?.modelGroups;
|
|
41
|
+
// No config section → backward compat: use hardcoded whitelist
|
|
42
|
+
if (!modelGroupsConfig) {
|
|
43
|
+
return groupName in DEFAULT_GROUP_MAPPING
|
|
44
|
+
? DEFAULT_GROUP_MAPPING[groupName]
|
|
45
|
+
: null; // filter out
|
|
46
|
+
}
|
|
47
|
+
const showAll = modelGroupsConfig.showAll ?? true; // Default to auto-discovery
|
|
48
|
+
const displayNames = modelGroupsConfig.displayNames ?? {};
|
|
49
|
+
if (showAll) {
|
|
50
|
+
// Auto-discovery mode: show all, apply overrides
|
|
51
|
+
return displayNames[groupName] ?? groupName;
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
// Whitelist mode: only show configured groups
|
|
55
|
+
return groupName in displayNames ? displayNames[groupName] : null;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
34
58
|
function normalizeTier(tier) {
|
|
35
59
|
if (!tier)
|
|
36
60
|
return "free";
|
|
@@ -39,7 +63,26 @@ function normalizeTier(tier) {
|
|
|
39
63
|
return "paid";
|
|
40
64
|
return "free";
|
|
41
65
|
}
|
|
42
|
-
function
|
|
66
|
+
function pickPreferredResetTime(current, incoming) {
|
|
67
|
+
if (!incoming)
|
|
68
|
+
return current ?? null;
|
|
69
|
+
if (!current)
|
|
70
|
+
return incoming;
|
|
71
|
+
const now = Date.now();
|
|
72
|
+
const currentTs = new Date(current).getTime();
|
|
73
|
+
const incomingTs = new Date(incoming).getTime();
|
|
74
|
+
const currentFuture = currentTs > now;
|
|
75
|
+
const incomingFuture = incomingTs > now;
|
|
76
|
+
if (currentFuture && incomingFuture) {
|
|
77
|
+
return incomingTs < currentTs ? incoming : current;
|
|
78
|
+
}
|
|
79
|
+
if (incomingFuture)
|
|
80
|
+
return incoming;
|
|
81
|
+
if (currentFuture)
|
|
82
|
+
return current;
|
|
83
|
+
return incomingTs > currentTs ? incoming : current;
|
|
84
|
+
}
|
|
85
|
+
function parseQuotaGroupsFromAggregation(quotaGroups, config) {
|
|
43
86
|
if (!quotaGroups)
|
|
44
87
|
return [];
|
|
45
88
|
const tiers = {
|
|
@@ -47,8 +90,8 @@ function parseQuotaGroupsFromAggregation(quotaGroups) {
|
|
|
47
90
|
free: new Map(),
|
|
48
91
|
};
|
|
49
92
|
for (const [groupName, groupData] of Object.entries(quotaGroups)) {
|
|
50
|
-
const
|
|
51
|
-
if (
|
|
93
|
+
const displayName = resolveDisplayName(groupName, config);
|
|
94
|
+
if (displayName === null)
|
|
52
95
|
continue;
|
|
53
96
|
const windows = groupData.windows || {};
|
|
54
97
|
const windowPriority = ["daily", "5h", "1h", "15m"];
|
|
@@ -68,11 +111,18 @@ function parseQuotaGroupsFromAggregation(quotaGroups) {
|
|
|
68
111
|
// Since these are already aggregated by provider, we split by tier if possible.
|
|
69
112
|
// However, the aggregate API provides tier-agnostic totals.
|
|
70
113
|
// For now, we put them into "paid" as the default high-level view.
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
114
|
+
const max = window.total_max ?? window.total_remaining;
|
|
115
|
+
const remaining = window.total_remaining;
|
|
116
|
+
const remainingPct = typeof window.remaining_pct === "number"
|
|
117
|
+
? Math.round(window.remaining_pct)
|
|
118
|
+
: max > 0
|
|
119
|
+
? Math.round((remaining / max) * 100)
|
|
120
|
+
: 0;
|
|
121
|
+
tiers.paid.set(displayName, {
|
|
122
|
+
name: displayName,
|
|
123
|
+
remaining,
|
|
124
|
+
max,
|
|
125
|
+
remainingPct,
|
|
76
126
|
resetTime: null, // Aggregated windows don't have a single reset_at
|
|
77
127
|
});
|
|
78
128
|
}
|
|
@@ -82,13 +132,14 @@ function parseQuotaGroupsFromAggregation(quotaGroups) {
|
|
|
82
132
|
}
|
|
83
133
|
return result;
|
|
84
134
|
}
|
|
85
|
-
function parseQuotaGroupsFromCredential(groupUsage) {
|
|
135
|
+
function parseQuotaGroupsFromCredential(groupUsage, config) {
|
|
86
136
|
if (!groupUsage)
|
|
87
137
|
return [];
|
|
88
138
|
const result = new Map();
|
|
89
139
|
for (const [groupName, groupData] of Object.entries(groupUsage)) {
|
|
90
|
-
|
|
91
|
-
|
|
140
|
+
// Apply config-based filtering and display name resolution
|
|
141
|
+
const displayName = resolveDisplayName(groupName, config);
|
|
142
|
+
if (displayName === null)
|
|
92
143
|
continue;
|
|
93
144
|
const windows = groupData.windows || {};
|
|
94
145
|
let bestWindow = null;
|
|
@@ -104,8 +155,8 @@ function parseQuotaGroupsFromCredential(groupUsage) {
|
|
|
104
155
|
}
|
|
105
156
|
if (!bestWindow)
|
|
106
157
|
continue;
|
|
107
|
-
result.set(
|
|
108
|
-
name:
|
|
158
|
+
result.set(displayName, {
|
|
159
|
+
name: displayName,
|
|
109
160
|
remaining: bestWindow.remaining,
|
|
110
161
|
max: bestWindow.limit || bestWindow.remaining,
|
|
111
162
|
remainingPct: bestWindow.limit ? Math.round((bestWindow.remaining / bestWindow.limit) * 100) : 0,
|
|
@@ -114,11 +165,10 @@ function parseQuotaGroupsFromCredential(groupUsage) {
|
|
|
114
165
|
}
|
|
115
166
|
return Array.from(result.values());
|
|
116
167
|
}
|
|
117
|
-
function aggregateByProvider(provider) {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
}
|
|
168
|
+
function aggregateByProvider(provider, config) {
|
|
169
|
+
const aggregated = provider.quota_groups && Object.keys(provider.quota_groups).length > 0
|
|
170
|
+
? parseQuotaGroupsFromAggregation(provider.quota_groups, config)
|
|
171
|
+
: [];
|
|
122
172
|
// Fallback to manual aggregation of credentials
|
|
123
173
|
const tiers = {
|
|
124
174
|
paid: new Map(),
|
|
@@ -127,15 +177,13 @@ function aggregateByProvider(provider) {
|
|
|
127
177
|
if (provider.credentials) {
|
|
128
178
|
for (const cred of Object.values(provider.credentials)) {
|
|
129
179
|
const tier = normalizeTier(cred.tier);
|
|
130
|
-
const groups = parseQuotaGroupsFromCredential(cred.group_usage);
|
|
180
|
+
const groups = parseQuotaGroupsFromCredential(cred.group_usage, config);
|
|
131
181
|
for (const group of groups) {
|
|
132
182
|
const existing = tiers[tier].get(group.name);
|
|
133
183
|
if (existing) {
|
|
134
184
|
existing.remaining += group.remaining;
|
|
135
185
|
existing.max += group.max;
|
|
136
|
-
|
|
137
|
-
existing.resetTime = group.resetTime;
|
|
138
|
-
}
|
|
186
|
+
existing.resetTime = pickPreferredResetTime(existing.resetTime, group.resetTime);
|
|
139
187
|
}
|
|
140
188
|
else {
|
|
141
189
|
tiers[tier].set(group.name, { ...group });
|
|
@@ -143,6 +191,20 @@ function aggregateByProvider(provider) {
|
|
|
143
191
|
}
|
|
144
192
|
}
|
|
145
193
|
}
|
|
194
|
+
if (aggregated.length > 0) {
|
|
195
|
+
const resetLookup = new Map();
|
|
196
|
+
for (const tierInfo of Object.values(tiers)) {
|
|
197
|
+
for (const group of tierInfo.values()) {
|
|
198
|
+
resetLookup.set(group.name, pickPreferredResetTime(resetLookup.get(group.name), group.resetTime));
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
for (const tier of aggregated) {
|
|
202
|
+
for (const group of tier.quotaGroups) {
|
|
203
|
+
group.resetTime = pickPreferredResetTime(group.resetTime, resetLookup.get(group.name));
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return aggregated;
|
|
207
|
+
}
|
|
146
208
|
for (const tierGroups of Object.values(tiers)) {
|
|
147
209
|
for (const group of tierGroups.values()) {
|
|
148
210
|
group.remainingPct = group.max > 0 ? Math.round((group.remaining / group.max) * 100) : 0;
|
|
@@ -157,20 +219,20 @@ function aggregateByProvider(provider) {
|
|
|
157
219
|
}
|
|
158
220
|
return result;
|
|
159
221
|
}
|
|
160
|
-
function parseProviders(data) {
|
|
222
|
+
function parseProviders(data, config) {
|
|
161
223
|
if (!data.providers)
|
|
162
224
|
return [];
|
|
163
225
|
return Object.entries(data.providers).map(([name, provider]) => {
|
|
164
226
|
return {
|
|
165
227
|
name,
|
|
166
|
-
tiers: aggregateByProvider(provider),
|
|
228
|
+
tiers: aggregateByProvider(provider, config),
|
|
167
229
|
};
|
|
168
230
|
});
|
|
169
231
|
}
|
|
170
|
-
function parseProxyQuota(data) {
|
|
232
|
+
function parseProxyQuota(data, config) {
|
|
171
233
|
const summary = data.summary;
|
|
172
234
|
return {
|
|
173
|
-
providers: parseProviders(data),
|
|
235
|
+
providers: parseProviders(data, config),
|
|
174
236
|
totalCredentials: summary?.total_credentials ?? 0,
|
|
175
237
|
activeCredentials: summary?.active_credentials ?? 0,
|
|
176
238
|
dataSource: data.data_source,
|
|
@@ -191,7 +253,7 @@ export const ProxyProvider = {
|
|
|
191
253
|
secondary: null,
|
|
192
254
|
codeReview: null,
|
|
193
255
|
credits: null,
|
|
194
|
-
proxyQuota: parseProxyQuota(data),
|
|
256
|
+
proxyQuota: parseProxyQuota(data, config),
|
|
195
257
|
updatedAt: Date.now(),
|
|
196
258
|
};
|
|
197
259
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/providers/proxy/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/providers/proxy/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fetch logic for Z.ai usage monitoring.
|
|
3
|
+
*/
|
|
4
|
+
import type { ZaiAuth } from "./types";
|
|
5
|
+
export declare function fetchZaiUsage(auth: ZaiAuth): Promise<{
|
|
6
|
+
quota: {
|
|
7
|
+
limits: import("./types").ZaiQuotaLimit[];
|
|
8
|
+
};
|
|
9
|
+
model: {
|
|
10
|
+
x_time: string[];
|
|
11
|
+
modelCallCount: (number | null)[];
|
|
12
|
+
tokensUsage: (number | null)[];
|
|
13
|
+
totalUsage: {
|
|
14
|
+
totalModelCallCount: number;
|
|
15
|
+
totalTokensUsage: number;
|
|
16
|
+
};
|
|
17
|
+
} | undefined;
|
|
18
|
+
tool: {
|
|
19
|
+
x_time: string[];
|
|
20
|
+
networkSearchCount: (number | null)[];
|
|
21
|
+
webReadMcpCount: (number | null)[];
|
|
22
|
+
zreadMcpCount: (number | null)[];
|
|
23
|
+
totalUsage: {
|
|
24
|
+
totalNetworkSearchCount: number;
|
|
25
|
+
totalWebReadMcpCount: number;
|
|
26
|
+
totalZreadMcpCount: number;
|
|
27
|
+
totalSearchMcpCount: number;
|
|
28
|
+
toolDetails: unknown[];
|
|
29
|
+
};
|
|
30
|
+
} | undefined;
|
|
31
|
+
}>;
|
|
32
|
+
//# sourceMappingURL=fetch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../../src/providers/zai/fetch.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAiE,MAAM,SAAS,CAAA;AAErG,wBAAsB,aAAa,CAAC,IAAI,EAAE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;GA4ChD"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fetch logic for Z.ai usage monitoring.
|
|
3
|
+
*/
|
|
4
|
+
import { loadUsageConfig } from "../../usage/config";
|
|
5
|
+
export async function fetchZaiUsage(auth) {
|
|
6
|
+
const config = await loadUsageConfig().catch(() => null);
|
|
7
|
+
const baseUrl = config?.zaiEndpoint?.replace(/\/$/, "") || "https://api.z.ai";
|
|
8
|
+
const monitorUrl = `${baseUrl}/api/monitor/usage`;
|
|
9
|
+
const now = new Date();
|
|
10
|
+
const endDate = new Date(now.getFullYear(), now.getMonth(), now.getDate(), now.getHours(), 0, 0, 0);
|
|
11
|
+
const startDate = new Date(endDate.getTime() - 24 * 60 * 60 * 1000);
|
|
12
|
+
const formatDateTime = (date) => {
|
|
13
|
+
const pad = (n) => String(n).padStart(2, "0");
|
|
14
|
+
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`;
|
|
15
|
+
};
|
|
16
|
+
const startTime = formatDateTime(startDate);
|
|
17
|
+
const endTime = formatDateTime(endDate);
|
|
18
|
+
const queryParams = `?startTime=${encodeURIComponent(startTime)}&endTime=${encodeURIComponent(endTime)}`;
|
|
19
|
+
const headers = {
|
|
20
|
+
"Authorization": auth.key,
|
|
21
|
+
"Accept-Language": "en-US,en",
|
|
22
|
+
"Content-Type": "application/json",
|
|
23
|
+
};
|
|
24
|
+
const [quotaRes, modelRes, toolRes] = await Promise.all([
|
|
25
|
+
fetch(`${monitorUrl}/quota/limit`, { headers }),
|
|
26
|
+
fetch(`${monitorUrl}/model-usage${queryParams}`, { headers }),
|
|
27
|
+
fetch(`${monitorUrl}/tool-usage${queryParams}`, { headers }),
|
|
28
|
+
]);
|
|
29
|
+
if (!quotaRes.ok) {
|
|
30
|
+
throw new Error(`Z.ai quota query failed: ${quotaRes.status} ${await quotaRes.text()}`);
|
|
31
|
+
}
|
|
32
|
+
const quota = (await quotaRes.json());
|
|
33
|
+
const model = modelRes.ok ? (await modelRes.json()) : null;
|
|
34
|
+
const tool = toolRes.ok ? (await toolRes.json()) : null;
|
|
35
|
+
return {
|
|
36
|
+
quota: quota.data,
|
|
37
|
+
model: model?.data,
|
|
38
|
+
tool: tool?.data,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/providers/zai/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAG5C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAEtC,eAAO,MAAM,WAAW,EAAE,aAAa,CAAC,OAAO,CAmC9C,CAAA"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Z.ai GLM Coding Plan provider.
|
|
3
|
+
*/
|
|
4
|
+
import { fetchZaiUsage } from "./fetch";
|
|
5
|
+
export const ZaiProvider = {
|
|
6
|
+
id: "zai-coding-plan",
|
|
7
|
+
displayName: "Z.ai GLM Coding Plan",
|
|
8
|
+
async fetchUsage(auth) {
|
|
9
|
+
try {
|
|
10
|
+
const data = await fetchZaiUsage(auth);
|
|
11
|
+
return {
|
|
12
|
+
timestamp: Date.now(),
|
|
13
|
+
provider: "zai-coding-plan",
|
|
14
|
+
planType: null, // Don't assume pro, let quota numbers show tier
|
|
15
|
+
primary: null,
|
|
16
|
+
secondary: null,
|
|
17
|
+
codeReview: null,
|
|
18
|
+
credits: null,
|
|
19
|
+
zaiQuota: {
|
|
20
|
+
limits: data.quota.limits.map(l => ({
|
|
21
|
+
type: l.type,
|
|
22
|
+
usage: l.usage,
|
|
23
|
+
currentValue: l.currentValue,
|
|
24
|
+
remaining: l.remaining,
|
|
25
|
+
percentage: l.percentage,
|
|
26
|
+
nextResetTime: l.nextResetTime,
|
|
27
|
+
usageDetails: l.usageDetails
|
|
28
|
+
})),
|
|
29
|
+
modelUsage: data.model?.totalUsage,
|
|
30
|
+
toolUsage: data.tool?.totalUsage
|
|
31
|
+
},
|
|
32
|
+
updatedAt: Date.now(),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
catch (e) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type definitions for the Z.ai GLM Coding Plan provider.
|
|
3
|
+
*/
|
|
4
|
+
export interface ZaiQuotaLimit {
|
|
5
|
+
type: string;
|
|
6
|
+
unit: number;
|
|
7
|
+
number: number;
|
|
8
|
+
usage: number;
|
|
9
|
+
currentValue: number;
|
|
10
|
+
remaining: number;
|
|
11
|
+
percentage: number;
|
|
12
|
+
usageDetails?: Array<{
|
|
13
|
+
modelCode: string;
|
|
14
|
+
usage: number;
|
|
15
|
+
}>;
|
|
16
|
+
nextResetTime?: number;
|
|
17
|
+
}
|
|
18
|
+
export interface ZaiQuotaResponse {
|
|
19
|
+
code: number;
|
|
20
|
+
msg: string;
|
|
21
|
+
data: {
|
|
22
|
+
limits: ZaiQuotaLimit[];
|
|
23
|
+
};
|
|
24
|
+
success: boolean;
|
|
25
|
+
}
|
|
26
|
+
export interface ZaiModelUsageResponse {
|
|
27
|
+
code: number;
|
|
28
|
+
msg: string;
|
|
29
|
+
data: {
|
|
30
|
+
x_time: string[];
|
|
31
|
+
modelCallCount: (number | null)[];
|
|
32
|
+
tokensUsage: (number | null)[];
|
|
33
|
+
totalUsage: {
|
|
34
|
+
totalModelCallCount: number;
|
|
35
|
+
totalTokensUsage: number;
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
success: boolean;
|
|
39
|
+
}
|
|
40
|
+
export interface ZaiToolUsageResponse {
|
|
41
|
+
code: number;
|
|
42
|
+
msg: string;
|
|
43
|
+
data: {
|
|
44
|
+
x_time: string[];
|
|
45
|
+
networkSearchCount: (number | null)[];
|
|
46
|
+
webReadMcpCount: (number | null)[];
|
|
47
|
+
zreadMcpCount: (number | null)[];
|
|
48
|
+
totalUsage: {
|
|
49
|
+
totalNetworkSearchCount: number;
|
|
50
|
+
totalWebReadMcpCount: number;
|
|
51
|
+
totalZreadMcpCount: number;
|
|
52
|
+
totalSearchMcpCount: number;
|
|
53
|
+
toolDetails: unknown[];
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
success: boolean;
|
|
57
|
+
}
|
|
58
|
+
export interface ZaiAuth {
|
|
59
|
+
key: string;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/providers/zai/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,YAAY,CAAC,EAAE,KAAK,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC1D,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE;QACJ,MAAM,EAAE,aAAa,EAAE,CAAA;KACxB,CAAA;IACD,OAAO,EAAE,OAAO,CAAA;CACjB;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE;QACJ,MAAM,EAAE,MAAM,EAAE,CAAA;QAChB,cAAc,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAA;QACjC,WAAW,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAA;QAC9B,UAAU,EAAE;YACV,mBAAmB,EAAE,MAAM,CAAA;YAC3B,gBAAgB,EAAE,MAAM,CAAA;SACzB,CAAA;KACF,CAAA;IACD,OAAO,EAAE,OAAO,CAAA;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE;QACJ,MAAM,EAAE,MAAM,EAAE,CAAA;QAChB,kBAAkB,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAA;QACrC,eAAe,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAA;QAClC,aAAa,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAA;QAChC,UAAU,EAAE;YACV,uBAAuB,EAAE,MAAM,CAAA;YAC/B,oBAAoB,EAAE,MAAM,CAAA;YAC5B,kBAAkB,EAAE,MAAM,CAAA;YAC1B,mBAAmB,EAAE,MAAM,CAAA;YAC3B,WAAW,EAAE,OAAO,EAAE,CAAA;SACvB,CAAA;KACF,CAAA;IACD,OAAO,EAAE,OAAO,CAAA;CACjB;AAED,MAAM,WAAW,OAAO;IACtB,GAAG,EAAE,MAAM,CAAA;CACZ"}
|
package/dist/types.d.ts
CHANGED
|
@@ -45,11 +45,40 @@ export interface ProxyQuota {
|
|
|
45
45
|
export interface UsageConfig {
|
|
46
46
|
endpoint?: string;
|
|
47
47
|
apiKey?: string;
|
|
48
|
+
zaiEndpoint?: string;
|
|
48
49
|
timeout?: number;
|
|
49
50
|
providers?: {
|
|
50
51
|
openai?: boolean;
|
|
51
52
|
proxy?: boolean;
|
|
52
53
|
copilot?: boolean;
|
|
54
|
+
zai?: boolean;
|
|
55
|
+
};
|
|
56
|
+
modelGroups?: {
|
|
57
|
+
showAll?: boolean;
|
|
58
|
+
displayNames?: Record<string, string>;
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
export interface ZaiQuota {
|
|
62
|
+
limits: Array<{
|
|
63
|
+
type: string;
|
|
64
|
+
usage: number;
|
|
65
|
+
currentValue: number;
|
|
66
|
+
remaining: number;
|
|
67
|
+
percentage: number;
|
|
68
|
+
nextResetTime?: number;
|
|
69
|
+
usageDetails?: Array<{
|
|
70
|
+
modelCode: string;
|
|
71
|
+
usage: number;
|
|
72
|
+
}>;
|
|
73
|
+
}>;
|
|
74
|
+
modelUsage?: {
|
|
75
|
+
totalModelCallCount: number;
|
|
76
|
+
totalTokensUsage: number;
|
|
77
|
+
};
|
|
78
|
+
toolUsage?: {
|
|
79
|
+
totalNetworkSearchCount: number;
|
|
80
|
+
totalWebReadMcpCount: number;
|
|
81
|
+
totalZreadMcpCount: number;
|
|
53
82
|
};
|
|
54
83
|
}
|
|
55
84
|
export interface UsageSnapshot {
|
|
@@ -62,6 +91,7 @@ export interface UsageSnapshot {
|
|
|
62
91
|
credits: CreditsSnapshot | null;
|
|
63
92
|
proxyQuota?: ProxyQuota;
|
|
64
93
|
copilotQuota?: CopilotQuota;
|
|
94
|
+
zaiQuota?: ZaiQuota;
|
|
65
95
|
updatedAt: number;
|
|
66
96
|
isMissing?: boolean;
|
|
67
97
|
missingReason?: string;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,SAAS,0IAcZ,CAAA;AAEV,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,CAAC,CAAA;AAEjD,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAA;IACnB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CACxB;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,OAAO,CAAA;IACnB,SAAS,EAAE,OAAO,CAAA;IAClB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,gBAAgB,EAAE,MAAM,CAAA;IACxB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC1B;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,GAAG,EAAE,MAAM,CAAA;IACX,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAC1B;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,GAAG,MAAM,CAAA;IACrB,WAAW,EAAE,eAAe,EAAE,CAAA;CAC/B;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,aAAa,EAAE,CAAA;CACvB;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,iBAAiB,EAAE,CAAA;IAC9B,gBAAgB,EAAE,MAAM,CAAA;IACxB,iBAAiB,EAAE,MAAM,CAAA;IACzB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE;QACV,MAAM,CAAC,EAAE,OAAO,CAAA;QAChB,KAAK,CAAC,EAAE,OAAO,CAAA;QACf,OAAO,CAAC,EAAE,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../../src/ui/formatters/proxy.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../../src/ui/formatters/proxy.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAOhD,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,EAAE,CAcrE"}
|
|
@@ -22,10 +22,16 @@ function formatProxyProvider(provider) {
|
|
|
22
22
|
if (!tier.quotaGroups?.length)
|
|
23
23
|
continue;
|
|
24
24
|
lines.push(` ${tier.tier === "paid" ? "Paid" : "Free"}:`);
|
|
25
|
-
|
|
26
|
-
const reset = group.resetTime ? formatResetSuffixISO(group.resetTime) : "";
|
|
27
|
-
lines.push(` ${group.name.padEnd(9)} ${formatBar(group.remainingPct)} ${group.remaining}/${group.max}${reset}`);
|
|
28
|
-
}
|
|
25
|
+
lines.push(...formatTierGroups(tier.quotaGroups));
|
|
29
26
|
}
|
|
30
27
|
return lines;
|
|
31
28
|
}
|
|
29
|
+
function formatTierGroups(groups) {
|
|
30
|
+
const nameWidth = Math.max(...groups.map(group => group.name.length), 9);
|
|
31
|
+
const quotaWidth = Math.max(...groups.map(group => `${group.remaining}/${group.max}`.length), 7);
|
|
32
|
+
return groups.map(group => {
|
|
33
|
+
const reset = group.resetTime ? formatResetSuffixISO(group.resetTime) : "";
|
|
34
|
+
const quota = `${group.remaining}/${group.max}`.padStart(quotaWidth);
|
|
35
|
+
return ` ${group.name.padEnd(nameWidth)} ${formatBar(group.remainingPct)} ${quota}${reset}`;
|
|
36
|
+
});
|
|
37
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/ui/formatters/shared.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAEhD,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAK7C;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/ui/formatters/shared.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAEhD,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAK7C;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAIhE;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAMxD;AAwBD,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,EAAE,CAgBvE"}
|
|
@@ -13,35 +13,43 @@ export function formatBar(pct) {
|
|
|
13
13
|
export function formatResetSuffix(resetAt) {
|
|
14
14
|
if (!resetAt)
|
|
15
15
|
return "";
|
|
16
|
-
|
|
16
|
+
const delta = formatTimeDelta(resetAt);
|
|
17
|
+
return delta === "just refreshed" ? ` (${delta})` : ` (resets in ${delta})`;
|
|
17
18
|
}
|
|
18
19
|
export function formatResetSuffixISO(iso) {
|
|
19
20
|
try {
|
|
20
21
|
const at = Math.floor(new Date(iso).getTime() / 1000);
|
|
21
|
-
|
|
22
|
+
const delta = formatTimeDelta(at);
|
|
23
|
+
return delta === "just refreshed" ? ` (${delta})` : ` (resets in ${delta})`;
|
|
22
24
|
}
|
|
23
25
|
catch {
|
|
24
26
|
return "";
|
|
25
27
|
}
|
|
26
28
|
}
|
|
27
29
|
function formatTimeDelta(at) {
|
|
28
|
-
const
|
|
30
|
+
const atSeconds = at > 1e11 ? Math.floor(at / 1000) : at;
|
|
31
|
+
const diff = atSeconds - Math.floor(Date.now() / 1000);
|
|
29
32
|
if (diff <= 0)
|
|
30
|
-
return "
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
return "just refreshed";
|
|
34
|
+
const days = Math.floor(diff / 86400);
|
|
35
|
+
const hours = Math.floor((diff % 86400) / 3600);
|
|
36
|
+
const minutes = Math.floor((diff % 3600) / 60);
|
|
37
|
+
if (days > 0) {
|
|
38
|
+
return hours > 0 ? `${days}d${hours}hrs` : `${days}d`;
|
|
39
|
+
}
|
|
40
|
+
if (hours > 0) {
|
|
41
|
+
return minutes > 0 ? `${hours}hrs${minutes}m` : `${hours}hrs`;
|
|
42
|
+
}
|
|
43
|
+
if (minutes > 0)
|
|
44
|
+
return `${minutes}m`;
|
|
45
|
+
return `${diff}s`;
|
|
38
46
|
}
|
|
39
47
|
export function formatMissingSnapshot(snapshot) {
|
|
40
48
|
const { provider } = snapshot;
|
|
41
49
|
const configPath = getConfigPath();
|
|
42
50
|
const instructions = {
|
|
43
51
|
codex: "if you dont have codex oauth, please set your usage-config.jsonc to openai: false",
|
|
44
|
-
proxy: "
|
|
52
|
+
proxy: "check your usage-config.jsonc. Default: endpoint http://localhost:8000, apiKey VerysecretKey. If you changed these during proxy setup, update your config to match. Or set proxy: false to disable.",
|
|
45
53
|
copilot: "if you are not running GitHub Copilot, please set your usage-config.jsonc to copilot: false"
|
|
46
54
|
};
|
|
47
55
|
const lines = [`→ [${provider.toUpperCase()}] - ${instructions[provider] || ""}`];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zai.d.ts","sourceRoot":"","sources":["../../../src/ui/formatters/zai.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAGhD,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,EAAE,CA8BnE"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Formats Z.ai GLM Coding Plan usage snapshots.
|
|
3
|
+
*/
|
|
4
|
+
import { formatBar, formatMissingSnapshot, formatResetSuffix } from "./shared";
|
|
5
|
+
export function formatZaiSnapshot(snapshot) {
|
|
6
|
+
const zai = snapshot.zaiQuota;
|
|
7
|
+
if (!zai?.limits?.length)
|
|
8
|
+
return formatMissingSnapshot(snapshot);
|
|
9
|
+
const lines = ["→ [Z.ai] GLM Coding Plan"];
|
|
10
|
+
for (const limit of zai.limits) {
|
|
11
|
+
const isTokens = limit.type === "TOKENS_LIMIT";
|
|
12
|
+
const label = isTokens ? "5 Hours Quota" : "Total Monthly Web Search / Reader / Zread Quota";
|
|
13
|
+
const remainingPct = 100 - limit.percentage;
|
|
14
|
+
const reset = isTokens
|
|
15
|
+
? (limit.nextResetTime ? formatResetSuffix(limit.nextResetTime) : "")
|
|
16
|
+
: " (resets on the 1st)";
|
|
17
|
+
lines.push(` ${label}`);
|
|
18
|
+
lines.push(` ${formatBar(remainingPct)} ${remainingPct.toFixed(0)}% left${reset}`);
|
|
19
|
+
const unit = isTokens ? "Tokens" : "Times";
|
|
20
|
+
lines.push(` Used: ${limit.currentValue.toLocaleString()} / ${limit.usage.toLocaleString()} ${unit}`);
|
|
21
|
+
lines.push("");
|
|
22
|
+
}
|
|
23
|
+
if (zai.modelUsage) {
|
|
24
|
+
lines.push(` 24h Activity:`);
|
|
25
|
+
lines.push(` Tokens: ${zai.modelUsage.totalTokensUsage.toLocaleString()}`);
|
|
26
|
+
lines.push(` Calls: ${zai.modelUsage.totalModelCallCount.toLocaleString()}`);
|
|
27
|
+
}
|
|
28
|
+
return lines;
|
|
29
|
+
}
|
package/dist/ui/status.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/ui/status.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAC7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/ui/status.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAC7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAM1C,KAAK,WAAW,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAA;AAExC,wBAAsB,iBAAiB,CAAC,OAAO,EAAE;IAC/C,MAAM,EAAE,WAAW,CAAA;IACnB,KAAK,EAAE,UAAU,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;CACb,GAAG,OAAO,CAAC,IAAI,CAAC,CAmBhB;AAkCD,wBAAsB,iBAAiB,CAAC,OAAO,EAAE;IAC/C,MAAM,EAAE,WAAW,CAAA;IACnB,KAAK,EAAE,UAAU,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,aAAa,EAAE,CAAA;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB,GAAG,OAAO,CAAC,IAAI,CAAC,CAahB"}
|
package/dist/ui/status.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { formatProxySnapshot } from "./formatters/proxy";
|
|
6
6
|
import { formatCopilotSnapshot } from "./formatters/copilot";
|
|
7
|
+
import { formatZaiSnapshot } from "./formatters/zai";
|
|
7
8
|
import { formatBar, formatResetSuffix, formatMissingSnapshot } from "./formatters/shared";
|
|
8
9
|
export async function sendStatusMessage(options) {
|
|
9
10
|
const bus = options.client.bus;
|
|
@@ -32,6 +33,8 @@ function formatSnapshot(snapshot) {
|
|
|
32
33
|
return formatProxySnapshot(snapshot);
|
|
33
34
|
if (snapshot.provider === "copilot")
|
|
34
35
|
return formatCopilotSnapshot(snapshot);
|
|
36
|
+
if (snapshot.provider === "zai-coding-plan")
|
|
37
|
+
return formatZaiSnapshot(snapshot);
|
|
35
38
|
const plan = snapshot.planType ? ` (${snapshot.planType.replace(/_/g, " ").replace(/\b\w/g, c => c.toUpperCase())})` : "";
|
|
36
39
|
const lines = [`→ [${snapshot.provider.toUpperCase()}]${plan}`];
|
|
37
40
|
const metrics = [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/usage/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAiB3C,wBAAsB,eAAe,IAAI,OAAO,CAAC,WAAW,CAAC,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/usage/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAiB3C,wBAAsB,eAAe,IAAI,OAAO,CAAC,WAAW,CAAC,CA0D5D"}
|
package/dist/usage/config.js
CHANGED
|
@@ -18,13 +18,26 @@ export async function loadUsageConfig() {
|
|
|
18
18
|
const file = Bun.file(CONFIG_PATH);
|
|
19
19
|
if (!(await file.exists())) {
|
|
20
20
|
const content = `{
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
// REQUIRED: Proxy server endpoint (default: "http://localhost:8000")
|
|
22
|
+
// Leave empty ONLY if you don't use the proxy
|
|
23
|
+
"endpoint": "http://localhost:8000",
|
|
24
|
+
|
|
25
|
+
// REQUIRED: API key for proxy auth (default: "VerysecretKey")
|
|
26
|
+
// Leave empty if your proxy doesn't require authentication
|
|
27
|
+
"apiKey": "VerysecretKey",
|
|
28
|
+
|
|
29
|
+
// Optional: Z.ai API endpoint (default: "https://api.z.ai")
|
|
30
|
+
"zaiEndpoint": "https://api.z.ai",
|
|
31
|
+
|
|
32
|
+
// Optional: Request timeout in milliseconds (default: 10000)
|
|
23
33
|
"timeout": 10000,
|
|
34
|
+
|
|
35
|
+
// Optional: Show/hide providers in /usage output
|
|
24
36
|
"providers": {
|
|
25
37
|
"openai": true,
|
|
26
38
|
"proxy": true,
|
|
27
|
-
"copilot": true
|
|
39
|
+
"copilot": true,
|
|
40
|
+
"zai": true
|
|
28
41
|
}
|
|
29
42
|
}
|
|
30
43
|
`;
|
|
@@ -37,6 +50,7 @@ export async function loadUsageConfig() {
|
|
|
37
50
|
openai: true,
|
|
38
51
|
proxy: true,
|
|
39
52
|
copilot: true,
|
|
53
|
+
zai: true,
|
|
40
54
|
},
|
|
41
55
|
};
|
|
42
56
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/usage/fetch.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAQ7C,wBAAsB,mBAAmB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/usage/fetch.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAQ7C,wBAAsB,mBAAmB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CA4CnF;AAYD,wBAAgB,qBAAqB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEzE;AA8BD,wBAAsB,SAAS,gDAG9B"}
|
package/dist/usage/fetch.js
CHANGED
|
@@ -6,7 +6,7 @@ import { providers } from "../providers";
|
|
|
6
6
|
import { loadUsageConfig } from "./config";
|
|
7
7
|
import { loadMergedAuths } from "./auth/loader";
|
|
8
8
|
import { resolveProviderAuths } from "./registry";
|
|
9
|
-
const CORE_PROVIDERS = ["codex", "proxy", "copilot"];
|
|
9
|
+
const CORE_PROVIDERS = ["codex", "proxy", "copilot", "zai-coding-plan"];
|
|
10
10
|
export async function fetchUsageSnapshots(filter) {
|
|
11
11
|
const target = resolveFilter(filter);
|
|
12
12
|
const config = await loadUsageConfig().catch(() => null);
|
|
@@ -14,6 +14,8 @@ export async function fetchUsageSnapshots(filter) {
|
|
|
14
14
|
const isEnabled = (id) => {
|
|
15
15
|
if (id === "codex")
|
|
16
16
|
return toggles.openai !== false;
|
|
17
|
+
if (id === "zai-coding-plan")
|
|
18
|
+
return toggles.zai !== false;
|
|
17
19
|
return toggles[id] !== false;
|
|
18
20
|
};
|
|
19
21
|
const { auths, codexDiagnostics } = await loadMergedAuths();
|
|
@@ -51,7 +53,8 @@ function resolveFilter(f) {
|
|
|
51
53
|
const aliases = {
|
|
52
54
|
codex: "codex", openai: "codex", gpt: "codex",
|
|
53
55
|
proxy: "proxy", agy: "proxy", gemini: "proxy",
|
|
54
|
-
copilot: "copilot", github: "copilot"
|
|
56
|
+
copilot: "copilot", github: "copilot",
|
|
57
|
+
zai: "zai-coding-plan", glm: "zai-coding-plan"
|
|
55
58
|
};
|
|
56
59
|
return f ? aliases[f.toLowerCase().trim()] : undefined;
|
|
57
60
|
}
|
package/dist/usage/registry.d.ts
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import type { CodexAuth } from "../providers/codex";
|
|
5
5
|
import type { CopilotAuthData } from "../providers/copilot/types";
|
|
6
|
+
import type { ZaiAuth } from "../providers/zai/types";
|
|
6
7
|
export type AuthEntry = {
|
|
7
8
|
type?: string;
|
|
8
9
|
access?: string;
|
|
@@ -18,6 +19,9 @@ type ProviderAuthEntry = {
|
|
|
18
19
|
} | {
|
|
19
20
|
providerID: "copilot";
|
|
20
21
|
auth: CopilotAuthData;
|
|
22
|
+
} | {
|
|
23
|
+
providerID: "zai-coding-plan";
|
|
24
|
+
auth: ZaiAuth;
|
|
21
25
|
};
|
|
22
26
|
export declare function resolveProviderAuths(auths: AuthRecord, usageToken: string | null): ProviderAuthEntry[];
|
|
23
27
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/usage/registry.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAA;
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/usage/registry.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAA;AACjE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAA;AAErD,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,GAAG,CAAC,EAAE,MAAM,CAAA;CACb,CAAA;AAED,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;AAElD,KAAK,iBAAiB,GAClB;IAAE,UAAU,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,SAAS,CAAA;CAAE,GACxC;IAAE,UAAU,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,eAAe,CAAA;CAAE,GAChD;IAAE,UAAU,EAAE,iBAAiB,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,CAAA;AAsCpD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,iBAAiB,EAAE,CActG"}
|
package/dist/usage/registry.js
CHANGED
|
@@ -20,6 +20,14 @@ const providerDescriptors = [
|
|
|
20
20
|
refresh: entry.refresh,
|
|
21
21
|
}),
|
|
22
22
|
},
|
|
23
|
+
{
|
|
24
|
+
id: "zai-coding-plan",
|
|
25
|
+
authKeys: ["zai-coding-plan", "zai", "glm"],
|
|
26
|
+
requiresOAuth: false,
|
|
27
|
+
buildAuth: (entry) => ({
|
|
28
|
+
key: entry.key || entry.access || "",
|
|
29
|
+
}),
|
|
30
|
+
},
|
|
23
31
|
];
|
|
24
32
|
export function resolveProviderAuths(auths, usageToken) {
|
|
25
33
|
const entries = [];
|