@narumitw/pi-usage 0.60.7 → 0.60.9
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 +1 -1
- package/dist/index.ts +91 -340
- package/dist/index.ts.map +2 -2
- package/docs/providers.md +2 -1
- package/package.json +73 -74
- package/src/codex-fast-runtime.ts +148 -184
- package/src/codex-fast.ts +73 -83
- package/src/codex-resets.ts +249 -278
- package/src/core.ts +204 -206
- package/src/format.ts +519 -574
- package/src/index.ts +77 -77
- package/src/oauth-credential-source.ts +57 -65
- package/src/providers/baseten.ts +32 -36
- package/src/providers/codex.ts +109 -120
- package/src/providers/deepseek.ts +59 -64
- package/src/providers/fireworks.ts +219 -238
- package/src/providers/github-copilot.ts +89 -95
- package/src/providers/kimi-coding.ts +202 -213
- package/src/providers/minimax.ts +214 -219
- package/src/providers/moonshot.ts +41 -46
- package/src/providers/opencode-zen.ts +56 -59
- package/src/providers/openrouter.ts +50 -53
- package/src/providers/vercel-ai-gateway.ts +33 -33
- package/src/providers/xai.ts +141 -148
- package/src/providers/zai-errors.ts +75 -75
- package/src/providers/zai.ts +173 -189
- package/src/query.ts +887 -967
- package/src/settings.ts +275 -304
- package/src/types.ts +145 -145
- package/src/usage-helpers.ts +18 -18
- package/src/usage-settings-ui.ts +117 -126
- package/src/usage-targets.ts +98 -114
- package/src/usage.ts +1264 -1426
package/src/index.ts
CHANGED
|
@@ -1,51 +1,51 @@
|
|
|
1
1
|
export {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
2
|
+
CODEX_FAST_MODEL_IDS,
|
|
3
|
+
CODEX_FAST_SERVICE_TIER,
|
|
4
|
+
CODEX_STANDARD_SERVICE_TIER,
|
|
5
|
+
codexFastAvailability,
|
|
6
|
+
codexFastIsEffective,
|
|
7
|
+
codexFastRequestTier,
|
|
8
|
+
codexFastStatusLabel,
|
|
9
|
+
correctCodexFastMessageCost,
|
|
10
|
+
rewriteCodexFastPayload,
|
|
11
11
|
} from "./codex-fast.js";
|
|
12
12
|
export type {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
CodexResetAvailability,
|
|
14
|
+
CodexResetOption,
|
|
15
|
+
CodexResetOutcome,
|
|
16
|
+
CodexResetOutcomeCode,
|
|
17
17
|
} from "./codex-resets.js";
|
|
18
18
|
export {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
consumeCodexResetCredit,
|
|
20
|
+
listCodexResetCredits,
|
|
21
|
+
normalizeCodexResetCreditsPayload,
|
|
22
|
+
resolveCodexResetAuth,
|
|
23
23
|
} from "./codex-resets.js";
|
|
24
24
|
export {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
25
|
+
abortError,
|
|
26
|
+
awaitWithDeadline,
|
|
27
|
+
errorMessage,
|
|
28
|
+
fingerprintResolvedAuth,
|
|
29
|
+
redactUsageError,
|
|
30
|
+
runWithConcurrency,
|
|
31
|
+
sanitizeDisplayText,
|
|
32
|
+
UsageCache,
|
|
33
33
|
} from "./core.js";
|
|
34
34
|
export { formatProviderStates, formatUsageReport, formatUsageStatusline } from "./format.js";
|
|
35
35
|
export { normalizeBasetenBillingUsagePayload } from "./providers/baseten.js";
|
|
36
36
|
export { normalizeCodexBackendPayload } from "./providers/codex.js";
|
|
37
37
|
export { normalizeDeepSeekBalancePayload } from "./providers/deepseek.js";
|
|
38
38
|
export {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
createFireworksAdapter,
|
|
40
|
+
normalizeFireworksAccountsPayload,
|
|
41
|
+
normalizeFireworksBillingSummaryPayload,
|
|
42
42
|
} from "./providers/fireworks.js";
|
|
43
43
|
export { normalizeGitHubCopilotUsagePayload } from "./providers/github-copilot.js";
|
|
44
44
|
export { normalizeKimiCodingUsagePayload } from "./providers/kimi-coding.js";
|
|
45
45
|
export type { MiniMaxProviderId, MiniMaxUsageKind } from "./providers/minimax.js";
|
|
46
46
|
export {
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
miniMaxUsageKind,
|
|
48
|
+
normalizeMiniMaxUsagePayload,
|
|
49
49
|
} from "./providers/minimax.js";
|
|
50
50
|
export type { MoonshotProviderId } from "./providers/moonshot.js";
|
|
51
51
|
export { normalizeMoonshotBalancePayload } from "./providers/moonshot.js";
|
|
@@ -55,61 +55,61 @@ export { normalizeVercelAIGatewayCreditsPayload } from "./providers/vercel-ai-ga
|
|
|
55
55
|
export { normalizeXaiBillingPayload } from "./providers/xai.js";
|
|
56
56
|
export { normalizeZaiQuotaPayload, normalizeZaiSubscriptionPayload } from "./providers/zai.js";
|
|
57
57
|
export {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
58
|
+
adapterForProvider,
|
|
59
|
+
isStaleExtensionContextError,
|
|
60
|
+
providerIsConfigured,
|
|
61
|
+
queryProviderUsage,
|
|
62
|
+
resolveUsageAuth,
|
|
63
|
+
SUPPORTED_ADAPTERS,
|
|
64
|
+
usageAdapters,
|
|
65
|
+
XAI_ADAPTER,
|
|
66
66
|
} from "./query.js";
|
|
67
67
|
export type {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
68
|
+
UsageSettings,
|
|
69
|
+
UsageSettingsRuntime,
|
|
70
|
+
UsageSettingsState,
|
|
71
|
+
UsageTargetPublicationCheck,
|
|
72
72
|
} from "./settings.js";
|
|
73
73
|
export {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
74
|
+
createUsageSettingsRuntime,
|
|
75
|
+
DEFAULT_USAGE_SETTINGS,
|
|
76
|
+
loadUsageSettings,
|
|
77
|
+
normalizeUsageSettings,
|
|
78
|
+
usageSettingsPath,
|
|
79
79
|
} from "./settings.js";
|
|
80
80
|
export type {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
81
|
+
BasetenBillingUsagePayload,
|
|
82
|
+
DeepSeekBalancePayload,
|
|
83
|
+
FireworksAccountsPayload,
|
|
84
|
+
FireworksBillingSummaryPayload,
|
|
85
|
+
KimiCodingUsagePayload,
|
|
86
|
+
MiniMaxUsagePayload,
|
|
87
|
+
MoonshotBalancePayload,
|
|
88
|
+
ProviderUsageState,
|
|
89
|
+
ResolvedUsageAuth,
|
|
90
|
+
UsageBucket,
|
|
91
|
+
UsageDisplayState,
|
|
92
|
+
UsageMetric,
|
|
93
|
+
UsageModel,
|
|
94
|
+
UsageProviderAdapter,
|
|
95
|
+
UsageProviderTarget,
|
|
96
|
+
UsageQuerySettings,
|
|
97
|
+
UsageReport,
|
|
98
|
+
UsageRequestGuard,
|
|
99
|
+
UsageSemantics,
|
|
100
|
+
UsageSemanticsKind,
|
|
101
|
+
UsageTargetResolver,
|
|
102
|
+
UsageUnit,
|
|
103
|
+
VercelAIGatewayCreditsPayload,
|
|
104
|
+
XaiBillingPayload,
|
|
105
|
+
XaiUserPayload,
|
|
106
106
|
} from "./types.js";
|
|
107
107
|
export { default } from "./usage.js";
|
|
108
108
|
export type { UsageTargetResolution, UsageTargetSelectOptions } from "./usage-targets.js";
|
|
109
109
|
export {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
110
|
+
createUsageTargetSelectOptions,
|
|
111
|
+
isBoundedTargetId,
|
|
112
|
+
listUsageTargets,
|
|
113
|
+
normalizeUsageTargets,
|
|
114
|
+
resolveUsageTarget,
|
|
115
115
|
} from "./usage-targets.js";
|
|
@@ -1,88 +1,80 @@
|
|
|
1
1
|
import type { OAuthCredential } from "@earendil-works/pi-ai";
|
|
2
|
-
import {
|
|
3
|
-
type ExtensionAPI,
|
|
4
|
-
type ExtensionContext,
|
|
5
|
-
readStoredCredential,
|
|
6
|
-
} from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { type ExtensionAPI, type ExtensionContext, readStoredCredential } from "@earendil-works/pi-coding-agent";
|
|
7
3
|
|
|
8
4
|
export const OAUTH_CREDENTIAL_SOURCE_CHANNEL = "oauth:credential-source:v1";
|
|
9
5
|
|
|
10
6
|
export type StoredCredentialReader = (providerId: string) => unknown;
|
|
11
7
|
|
|
12
8
|
export type OAuthCredentialCandidates =
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
| { ok: true; candidates: readonly OAuthCredential[]; offeredCount?: number }
|
|
10
|
+
| { ok: false };
|
|
15
11
|
|
|
16
|
-
export type OAuthCredentialCandidateReader = (
|
|
17
|
-
ctx: ExtensionContext,
|
|
18
|
-
providerId: string,
|
|
19
|
-
) => OAuthCredentialCandidates;
|
|
12
|
+
export type OAuthCredentialCandidateReader = (ctx: ExtensionContext, providerId: string) => OAuthCredentialCandidates;
|
|
20
13
|
|
|
21
14
|
export function createOAuthCredentialCandidateReader(
|
|
22
|
-
|
|
23
|
-
|
|
15
|
+
pi: ExtensionAPI,
|
|
16
|
+
credentialReader: StoredCredentialReader = readStoredCredential,
|
|
24
17
|
): OAuthCredentialCandidateReader {
|
|
25
|
-
|
|
26
|
-
collectOAuthCredentialCandidates(pi, ctx, providerId, credentialReader);
|
|
18
|
+
return (ctx, providerId) => collectOAuthCredentialCandidates(pi, ctx, providerId, credentialReader);
|
|
27
19
|
}
|
|
28
20
|
|
|
29
21
|
export function collectOAuthCredentialCandidates(
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
22
|
+
pi: Pick<ExtensionAPI, "events">,
|
|
23
|
+
ctx: ExtensionContext,
|
|
24
|
+
providerId: string,
|
|
25
|
+
credentialReader: StoredCredentialReader = readStoredCredential,
|
|
34
26
|
): OAuthCredentialCandidates {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
27
|
+
const candidates: OAuthCredential[] = [];
|
|
28
|
+
let collecting = true;
|
|
29
|
+
const request = Object.freeze({
|
|
30
|
+
session: ctx.sessionManager,
|
|
31
|
+
provider: providerId,
|
|
32
|
+
offer(candidate: unknown) {
|
|
33
|
+
if (!collecting) return;
|
|
34
|
+
const clone = cloneOAuthCredential(candidate);
|
|
35
|
+
if (clone) candidates.push(clone);
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
try {
|
|
39
|
+
pi.events.emit(OAUTH_CREDENTIAL_SOURCE_CHANNEL, request);
|
|
40
|
+
} catch {
|
|
41
|
+
return { ok: false };
|
|
42
|
+
} finally {
|
|
43
|
+
collecting = false;
|
|
44
|
+
}
|
|
45
|
+
const offeredCount = candidates.length;
|
|
46
|
+
try {
|
|
47
|
+
const fallback = cloneOAuthCredential(credentialReader(providerId));
|
|
48
|
+
if (fallback) candidates.push(fallback);
|
|
49
|
+
} catch {
|
|
50
|
+
// A malformed or unavailable standalone credential is equivalent to no fallback.
|
|
51
|
+
}
|
|
52
|
+
return { ok: true, candidates, offeredCount };
|
|
61
53
|
}
|
|
62
54
|
|
|
63
55
|
export function fallbackOAuthCredentialCandidates(
|
|
64
|
-
|
|
65
|
-
|
|
56
|
+
providerId: string,
|
|
57
|
+
credentialReader: StoredCredentialReader,
|
|
66
58
|
): OAuthCredentialCandidates {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
59
|
+
try {
|
|
60
|
+
const credential = cloneOAuthCredential(credentialReader(providerId));
|
|
61
|
+
return { ok: true, candidates: credential ? [credential] : [], offeredCount: 0 };
|
|
62
|
+
} catch {
|
|
63
|
+
return { ok: true, candidates: [], offeredCount: 0 };
|
|
64
|
+
}
|
|
73
65
|
}
|
|
74
66
|
|
|
75
67
|
function cloneOAuthCredential(value: unknown): OAuthCredential | undefined {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
68
|
+
try {
|
|
69
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return undefined;
|
|
70
|
+
const clone = structuredClone(value) as OAuthCredential;
|
|
71
|
+
if (!clone || typeof clone !== "object" || Array.isArray(clone)) return undefined;
|
|
72
|
+
if (clone.type !== "oauth") return undefined;
|
|
73
|
+
if (typeof clone.access !== "string" || !clone.access) return undefined;
|
|
74
|
+
if (typeof clone.refresh !== "string" || !clone.refresh) return undefined;
|
|
75
|
+
if (typeof clone.expires !== "number" || !Number.isFinite(clone.expires)) return undefined;
|
|
76
|
+
return clone;
|
|
77
|
+
} catch {
|
|
78
|
+
return undefined;
|
|
79
|
+
}
|
|
88
80
|
}
|
package/src/providers/baseten.ts
CHANGED
|
@@ -3,53 +3,49 @@ import type { BasetenBillingUsagePayload, UsageMetric, UsageReport } from "../ty
|
|
|
3
3
|
const DECIMAL_AMOUNT = /^(?:0|[1-9]\d*)(?:\.\d+)?$/u;
|
|
4
4
|
|
|
5
5
|
export function normalizeBasetenBillingUsagePayload(
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
payload: BasetenBillingUsagePayload,
|
|
7
|
+
capturedAt: number,
|
|
8
8
|
): UsageReport {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
9
|
+
if (payload.model_apis_usage === undefined || payload.model_apis_usage === null) {
|
|
10
|
+
return report(capturedAt, [], ["Baseten returned no Model APIs usage for the last 30 days."]);
|
|
11
|
+
}
|
|
12
|
+
const usage = asObject(payload.model_apis_usage);
|
|
13
|
+
if (!usage) throw new Error("Baseten Model APIs usage was not an object.");
|
|
14
|
+
const metrics: UsageMetric[] = [
|
|
15
|
+
metric("gross-usage", "Gross usage", usage.total),
|
|
16
|
+
metric("credits-used", "Credits used", usage.credits_used),
|
|
17
|
+
metric("net-subtotal", "Net subtotal", usage.subtotal),
|
|
18
|
+
];
|
|
19
|
+
return report(capturedAt, metrics);
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
function report(capturedAt: number, metrics: UsageMetric[], notes?: string[]): UsageReport {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
23
|
+
return {
|
|
24
|
+
providerId: "baseten",
|
|
25
|
+
providerName: "Baseten",
|
|
26
|
+
capturedAt,
|
|
27
|
+
source: "baseten-billing-usage-summary",
|
|
28
|
+
semantics: { kind: "api-key", label: "Organization Model APIs spend" },
|
|
29
|
+
buckets: [],
|
|
30
|
+
metrics,
|
|
31
|
+
...(notes ? { notes } : {}),
|
|
32
|
+
};
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
function metric(id: string, label: string, value: unknown): UsageMetric {
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
const amount = decimalAmount(value, label);
|
|
37
|
+
return { id, label, value: amount, unit: "currency", currency: "USD" };
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
function decimalAmount(value: unknown, label: string): string {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
) {
|
|
47
|
-
throw new Error(`Baseten ${label.toLowerCase()} was not a valid nonnegative amount.`);
|
|
48
|
-
}
|
|
49
|
-
return normalized;
|
|
41
|
+
const normalized = typeof value === "number" && Number.isFinite(value) ? String(value) : value;
|
|
42
|
+
if (typeof normalized !== "string" || normalized.length > 64 || !DECIMAL_AMOUNT.test(normalized)) {
|
|
43
|
+
throw new Error(`Baseten ${label.toLowerCase()} was not a valid nonnegative amount.`);
|
|
44
|
+
}
|
|
45
|
+
return normalized;
|
|
50
46
|
}
|
|
51
47
|
|
|
52
48
|
function asObject(value: unknown): Record<string, unknown> | undefined {
|
|
53
|
-
|
|
54
|
-
|
|
49
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return undefined;
|
|
50
|
+
return value as Record<string, unknown>;
|
|
55
51
|
}
|