Files
openchamber/packages/web/server/lib/quota/providers/index.js
T
Bohdan Triapitsyn 0d50253efa refactor(integrations): retire unavailable options
Remove retired Command Code, Discord, and Telegram integration entries, search targets, and documentation. Keep Command Code provider usage and logo support available through normalized provider ID aliases.
2026-08-22 01:10:19 +03:00

242 lines
7.5 KiB
JavaScript

/**
* Quota Providers Registry
*
* Implements quota fetching for various AI providers using a registry pattern.
* @module quota/providers
*/
import { buildResult } from '../utils/index.js';
import * as claude from './claude/index.js';
import * as codex from './codex.js';
import * as commandCode from './command-code.js';
import * as copilot from './copilot.js';
import * as crof from './crof.js';
import * as cursor from './cursor.js';
import * as deepseek from './deepseek.js';
import * as google from './google/index.js';
import * as kimi from './kimi.js';
import * as nanogpt from './nanogpt.js';
import * as openai from './openai.js';
import * as openrouter from './openrouter.js';
import * as zai from './zai.js';
import * as zhipuaiCodingPlan from './zhipuai-coding-plan.js';
import * as minimaxCodingPlan from './minimax-coding-plan.js';
import * as minimaxCnCodingPlan from './minimax-cn-coding-plan.js';
import * as neuralwatt from './neuralwatt.js';
import * as ollamaCloud from './ollama-cloud.js';
import * as wafer from './wafer.js';
import * as opencodeGo from './opencode-go.js';
import * as xai from './xai.js';
const registry = {
'command-code': {
providerId: commandCode.providerId,
providerName: commandCode.providerName,
isConfigured: commandCode.isConfigured,
fetchQuota: commandCode.fetchQuota
},
claude: {
providerId: claude.providerId,
providerName: claude.providerName,
isConfigured: claude.isConfigured,
fetchQuota: claude.fetchQuota
},
codex: {
providerId: codex.providerId,
providerName: codex.providerName,
isConfigured: codex.isConfigured,
fetchQuota: codex.fetchQuota
},
crof: {
providerId: crof.providerId,
providerName: crof.providerName,
isConfigured: crof.isConfigured,
fetchQuota: crof.fetchQuota
},
cursor: {
providerId: cursor.providerId,
providerName: cursor.providerName,
isConfigured: cursor.isConfigured,
fetchQuota: cursor.fetchQuota
},
deepseek: {
providerId: deepseek.providerId,
providerName: deepseek.providerName,
isConfigured: deepseek.isConfigured,
fetchQuota: deepseek.fetchQuota
},
google: {
providerId: google.providerId,
providerName: google.providerName,
isConfigured: google.isConfigured,
fetchQuota: google.fetchGoogleQuota
},
'zai-coding-plan': {
providerId: zai.providerId,
providerName: zai.providerName,
isConfigured: zai.isConfigured,
fetchQuota: zai.fetchQuota
},
'zhipuai-coding-plan': {
providerId: zhipuaiCodingPlan.providerId,
providerName: zhipuaiCodingPlan.providerName,
isConfigured: zhipuaiCodingPlan.isConfigured,
fetchQuota: zhipuaiCodingPlan.fetchQuota
},
'kimi-for-coding': {
providerId: kimi.providerId,
providerName: kimi.providerName,
isConfigured: kimi.isConfigured,
fetchQuota: kimi.fetchQuota
},
openrouter: {
providerId: openrouter.providerId,
providerName: openrouter.providerName,
isConfigured: openrouter.isConfigured,
fetchQuota: openrouter.fetchQuota
},
'nano-gpt': {
providerId: nanogpt.providerId,
providerName: nanogpt.providerName,
isConfigured: nanogpt.isConfigured,
fetchQuota: nanogpt.fetchQuota
},
'github-copilot': {
providerId: copilot.providerId,
providerName: copilot.providerName,
isConfigured: copilot.isConfigured,
fetchQuota: copilot.fetchQuota
},
'github-copilot-addon': {
providerId: copilot.providerIdAddon,
providerName: copilot.providerNameAddon,
isConfigured: copilot.isConfigured,
fetchQuota: copilot.fetchQuotaAddon
},
'minimax-coding-plan': {
providerId: minimaxCodingPlan.providerId,
providerName: minimaxCodingPlan.providerName,
isConfigured: minimaxCodingPlan.isConfigured,
fetchQuota: minimaxCodingPlan.fetchQuota
},
'minimax-cn-coding-plan': {
providerId: minimaxCnCodingPlan.providerId,
providerName: minimaxCnCodingPlan.providerName,
isConfigured: minimaxCnCodingPlan.isConfigured,
fetchQuota: minimaxCnCodingPlan.fetchQuota
},
'ollama-cloud': {
providerId: ollamaCloud.providerId,
providerName: ollamaCloud.providerName,
isConfigured: ollamaCloud.isConfigured,
fetchQuota: ollamaCloud.fetchQuota
},
wafer: {
providerId: wafer.providerId,
providerName: wafer.providerName,
isConfigured: wafer.isConfigured,
fetchQuota: wafer.fetchQuota
},
'opencode-go': {
providerId: opencodeGo.providerId,
providerName: opencodeGo.providerName,
isConfigured: opencodeGo.isConfigured,
fetchQuota: opencodeGo.fetchQuota
},
neuralwatt: {
providerId: neuralwatt.providerId,
providerName: neuralwatt.providerName,
isConfigured: neuralwatt.isConfigured,
fetchQuota: neuralwatt.fetchQuota
},
xai: {
providerId: xai.providerId,
providerName: xai.providerName,
isConfigured: xai.isConfigured,
fetchQuota: xai.fetchQuota
}
};
const pendingFetches = new Map();
const normalizeQuotaProviderId = (providerId) => {
if (typeof providerId !== 'string') return providerId;
return ['command-code', 'commandcode', 'command_code', 'command code'].includes(providerId.trim().toLowerCase())
? 'command-code'
: providerId;
};
export const listConfiguredQuotaProviders = () => {
const configured = [];
for (const [id, provider] of Object.entries(registry)) {
try {
if (provider.isConfigured()) {
configured.push(id);
}
} catch {
// Ignore provider-specific config errors in list API.
}
}
return configured;
};
const fetchQuotaForProviderUncoalesced = async (providerId) => {
const provider = registry[providerId];
if (!provider) {
return buildResult({
providerId,
providerName: providerId,
ok: false,
configured: false,
error: 'Unsupported provider'
});
}
try {
return await provider.fetchQuota();
} catch (error) {
return buildResult({
providerId: provider.providerId,
providerName: provider.providerName,
ok: false,
configured: true,
error: error instanceof Error ? error.message : 'Request failed'
});
}
};
export const fetchQuotaForProvider = (providerId) => {
const normalizedProviderId = normalizeQuotaProviderId(providerId);
const existing = pendingFetches.get(normalizedProviderId);
if (existing) return existing;
const pending = fetchQuotaForProviderUncoalesced(normalizedProviderId).finally(() => {
if (pendingFetches.get(normalizedProviderId) === pending) pendingFetches.delete(normalizedProviderId);
});
pendingFetches.set(normalizedProviderId, pending);
return pending;
};
export const fetchClaudeQuota = claude.fetchQuota;
export const fetchOpenaiQuota = openai.fetchQuota;
export const fetchGoogleQuota = google.fetchGoogleQuota;
export const fetchCodexQuota = codex.fetchQuota;
export const fetchCursorQuota = cursor.fetchQuota;
export const fetchDeepseekQuota = deepseek.fetchQuota;
export const fetchCopilotQuota = copilot.fetchQuota;
export const fetchCopilotAddonQuota = copilot.fetchQuotaAddon;
export const fetchKimiQuota = kimi.fetchQuota;
export const fetchOpenRouterQuota = openrouter.fetchQuota;
export const fetchZaiQuota = zai.fetchQuota;
const fetchZhipuaiCodingPlanQuota = zhipuaiCodingPlan.fetchQuota;
export const fetchNanoGptQuota = nanogpt.fetchQuota;
export const fetchMinimaxCodingPlanQuota = minimaxCodingPlan.fetchQuota;
export const fetchMinimaxCnCodingPlanQuota = minimaxCnCodingPlan.fetchQuota;
export const fetchOllamaCloudQuota = ollamaCloud.fetchQuota;
export const fetchWaferQuota = wafer.fetchQuota;
export const fetchZhipuaiQuota = zhipuaiCodingPlan.fetchQuota;