mirror of
https://github.com/router-for-me/Cli-Proxy-API-Management-Center.git
synced 2026-02-18 02:30:51 +08:00
feat(quota): add normalization for Gemini CLI model IDs and update quota groups
This commit is contained in:
@@ -28,6 +28,7 @@ import {
|
||||
GEMINI_CLI_QUOTA_URL,
|
||||
GEMINI_CLI_REQUEST_HEADERS,
|
||||
normalizeAuthIndexValue,
|
||||
normalizeGeminiCliModelId,
|
||||
normalizeNumberValue,
|
||||
normalizePlanType,
|
||||
normalizeQuotaFraction,
|
||||
@@ -368,7 +369,7 @@ const fetchGeminiCliQuota = async (
|
||||
|
||||
const parsedBuckets = buckets
|
||||
.map((bucket) => {
|
||||
const modelId = normalizeStringValue(bucket.modelId ?? bucket.model_id);
|
||||
const modelId = normalizeGeminiCliModelId(bucket.modelId ?? bucket.model_id);
|
||||
if (!modelId) return null;
|
||||
const tokenType = normalizeStringValue(bucket.tokenType ?? bucket.token_type);
|
||||
const remainingFractionRaw = normalizeQuotaFraction(
|
||||
|
||||
@@ -10,7 +10,11 @@ import type {
|
||||
GeminiCliParsedBucket,
|
||||
GeminiCliQuotaBucketState,
|
||||
} from '@/types';
|
||||
import { ANTIGRAVITY_QUOTA_GROUPS, GEMINI_CLI_GROUP_LOOKUP } from './constants';
|
||||
import {
|
||||
ANTIGRAVITY_QUOTA_GROUPS,
|
||||
GEMINI_CLI_GROUP_LOOKUP,
|
||||
GEMINI_CLI_GROUP_ORDER,
|
||||
} from './constants';
|
||||
import { normalizeQuotaFraction } from './parsers';
|
||||
import { isIgnoredGeminiCliModel } from './validators';
|
||||
|
||||
@@ -92,24 +96,40 @@ export function buildGeminiCliQuotaBuckets(
|
||||
}
|
||||
});
|
||||
|
||||
return Array.from(grouped.values()).map((bucket) => {
|
||||
const uniqueModelIds = Array.from(new Set(bucket.modelIds));
|
||||
const preferred = bucket.preferredBucket;
|
||||
const remainingFraction = preferred
|
||||
? preferred.remainingFraction
|
||||
: bucket.fallbackRemainingFraction;
|
||||
const remainingAmount = preferred ? preferred.remainingAmount : bucket.fallbackRemainingAmount;
|
||||
const resetTime = preferred ? preferred.resetTime : bucket.fallbackResetTime;
|
||||
return {
|
||||
id: bucket.id,
|
||||
label: bucket.label,
|
||||
remainingFraction,
|
||||
remainingAmount,
|
||||
resetTime,
|
||||
tokenType: bucket.tokenType,
|
||||
modelIds: uniqueModelIds,
|
||||
};
|
||||
});
|
||||
const toGroupOrder = (bucket: GeminiCliQuotaBucketGroup): number => {
|
||||
const tokenSuffix = bucket.tokenType ? `-${bucket.tokenType}` : '';
|
||||
const groupId = bucket.id.endsWith(tokenSuffix)
|
||||
? bucket.id.slice(0, bucket.id.length - tokenSuffix.length)
|
||||
: bucket.id;
|
||||
return GEMINI_CLI_GROUP_ORDER.get(groupId) ?? Number.MAX_SAFE_INTEGER;
|
||||
};
|
||||
|
||||
return Array.from(grouped.values())
|
||||
.sort((a, b) => {
|
||||
const orderDiff = toGroupOrder(a) - toGroupOrder(b);
|
||||
if (orderDiff !== 0) return orderDiff;
|
||||
const tokenTypeA = a.tokenType ?? '';
|
||||
const tokenTypeB = b.tokenType ?? '';
|
||||
return tokenTypeA.localeCompare(tokenTypeB);
|
||||
})
|
||||
.map((bucket) => {
|
||||
const uniqueModelIds = Array.from(new Set(bucket.modelIds));
|
||||
const preferred = bucket.preferredBucket;
|
||||
const remainingFraction = preferred
|
||||
? preferred.remainingFraction
|
||||
: bucket.fallbackRemainingFraction;
|
||||
const remainingAmount = preferred ? preferred.remainingAmount : bucket.fallbackRemainingAmount;
|
||||
const resetTime = preferred ? preferred.resetTime : bucket.fallbackResetTime;
|
||||
return {
|
||||
id: bucket.id,
|
||||
label: bucket.label,
|
||||
remainingFraction,
|
||||
remainingAmount,
|
||||
resetTime,
|
||||
tokenType: bucket.tokenType,
|
||||
modelIds: uniqueModelIds,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
export function getAntigravityQuotaInfo(entry?: AntigravityQuotaInfo): {
|
||||
|
||||
@@ -119,11 +119,17 @@ export const GEMINI_CLI_REQUEST_HEADERS = {
|
||||
};
|
||||
|
||||
export const GEMINI_CLI_QUOTA_GROUPS: GeminiCliQuotaGroupDefinition[] = [
|
||||
{
|
||||
id: 'gemini-flash-lite-series',
|
||||
label: 'Gemini Flash Lite Series',
|
||||
preferredModelId: 'gemini-2.5-flash-lite',
|
||||
modelIds: ['gemini-2.5-flash-lite'],
|
||||
},
|
||||
{
|
||||
id: 'gemini-flash-series',
|
||||
label: 'Gemini Flash Series',
|
||||
preferredModelId: 'gemini-3-flash-preview',
|
||||
modelIds: ['gemini-3-flash-preview', 'gemini-2.5-flash', 'gemini-2.5-flash-lite'],
|
||||
modelIds: ['gemini-3-flash-preview', 'gemini-2.5-flash'],
|
||||
},
|
||||
{
|
||||
id: 'gemini-pro-series',
|
||||
@@ -133,6 +139,10 @@ export const GEMINI_CLI_QUOTA_GROUPS: GeminiCliQuotaGroupDefinition[] = [
|
||||
},
|
||||
];
|
||||
|
||||
export const GEMINI_CLI_GROUP_ORDER = new Map(
|
||||
GEMINI_CLI_QUOTA_GROUPS.map((group, index) => [group.id, index] as const)
|
||||
);
|
||||
|
||||
export const GEMINI_CLI_GROUP_LOOKUP = new Map(
|
||||
GEMINI_CLI_QUOTA_GROUPS.flatMap((group) =>
|
||||
group.modelIds.map((modelId) => [modelId, group] as const)
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
import type { CodexUsagePayload, GeminiCliQuotaPayload } from '@/types';
|
||||
|
||||
const GEMINI_CLI_MODEL_SUFFIX = '_vertex';
|
||||
|
||||
export function normalizeAuthIndexValue(value: unknown): string | null {
|
||||
if (typeof value === 'number' && Number.isFinite(value)) {
|
||||
return value.toString();
|
||||
@@ -26,6 +28,15 @@ export function normalizeStringValue(value: unknown): string | null {
|
||||
return null;
|
||||
}
|
||||
|
||||
export function normalizeGeminiCliModelId(value: unknown): string | null {
|
||||
const modelId = normalizeStringValue(value);
|
||||
if (!modelId) return null;
|
||||
if (modelId.endsWith(GEMINI_CLI_MODEL_SUFFIX)) {
|
||||
return modelId.slice(0, -GEMINI_CLI_MODEL_SUFFIX.length);
|
||||
}
|
||||
return modelId;
|
||||
}
|
||||
|
||||
export function normalizeNumberValue(value: unknown): number | null {
|
||||
if (typeof value === 'number' && Number.isFinite(value)) return value;
|
||||
if (typeof value === 'string') {
|
||||
|
||||
Reference in New Issue
Block a user