feat: account management overhaul + 7 issue resolutions (#147)

- Add smart JSON export/import with schema validation and deduplication
- Add per-account proxy configurations (Issue #79)
- Add advanced account sorting engine (Issues #126 & #99)
- Add compact horizontal layout, AI credits, inline model visibility (Issues #145 & #134)
- Add desktop push notifications for low quota (Issue #53)
- Fix Arch Linux AUR process detection bug (Issue #117)
- Default theme set to Dark Mode (it's better)
- UI Polishing: Improved sort dropdown and symmetrical dialog layouts
- Dev Mode: Resolved port conflicts and single-instance locks
- Updated README and README.zh-CN with new features
This commit is contained in:
vd authored and GitHub committed 2026-04-06 20:32:42 +08:00
1 parent 50a325be11
commit ed0dd811a8
37 files changed
+1989 -455

No files matched your search

+15 -11
View File
@@ -70,11 +70,7 @@ const CLAUDE_TO_GEMINI: Record<string, string> = {
const DYNAMIC_IMAGE_BASE_MODEL = 'gemini-3-pro-image';
const DYNAMIC_IMAGE_RESOLUTIONS = ['', '-2k', '-4k'];
const DYNAMIC_IMAGE_RATIOS = ['', '-1x1', '-4x3', '-3x4', '-16x9', '-9x16', '-21x9'];
const EXTRA_DYNAMIC_MODELS = [
'gemini-3-flash',
'gemini-3.1-pro-high',
'gemini-3.1-pro-low',
];
const EXTRA_DYNAMIC_MODELS = ['gemini-3-flash', 'gemini-3.1-pro-high', 'gemini-3.1-pro-low'];
const DYNAMIC_MODEL_FORWARDING_RULES = new Map<string, string>();
@@ -95,13 +91,18 @@ export function getSupportedModels(): string[] {
}
export function updateDynamicForwardingRules(oldModel: string, newModel: string): void {
if (typeof oldModel !== 'string' || typeof newModel !== 'string') {
return;
}
const normalizedOld = oldModel.trim();
const normalizedNew = newModel.trim();
if (!normalizedOld || !normalizedNew) {
return;
}
if (!DYNAMIC_MODEL_FORWARDING_RULES.has(normalizedOld)) {
logger.info(`[Router] Registered dynamic forwarding rule: ${normalizedOld} -> ${normalizedNew}`);
logger.info(
`[Router] Registered dynamic forwarding rule: ${normalizedOld} -> ${normalizedNew}`,
);
}
DYNAMIC_MODEL_FORWARDING_RULES.set(normalizedOld, normalizedNew);
}
@@ -142,12 +143,13 @@ export function getAllDynamicModels(
}
}
return [...modelIds]
.filter((id) => !shouldHideDeprecatedModelFromList(id))
.sort();
return [...modelIds].filter((id) => !shouldHideDeprecatedModelFromList(id)).sort();
}
export function mapClaudeModelToGemini(input: string): string {
if (!input || typeof input !== 'string') {
return '';
}
const mappedModel = CLAUDE_TO_GEMINI[input];
if (mappedModel) {
return mappedModel;
@@ -172,8 +174,10 @@ export function resolveModelRoute(
anthropicMapping: Record<string, string>,
): string {
const dynamicForwarded = getDynamicForwardingTarget(originalModel);
if (dynamicForwarded) {
logger.info(`[Router] Dynamic deprecated-model forwarding: ${originalModel} -> ${dynamicForwarded}`);
if (dynamicForwarded && getSupportedModels().includes(dynamicForwarded)) {
logger.info(
`[Router] Dynamic deprecated-model forwarding: ${originalModel} -> ${dynamicForwarded}`,
);
return dynamicForwarded;
}