@allixsenos/asu 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +497 -0
- package/dist/cache.d.ts +15 -0
- package/dist/cache.js +112 -0
- package/dist/cache.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.js +95 -0
- package/dist/cli.js.map +1 -0
- package/dist/errors.d.ts +10 -0
- package/dist/errors.js +24 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/local.d.ts +14 -0
- package/dist/local.js +121 -0
- package/dist/local.js.map +1 -0
- package/dist/models.d.ts +184 -0
- package/dist/models.js +57 -0
- package/dist/models.js.map +1 -0
- package/dist/output.d.ts +13 -0
- package/dist/output.js +187 -0
- package/dist/output.js.map +1 -0
- package/dist/providers/base.d.ts +25 -0
- package/dist/providers/base.js +2 -0
- package/dist/providers/base.js.map +1 -0
- package/dist/providers/claude.d.ts +4 -0
- package/dist/providers/claude.js +167 -0
- package/dist/providers/claude.js.map +1 -0
- package/dist/providers/codex.d.ts +4 -0
- package/dist/providers/codex.js +66 -0
- package/dist/providers/codex.js.map +1 -0
- package/dist/providers/copilot.d.ts +4 -0
- package/dist/providers/copilot.js +64 -0
- package/dist/providers/copilot.js.map +1 -0
- package/dist/providers/cursor.d.ts +6 -0
- package/dist/providers/cursor.js +69 -0
- package/dist/providers/cursor.js.map +1 -0
- package/dist/providers/grok.d.ts +4 -0
- package/dist/providers/grok.js +59 -0
- package/dist/providers/grok.js.map +1 -0
- package/dist/providers/kimi.d.ts +4 -0
- package/dist/providers/kimi.js +49 -0
- package/dist/providers/kimi.js.map +1 -0
- package/dist/providers/minimax.d.ts +4 -0
- package/dist/providers/minimax.js +73 -0
- package/dist/providers/minimax.js.map +1 -0
- package/dist/providers/parse.d.ts +16 -0
- package/dist/providers/parse.js +78 -0
- package/dist/providers/parse.js.map +1 -0
- package/dist/providers/zai.d.ts +5 -0
- package/dist/providers/zai.js +67 -0
- package/dist/providers/zai.js.map +1 -0
- package/dist/registry.d.ts +4 -0
- package/dist/registry.js +45 -0
- package/dist/registry.js.map +1 -0
- package/dist/service.d.ts +28 -0
- package/dist/service.js +117 -0
- package/dist/service.js.map +1 -0
- package/dist/transport.d.ts +8 -0
- package/dist/transport.js +63 -0
- package/dist/transport.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.js +4 -0
- package/dist/version.js.map +1 -0
- package/docs/architecture.md +83 -0
- package/docs/provider-contracts.md +32 -0
- package/docs/releasing.md +51 -0
- package/package.json +48 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import { UsageError } from '../errors.js';
|
|
3
|
+
import { detectCommands, homePath } from '../local.js';
|
|
4
|
+
import { emptyUsage } from '../models.js';
|
|
5
|
+
import { credentialObject, nonnegative, object, optionalObject, ratio, requireUsage, string, timestamp } from './parse.js';
|
|
6
|
+
export function cursorDatabasePaths(context) {
|
|
7
|
+
const suffix = ['Cursor', 'User', 'globalStorage', 'state.vscdb'];
|
|
8
|
+
if (context.platform === 'win32')
|
|
9
|
+
return context.env.APPDATA ? [join(context.env.APPDATA, ...suffix)] : [];
|
|
10
|
+
if (context.platform === 'darwin')
|
|
11
|
+
return [join(context.home, 'Library', 'Application Support', ...suffix)];
|
|
12
|
+
return [join(homePath(context, context.env.XDG_CONFIG_HOME, '.config'), ...suffix)];
|
|
13
|
+
}
|
|
14
|
+
export function normalizeCursor(payload) {
|
|
15
|
+
const raw = object(payload), data = emptyUsage(), plan = optionalObject(raw.planUsage);
|
|
16
|
+
const used = nonnegative(plan.totalSpend), limit = nonnegative(plan.limit), remaining = nonnegative(plan.remaining);
|
|
17
|
+
if (used !== undefined || remaining !== undefined || limit !== undefined) {
|
|
18
|
+
data.balances.push({ id: 'plan', label: 'Plan usage', unit: 'USD',
|
|
19
|
+
used: used === undefined ? undefined : used / 100,
|
|
20
|
+
remaining: remaining === undefined ? undefined : remaining / 100,
|
|
21
|
+
limit: limit === undefined ? undefined : limit / 100 });
|
|
22
|
+
data.windows.push({ id: 'billing-period', label: 'Billing period',
|
|
23
|
+
percentUsed: ratio(used, limit), resetsAt: timestamp(raw.billingCycleEnd) });
|
|
24
|
+
}
|
|
25
|
+
return requireUsage(data);
|
|
26
|
+
}
|
|
27
|
+
export const cursor = {
|
|
28
|
+
id: 'cursor', displayName: 'Cursor', version: 1, experimental: true,
|
|
29
|
+
detect: context => detectCommands(context, ['cursor', 'cursor-agent'], context.platform === 'darwin' ? ['/Applications/Cursor.app', join(context.home, 'Applications', 'Cursor.app')] : []),
|
|
30
|
+
async resolveCredentials(context) {
|
|
31
|
+
const token = string(context.env.CURSOR_ACCESS_TOKEN) ?? string(context.env.CURSOR_TOKEN);
|
|
32
|
+
if (token)
|
|
33
|
+
return { token };
|
|
34
|
+
let failure;
|
|
35
|
+
for (const path of cursorDatabasePaths(context)) {
|
|
36
|
+
try {
|
|
37
|
+
const modern = await context.sqliteToken(path, 'cursorAuth/accessToken');
|
|
38
|
+
if (modern)
|
|
39
|
+
return { token: modern };
|
|
40
|
+
const legacy = await context.sqliteToken(path, 'cursorAuthStatus');
|
|
41
|
+
if (legacy) {
|
|
42
|
+
const token = string(credentialObject(JSON.parse(legacy)).accessToken);
|
|
43
|
+
if (token)
|
|
44
|
+
return { token };
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
failure = new UsageError('credential_read_error');
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
const config = homePath(context, context.env.XDG_CONFIG_HOME, '.config');
|
|
52
|
+
const raw = await context.readJson(join(config, 'cursor', 'auth.json'));
|
|
53
|
+
if (raw != null) {
|
|
54
|
+
const token = string(credentialObject(raw).accessToken);
|
|
55
|
+
if (token)
|
|
56
|
+
return { token };
|
|
57
|
+
}
|
|
58
|
+
if (failure)
|
|
59
|
+
throw failure;
|
|
60
|
+
return null;
|
|
61
|
+
},
|
|
62
|
+
async fetchUsage(context, credentials) {
|
|
63
|
+
return normalizeCursor(await context.request('https://api2.cursor.sh/aiserver.v1.DashboardService/GetCurrentPeriodUsage', {
|
|
64
|
+
method: 'POST', body: {}, signal: context.signal,
|
|
65
|
+
headers: { Authorization: `Bearer ${credentials.token}`, 'Connect-Protocol-Version': '1' },
|
|
66
|
+
}));
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
//# sourceMappingURL=cursor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor.js","sourceRoot":"","sources":["../../src/providers/cursor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import { detectCommands } from '../local.js';
|
|
3
|
+
import { emptyUsage } from '../models.js';
|
|
4
|
+
import { credentialObject, nonnegative, object, optionalObject, percent, ratio, requireUsage, string, timestamp } from './parse.js';
|
|
5
|
+
function cents(raw) {
|
|
6
|
+
if (raw == null)
|
|
7
|
+
return undefined;
|
|
8
|
+
const amount = object(raw);
|
|
9
|
+
// Protobuf omits zero scalar values: an explicitly present {} Cent means zero.
|
|
10
|
+
return nonnegative(amount.val ?? 0);
|
|
11
|
+
}
|
|
12
|
+
export function normalizeGrok(payload) {
|
|
13
|
+
const raw = object(payload), config = optionalObject(raw.config), data = emptyUsage();
|
|
14
|
+
data.planLabel = string(raw.subscription_tier) ?? string(raw.subscriptionTier) ?? null;
|
|
15
|
+
const used = cents(config.used), limit = cents(config.monthlyLimit), prepaid = cents(config.prepaidBalance);
|
|
16
|
+
const current = optionalObject(config.currentPeriod);
|
|
17
|
+
const resetsAt = timestamp(current.end ?? config.billingPeriodEnd);
|
|
18
|
+
const percentUsed = config.creditUsagePercent == null ? ratio(used, limit) : percent(config.creditUsagePercent);
|
|
19
|
+
if (percentUsed !== null)
|
|
20
|
+
data.windows.push({ id: 'included', label: string(current.type)?.includes('WEEKLY') ? 'Weekly' : 'Billing period', percentUsed, resetsAt });
|
|
21
|
+
if (used !== undefined || limit !== undefined)
|
|
22
|
+
data.balances.push({ id: 'included', label: 'Included allowance', unit: 'USD',
|
|
23
|
+
used: used === undefined ? undefined : used / 100, limit: limit === undefined ? undefined : limit / 100,
|
|
24
|
+
remaining: used === undefined || limit === undefined ? undefined : Math.max(0, limit - used) / 100 });
|
|
25
|
+
if (prepaid !== undefined)
|
|
26
|
+
data.balances.push({ id: 'prepaid', label: 'Prepaid balance', unit: 'USD', remaining: prepaid / 100 });
|
|
27
|
+
if (config.isUnifiedBillingUser === true)
|
|
28
|
+
data.details.push({ label: 'Billing', value: 'Shared subscription usage' });
|
|
29
|
+
return requireUsage(data);
|
|
30
|
+
}
|
|
31
|
+
export const grok = {
|
|
32
|
+
id: 'grok', displayName: 'Grok', version: 1, experimental: true,
|
|
33
|
+
detect: context => detectCommands(context, ['grok']),
|
|
34
|
+
async resolveCredentials(context) {
|
|
35
|
+
const token = string(context.env.GROK_API_KEY) ?? string(context.env.GROK_TOKEN);
|
|
36
|
+
if (token)
|
|
37
|
+
return { token };
|
|
38
|
+
const raw = await context.readJson(join(context.home, '.grok', 'auth.json'));
|
|
39
|
+
if (raw == null)
|
|
40
|
+
return null;
|
|
41
|
+
const auth = credentialObject(raw), legacy = string(auth.access_token);
|
|
42
|
+
if (legacy)
|
|
43
|
+
return { token: legacy };
|
|
44
|
+
for (const [key, value] of Object.entries(auth)) {
|
|
45
|
+
if (!key.startsWith('https://auth.x.ai::'))
|
|
46
|
+
continue;
|
|
47
|
+
const token = string(credentialObject(value).key);
|
|
48
|
+
if (token)
|
|
49
|
+
return { token };
|
|
50
|
+
}
|
|
51
|
+
return null;
|
|
52
|
+
},
|
|
53
|
+
async fetchUsage(context, credentials) {
|
|
54
|
+
return normalizeGrok(await context.request('https://cli-chat-proxy.grok.com/v1/billing?format=credits', {
|
|
55
|
+
signal: context.signal, headers: { Authorization: `Bearer ${credentials.token}`, 'X-XAI-Token-Auth': 'xai-grok-cli' },
|
|
56
|
+
}));
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
//# sourceMappingURL=grok.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grok.js","sourceRoot":"","sources":["../../src/providers/grok.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import { detectCommands, homePath } from '../local.js';
|
|
3
|
+
import { emptyUsage } from '../models.js';
|
|
4
|
+
import { countWindow, credentialObject, list, nonnegative, object, optionalObject, requireUsage, string, timestamp } from './parse.js';
|
|
5
|
+
export function normalizeKimi(payload) {
|
|
6
|
+
const raw = object(payload), data = emptyUsage();
|
|
7
|
+
function add(id, label, value) {
|
|
8
|
+
const row = { ...object(value) }, remaining = nonnegative(row.remaining), limit = nonnegative(row.limit);
|
|
9
|
+
if (row.used == null && remaining !== undefined && limit !== undefined)
|
|
10
|
+
row.used = Math.max(0, limit - remaining);
|
|
11
|
+
data.windows.push(countWindow(id, label, row, row.resetTime ?? row.resetAt ?? row.reset_time ?? row.reset_at));
|
|
12
|
+
}
|
|
13
|
+
if (raw.usage != null)
|
|
14
|
+
add('weekly', 'Weekly', raw.usage);
|
|
15
|
+
for (const [index, value] of list(raw.limits).entries()) {
|
|
16
|
+
const row = object(value), window = optionalObject(row.window);
|
|
17
|
+
const duration = nonnegative(window.duration), unit = string(window.timeUnit)?.replace('TIME_UNIT_', '').toLowerCase();
|
|
18
|
+
const period = duration === 300 && unit === 'minute' ? '5 hours' : duration && unit ? `${duration} ${unit}` : `Limit ${index + 1}`;
|
|
19
|
+
add(`limit-${index}`, string(row.name) ?? period, row.detail ?? row);
|
|
20
|
+
}
|
|
21
|
+
return requireUsage(data);
|
|
22
|
+
}
|
|
23
|
+
export const kimi = {
|
|
24
|
+
id: 'kimi', displayName: 'Kimi', version: 1, experimental: true,
|
|
25
|
+
detect: context => detectCommands(context, ['kimi']),
|
|
26
|
+
async resolveCredentials(context) {
|
|
27
|
+
const token = string(context.env.KIMI_TOKEN) ?? string(context.env.KIMI_API_KEY);
|
|
28
|
+
if (token)
|
|
29
|
+
return { token };
|
|
30
|
+
const homes = [homePath(context, context.env.KIMI_CODE_HOME, '.kimi-code'), join(context.home, '.kimi')];
|
|
31
|
+
for (const home of homes) {
|
|
32
|
+
const raw = await context.readJson(join(home, 'credentials', 'kimi-code.json'));
|
|
33
|
+
if (raw == null)
|
|
34
|
+
continue;
|
|
35
|
+
const auth = credentialObject(raw), token = string(auth.access_token);
|
|
36
|
+
if (token) {
|
|
37
|
+
const expiry = timestamp(auth.expires_at);
|
|
38
|
+
return { token, expiresAt: expiry ? Date.parse(expiry) : undefined };
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return null;
|
|
42
|
+
},
|
|
43
|
+
async fetchUsage(context, credentials) {
|
|
44
|
+
return normalizeKimi(await context.request('https://api.kimi.com/coding/v1/usages', {
|
|
45
|
+
signal: context.signal, headers: { Authorization: `Bearer ${credentials.token}` },
|
|
46
|
+
}));
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
//# sourceMappingURL=kimi.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kimi.js","sourceRoot":"","sources":["../../src/providers/kimi.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import { UsageError } from '../errors.js';
|
|
3
|
+
import { detectCommands } from '../local.js';
|
|
4
|
+
import { emptyUsage } from '../models.js';
|
|
5
|
+
import { credentialObject, list, nonnegative, object, optionalObject, percent, ratio, requireUsage, slug, string, timestamp } from './parse.js';
|
|
6
|
+
function baseUrl(value, region) {
|
|
7
|
+
if (!value)
|
|
8
|
+
return region === 'cn' ? 'https://api.minimaxi.com' : 'https://api.minimax.io';
|
|
9
|
+
try {
|
|
10
|
+
const url = new URL(value);
|
|
11
|
+
if (url.protocol !== 'https:' || url.username || url.password || url.port)
|
|
12
|
+
throw new Error();
|
|
13
|
+
if (['api.minimaxi.com', 'www.minimaxi.com'].includes(url.hostname))
|
|
14
|
+
return url.origin;
|
|
15
|
+
if (['api.minimax.io', 'www.minimax.io'].includes(url.hostname))
|
|
16
|
+
return url.origin;
|
|
17
|
+
}
|
|
18
|
+
catch { /* Never forward a subscription key to an arbitrary configured host. */ }
|
|
19
|
+
throw new UsageError('invalid_credentials');
|
|
20
|
+
}
|
|
21
|
+
function auth(token, url, region, expiry) {
|
|
22
|
+
const expiresAt = timestamp(expiry);
|
|
23
|
+
return { token, metadata: { baseUrl: baseUrl(url, region) }, expiresAt: expiresAt ? Date.parse(expiresAt) : undefined };
|
|
24
|
+
}
|
|
25
|
+
export function normalizeMiniMax(payload) {
|
|
26
|
+
const raw = object(payload), data = emptyUsage(), status = optionalObject(raw.base_resp);
|
|
27
|
+
if (status.status_code != null && status.status_code !== 0 && status.status_code !== '0')
|
|
28
|
+
throw new UsageError(status.status_code === 1004 ? 'unauthorized' : 'provider_error');
|
|
29
|
+
for (const [index, value] of list(raw.model_remains).entries()) {
|
|
30
|
+
const model = object(value), name = string(model.model_name) ?? 'Token plan';
|
|
31
|
+
for (const [prefix, label, reset] of [['current_interval', '5 hours', model.end_time], ['current_weekly', 'Weekly', model.weekly_end_time]]) {
|
|
32
|
+
const remaining = nonnegative(model[`${prefix}_remaining_percent`]);
|
|
33
|
+
if (remaining !== undefined && remaining > 100)
|
|
34
|
+
throw new UsageError('invalid_response');
|
|
35
|
+
const used = nonnegative(model[`${prefix}_usage_count`]), limit = nonnegative(model[`${prefix}_total_count`]);
|
|
36
|
+
const percentUsed = remaining === undefined ? ratio(used, limit) : percent(100 - remaining);
|
|
37
|
+
if (percentUsed === null)
|
|
38
|
+
continue;
|
|
39
|
+
data.windows.push({ id: `${slug(name).slice(0, 50)}-${index}-${prefix}`, label: `${name} · ${label}`,
|
|
40
|
+
percentUsed, resetsAt: timestamp(reset), scope: { model: name } });
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return requireUsage(data);
|
|
44
|
+
}
|
|
45
|
+
export const minimax = {
|
|
46
|
+
id: 'minimax', displayName: 'MiniMax', version: 1, experimental: true,
|
|
47
|
+
detect: context => detectCommands(context, ['mmx', 'minimax']),
|
|
48
|
+
async resolveCredentials(context) {
|
|
49
|
+
const token = string(context.env.MINIMAX_API_KEY);
|
|
50
|
+
if (token)
|
|
51
|
+
return auth(token, string(context.env.MINIMAX_BASE_URL), string(context.env.MINIMAX_REGION));
|
|
52
|
+
const raw = await context.readJson(join(context.home, '.mmx', 'credentials.json'));
|
|
53
|
+
if (raw != null) {
|
|
54
|
+
const credentials = credentialObject(raw), token = string(credentials.access_token);
|
|
55
|
+
if (token)
|
|
56
|
+
return auth(token, string(credentials.resource_url), undefined, credentials.expires_at);
|
|
57
|
+
}
|
|
58
|
+
const configRaw = await context.readJson(join(context.home, '.mmx', 'config.json'));
|
|
59
|
+
if (configRaw == null)
|
|
60
|
+
return null;
|
|
61
|
+
const config = credentialObject(configRaw), apiKey = string(config.api_key);
|
|
62
|
+
if (apiKey)
|
|
63
|
+
return auth(apiKey, string(config.base_url), string(config.region));
|
|
64
|
+
const oauth = config.oauth == null ? {} : credentialObject(config.oauth), accessToken = string(oauth.access_token);
|
|
65
|
+
return accessToken ? auth(accessToken, string(oauth.resource_url) ?? string(config.base_url), string(config.region), oauth.expires_at) : null;
|
|
66
|
+
},
|
|
67
|
+
async fetchUsage(context, credentials) {
|
|
68
|
+
return normalizeMiniMax(await context.request(`${credentials.metadata?.baseUrl ?? 'https://api.minimax.io'}/v1/token_plan/remains`, {
|
|
69
|
+
signal: context.signal, headers: { Authorization: `Bearer ${credentials.token}`, 'Content-Type': 'application/json' },
|
|
70
|
+
}));
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
//# sourceMappingURL=minimax.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"minimax.js","sourceRoot":"","sources":["../../src/providers/minimax.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { UsageData, UsageWindow } from '../models.js';
|
|
2
|
+
export type Obj = Record<string, unknown>;
|
|
3
|
+
export declare function object(value: unknown): Obj;
|
|
4
|
+
export declare function optionalObject(value: unknown): Obj;
|
|
5
|
+
export declare function list(value: unknown): unknown[];
|
|
6
|
+
export declare function string(value: unknown): string | undefined;
|
|
7
|
+
export declare function number(value: unknown): number | undefined;
|
|
8
|
+
export declare function nonnegative(value: unknown): number | undefined;
|
|
9
|
+
export declare function percent(value: unknown): number;
|
|
10
|
+
export declare function timestamp(value: unknown): string | null;
|
|
11
|
+
export declare function slug(value: string): string;
|
|
12
|
+
export declare function title(value: string): string;
|
|
13
|
+
export declare function ratio(used: unknown, limit: unknown): number | null;
|
|
14
|
+
export declare function countWindow(id: string, label: string, raw: Obj, reset: unknown, unit?: string): UsageWindow;
|
|
15
|
+
export declare function requireUsage(data: UsageData): UsageData;
|
|
16
|
+
export declare function credentialObject(value: unknown): Obj;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { UsageError } from '../errors.js';
|
|
2
|
+
export function object(value) {
|
|
3
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
4
|
+
throw new UsageError('invalid_response');
|
|
5
|
+
return value;
|
|
6
|
+
}
|
|
7
|
+
export function optionalObject(value) { return value == null ? {} : object(value); }
|
|
8
|
+
export function list(value) {
|
|
9
|
+
if (value == null)
|
|
10
|
+
return [];
|
|
11
|
+
if (!Array.isArray(value))
|
|
12
|
+
throw new UsageError('invalid_response');
|
|
13
|
+
return value;
|
|
14
|
+
}
|
|
15
|
+
export function string(value) {
|
|
16
|
+
return typeof value === 'string' && value.trim() ? value.trim() : undefined;
|
|
17
|
+
}
|
|
18
|
+
export function number(value) {
|
|
19
|
+
if (typeof value !== 'number' && (typeof value !== 'string' || !/^-?\d+(\.\d+)?$/.test(value)))
|
|
20
|
+
return undefined;
|
|
21
|
+
const n = Number(value);
|
|
22
|
+
return Number.isFinite(n) ? n : undefined;
|
|
23
|
+
}
|
|
24
|
+
export function nonnegative(value) {
|
|
25
|
+
const n = number(value);
|
|
26
|
+
return n !== undefined && n >= 0 ? n : undefined;
|
|
27
|
+
}
|
|
28
|
+
export function percent(value) {
|
|
29
|
+
const n = nonnegative(value);
|
|
30
|
+
if (n === undefined)
|
|
31
|
+
throw new UsageError('invalid_response');
|
|
32
|
+
return n; // Providers may report overage above 100%; do not hide it.
|
|
33
|
+
}
|
|
34
|
+
export function timestamp(value) {
|
|
35
|
+
if (value == null || value === '')
|
|
36
|
+
return null;
|
|
37
|
+
const numeric = number(value);
|
|
38
|
+
const ms = numeric === undefined ? (typeof value === 'string' ? Date.parse(value) : NaN)
|
|
39
|
+
: numeric < 100_000_000_000 ? numeric * 1000 : numeric;
|
|
40
|
+
if (!Number.isFinite(ms))
|
|
41
|
+
throw new UsageError('invalid_response');
|
|
42
|
+
try {
|
|
43
|
+
return new Date(ms).toISOString();
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
throw new UsageError('invalid_response');
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
export function slug(value) {
|
|
50
|
+
return value.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '').slice(0, 100) || 'scope';
|
|
51
|
+
}
|
|
52
|
+
export function title(value) {
|
|
53
|
+
return value.replace(/[_-]+/g, ' ').replace(/\b\w/g, char => char.toUpperCase());
|
|
54
|
+
}
|
|
55
|
+
export function ratio(used, limit) {
|
|
56
|
+
const u = nonnegative(used), l = nonnegative(limit);
|
|
57
|
+
return u !== undefined && l !== undefined && l > 0 ? u / l * 100 : null;
|
|
58
|
+
}
|
|
59
|
+
export function countWindow(id, label, raw, reset, unit = 'requests') {
|
|
60
|
+
const used = nonnegative(raw.used), limit = nonnegative(raw.limit);
|
|
61
|
+
if (used === undefined && limit === undefined)
|
|
62
|
+
throw new UsageError('invalid_response');
|
|
63
|
+
return { id, label, used, limit, unit, percentUsed: ratio(used, limit), resetsAt: timestamp(reset) };
|
|
64
|
+
}
|
|
65
|
+
export function requireUsage(data) {
|
|
66
|
+
if (!data.planLabel && !data.windows.length && !data.balances.length && !data.details.length)
|
|
67
|
+
throw new UsageError('invalid_response');
|
|
68
|
+
return data;
|
|
69
|
+
}
|
|
70
|
+
export function credentialObject(value) {
|
|
71
|
+
try {
|
|
72
|
+
return object(value);
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
throw new UsageError('invalid_credentials');
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=parse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.js","sourceRoot":"","sources":["../../src/providers/parse.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { UsageData } from '../models.js';
|
|
2
|
+
import type { Provider } from './base.js';
|
|
3
|
+
export declare function normalizeZaiPlan(payload: unknown): UsageData;
|
|
4
|
+
export declare function normalizeZaiQuota(payload: unknown): UsageData;
|
|
5
|
+
export declare const zai: Provider;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { UsageError } from '../errors.js';
|
|
2
|
+
import { emptyUsage } from '../models.js';
|
|
3
|
+
import { list, nonnegative, object, percent, requireUsage, slug, string, timestamp } from './parse.js';
|
|
4
|
+
function envelope(payload) {
|
|
5
|
+
const raw = object(payload);
|
|
6
|
+
if (raw.success === false || (raw.code !== undefined && ![0, 200, '0', '200'].includes(raw.code)))
|
|
7
|
+
throw new UsageError(raw.code === 401 || raw.code === 403 ? 'unauthorized' : 'provider_error');
|
|
8
|
+
return raw.data;
|
|
9
|
+
}
|
|
10
|
+
export function normalizeZaiPlan(payload) {
|
|
11
|
+
const data = emptyUsage();
|
|
12
|
+
const subscriptions = list(envelope(payload)).map(object);
|
|
13
|
+
const names = subscriptions.map(sub => string(sub.productName)).filter((name) => Boolean(name));
|
|
14
|
+
data.planLabel = [...new Set(names)].join(' / ') || null;
|
|
15
|
+
for (const sub of subscriptions) {
|
|
16
|
+
for (const field of ['status', 'valid', 'purchaseTime']) {
|
|
17
|
+
const value = string(sub[field]);
|
|
18
|
+
if (value)
|
|
19
|
+
data.details.push({ label: `${string(sub.productName) ?? 'Subscription'} ${field}`, value });
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return requireUsage(data);
|
|
23
|
+
}
|
|
24
|
+
export function normalizeZaiQuota(payload) {
|
|
25
|
+
const raw = object(envelope(payload)), data = emptyUsage();
|
|
26
|
+
for (const [index, value] of list(raw.limits).entries()) {
|
|
27
|
+
const quota = object(value), type = string(quota.type) ?? 'Quota';
|
|
28
|
+
const label = type === 'TOKENS_LIMIT' ? '5 hours' : type === 'TIME_LIMIT' ? 'MCP monthly' : type;
|
|
29
|
+
if (quota.percentage == null)
|
|
30
|
+
continue;
|
|
31
|
+
data.windows.push({ id: `${slug(type)}-${index}`, label, percentUsed: percent(quota.percentage),
|
|
32
|
+
resetsAt: timestamp(quota.nextResetTime),
|
|
33
|
+
used: type === 'TIME_LIMIT' ? nonnegative(quota.currentValue) : undefined,
|
|
34
|
+
limit: type === 'TIME_LIMIT' ? nonnegative(quota.usage) : undefined });
|
|
35
|
+
}
|
|
36
|
+
return requireUsage(data);
|
|
37
|
+
}
|
|
38
|
+
export const zai = {
|
|
39
|
+
id: 'zai', displayName: 'Z.ai', version: 1, experimental: true,
|
|
40
|
+
// A subscription provider used through other CLIs; no distinct installation to prove.
|
|
41
|
+
detect: async () => null,
|
|
42
|
+
async resolveCredentials(context) {
|
|
43
|
+
const token = string(context.env.ZAI_API_KEY) ?? string(context.env.GLM_API_KEY);
|
|
44
|
+
return token ? { token } : null;
|
|
45
|
+
},
|
|
46
|
+
async fetchUsage(context, credentials) {
|
|
47
|
+
const [plan, quota] = await Promise.allSettled([
|
|
48
|
+
context.request('https://api.z.ai/api/biz/subscription/list', {
|
|
49
|
+
signal: context.signal, headers: { Authorization: `Bearer ${credentials.token}` },
|
|
50
|
+
}).then(normalizeZaiPlan),
|
|
51
|
+
context.request('https://api.z.ai/api/monitor/usage/quota/limit', {
|
|
52
|
+
signal: context.signal, headers: { Authorization: credentials.token, 'Accept-Language': 'en-US,en' },
|
|
53
|
+
}).then(normalizeZaiQuota),
|
|
54
|
+
]);
|
|
55
|
+
if (plan.status === 'rejected' && quota.status === 'rejected')
|
|
56
|
+
throw quota.reason;
|
|
57
|
+
const data = plan.status === 'fulfilled' ? plan.value : emptyUsage();
|
|
58
|
+
if (quota.status === 'fulfilled')
|
|
59
|
+
data.windows = quota.value.windows;
|
|
60
|
+
else
|
|
61
|
+
data.details.push({ label: 'Quota', value: 'Usage figures could not be retrieved' });
|
|
62
|
+
if (plan.status === 'rejected')
|
|
63
|
+
data.details.push({ label: 'Plan', value: 'Plan metadata could not be retrieved' });
|
|
64
|
+
return data;
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
//# sourceMappingURL=zai.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zai.js","sourceRoot":"","sources":["../../src/providers/zai.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Provider } from './providers/base.js';
|
|
2
|
+
export declare const builtInProviders: readonly Provider[];
|
|
3
|
+
export declare function validateProvider(value: unknown): Provider;
|
|
4
|
+
export declare function loadProviders(plugins?: string[], cwd?: string): Promise<Provider[]>;
|
package/dist/registry.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
import { pathToFileURL } from 'node:url';
|
|
4
|
+
import { claude } from './providers/claude.js';
|
|
5
|
+
import { codex } from './providers/codex.js';
|
|
6
|
+
import { copilot } from './providers/copilot.js';
|
|
7
|
+
import { cursor } from './providers/cursor.js';
|
|
8
|
+
import { zai } from './providers/zai.js';
|
|
9
|
+
import { grok } from './providers/grok.js';
|
|
10
|
+
import { kimi } from './providers/kimi.js';
|
|
11
|
+
import { minimax } from './providers/minimax.js';
|
|
12
|
+
export const builtInProviders = [claude, codex, copilot, cursor, zai, grok, kimi, minimax];
|
|
13
|
+
export function validateProvider(value) {
|
|
14
|
+
if (!value || typeof value !== 'object')
|
|
15
|
+
throw new Error('Invalid provider plugin');
|
|
16
|
+
const p = value;
|
|
17
|
+
if (typeof p.id !== 'string' || !/^[a-z0-9][a-z0-9-]{0,47}$/.test(p.id)
|
|
18
|
+
|| typeof p.displayName !== 'string' || !/^[\p{L}\p{N} ._-]{1,80}$/u.test(p.displayName)
|
|
19
|
+
|| !Number.isSafeInteger(p.version) || (p.version ?? 0) < 1
|
|
20
|
+
|| typeof p.detect !== 'function' || typeof p.resolveCredentials !== 'function' || typeof p.fetchUsage !== 'function'
|
|
21
|
+
|| (p.experimental !== undefined && typeof p.experimental !== 'boolean'))
|
|
22
|
+
throw new Error('Invalid provider plugin');
|
|
23
|
+
return value;
|
|
24
|
+
}
|
|
25
|
+
export async function loadProviders(plugins = [], cwd = process.cwd()) {
|
|
26
|
+
const providers = [...builtInProviders], ids = new Set(providers.map(p => p.id));
|
|
27
|
+
const require = createRequire(resolve(cwd, '__asu_resolve__.cjs'));
|
|
28
|
+
for (const specifier of plugins) {
|
|
29
|
+
try {
|
|
30
|
+
// Explicit local/package imports only. No remote downloads or auto-scanning directories.
|
|
31
|
+
const file = specifier.startsWith('.') || specifier.startsWith('/') ? resolve(cwd, specifier) : require.resolve(specifier);
|
|
32
|
+
const module = await import(pathToFileURL(file).href);
|
|
33
|
+
const provider = validateProvider(module.default ?? module.provider);
|
|
34
|
+
if (ids.has(provider.id))
|
|
35
|
+
throw new Error('Duplicate provider ID');
|
|
36
|
+
providers.push(provider);
|
|
37
|
+
ids.add(provider.id);
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
throw new Error('Could not load a provider plugin. Check its path, exports, and unique provider ID.');
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return providers;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { UsageCache } from './cache.js';
|
|
2
|
+
import type { UsageReport } from './models.js';
|
|
3
|
+
import type { LocalContext } from './local.js';
|
|
4
|
+
import type { RequestJson } from './transport.js';
|
|
5
|
+
import type { Provider } from './providers/base.js';
|
|
6
|
+
export interface ServiceOptions {
|
|
7
|
+
local?: LocalContext;
|
|
8
|
+
request?: RequestJson;
|
|
9
|
+
cache?: UsageCache;
|
|
10
|
+
now?: () => number;
|
|
11
|
+
timeoutMs?: number;
|
|
12
|
+
}
|
|
13
|
+
export declare function deadline<T>(work: (signal: AbortSignal) => Promise<T>, timeoutMs: number): Promise<T>;
|
|
14
|
+
export declare class UsageService {
|
|
15
|
+
private readonly providers;
|
|
16
|
+
private readonly local;
|
|
17
|
+
private readonly request;
|
|
18
|
+
private readonly cache;
|
|
19
|
+
private readonly now;
|
|
20
|
+
private readonly timeoutMs;
|
|
21
|
+
constructor(providers: readonly Provider[], options?: ServiceOptions);
|
|
22
|
+
collect(options?: {
|
|
23
|
+
providerIds?: string[];
|
|
24
|
+
fresh?: boolean;
|
|
25
|
+
}): Promise<UsageReport>;
|
|
26
|
+
private result;
|
|
27
|
+
private collectProvider;
|
|
28
|
+
}
|