@leo000001/opencode-quota-sidebar 3.0.1 → 3.0.3
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 +14 -2
- package/CONTRIBUTING.md +4 -1
- package/README.md +210 -514
- package/README.zh-CN.md +337 -0
- package/SECURITY.md +2 -2
- package/assets/OpenCode-Quota-Sidebar.png +0 -0
- package/dist/cost.d.ts +3 -3
- package/dist/cost.js +258 -169
- package/dist/format.js +10 -3
- package/dist/index.js +4 -3
- package/dist/providers/common.d.ts +6 -0
- package/dist/providers/common.js +32 -12
- package/dist/providers/core/anthropic.d.ts +1 -1
- package/dist/providers/core/anthropic.js +43 -39
- package/dist/providers/core/kimi_for_coding.d.ts +1 -1
- package/dist/providers/core/kimi_for_coding.js +44 -64
- package/dist/providers/core/minimax_cn_coding_plan.d.ts +2 -0
- package/dist/providers/core/minimax_cn_coding_plan.js +214 -0
- package/dist/providers/core/zhipu_coding_plan.d.ts +1 -1
- package/dist/providers/core/zhipu_coding_plan.js +41 -61
- package/dist/providers/index.d.ts +3 -3
- package/dist/providers/index.js +5 -5
- package/dist/providers/third_party/rightcode.d.ts +1 -1
- package/dist/providers/third_party/rightcode.js +41 -61
- package/dist/providers/third_party/xyai.d.ts +2 -0
- package/dist/providers/third_party/{xyai_vibe.js → xyai.js} +113 -79
- package/dist/quota.d.ts +2 -2
- package/dist/quota.js +24 -18
- package/dist/quota_render.d.ts +1 -1
- package/dist/quota_render.js +23 -17
- package/dist/storage_parse.js +1 -0
- package/dist/title.js +7 -7
- package/dist/title_apply.js +18 -1
- package/dist/tools.d.ts +13 -8
- package/dist/tools.js +4 -2
- package/dist/tui.tsx +2 -1
- package/dist/tui_helpers.d.ts +2 -1
- package/dist/tui_helpers.js +6 -1
- package/dist/types.d.ts +2 -0
- package/package.json +11 -3
- package/quota-sidebar.config.example.json +45 -45
- package/dist/providers/third_party/buzz.d.ts +0 -2
- package/dist/providers/third_party/buzz.js +0 -156
- package/dist/providers/third_party/xyai_vibe.d.ts +0 -2
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
import { isRecord, swallow } from '../../helpers.js';
|
|
2
|
-
import { asNumber, configuredProviderEnabled, fetchWithTimeout, sanitizeBaseURL, toIso, } from '../common.js';
|
|
3
|
-
function isBuzzBaseURL(value) {
|
|
4
|
-
const normalized = sanitizeBaseURL(value);
|
|
5
|
-
if (!normalized)
|
|
6
|
-
return false;
|
|
7
|
-
try {
|
|
8
|
-
const parsed = new URL(normalized);
|
|
9
|
-
if (parsed.protocol !== 'https:')
|
|
10
|
-
return false;
|
|
11
|
-
return parsed.host === 'buzzai.cc' || parsed.host === 'www.buzzai.cc';
|
|
12
|
-
}
|
|
13
|
-
catch {
|
|
14
|
-
return false;
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
function resolveApiKey(auth, providerOptions) {
|
|
18
|
-
const optionKey = providerOptions?.apiKey;
|
|
19
|
-
if (typeof optionKey === 'string' && optionKey)
|
|
20
|
-
return optionKey;
|
|
21
|
-
if (!auth)
|
|
22
|
-
return undefined;
|
|
23
|
-
if (auth.type === 'api' && typeof auth.key === 'string' && auth.key) {
|
|
24
|
-
return auth.key;
|
|
25
|
-
}
|
|
26
|
-
if (auth.type === 'wellknown') {
|
|
27
|
-
if (typeof auth.key === 'string' && auth.key)
|
|
28
|
-
return auth.key;
|
|
29
|
-
if (typeof auth.token === 'string' && auth.token)
|
|
30
|
-
return auth.token;
|
|
31
|
-
}
|
|
32
|
-
if (auth.type === 'oauth' && typeof auth.access === 'string' && auth.access) {
|
|
33
|
-
return auth.access;
|
|
34
|
-
}
|
|
35
|
-
return undefined;
|
|
36
|
-
}
|
|
37
|
-
function dashboardUrl(baseURL, pathname) {
|
|
38
|
-
const normalized = sanitizeBaseURL(baseURL);
|
|
39
|
-
if (normalized) {
|
|
40
|
-
try {
|
|
41
|
-
return new URL(pathname, normalized).toString();
|
|
42
|
-
}
|
|
43
|
-
catch {
|
|
44
|
-
// Fall through to the stable default host below.
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
return `https://buzzai.cc${pathname}`;
|
|
48
|
-
}
|
|
49
|
-
async function fetchBuzzQuota({ sourceProviderID, providerID, providerOptions, auth, config, }) {
|
|
50
|
-
const checkedAt = Date.now();
|
|
51
|
-
const runtimeProviderID = typeof sourceProviderID === 'string' && sourceProviderID
|
|
52
|
-
? sourceProviderID
|
|
53
|
-
: providerID;
|
|
54
|
-
const base = {
|
|
55
|
-
providerID: runtimeProviderID,
|
|
56
|
-
adapterID: 'buzz',
|
|
57
|
-
label: 'Buzz',
|
|
58
|
-
shortLabel: 'Buzz',
|
|
59
|
-
sortOrder: 6,
|
|
60
|
-
};
|
|
61
|
-
const apiKey = resolveApiKey(auth, providerOptions);
|
|
62
|
-
if (!apiKey) {
|
|
63
|
-
return {
|
|
64
|
-
...base,
|
|
65
|
-
status: 'unavailable',
|
|
66
|
-
checkedAt,
|
|
67
|
-
note: 'missing api key',
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
const subscriptionEndpoint = dashboardUrl(providerOptions?.baseURL, '/v1/dashboard/billing/subscription');
|
|
71
|
-
const usageEndpoint = dashboardUrl(providerOptions?.baseURL, '/v1/dashboard/billing/usage');
|
|
72
|
-
const requestInit = {
|
|
73
|
-
headers: {
|
|
74
|
-
Accept: 'application/json',
|
|
75
|
-
Authorization: `Bearer ${apiKey}`,
|
|
76
|
-
'User-Agent': 'opencode-quota-sidebar',
|
|
77
|
-
},
|
|
78
|
-
};
|
|
79
|
-
const [subscriptionResponse, usageResponse] = await Promise.all([
|
|
80
|
-
fetchWithTimeout(subscriptionEndpoint, requestInit, config.quota.requestTimeoutMs).catch(swallow('fetchBuzzQuota:subscription')),
|
|
81
|
-
fetchWithTimeout(usageEndpoint, requestInit, config.quota.requestTimeoutMs).catch(swallow('fetchBuzzQuota:usage')),
|
|
82
|
-
]);
|
|
83
|
-
if (!subscriptionResponse || !usageResponse) {
|
|
84
|
-
return {
|
|
85
|
-
...base,
|
|
86
|
-
status: 'error',
|
|
87
|
-
checkedAt,
|
|
88
|
-
note: 'network request failed',
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
if (!subscriptionResponse.ok || !usageResponse.ok) {
|
|
92
|
-
const note = [
|
|
93
|
-
!subscriptionResponse.ok
|
|
94
|
-
? `subscription http ${subscriptionResponse.status}`
|
|
95
|
-
: undefined,
|
|
96
|
-
!usageResponse.ok ? `usage http ${usageResponse.status}` : undefined,
|
|
97
|
-
]
|
|
98
|
-
.filter((value) => Boolean(value))
|
|
99
|
-
.join(', ');
|
|
100
|
-
return {
|
|
101
|
-
...base,
|
|
102
|
-
status: 'error',
|
|
103
|
-
checkedAt,
|
|
104
|
-
note,
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
const [subscriptionPayload, usagePayload] = await Promise.all([
|
|
108
|
-
subscriptionResponse
|
|
109
|
-
.json()
|
|
110
|
-
.catch(swallow('fetchBuzzQuota:subscriptionJson')),
|
|
111
|
-
usageResponse.json().catch(swallow('fetchBuzzQuota:usageJson')),
|
|
112
|
-
]);
|
|
113
|
-
if (!isRecord(subscriptionPayload) || !isRecord(usagePayload)) {
|
|
114
|
-
return {
|
|
115
|
-
...base,
|
|
116
|
-
status: 'error',
|
|
117
|
-
checkedAt,
|
|
118
|
-
note: 'invalid response',
|
|
119
|
-
};
|
|
120
|
-
}
|
|
121
|
-
const totalQuota = asNumber(subscriptionPayload.soft_limit_usd);
|
|
122
|
-
const totalUsage = asNumber(usagePayload.total_usage);
|
|
123
|
-
if (totalQuota === undefined || totalUsage === undefined) {
|
|
124
|
-
return {
|
|
125
|
-
...base,
|
|
126
|
-
status: 'error',
|
|
127
|
-
checkedAt,
|
|
128
|
-
note: 'missing billing fields',
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
|
-
const accessUntil = asNumber(subscriptionPayload.access_until);
|
|
132
|
-
const resetAt = accessUntil !== undefined && accessUntil > 0
|
|
133
|
-
? toIso(accessUntil)
|
|
134
|
-
: undefined;
|
|
135
|
-
const balance = totalQuota - totalUsage / 100;
|
|
136
|
-
return {
|
|
137
|
-
...base,
|
|
138
|
-
status: 'ok',
|
|
139
|
-
checkedAt,
|
|
140
|
-
resetAt,
|
|
141
|
-
balance: {
|
|
142
|
-
amount: balance,
|
|
143
|
-
currency: '¥',
|
|
144
|
-
},
|
|
145
|
-
note: 'remaining balance = soft_limit_usd - total_usage / 100',
|
|
146
|
-
};
|
|
147
|
-
}
|
|
148
|
-
export const buzzAdapter = {
|
|
149
|
-
id: 'buzz',
|
|
150
|
-
label: 'Buzz',
|
|
151
|
-
shortLabel: 'Buzz',
|
|
152
|
-
sortOrder: 6,
|
|
153
|
-
matchScore: ({ providerOptions }) => isBuzzBaseURL(providerOptions?.baseURL) ? 100 : 0,
|
|
154
|
-
isEnabled: (config) => configuredProviderEnabled(config.quota, 'buzz', true),
|
|
155
|
-
fetch: fetchBuzzQuota,
|
|
156
|
-
};
|