Merge the MIBP fork (v1.0.14, synced to decolua v0.5.81) into our master
(0.5.86) at merge-base a8c9d380. Keep HEAD's infra policy (untracked
lockfile, mirror-configurable Dockerfile, decolua GHCR/DockerHub, README)
while absorbing the fork's engine features:
- feat(providers): freebuff provider + executor + OAuth + usage tracking
- feat(providers): cline free-tier models, Freebuff catalog sync
- feat(proxy-pools): pool egress geo probe, proxy-pool fitness + retry
- fix(usage): hide noAuth providers (devin-cli, mimo-free) from usage list
- test(harness): DATA_DIR isolation so tests never write the real DB
- fix(codebuddy-intl): probe token in connection test, OAuth by identity
- chore(guards): durable markers so fixes aren't silently dropped
Resolutions:
- registry/index.js regenerated deterministically (122 providers, alpha
order). trae/windsurf/devin-cli stay hidden per HEAD security posture
(no tool-calling / local-agent shell access) — not re-enabled.
- nonStreamingHandler: drop the generic unconditional unwrapDataEnvelope
call; envelope unwrap stays scoped to clineEnvelope-quirk providers
(unwrapClineEnvelope), fixing a latent mibp bug where non-opted-in
providers ({success,data} bodies) were stripped.
- Drop fork-local Docker lockfile policy (package-lock.json, AGENTS.md,
.npmrc verify scripts): this repo keeps package-lock untracked (nix
build deploy). .npmrc (audit=false/fund=false) kept.
- Keep gitbook-pages workflow enabled (ours); mibp disabled it.
- Restore 13 upstream tests mibp deleted (they cover features we keep).
Verified: 2841 tests, 2687 pass, fail set byte-identical to HEAD (zero
new regressions); providers/alias/oauth baselines regenerated to merged
code and all green.
96 lines
4.7 KiB
JavaScript
96 lines
4.7 KiB
JavaScript
/**
|
|
* Usage Fetcher - Get usage data from provider APIs
|
|
*/
|
|
|
|
import { getGitHubUsage } from "./usage/github.js";
|
|
import { getGeminiUsage, getAntigravityUsage } from "./usage/google.js";
|
|
import { getClaudeUsage } from "./usage/claude.js";
|
|
import { getCodexUsage, consumeCodexRateLimitResetCredit, getCodexRateLimitResetCredits } from "./usage/codex.js";
|
|
|
|
export { consumeCodexRateLimitResetCredit, getCodexRateLimitResetCredits };
|
|
import { getKiroUsage } from "./usage/kiro.js";
|
|
import { getMiniMaxUsage } from "./usage/minimax.js";
|
|
import { getCodeBuddyCnUsage, getCodeBuddyIntlUsage } from "./usage/codebuddy-cn.js";
|
|
import { getGrokCliUsage } from "./usage/grok-cli.js";
|
|
import { getKimiUsage } from "./usage/kimi.js";
|
|
import { getDeepseekUsage } from "./usage/deepseek.js";
|
|
import { getFreebuffUsage } from "./usage/freebuff.js";
|
|
import { getOpenCodeGoUsage } from "./usage/opencode-go.js";
|
|
import { getOpenCodeZenUsage } from "./usage/opencode-zen.js";
|
|
import { getGroqUsage } from "./usage/groq.js";
|
|
import { getZedUsage } from "./usage/zed.js";
|
|
import { getXiaomiMimoUsage } from "./usage/xiaomi-mimo.js";
|
|
import { resolveQoderCredentials } from "./qoderModels.js";
|
|
import { getGlmUsage } from "./usage/glm.js";
|
|
import { getCommandCodeUsage } from "./usage/commandcode.js";
|
|
import {
|
|
getIflowUsage,
|
|
getOllamaUsage,
|
|
getVercelAiGatewayUsage,
|
|
getQoderUsage,
|
|
} from "./usage/misc.js";
|
|
|
|
/**
|
|
* Get usage data for a provider connection
|
|
* @param {Object} connection - Provider connection with accessToken
|
|
* @returns {Object} Usage data with quotas
|
|
*/
|
|
// provider → usage handler (ctx carries every arg each handler needs)
|
|
const USAGE_HANDLERS = {
|
|
github: (c) => getGitHubUsage(c.accessToken, c.providerSpecificData, c.proxyOptions),
|
|
"gemini-cli": (c) => getGeminiUsage(c.accessToken, c.providerDataWithProjectId, c.proxyOptions),
|
|
antigravity: (c) => getAntigravityUsage(c.accessToken, c.providerSpecificData, c.proxyOptions),
|
|
claude: (c) => getClaudeUsage(c.accessToken, c.proxyOptions, { force: c.force }),
|
|
codex: (c) => getCodexUsage(c.accessToken, c.proxyOptions),
|
|
kiro: (c) => getKiroUsage(c.accessToken, c.providerSpecificData, c.proxyOptions),
|
|
qoder: (c) => getQoderUsageFor(c),
|
|
"qoder-cn": (c) => getQoderUsageFor(c),
|
|
iflow: (c) => getIflowUsage(c.accessToken),
|
|
ollama: (c) => getOllamaUsage(c.apiKey, c.providerSpecificData, c.proxyOptions),
|
|
glm: (c) => getGlmUsage(c.apiKey, c.provider, c.proxyOptions),
|
|
"glm-cn": (c) => getGlmUsage(c.apiKey, c.provider, c.proxyOptions),
|
|
minimax: (c) => getMiniMaxUsage(c.apiKey, c.provider, c.proxyOptions),
|
|
"minimax-cn": (c) => getMiniMaxUsage(c.apiKey, c.provider, c.proxyOptions),
|
|
"vercel-ai-gateway": (c) => getVercelAiGatewayUsage(c.apiKey, c.proxyOptions),
|
|
"codebuddy-cn": (c) => getCodeBuddyCnUsage(c.accessToken, c.apiKey, c.providerSpecificData, c.proxyOptions),
|
|
"codebuddy-intl": (c) => getCodeBuddyIntlUsage(c.accessToken, c.apiKey, c.providerSpecificData, c.proxyOptions),
|
|
"grok-cli": (c) => getGrokCliUsage(c.accessToken, c.providerSpecificData, c.proxyOptions),
|
|
kimi: (c) => getKimiUsage(c.accessToken, c.apiKey, c.proxyOptions, c.providerSpecificData),
|
|
"opencode-go": (c) => getOpenCodeGoUsage(c.apiKey, c.proxyOptions),
|
|
"opencode-zen": (c) => getOpenCodeZenUsage(c.apiKey, c.proxyOptions),
|
|
deepseek: (c) => getDeepseekUsage(c.apiKey, c.proxyOptions),
|
|
freebuff: (c) => getFreebuffUsage(c.accessToken, c.providerSpecificData, c.proxyOptions),
|
|
groq: (c) => getGroqUsage(c.apiKey, c.proxyOptions),
|
|
zed: (c) => getZedUsage(c.accessToken, c.providerSpecificData, c.proxyOptions),
|
|
"xiaomi-mimo": (c) => getXiaomiMimoUsage(c.accessToken, c.providerSpecificData, c.proxyOptions),
|
|
commandcode: (c) => getCommandCodeUsage(c.apiKey, c.proxyOptions),
|
|
};
|
|
|
|
// Qoder intl/CN share one usage path: PATs must be exchanged to a job token
|
|
// before the quota endpoint accepts them, and the quota URL comes from the
|
|
// provider's own registry usage block (region-correct via c.provider).
|
|
async function getQoderUsageFor(c) {
|
|
const resolved = await resolveQoderCredentials(c, c.proxyOptions).catch(() => null);
|
|
return getQoderUsage(resolved?.accessToken || c.accessToken, c.proxyOptions, c.provider || "qoder");
|
|
}
|
|
|
|
export async function getUsageForProvider(connection, proxyOptions = null, options = {}) {
|
|
const { provider, accessToken, apiKey, providerSpecificData, projectId } = connection;
|
|
const providerDataWithProjectId = {
|
|
...(providerSpecificData || {}),
|
|
...(projectId ? { projectId } : {}),
|
|
};
|
|
|
|
const handler = USAGE_HANDLERS[provider];
|
|
if (!handler) return { message: `Usage API not implemented for ${provider}` };
|
|
return await handler({
|
|
provider,
|
|
accessToken,
|
|
apiKey,
|
|
providerSpecificData,
|
|
providerDataWithProjectId,
|
|
proxyOptions,
|
|
force: options.force === true,
|
|
});
|
|
}
|