mirror of
https://github.com/router-for-me/Cli-Proxy-API-Management-Center.git
synced 2026-02-19 11:10:49 +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_QUOTA_URL,
|
||||||
GEMINI_CLI_REQUEST_HEADERS,
|
GEMINI_CLI_REQUEST_HEADERS,
|
||||||
normalizeAuthIndexValue,
|
normalizeAuthIndexValue,
|
||||||
|
normalizeGeminiCliModelId,
|
||||||
normalizeNumberValue,
|
normalizeNumberValue,
|
||||||
normalizePlanType,
|
normalizePlanType,
|
||||||
normalizeQuotaFraction,
|
normalizeQuotaFraction,
|
||||||
@@ -368,7 +369,7 @@ const fetchGeminiCliQuota = async (
|
|||||||
|
|
||||||
const parsedBuckets = buckets
|
const parsedBuckets = buckets
|
||||||
.map((bucket) => {
|
.map((bucket) => {
|
||||||
const modelId = normalizeStringValue(bucket.modelId ?? bucket.model_id);
|
const modelId = normalizeGeminiCliModelId(bucket.modelId ?? bucket.model_id);
|
||||||
if (!modelId) return null;
|
if (!modelId) return null;
|
||||||
const tokenType = normalizeStringValue(bucket.tokenType ?? bucket.token_type);
|
const tokenType = normalizeStringValue(bucket.tokenType ?? bucket.token_type);
|
||||||
const remainingFractionRaw = normalizeQuotaFraction(
|
const remainingFractionRaw = normalizeQuotaFraction(
|
||||||
|
|||||||
@@ -10,7 +10,11 @@ import type {
|
|||||||
GeminiCliParsedBucket,
|
GeminiCliParsedBucket,
|
||||||
GeminiCliQuotaBucketState,
|
GeminiCliQuotaBucketState,
|
||||||
} from '@/types';
|
} 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 { normalizeQuotaFraction } from './parsers';
|
||||||
import { isIgnoredGeminiCliModel } from './validators';
|
import { isIgnoredGeminiCliModel } from './validators';
|
||||||
|
|
||||||
@@ -92,7 +96,23 @@ export function buildGeminiCliQuotaBuckets(
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return Array.from(grouped.values()).map((bucket) => {
|
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 uniqueModelIds = Array.from(new Set(bucket.modelIds));
|
||||||
const preferred = bucket.preferredBucket;
|
const preferred = bucket.preferredBucket;
|
||||||
const remainingFraction = preferred
|
const remainingFraction = preferred
|
||||||
|
|||||||
@@ -119,11 +119,17 @@ export const GEMINI_CLI_REQUEST_HEADERS = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const GEMINI_CLI_QUOTA_GROUPS: GeminiCliQuotaGroupDefinition[] = [
|
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',
|
id: 'gemini-flash-series',
|
||||||
label: 'Gemini Flash Series',
|
label: 'Gemini Flash Series',
|
||||||
preferredModelId: 'gemini-3-flash-preview',
|
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',
|
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(
|
export const GEMINI_CLI_GROUP_LOOKUP = new Map(
|
||||||
GEMINI_CLI_QUOTA_GROUPS.flatMap((group) =>
|
GEMINI_CLI_QUOTA_GROUPS.flatMap((group) =>
|
||||||
group.modelIds.map((modelId) => [modelId, group] as const)
|
group.modelIds.map((modelId) => [modelId, group] as const)
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
import type { CodexUsagePayload, GeminiCliQuotaPayload } from '@/types';
|
import type { CodexUsagePayload, GeminiCliQuotaPayload } from '@/types';
|
||||||
|
|
||||||
|
const GEMINI_CLI_MODEL_SUFFIX = '_vertex';
|
||||||
|
|
||||||
export function normalizeAuthIndexValue(value: unknown): string | null {
|
export function normalizeAuthIndexValue(value: unknown): string | null {
|
||||||
if (typeof value === 'number' && Number.isFinite(value)) {
|
if (typeof value === 'number' && Number.isFinite(value)) {
|
||||||
return value.toString();
|
return value.toString();
|
||||||
@@ -26,6 +28,15 @@ export function normalizeStringValue(value: unknown): string | null {
|
|||||||
return 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 {
|
export function normalizeNumberValue(value: unknown): number | null {
|
||||||
if (typeof value === 'number' && Number.isFinite(value)) return value;
|
if (typeof value === 'number' && Number.isFinite(value)) return value;
|
||||||
if (typeof value === 'string') {
|
if (typeof value === 'string') {
|
||||||
|
|||||||
Reference in New Issue
Block a user