feat: implement the feature for checking quota of orbit provider

This commit is contained in:
2026-07-17 16:43:15 +07:00
parent 7ff4ebeed1
commit 2e595627d0
6 changed files with 288 additions and 0 deletions
+118
View File
@@ -0,0 +1,118 @@
/**
* Orbit Provider usage handler.
*/
import { proxyAwareFetch } from "../../utils/proxyFetch.js";
import { U, parseResetTime, toFiniteNumber } from "./shared.js";
const ORBIT_USAGE_URL = U("orbit-provider").url;
function clampPercentage(value) {
return Math.min(100, Math.max(0, value));
}
function getRemainingPercentage(used, total, upstreamUsagePercent) {
if (total <= 0) return 0;
const usagePercent = Number.isFinite(Number(upstreamUsagePercent))
? toFiniteNumber(upstreamUsagePercent)
: (used / total) * 100;
return clampPercentage(100 - usagePercent);
}
/**
* Normalize Orbit's usage response into quota rows consumed by the dashboard.
* @param {object} responseBody Orbit API response.
* @returns {object} Normalized provider usage.
*/
export function parseOrbitUsage(responseBody) {
if (responseBody?.success !== true || !responseBody?.data || typeof responseBody.data !== "object") {
return { message: "Orbit Provider usage response was invalid." };
}
const data = responseBody.data;
const used = Math.max(0, toFiniteNumber(data.tokensUsed));
const total = Math.max(0, toFiniteNumber(data.tokenLimit));
const upstreamRemaining = Math.max(0, toFiniteNumber(data.tokensRemaining, Math.max(0, total - used)));
const remaining = data.isExhausted === true ? 0 : Math.min(total, upstreamRemaining);
const remainingPercentage = data.isExhausted === true
? 0
: getRemainingPercentage(used, total, data.usagePercent);
const resetPeriod = typeof data.resetPeriod === "string" && data.resetPeriod.trim()
? data.resetPeriod.trim().toLowerCase()
: "period";
const resetAt = parseResetTime(data.periodEnd);
const quotas = {
[`Tokens (${resetPeriod})`]: {
used,
total,
remaining,
remainingPercentage,
resetAt,
unlimited: false,
},
};
const credit = data.credit;
if (credit && typeof credit === "object") {
const balance = Math.max(0, toFiniteNumber(credit.balanceUsd));
const granted = Math.max(0, toFiniteNumber(credit.grantedUsd));
const spent = Math.max(0, toFiniteNumber(credit.spentUsd));
const creditTotal = granted > 0 ? granted : balance + spent;
const creditRemainingPercentage = creditTotal > 0
? clampPercentage((balance / creditTotal) * 100)
: 0;
quotas["Credit (USD)"] = {
used: spent,
total: creditTotal,
remaining: balance,
remainingPercentage: creditRemainingPercentage,
resetAt: null,
unlimited: false,
};
}
return {
plan: typeof data.plan === "string" && data.plan.trim() ? data.plan.trim() : "Unknown",
quotas,
isExhausted: data.isExhausted === true,
resetPeriod,
};
}
/**
* Fetch usage for an Orbit Provider API-key connection.
* @param {string} apiKey Orbit API key.
* @param {object|null} proxyOptions Connection proxy configuration.
* @returns {Promise<object>} Normalized usage data.
*/
export async function getOrbitUsage(apiKey, proxyOptions = null) {
if (!apiKey) {
return { message: "Orbit Provider API key not available." };
}
try {
const response = await proxyAwareFetch(ORBIT_USAGE_URL, {
method: "GET",
headers: {
Authorization: `Bearer ${apiKey}`,
Accept: "application/json",
},
}, proxyOptions);
if (response.status === 401 || response.status === 403) {
return { message: "Orbit Provider API key invalid or expired." };
}
if (!response.ok) {
const errorText = await response.text().catch(() => "");
const detail = errorText ? `: ${errorText.slice(0, 200)}` : "";
return { message: `Orbit Provider usage API error (${response.status})${detail}` };
}
const body = await response.json().catch(() => null);
return parseOrbitUsage(body);
} catch (error) {
return { message: `Orbit Provider usage error: ${error.message}` };
}
}