@tokenbuddy/tb-admin 1.0.33 → 1.0.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/dist/src/cli.d.ts.map +1 -1
- package/dist/src/cli.js +28 -0
- package/dist/src/cli.js.map +1 -1
- package/dist/src/seller.d.ts +40 -1
- package/dist/src/seller.d.ts.map +1 -1
- package/dist/src/seller.js +132 -2
- package/dist/src/seller.js.map +1 -1
- package/dist/src/ui-actions.d.ts +2 -0
- package/dist/src/ui-actions.d.ts.map +1 -1
- package/dist/src/ui-actions.js +8 -6
- package/dist/src/ui-actions.js.map +1 -1
- package/dist/src/ui-command.d.ts +1 -0
- package/dist/src/ui-command.d.ts.map +1 -1
- package/dist/src/ui-command.js +7 -2
- package/dist/src/ui-command.js.map +1 -1
- package/dist/src/ui-server.js +17 -0
- package/dist/src/ui-server.js.map +1 -1
- package/dist/src/ui-state.d.ts +31 -0
- package/dist/src/ui-state.d.ts.map +1 -1
- package/dist/src/ui-state.js +461 -115
- package/dist/src/ui-state.js.map +1 -1
- package/dist/src/ui-static.d.ts.map +1 -1
- package/dist/src/ui-static.js +267 -144
- package/dist/src/ui-static.js.map +1 -1
- package/dist/src/upstream-balance-probe.d.ts +2 -40
- package/dist/src/upstream-balance-probe.d.ts.map +1 -1
- package/dist/src/upstream-balance-probe.js +1 -378
- package/dist/src/upstream-balance-probe.js.map +1 -1
- package/package.json +1 -1
- package/src/cli.ts +31 -0
- package/src/seller.ts +179 -3
- package/src/ui-actions.ts +10 -6
- package/src/ui-command.ts +7 -2
- package/src/ui-server.ts +18 -1
- package/src/ui-state.ts +541 -115
- package/src/ui-static.ts +267 -144
- package/src/upstream-balance-probe.ts +13 -505
- package/tests/admin.test.ts +418 -39
- package/tests/seller.test.ts +51 -0
- package/tests/ui-state-fleet.test.ts +272 -3
- package/tests/ui-static-row.test.ts +273 -8
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui-static.js","sourceRoot":"","sources":["../../src/ui-static.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,EAAE;AACF,qEAAqE;AACrE,qEAAqE;AACrE,0DAA0D;AAE1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE1D,MAAM,UAAU,WAAW;IACzB,OAAO
|
|
1
|
+
{"version":3,"file":"ui-static.js","sourceRoot":"","sources":["../../src/ui-static.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,EAAE;AACF,qEAAqE;AACrE,qEAAqE;AACrE,0DAA0D;AAE1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE1D,MAAM,UAAU,WAAW;IACzB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YA4UG,aAAa,EAAE;;QAEnB,CAAC;AACT,CAAC;AAED,SAAS,aAAa;IACpB,gFAAgF;IAChF,OAAO;EACP,mBAAmB,EAAE;EACrB,mBAAmB,EAAE;CACtB,CAAC;AACF,CAAC;AAED,SAAS,mBAAmB;IAC1B,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4TR,CAAC;AACF,CAAC"}
|
|
@@ -1,41 +1,3 @@
|
|
|
1
|
-
export
|
|
2
|
-
export type
|
|
3
|
-
export type BalanceProbeTemplate = "auto" | "deepseek" | "stepfun" | "siliconflow" | "openrouter" | "novita" | "newapi_generic" | "usage_generic" | "none";
|
|
4
|
-
export interface BalanceSnapshot {
|
|
5
|
-
rawAmount: number | null;
|
|
6
|
-
amountUsdMicros: number | null;
|
|
7
|
-
currency: BalanceCurrency;
|
|
8
|
-
source: BalanceSource;
|
|
9
|
-
fetchedAt: number;
|
|
10
|
-
error?: {
|
|
11
|
-
httpStatus: number;
|
|
12
|
-
message: string;
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
export interface BalanceProbeConfig {
|
|
16
|
-
upstreamUrl?: string;
|
|
17
|
-
upstreamBalanceUrl?: string;
|
|
18
|
-
upstreamApiKey?: string;
|
|
19
|
-
upstreamUserId?: string;
|
|
20
|
-
upstreamBalanceProbe?: {
|
|
21
|
-
template?: BalanceProbeTemplate;
|
|
22
|
-
url?: string;
|
|
23
|
-
userId?: string;
|
|
24
|
-
rechargeUrl?: string;
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
export interface BalanceProbeOptions {
|
|
28
|
-
fetch?: typeof fetch;
|
|
29
|
-
now?: () => number;
|
|
30
|
-
timeoutMs?: number;
|
|
31
|
-
cnyUsdRate?: number;
|
|
32
|
-
cache?: BalanceProbeCache;
|
|
33
|
-
}
|
|
34
|
-
export declare class BalanceProbeCache {
|
|
35
|
-
private readonly entries;
|
|
36
|
-
get(key: string, now: number): BalanceSnapshot | undefined;
|
|
37
|
-
setFailure(key: string, snapshot: BalanceSnapshot, now: number): void;
|
|
38
|
-
}
|
|
39
|
-
export declare const defaultBalanceProbeCache: BalanceProbeCache;
|
|
40
|
-
export declare function probeUpstreamBalance(config: BalanceProbeConfig, options?: BalanceProbeOptions): Promise<BalanceSnapshot>;
|
|
1
|
+
export { BalanceProbeCache, defaultBalanceProbeCache, probeUpstreamBalance } from "@tokenbuddy/contracts";
|
|
2
|
+
export type { BalanceCurrency, BalanceProbeConfig, BalanceProbeOptions, BalanceProbeTemplate, BalanceSnapshot, BalanceSource } from "@tokenbuddy/contracts";
|
|
41
3
|
//# sourceMappingURL=upstream-balance-probe.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upstream-balance-probe.d.ts","sourceRoot":"","sources":["../../src/upstream-balance-probe.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"upstream-balance-probe.d.ts","sourceRoot":"","sources":["../../src/upstream-balance-probe.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,wBAAwB,EACxB,oBAAoB,EACrB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,eAAe,EACf,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,eAAe,EACf,aAAa,EACd,MAAM,uBAAuB,CAAC"}
|
|
@@ -1,379 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
const FAILURE_CACHE_TTL_MS = 30000;
|
|
3
|
-
const DEFAULT_CNY_USD_RATE = 0.14;
|
|
4
|
-
export class BalanceProbeCache {
|
|
5
|
-
entries = new Map();
|
|
6
|
-
get(key, now) {
|
|
7
|
-
const entry = this.entries.get(key);
|
|
8
|
-
if (!entry || entry.expiresAt <= now) {
|
|
9
|
-
if (entry) {
|
|
10
|
-
this.entries.delete(key);
|
|
11
|
-
}
|
|
12
|
-
return undefined;
|
|
13
|
-
}
|
|
14
|
-
return entry.snapshot;
|
|
15
|
-
}
|
|
16
|
-
setFailure(key, snapshot, now) {
|
|
17
|
-
this.entries.set(key, {
|
|
18
|
-
snapshot,
|
|
19
|
-
expiresAt: now + FAILURE_CACHE_TTL_MS
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
export const defaultBalanceProbeCache = new BalanceProbeCache();
|
|
24
|
-
export async function probeUpstreamBalance(config, options = {}) {
|
|
25
|
-
const now = options.now || Date.now;
|
|
26
|
-
const fetchedAt = now();
|
|
27
|
-
const key = cacheKey(config);
|
|
28
|
-
const cache = options.cache || defaultBalanceProbeCache;
|
|
29
|
-
const cached = cache.get(key, fetchedAt);
|
|
30
|
-
if (cached) {
|
|
31
|
-
return cached;
|
|
32
|
-
}
|
|
33
|
-
const plan = requestPlan(config);
|
|
34
|
-
if (!plan) {
|
|
35
|
-
const snapshot = failure("unknown", fetchedAt, 0, "unsupported upstream - configure a balance parser");
|
|
36
|
-
cache.setFailure(key, snapshot, fetchedAt);
|
|
37
|
-
return snapshot;
|
|
38
|
-
}
|
|
39
|
-
if (!config.upstreamApiKey) {
|
|
40
|
-
const snapshot = failure(plan.source, fetchedAt, 0, "missing upstreamApiKey for balance probe");
|
|
41
|
-
cache.setFailure(key, snapshot, fetchedAt);
|
|
42
|
-
return snapshot;
|
|
43
|
-
}
|
|
44
|
-
const upstreamUserId = stringValue(config.upstreamBalanceProbe?.userId) || stringValue(config.upstreamUserId);
|
|
45
|
-
if (plan.requiresUserId && !upstreamUserId) {
|
|
46
|
-
const snapshot = failure(plan.source, fetchedAt, 0, "missing upstreamUserId for newapi upstream");
|
|
47
|
-
cache.setFailure(key, snapshot, fetchedAt);
|
|
48
|
-
return snapshot;
|
|
49
|
-
}
|
|
50
|
-
try {
|
|
51
|
-
const response = await fetchWithTimeout(plan.url, {
|
|
52
|
-
method: "GET",
|
|
53
|
-
headers: requestHeaders(config.upstreamApiKey, plan.requiresUserId ? upstreamUserId : undefined)
|
|
54
|
-
}, options.fetch || fetch, options.timeoutMs ?? DEFAULT_TIMEOUT_MS);
|
|
55
|
-
if (!response.ok) {
|
|
56
|
-
const snapshot = failure(plan.source, fetchedAt, response.status, httpErrorMessage(response.status));
|
|
57
|
-
cache.setFailure(key, snapshot, fetchedAt);
|
|
58
|
-
return snapshot;
|
|
59
|
-
}
|
|
60
|
-
const payload = await response.json();
|
|
61
|
-
const snapshot = parseBalancePayload(payload, plan, fetchedAt, cnyUsdRate(options.cnyUsdRate));
|
|
62
|
-
if (snapshot.error) {
|
|
63
|
-
cache.setFailure(key, snapshot, fetchedAt);
|
|
64
|
-
}
|
|
65
|
-
return snapshot;
|
|
66
|
-
}
|
|
67
|
-
catch (err) {
|
|
68
|
-
const snapshot = failure(plan.source, fetchedAt, 0, `network: ${err instanceof Error ? err.message : String(err)}`);
|
|
69
|
-
cache.setFailure(key, snapshot, fetchedAt);
|
|
70
|
-
return snapshot;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
function requestPlan(config) {
|
|
74
|
-
const template = balanceProbeTemplateValue(config.upstreamBalanceProbe?.template);
|
|
75
|
-
if (template === "none") {
|
|
76
|
-
return undefined;
|
|
77
|
-
}
|
|
78
|
-
const balanceUrl = stringValue(config.upstreamBalanceProbe?.url) || stringValue(config.upstreamBalanceUrl);
|
|
79
|
-
const upstreamUrl = stringValue(config.upstreamUrl);
|
|
80
|
-
if (template && template !== "auto") {
|
|
81
|
-
return explicitRequestPlan(template, balanceUrl, upstreamUrl);
|
|
82
|
-
}
|
|
83
|
-
const host = hostName(balanceUrl || upstreamUrl);
|
|
84
|
-
if (host === "api.deepseek.com") {
|
|
85
|
-
return { source: "deepseek", url: "https://api.deepseek.com/user/balance", currency: "CNY", requiresUserId: false };
|
|
86
|
-
}
|
|
87
|
-
if (host === "api.stepfun.ai" || host === "api.stepfun.com") {
|
|
88
|
-
return { source: "stepfun", url: "https://api.stepfun.com/v1/accounts", currency: "CNY", requiresUserId: false };
|
|
89
|
-
}
|
|
90
|
-
if (host === "api.siliconflow.cn" || host === "api.siliconflow.com") {
|
|
91
|
-
const currency = host.endsWith(".cn") ? "CNY" : "USD";
|
|
92
|
-
const url = host.endsWith(".cn") ? "https://api.siliconflow.cn/v1/user/info" : "https://api.siliconflow.com/v1/user/info";
|
|
93
|
-
return { source: "siliconflow", url, currency, requiresUserId: false };
|
|
94
|
-
}
|
|
95
|
-
if (host === "openrouter.ai") {
|
|
96
|
-
return { source: "openrouter", url: "https://openrouter.ai/api/v1/credits", currency: "USD", requiresUserId: false };
|
|
97
|
-
}
|
|
98
|
-
if (host === "api.novita.ai") {
|
|
99
|
-
return { source: "novita", url: "https://api.novita.ai/v3/user/balance", currency: "USD", requiresUserId: false };
|
|
100
|
-
}
|
|
101
|
-
if (balanceUrl && isUsageEndpoint(balanceUrl)) {
|
|
102
|
-
return { source: "usage_generic", url: balanceUrl, currency: "USD", requiresUserId: false };
|
|
103
|
-
}
|
|
104
|
-
if (balanceUrl) {
|
|
105
|
-
return { source: "newapi_generic", url: balanceUrl, currency: "USD", requiresUserId: true };
|
|
106
|
-
}
|
|
107
|
-
const genericUsageUrl = upstreamUrl ? usageUrl(upstreamUrl) : undefined;
|
|
108
|
-
if (genericUsageUrl) {
|
|
109
|
-
return { source: "usage_generic", url: genericUsageUrl, currency: "USD", requiresUserId: false };
|
|
110
|
-
}
|
|
111
|
-
return undefined;
|
|
112
|
-
}
|
|
113
|
-
function explicitRequestPlan(template, balanceUrl, upstreamUrl) {
|
|
114
|
-
if (template === "deepseek") {
|
|
115
|
-
return { source: "deepseek", url: balanceUrl || "https://api.deepseek.com/user/balance", currency: "CNY", requiresUserId: false };
|
|
116
|
-
}
|
|
117
|
-
if (template === "stepfun") {
|
|
118
|
-
return { source: "stepfun", url: balanceUrl || "https://api.stepfun.com/v1/accounts", currency: "CNY", requiresUserId: false };
|
|
119
|
-
}
|
|
120
|
-
if (template === "siliconflow") {
|
|
121
|
-
const host = hostName(balanceUrl || upstreamUrl);
|
|
122
|
-
const currency = host.endsWith(".com") ? "USD" : "CNY";
|
|
123
|
-
const url = balanceUrl || (currency === "USD" ? "https://api.siliconflow.com/v1/user/info" : "https://api.siliconflow.cn/v1/user/info");
|
|
124
|
-
return { source: "siliconflow", url, currency, requiresUserId: false };
|
|
125
|
-
}
|
|
126
|
-
if (template === "openrouter") {
|
|
127
|
-
return { source: "openrouter", url: balanceUrl || "https://openrouter.ai/api/v1/credits", currency: "USD", requiresUserId: false };
|
|
128
|
-
}
|
|
129
|
-
if (template === "novita") {
|
|
130
|
-
return { source: "novita", url: balanceUrl || "https://api.novita.ai/v3/user/balance", currency: "USD", requiresUserId: false };
|
|
131
|
-
}
|
|
132
|
-
if (template === "newapi_generic") {
|
|
133
|
-
return balanceUrl ? { source: "newapi_generic", url: balanceUrl, currency: "USD", requiresUserId: true } : undefined;
|
|
134
|
-
}
|
|
135
|
-
if (template === "usage_generic") {
|
|
136
|
-
const url = balanceUrl || (upstreamUrl ? usageUrl(upstreamUrl) : undefined);
|
|
137
|
-
return url ? { source: "usage_generic", url, currency: "USD", requiresUserId: false } : undefined;
|
|
138
|
-
}
|
|
139
|
-
return undefined;
|
|
140
|
-
}
|
|
141
|
-
function requestHeaders(upstreamApiKey, upstreamUserId) {
|
|
142
|
-
const headers = {
|
|
143
|
-
"Authorization": `Bearer ${upstreamApiKey}`
|
|
144
|
-
};
|
|
145
|
-
if (upstreamUserId) {
|
|
146
|
-
headers["New-Api-User"] = upstreamUserId;
|
|
147
|
-
}
|
|
148
|
-
return headers;
|
|
149
|
-
}
|
|
150
|
-
async function fetchWithTimeout(url, init, fetchFn, timeoutMs) {
|
|
151
|
-
const controller = new AbortController();
|
|
152
|
-
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
153
|
-
try {
|
|
154
|
-
return await fetchFn(url, { ...init, signal: controller.signal });
|
|
155
|
-
}
|
|
156
|
-
finally {
|
|
157
|
-
clearTimeout(timer);
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
function parseBalancePayload(payload, plan, fetchedAt, cnyRate) {
|
|
161
|
-
const object = objectValue(payload);
|
|
162
|
-
if (!object) {
|
|
163
|
-
return failure(plan.source, fetchedAt, 200, "balance response must be an object");
|
|
164
|
-
}
|
|
165
|
-
if (plan.source === "deepseek") {
|
|
166
|
-
return parseDeepSeek(object, fetchedAt, cnyRate);
|
|
167
|
-
}
|
|
168
|
-
if (plan.source === "stepfun") {
|
|
169
|
-
return amountSnapshot(numberFrom(object.balance), "CNY", "stepfun", fetchedAt, cnyRate);
|
|
170
|
-
}
|
|
171
|
-
if (plan.source === "siliconflow") {
|
|
172
|
-
return parseSiliconFlow(object, plan.currency, fetchedAt, cnyRate);
|
|
173
|
-
}
|
|
174
|
-
if (plan.source === "openrouter") {
|
|
175
|
-
return parseOpenRouter(object, fetchedAt, cnyRate);
|
|
176
|
-
}
|
|
177
|
-
if (plan.source === "novita") {
|
|
178
|
-
const availableBalance = numberFrom(object.availableBalance);
|
|
179
|
-
return amountSnapshot(availableBalance === null ? null : availableBalance / 10000, "USD", "novita", fetchedAt, cnyRate);
|
|
180
|
-
}
|
|
181
|
-
if (plan.source === "newapi_generic") {
|
|
182
|
-
return parseNewApi(object, fetchedAt, cnyRate);
|
|
183
|
-
}
|
|
184
|
-
if (plan.source === "usage_generic") {
|
|
185
|
-
return parseUsageGeneric(object, fetchedAt, cnyRate);
|
|
186
|
-
}
|
|
187
|
-
return failure("unknown", fetchedAt, 0, "unsupported upstream - configure a balance parser");
|
|
188
|
-
}
|
|
189
|
-
function parseDeepSeek(payload, fetchedAt, cnyRate) {
|
|
190
|
-
const infos = Array.isArray(payload.balance_infos) ? payload.balance_infos : [];
|
|
191
|
-
const first = objectValue(infos[0]);
|
|
192
|
-
const currency = currencyValue(first?.currency) || "CNY";
|
|
193
|
-
const rawAmount = numberFrom(first?.total_balance);
|
|
194
|
-
if (payload.is_available === false) {
|
|
195
|
-
return {
|
|
196
|
-
...amountSnapshot(rawAmount, currency, "deepseek", fetchedAt, cnyRate),
|
|
197
|
-
error: { httpStatus: 200, message: "Insufficient balance" }
|
|
198
|
-
};
|
|
199
|
-
}
|
|
200
|
-
if (!first) {
|
|
201
|
-
return amountSnapshot(null, currency, "deepseek", fetchedAt, cnyRate);
|
|
202
|
-
}
|
|
203
|
-
if (rawAmount === null) {
|
|
204
|
-
return failure("deepseek", fetchedAt, 200, "missing field: balance_infos[].total_balance", currency);
|
|
205
|
-
}
|
|
206
|
-
return amountSnapshot(rawAmount, currency, "deepseek", fetchedAt, cnyRate);
|
|
207
|
-
}
|
|
208
|
-
function parseSiliconFlow(payload, currency, fetchedAt, cnyRate) {
|
|
209
|
-
const code = numberFrom(payload.code);
|
|
210
|
-
if (code !== null && code !== 20000) {
|
|
211
|
-
return failure("siliconflow", fetchedAt, 200, `upstream code: ${code}`, currency);
|
|
212
|
-
}
|
|
213
|
-
const data = objectValue(payload.data);
|
|
214
|
-
if (!data) {
|
|
215
|
-
return failure("siliconflow", fetchedAt, 200, "missing field: data", currency);
|
|
216
|
-
}
|
|
217
|
-
const snapshot = amountSnapshot(numberFrom(data.totalBalance), currency, "siliconflow", fetchedAt, cnyRate);
|
|
218
|
-
const status = stringValue(data.status);
|
|
219
|
-
if (status && status !== "ok") {
|
|
220
|
-
return {
|
|
221
|
-
...snapshot,
|
|
222
|
-
error: { httpStatus: 200, message: `upstream status: ${status}` }
|
|
223
|
-
};
|
|
224
|
-
}
|
|
225
|
-
return snapshot;
|
|
226
|
-
}
|
|
227
|
-
function parseOpenRouter(payload, fetchedAt, cnyRate) {
|
|
228
|
-
const data = objectValue(payload.data) || payload;
|
|
229
|
-
const totalCredits = numberFrom(data.total_credits);
|
|
230
|
-
const totalUsage = numberFrom(data.total_usage);
|
|
231
|
-
if (totalCredits === null || totalUsage === null) {
|
|
232
|
-
return failure("openrouter", fetchedAt, 200, "missing field: data.total_credits or data.total_usage", "USD");
|
|
233
|
-
}
|
|
234
|
-
return amountSnapshot(Math.max(0, totalCredits - totalUsage), "USD", "openrouter", fetchedAt, cnyRate);
|
|
235
|
-
}
|
|
236
|
-
function parseNewApi(payload, fetchedAt, cnyRate) {
|
|
237
|
-
const data = objectValue(payload.data);
|
|
238
|
-
if (!data) {
|
|
239
|
-
return failure("newapi_generic", fetchedAt, 200, "missing field: data", "USD");
|
|
240
|
-
}
|
|
241
|
-
const quota = numberFrom(data.quota);
|
|
242
|
-
const usedQuota = numberFrom(data.used_quota);
|
|
243
|
-
if (quota === null || usedQuota === null) {
|
|
244
|
-
return failure("newapi_generic", fetchedAt, 200, "missing field: data.quota or data.used_quota", "USD");
|
|
245
|
-
}
|
|
246
|
-
return amountSnapshot((quota - usedQuota) / 500000, "USD", "newapi_generic", fetchedAt, cnyRate);
|
|
247
|
-
}
|
|
248
|
-
function parseUsageGeneric(payload, fetchedAt, cnyRate) {
|
|
249
|
-
const quota = objectValue(payload.quota);
|
|
250
|
-
const rawAmount = numberFrom(payload.remaining) ?? numberFrom(quota?.remaining) ?? numberFrom(payload.balance);
|
|
251
|
-
const currency = currencyValue(payload.unit) || currencyValue(quota?.unit) || "USD";
|
|
252
|
-
if (rawAmount === null) {
|
|
253
|
-
return failure("usage_generic", fetchedAt, 200, "missing field: remaining, quota.remaining, or balance", currency);
|
|
254
|
-
}
|
|
255
|
-
const snapshot = amountSnapshot(rawAmount, currency, "usage_generic", fetchedAt, cnyRate);
|
|
256
|
-
const isValid = booleanValue(payload.is_active) ?? booleanValue(payload.isValid) ?? true;
|
|
257
|
-
if (!isValid) {
|
|
258
|
-
return {
|
|
259
|
-
...snapshot,
|
|
260
|
-
error: { httpStatus: 200, message: "upstream key is not active" }
|
|
261
|
-
};
|
|
262
|
-
}
|
|
263
|
-
return snapshot;
|
|
264
|
-
}
|
|
265
|
-
function amountSnapshot(rawAmount, currency, source, fetchedAt, cnyRate) {
|
|
266
|
-
return {
|
|
267
|
-
rawAmount,
|
|
268
|
-
amountUsdMicros: rawAmount === null ? null : Math.round(rawAmount * (currency === "CNY" ? cnyRate : 1) * 1000000),
|
|
269
|
-
currency,
|
|
270
|
-
source,
|
|
271
|
-
fetchedAt
|
|
272
|
-
};
|
|
273
|
-
}
|
|
274
|
-
function failure(source, fetchedAt, httpStatus, message, currency = null) {
|
|
275
|
-
return {
|
|
276
|
-
rawAmount: null,
|
|
277
|
-
amountUsdMicros: null,
|
|
278
|
-
currency,
|
|
279
|
-
source,
|
|
280
|
-
fetchedAt,
|
|
281
|
-
error: { httpStatus, message }
|
|
282
|
-
};
|
|
283
|
-
}
|
|
284
|
-
function httpErrorMessage(status) {
|
|
285
|
-
if (status === 401) {
|
|
286
|
-
return "unauthorized: check upstreamApiKey";
|
|
287
|
-
}
|
|
288
|
-
if (status === 403) {
|
|
289
|
-
return "forbidden: upstream rejected the credentials";
|
|
290
|
-
}
|
|
291
|
-
if (status === 429) {
|
|
292
|
-
return "rate limited";
|
|
293
|
-
}
|
|
294
|
-
if (status >= 500) {
|
|
295
|
-
return "upstream 5xx";
|
|
296
|
-
}
|
|
297
|
-
return `upstream http ${status}`;
|
|
298
|
-
}
|
|
299
|
-
function cnyUsdRate(value) {
|
|
300
|
-
if (value !== undefined && Number.isFinite(value) && value > 0) {
|
|
301
|
-
return value;
|
|
302
|
-
}
|
|
303
|
-
const envValue = Number(process.env.TB_CNY_USD_RATE);
|
|
304
|
-
return Number.isFinite(envValue) && envValue > 0 ? envValue : DEFAULT_CNY_USD_RATE;
|
|
305
|
-
}
|
|
306
|
-
function cacheKey(config) {
|
|
307
|
-
return [
|
|
308
|
-
stringValue(config.upstreamBalanceProbe?.template),
|
|
309
|
-
stringValue(config.upstreamBalanceProbe?.url),
|
|
310
|
-
stringValue(config.upstreamBalanceProbe?.userId),
|
|
311
|
-
stringValue(config.upstreamBalanceUrl),
|
|
312
|
-
stringValue(config.upstreamUrl),
|
|
313
|
-
stringValue(config.upstreamApiKey),
|
|
314
|
-
stringValue(config.upstreamUserId)
|
|
315
|
-
].join("|");
|
|
316
|
-
}
|
|
317
|
-
function balanceProbeTemplateValue(value) {
|
|
318
|
-
return value === "auto" ||
|
|
319
|
-
value === "deepseek" ||
|
|
320
|
-
value === "stepfun" ||
|
|
321
|
-
value === "siliconflow" ||
|
|
322
|
-
value === "openrouter" ||
|
|
323
|
-
value === "novita" ||
|
|
324
|
-
value === "newapi_generic" ||
|
|
325
|
-
value === "usage_generic" ||
|
|
326
|
-
value === "none"
|
|
327
|
-
? value
|
|
328
|
-
: undefined;
|
|
329
|
-
}
|
|
330
|
-
function hostName(value) {
|
|
331
|
-
if (!value) {
|
|
332
|
-
return "";
|
|
333
|
-
}
|
|
334
|
-
try {
|
|
335
|
-
return new URL(value).hostname.replace(/^www\./, "");
|
|
336
|
-
}
|
|
337
|
-
catch {
|
|
338
|
-
return "";
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
function usageUrl(value) {
|
|
342
|
-
try {
|
|
343
|
-
const url = new URL(value);
|
|
344
|
-
url.pathname = "/v1/usage";
|
|
345
|
-
url.search = "";
|
|
346
|
-
url.hash = "";
|
|
347
|
-
return url.toString();
|
|
348
|
-
}
|
|
349
|
-
catch {
|
|
350
|
-
return undefined;
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
function isUsageEndpoint(value) {
|
|
354
|
-
try {
|
|
355
|
-
return new URL(value).pathname.replace(/\/+$/, "") === "/v1/usage";
|
|
356
|
-
}
|
|
357
|
-
catch {
|
|
358
|
-
return false;
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
function objectValue(value) {
|
|
362
|
-
return value && typeof value === "object" && !Array.isArray(value)
|
|
363
|
-
? value
|
|
364
|
-
: undefined;
|
|
365
|
-
}
|
|
366
|
-
function stringValue(value) {
|
|
367
|
-
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
|
368
|
-
}
|
|
369
|
-
function numberFrom(value) {
|
|
370
|
-
const parsed = typeof value === "number" ? value : typeof value === "string" ? Number(value) : Number.NaN;
|
|
371
|
-
return Number.isFinite(parsed) ? parsed : null;
|
|
372
|
-
}
|
|
373
|
-
function booleanValue(value) {
|
|
374
|
-
return typeof value === "boolean" ? value : undefined;
|
|
375
|
-
}
|
|
376
|
-
function currencyValue(value) {
|
|
377
|
-
return value === "USD" || value === "CNY" ? value : undefined;
|
|
378
|
-
}
|
|
1
|
+
export { BalanceProbeCache, defaultBalanceProbeCache, probeUpstreamBalance } from "@tokenbuddy/contracts";
|
|
379
2
|
//# sourceMappingURL=upstream-balance-probe.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upstream-balance-probe.js","sourceRoot":"","sources":["../../src/upstream-balance-probe.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"upstream-balance-probe.js","sourceRoot":"","sources":["../../src/upstream-balance-probe.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,wBAAwB,EACxB,oBAAoB,EACrB,MAAM,uBAAuB,CAAC"}
|
package/package.json
CHANGED
package/src/cli.ts
CHANGED
|
@@ -1356,6 +1356,37 @@ export function buildAdminCli(configManager: ConfigManager): Command {
|
|
|
1356
1356
|
}
|
|
1357
1357
|
});
|
|
1358
1358
|
|
|
1359
|
+
sellerCmd
|
|
1360
|
+
.command("roll")
|
|
1361
|
+
.description("Sequentially redeploy every tbs-* seller app (live candidate list from `fly apps list`) to a single image, image-only, fail-fast. Replaces deploy/fly.io/deploy-seller-fleet-to-flyio.sh.")
|
|
1362
|
+
.requiredOption("--image <image>", "Published Docker image, for example registry.fly.io/tb-seller:<v>")
|
|
1363
|
+
.option("--exclude <list>", "Comma-separated list of seller app names to skip (e.g. tbs-86d81e,tbs-719577)")
|
|
1364
|
+
.option("--dry-run", "List the planned candidate set and per-app plans, do not actually redeploy")
|
|
1365
|
+
.option("--json", "Output structured JSON: candidates / excluded / attempts / completed")
|
|
1366
|
+
.action((options) => {
|
|
1367
|
+
try {
|
|
1368
|
+
const exclude = options.exclude
|
|
1369
|
+
? String(options.exclude).split(",").map((s) => s.trim()).filter(Boolean)
|
|
1370
|
+
: [];
|
|
1371
|
+
const res = getSellerRunner().roll(
|
|
1372
|
+
{ image: options.image, exclude, dryRun: options.dryRun },
|
|
1373
|
+
Boolean(options.json)
|
|
1374
|
+
);
|
|
1375
|
+
printResult(res, Boolean(options.json));
|
|
1376
|
+
// 文本路径下, 失败时给非零退出码 (CI / script 可感知)
|
|
1377
|
+
if (!options.json && typeof res === "string" && res.includes("roll stopped at failure")) {
|
|
1378
|
+
process.exit(1);
|
|
1379
|
+
}
|
|
1380
|
+
// json 路径下, completed=false 也给非零
|
|
1381
|
+
if (options.json && typeof res !== "string" && res.completed === false) {
|
|
1382
|
+
process.exit(1);
|
|
1383
|
+
}
|
|
1384
|
+
} catch (err: any) {
|
|
1385
|
+
console.error("Error:", err.message);
|
|
1386
|
+
process.exit(1);
|
|
1387
|
+
}
|
|
1388
|
+
});
|
|
1389
|
+
|
|
1359
1390
|
sellerCmd
|
|
1360
1391
|
.command("remove <name>")
|
|
1361
1392
|
.description("Completely destroy a seller app on Fly.io")
|