diff --git a/open-sse/config/providerRegistry.ts b/open-sse/config/providerRegistry.ts index c9cb25c0b3..4da9053666 100644 --- a/open-sse/config/providerRegistry.ts +++ b/open-sse/config/providerRegistry.ts @@ -192,22 +192,9 @@ export const REGISTRY: Record = { clientSecretEnv: "GEMINI_OAUTH_CLIENT_SECRET", clientSecretDefault: "", }, - models: [ - { id: "gemini-3.1-pro-high", name: "Gemini 3.1 Pro High" }, - { id: "gemini-3.1-pro-low", name: "Gemini 3.1 Pro Low" }, - { id: "gemini-3.1-pro", name: "Gemini 3.1 Pro" }, - { id: "gemini-3-1-pro", name: "Gemini 3.1 Pro (Alt ID)" }, - { id: "gemini-3.1-pro-preview", name: "Gemini 3.1 Pro Preview" }, - { id: "gemini-3.1-flash-lite-preview", name: "Gemini 3.1 Flash Lite Preview" }, - { id: "gemini-3-flash-preview", name: "Gemini 3 Flash Preview" }, - { id: "gemini-2.5-pro", name: "Gemini 2.5 Pro" }, - { id: "gemini-2.5-flash", name: "Gemini 2.5 Flash" }, - { id: "gemini-2.5-flash-lite", name: "Gemini 2.5 Flash Lite" }, - { id: "gemini-2.0-flash", name: "Gemini 2.0 Flash" }, - { id: "gemini-2.0-flash-exp", name: "Gemini 2.0 Flash Exp" }, - { id: "gemini-1.5-pro", name: "Gemini 1.5 Pro" }, - { id: "gemini-1.5-flash", name: "Gemini 1.5 Flash" }, - ], + models: [], + // Models are populated from Google's API via sync-models (per API key). + // No hardcoded fallback — show nothing until a key is added. }, "gemini-cli": { diff --git a/src/app/(dashboard)/dashboard/providers/[id]/page.tsx b/src/app/(dashboard)/dashboard/providers/[id]/page.tsx index d1ef2eb525..e6572d7c6a 100644 --- a/src/app/(dashboard)/dashboard/providers/[id]/page.tsx +++ b/src/app/(dashboard)/dashboard/providers/[id]/page.tsx @@ -1093,11 +1093,70 @@ export default function ProviderDetailPage() { body: JSON.stringify({ provider: providerId, ...formData }), }); if (res.ok) { + const connectionData = await res.json(); + const newConnection = connectionData?.connection; await fetchConnections(); setShowAddApiKeyModal(false); - // For Gemini: auto-sync is fire-and-forget, poll for model updates - if (providerId === "gemini") { - setTimeout(() => fetchProviderModelMeta(), 3000); + + // For Gemini: show progress dialog and sync models from endpoint + if (providerId === "gemini" && newConnection?.id) { + setShowImportModal(true); + setImportProgress({ + current: 0, + total: 0, + phase: "fetching", + status: t("fetchingModels"), + logs: [], + error: "", + importedCount: 0, + }); + + try { + const syncRes = await fetch(`/api/providers/${newConnection.id}/sync-models`, { + method: "POST", + }); + const syncData = await syncRes.json(); + + if (!syncRes.ok || syncData.error) { + setImportProgress((prev) => ({ + ...prev, + phase: "error", + status: t("failedFetchModels"), + error: syncData.error?.message || syncData.error || t("failedImportModels"), + })); + return null; + } + + const syncedCount = syncData.syncedModels || 0; + const syncedModelList: Array<{ id: string; name?: string }> = syncData.models || []; + const logs: string[] = []; + if (syncedModelList.length > 0) { + logs.push(`✓ ${syncedCount} models available`); + logs.push(""); + for (const m of syncedModelList) { + logs.push(` ${m.name || m.id}`); + } + } + + setImportProgress((prev) => ({ + ...prev, + phase: "done", + status: t("modelsImported", { count: syncedCount }), + total: syncedCount, + current: syncedCount, + importedCount: syncedCount, + logs, + })); + + await fetchProviderModelMeta(); + } catch (syncError) { + setImportProgress((prev) => ({ + ...prev, + phase: "error", + status: t("failedFetchModels"), + error: String(syncError), + })); + } } return null; } @@ -1968,7 +2027,7 @@ export default function ProviderDetailPage() { ); } - const importButton = ( + const importButton = providerId === "gemini" ? null : (
+
)} diff --git a/src/app/api/providers/route.ts b/src/app/api/providers/route.ts index 5b8fb981f3..35bfcdd376 100644 --- a/src/app/api/providers/route.ts +++ b/src/app/api/providers/route.ts @@ -15,7 +15,6 @@ import { getConsistentMachineId } from "@/shared/utils/machineId"; import { syncToCloud } from "@/lib/cloudSync"; import { createProviderSchema } from "@/shared/validation/schemas"; import { isValidationFailure, validateBody } from "@/shared/validation/helpers"; -import { buildModelSyncInternalHeaders } from "@/shared/services/modelSyncScheduler"; // GET /api/providers - List all connections export async function GET() { @@ -140,22 +139,7 @@ export async function POST(request: Request) { testStatus: testStatus || "unknown", }); - // Auto-trigger model sync for Gemini when API key is saved - if (provider === "gemini" && newConnection?.id) { - try { - const origin = new URL(request.url).origin; - fetch(`${origin}/api/providers/${newConnection.id}/sync-models`, { - method: "POST", - headers: { - ...buildModelSyncInternalHeaders(), - cookie: request.headers.get("cookie") || "", - }, - }).catch((e) => console.error("Auto-sync failed for gemini:", e)); - } catch (e) { - // Non-blocking — don't fail the connection save - console.error("Failed to trigger auto-sync for gemini:", e); - } - } + // Note: Gemini model sync is now triggered client-side with progress dialog // Hide sensitive fields const result: Record = { ...newConnection }; diff --git a/src/app/api/v1/models/catalog.ts b/src/app/api/v1/models/catalog.ts index 3eea6ea2c0..94ffabd93d 100644 --- a/src/app/api/v1/models/catalog.ts +++ b/src/app/api/v1/models/catalog.ts @@ -180,7 +180,7 @@ export async function getUnifiedModelsResponse( connections = connections.filter((c) => c.isActive !== false); } catch (e) { // If database not available, show no provider models (safe default) - console.log("Could not fetch providers, showing only combos/custom models"); + console.log("[catalog] Could not fetch providers:", e); } // Get provider nodes (for compatible providers with custom prefixes) @@ -255,30 +255,6 @@ export async function getUnifiedModelsResponse( const registryEntry = REGISTRY[alias] || REGISTRY[canonicalProviderId]; const defaultContextLength = registryEntry?.defaultContextLength; - // For Gemini: use synced API models exclusively (no hardcoded fallback) - if (alias === "gemini") { - try { - const syncedModels = await getSyncedAvailableModels("gemini"); - for (const sm of syncedModels) { - const aliasId = `gemini/${sm.id}`; - if (getModelIsHidden("gemini", sm.id)) continue; - models.push({ - id: aliasId, - object: "model", - created: timestamp, - owned_by: "gemini", - permission: [], - root: sm.id, - parent: null, - ...(sm.inputTokenLimit ? { context_length: sm.inputTokenLimit } : {}), - }); - } - } catch { - // No synced models — show nothing for Gemini - } - continue; // Always skip hardcoded models for Gemini - } - for (const model of providerModels) { const aliasId = `${alias}/${model.id}`; if (getModelIsHidden(canonicalProviderId, model.id)) continue; @@ -321,6 +297,63 @@ export async function getUnifiedModelsResponse( } } + // Gemini: synced API models exclusively (outside PROVIDER_MODELS loop since registry is empty) + if (activeAliases.has("gemini") && !blockedProviders.has("gemini")) { + try { + const syncedModels = await getSyncedAvailableModels("gemini"); + for (const sm of syncedModels) { + const aliasId = `gemini/${sm.id}`; + if (getModelIsHidden("gemini", sm.id)) continue; + + // Convert supportedEndpoints to type/subtype for endpoint categorization + const endpoints = Array.isArray(sm.supportedEndpoints) + ? sm.supportedEndpoints + : ["chat"]; + let modelType: string | undefined; + if (endpoints.includes("embeddings")) modelType = "embedding"; + else if (endpoints.includes("images")) modelType = "image"; + else if (endpoints.includes("audio")) modelType = "audio"; + + models.push({ + id: aliasId, + object: "model", + created: timestamp, + owned_by: "gemini", + permission: [], + root: sm.id, + parent: null, + ...(modelType ? { type: modelType } : {}), + ...(modelType === "audio" ? { subtype: "transcription" } : {}), + ...(sm.inputTokenLimit ? { context_length: sm.inputTokenLimit } : {}), + ...(endpoints.length > 1 || !endpoints.includes("chat") + ? { supported_endpoints: endpoints } + : {}), + }); + + // For audio models, also add a speech variant so they appear in both sections + if (modelType === "audio") { + models.push({ + id: aliasId, + object: "model", + created: timestamp, + owned_by: "gemini", + permission: [], + root: sm.id, + parent: null, + type: "audio", + subtype: "speech", + ...(sm.inputTokenLimit ? { context_length: sm.inputTokenLimit } : {}), + ...(endpoints.length > 1 || !endpoints.includes("chat") + ? { supported_endpoints: endpoints } + : {}), + }); + } + } + } catch { + // No synced models — show nothing for Gemini + } + } + // Helper: check if a provider is active (by provider id or alias) const isProviderActive = (provider: string) => { if (activeAliases.size === 0) return false; // No active connections = show nothing @@ -419,6 +452,8 @@ export async function getUnifiedModelsResponse( try { const customModelsMap = (await getAllCustomModels()) as Record; for (const [providerId, rawProviderCustomModels] of Object.entries(customModelsMap)) { + // Skip Gemini — handled by syncedAvailableModels above + if (providerId === "gemini") continue; const providerCustomModels = Array.isArray(rawProviderCustomModels) ? rawProviderCustomModels.filter( (model): model is Record => diff --git a/src/i18n/messages/ar.json b/src/i18n/messages/ar.json index e4446b6d00..254fbc83f4 100644 --- a/src/i18n/messages/ar.json +++ b/src/i18n/messages/ar.json @@ -1491,6 +1491,7 @@ "importFailed": "فشل الاستيراد", "noNewModelsAdded": "لم تتم إضافة نماذج جديدة.", "adding": "جارٍ الإضافة...", + "close": "Close", "importingModelsTitle": "استيراد النماذج", "copyModel": "نموذج النسخ", "removeModel": "إزالة النموذج", @@ -1651,6 +1652,7 @@ "autoSyncEnabled": "تم تمكين المزامنة التلقائية — سيتم تحديث النماذج بشكل دوري", "autoSyncDisabled": "تم تعطيل المزامنة التلقائية", "autoSyncToggleFailed": "فشل في تبديل المزامنة التلقائية", + "modelsImported": "{count} models imported", "allModelsAlreadyImported": "جميع النماذج مستوردة بالفعل", "noNewModelsToImport": "لا توجد نماذج جديدة للاستيراد — جميع النماذج موجودة بالفعل في السجل أو قائمة النماذج المخصصة", "skippingExistingModels": "تخطي {count} نماذج موجودة", diff --git a/src/i18n/messages/bg.json b/src/i18n/messages/bg.json index ccf43cdcae..d78b93e824 100644 --- a/src/i18n/messages/bg.json +++ b/src/i18n/messages/bg.json @@ -1491,6 +1491,7 @@ "importFailed": "Неуспешно импортиране", "noNewModelsAdded": "Няма добавени нови модели.", "adding": "Добавяне...", + "close": "Close", "importingModelsTitle": "Импортиране на модели", "copyModel": "Копиране на модел", "removeModel": "Премахване на модела", @@ -1651,6 +1652,7 @@ "autoSyncEnabled": "Автоматичното синхронизиране е активирано — моделите ще се опресняват периодично", "autoSyncDisabled": "Автоматичното синхронизиране е деактивирано", "autoSyncToggleFailed": "Неуспешно превключване на автоматичното синхронизиране", + "modelsImported": "{count} models imported", "allModelsAlreadyImported": "Всички модели вече са импортирани", "noNewModelsToImport": "Няма нови модели за импортиране — всички модели вече са в регистъра или списъка с персонализирани модели", "skippingExistingModels": "Пропускане на {count} съществуващи модела", diff --git a/src/i18n/messages/cs.json b/src/i18n/messages/cs.json index e5f414edf7..149df75799 100644 --- a/src/i18n/messages/cs.json +++ b/src/i18n/messages/cs.json @@ -1555,6 +1555,7 @@ "importFailed": "Import selhal", "noNewModelsAdded": "Nebyly přidány žádné nové modely.", "adding": "Přidávám...", + "close": "Close", "importingModelsTitle": "Import modelů", "copyModel": "Kopírovat model", "removeModel": "Odebrat model", @@ -1714,6 +1715,7 @@ "autoSyncEnabled": "Automatická synchronizace povolena – modely se budou pravidelně obnovovat", "autoSyncDisabled": "Automatická synchronizace zakázána", "autoSyncToggleFailed": "Nepodařilo se přepnout automatickou synchronizaci", + "modelsImported": "{count} models imported", "allModelsAlreadyImported": "Všechny modely jsou již importovány", "noNewModelsToImport": "Žádné nové modely k importu — všechny modely jsou již v registru nebo v seznamu vlastních modelů", "skippingExistingModels": "Přeskakování {count} existujících modelů", diff --git a/src/i18n/messages/da.json b/src/i18n/messages/da.json index 228f38be26..f3711ee8f3 100644 --- a/src/i18n/messages/da.json +++ b/src/i18n/messages/da.json @@ -1491,6 +1491,7 @@ "importFailed": "Import mislykkedes", "noNewModelsAdded": "Der blev ikke tilføjet nye modeller.", "adding": "Tilføjer...", + "close": "Close", "importingModelsTitle": "Import af modeller", "copyModel": "Kopi model", "removeModel": "Fjern modellen", @@ -1651,6 +1652,7 @@ "autoSyncEnabled": "Automatisk synkronisering aktiveret - modellerne opdateres med jævne mellemrum", "autoSyncDisabled": "Automatisk synkronisering deaktiveret", "autoSyncToggleFailed": "Automatisk synkronisering kunne ikke slås til eller fra", + "modelsImported": "{count} models imported", "allModelsAlreadyImported": "Alle modeller er allerede importeret", "noNewModelsToImport": "Ingen nye modeller at importere — alle modeller findes allerede i registreret eller brugerdefineret liste", "skippingExistingModels": "Springer {count} eksisterende modeller over", diff --git a/src/i18n/messages/de.json b/src/i18n/messages/de.json index 828599e834..9860f5bd6a 100644 --- a/src/i18n/messages/de.json +++ b/src/i18n/messages/de.json @@ -1491,6 +1491,7 @@ "importFailed": "Der Import ist fehlgeschlagen", "noNewModelsAdded": "Es wurden keine neuen Modelle hinzugefügt.", "adding": "Hinzufügen...", + "close": "Close", "importingModelsTitle": "Modelle importieren", "copyModel": "Modell kopieren", "removeModel": "Modell entfernen", @@ -1651,6 +1652,7 @@ "autoSyncEnabled": "Auto-Sync aktiviert — Modelle werden regelmäßig aktualisiert", "autoSyncDisabled": "Auto-Sync deaktiviert", "autoSyncToggleFailed": "Auto-Sync umschalten fehlgeschlagen", + "modelsImported": "{count} models imported", "allModelsAlreadyImported": "Alle Modelle sind bereits importiert", "noNewModelsToImport": "Keine neuen Modelle zum Importieren — alle Modelle sind bereits in der Registry oder der Liste benutzerdefinierter Modelle", "skippingExistingModels": "Überspringe {count} vorhandene Modelle", diff --git a/src/i18n/messages/en.json b/src/i18n/messages/en.json index 1e0ffaeaca..7a31b0b813 100644 --- a/src/i18n/messages/en.json +++ b/src/i18n/messages/en.json @@ -1542,6 +1542,7 @@ "chatCompletions": "Chat Completions", "importingModels": "Importing...", "importFromModels": "Import from /models", + "modelsImported": "{count} models imported", "allModelsAlreadyImported": "All models already imported", "noNewModelsToImport": "No new models to import — all models are already in the registry or custom models list", "skippingExistingModels": "Skipping {count} existing models", @@ -1563,6 +1564,7 @@ "importFailed": "Import failed", "noNewModelsAdded": "No new models were added.", "adding": "Adding...", + "close": "Close", "importingModelsTitle": "Importing Models", "copyModel": "Copy model", "removeModel": "Remove model", diff --git a/src/i18n/messages/es.json b/src/i18n/messages/es.json index 20a127b1e3..121c348475 100644 --- a/src/i18n/messages/es.json +++ b/src/i18n/messages/es.json @@ -1491,6 +1491,7 @@ "importFailed": "Importación fallida", "noNewModelsAdded": "No se agregaron nuevos modelos.", "adding": "Añadiendo...", + "close": "Close", "importingModelsTitle": "Importar modelos", "copyModel": "Copiar modelo", "removeModel": "Quitar modelo", @@ -1651,6 +1652,7 @@ "autoSyncEnabled": "Sincronización automática activada — los modelos se actualizarán periódicamente", "autoSyncDisabled": "Sincronización automática desactivada", "autoSyncToggleFailed": "Error al alternar sincronización automática", + "modelsImported": "{count} models imported", "allModelsAlreadyImported": "Todos los modelos ya están importados", "noNewModelsToImport": "No hay modelos nuevos para importar — todos los modelos ya están en el registro o en la lista de modelos personalizados", "skippingExistingModels": "Omitiendo {count} modelos existentes", diff --git a/src/i18n/messages/fi.json b/src/i18n/messages/fi.json index 120a4833c1..e2ac0fa621 100644 --- a/src/i18n/messages/fi.json +++ b/src/i18n/messages/fi.json @@ -1491,6 +1491,7 @@ "importFailed": "Tuonti epäonnistui", "noNewModelsAdded": "Uusia malleja ei lisätty.", "adding": "Lisätään...", + "close": "Close", "importingModelsTitle": "Mallien tuonti", "copyModel": "Kopioi malli", "removeModel": "Poista malli", @@ -1651,6 +1652,7 @@ "autoSyncEnabled": "Automaattinen synkronointi käytössä – mallit päivittyvät säännöllisesti", "autoSyncDisabled": "Automaattinen synkronointi poistettu käytöstä", "autoSyncToggleFailed": "Automaattisen synkronoinnin vaihtaminen epäonnistui", + "modelsImported": "{count} models imported", "allModelsAlreadyImported": "Kaikki mallit on jo tuotu", "noNewModelsToImport": "Ei uusia malleja tuotavaksi — kaikki mallit ovat jo rekisterissä tai mukautetulla mallilistalla", "skippingExistingModels": "Ohitetaan {count} olemassa olevaa mallia", diff --git a/src/i18n/messages/fr.json b/src/i18n/messages/fr.json index b0727d6c19..bceca6b69e 100644 --- a/src/i18n/messages/fr.json +++ b/src/i18n/messages/fr.json @@ -1491,6 +1491,7 @@ "importFailed": "Échec de l'importation", "noNewModelsAdded": "Aucun nouveau modèle n'a été ajouté.", "adding": "Ajout...", + "close": "Close", "importingModelsTitle": "Importation de modèles", "copyModel": "Copier le modèle", "removeModel": "Supprimer le modèle", @@ -1651,6 +1652,7 @@ "autoSyncEnabled": "Synchronisation automatique activée — les modèles seront actualisés périodiquement", "autoSyncDisabled": "Synchronisation automatique désactivée", "autoSyncToggleFailed": "Échec de l'activation de la synchronisation automatique", + "modelsImported": "{count} models imported", "allModelsAlreadyImported": "Tous les modèles sont déjà importés", "noNewModelsToImport": "Aucun nouveau modèle à importer — tous les modèles sont déjà dans le registre ou la liste de modèles personnalisés", "skippingExistingModels": "Ignorance de {count} modèles existants", diff --git a/src/i18n/messages/he.json b/src/i18n/messages/he.json index 538de98613..2c6f6379c0 100644 --- a/src/i18n/messages/he.json +++ b/src/i18n/messages/he.json @@ -1491,6 +1491,7 @@ "importFailed": "הייבוא נכשל", "noNewModelsAdded": "לא נוספו דגמים חדשים.", "adding": "מוסיף...", + "close": "Close", "importingModelsTitle": "ייבוא דגמים", "copyModel": "העתק דגם", "removeModel": "הסר את הדגם", @@ -1651,6 +1652,7 @@ "autoSyncEnabled": "סנכרון אוטומטי מופעל - הדגמים יתרעננו מעת לעת", "autoSyncDisabled": "הסנכרון האוטומטי מושבת", "autoSyncToggleFailed": "החלפת הסנכרון האוטומטי נכשלה", + "modelsImported": "{count} models imported", "allModelsAlreadyImported": "כל הדגמים כבר מיובאים", "noNewModelsToImport": "אין דגמים חדשים לייבוא — כל הדגמים כבר קיימים ברישום או ברשימת הדגמים המותאמים", "skippingExistingModels": "מדלג על {count} דגמים קיימים", diff --git a/src/i18n/messages/hi.json b/src/i18n/messages/hi.json index 88feadfed1..bd7acfda5e 100644 --- a/src/i18n/messages/hi.json +++ b/src/i18n/messages/hi.json @@ -1511,6 +1511,7 @@ "importFailed": "आयात विफल", "noNewModelsAdded": "कोई नया मॉडल नहीं जोड़ा गया.", "adding": "जोड़ा जा रहा है...", + "close": "Close", "importingModelsTitle": "मॉडल आयात करना", "copyModel": "मॉडल कॉपी करें", "removeModel": "मॉडल हटाएँ", @@ -1666,6 +1667,7 @@ "compatUpstreamHeadersHint": "High-privilege setting — same trust level as editing provider API credentials; only trusted admins should use it. Merged after OmniRoute adds auth from the provider API key. If a custom header uses the same name as an existing one (e.g. Authorization), your value fully replaces the auto-generated header (including the Bearer token) — the upstream only sees what you typed, not the key from settings. Misconfiguration can cause 401 or broken upstream auth. One row per header (e.g. extra Authentication for some gateways). Hover or focus the value to preview. Saves on blur, outside click, or closing this panel.", "compatUpstreamHeadersLabel": "Extra upstream headers", "compatUpstreamRemoveRow": "Remove row", + "modelsImported": "{count} models imported", "allModelsAlreadyImported": "सभी मॉडल पहले से ही आयातित हैं", "noNewModelsToImport": "आयात करने के लिए कोई नए मॉडल नहीं — सभी मॉडल पहले से ही रजिस्ट्री या कस्टम मॉडल सूची में हैं", "skippingExistingModels": "{count} मौजूदा मॉडल छोड़े जा रहे हैं", diff --git a/src/i18n/messages/hu.json b/src/i18n/messages/hu.json index f34e03caf2..64cdd88e34 100644 --- a/src/i18n/messages/hu.json +++ b/src/i18n/messages/hu.json @@ -1491,6 +1491,7 @@ "importFailed": "Az importálás sikertelen", "noNewModelsAdded": "Nem adtak hozzá új modelleket.", "adding": "Hozzáadás...", + "close": "Close", "importingModelsTitle": "Modellek importálása", "copyModel": "Modell másolása", "removeModel": "Modell eltávolítása", @@ -1651,6 +1652,7 @@ "autoSyncEnabled": "Automatikus szinkronizálás engedélyezve – a modellek rendszeresen frissülnek", "autoSyncDisabled": "Az automatikus szinkronizálás letiltva", "autoSyncToggleFailed": "Failed to toggle auto-sync", + "modelsImported": "{count} models imported", "allModelsAlreadyImported": "Minden modell már importálva van", "noNewModelsToImport": "Nincs új modell az importáláshoz — minden modell már a nyilvántartásban vagy az egyéni modellek listájában van", "skippingExistingModels": "{count} meglévő modell kihagyása", diff --git a/src/i18n/messages/id.json b/src/i18n/messages/id.json index 4966e4f5c5..25976280f4 100644 --- a/src/i18n/messages/id.json +++ b/src/i18n/messages/id.json @@ -1491,6 +1491,7 @@ "importFailed": "Impor gagal", "noNewModelsAdded": "Tidak ada model baru yang ditambahkan.", "adding": "Menambahkan...", + "close": "Close", "importingModelsTitle": "Mengimpor Model", "copyModel": "Salin modelnya", "removeModel": "Hapus modelnya", @@ -1651,6 +1652,7 @@ "autoSyncEnabled": "Sinkronisasi otomatis diaktifkan — model akan disegarkan secara berkala", "autoSyncDisabled": "Sinkronisasi otomatis dinonaktifkan", "autoSyncToggleFailed": "Gagal mengaktifkan sinkronisasi otomatis", + "modelsImported": "{count} models imported", "allModelsAlreadyImported": "Semua model sudah diimpor", "noNewModelsToImport": "Tidak ada model baru untuk diimpor — semua model sudah ada di registri atau daftar model kustom", "skippingExistingModels": "Melewatkan {count} model yang sudah ada", diff --git a/src/i18n/messages/in.json b/src/i18n/messages/in.json index 447c9bbcf2..b6a96f2c33 100644 --- a/src/i18n/messages/in.json +++ b/src/i18n/messages/in.json @@ -1560,6 +1560,7 @@ "importFailed": "आयात विफल", "noNewModelsAdded": "कोई नया मॉडल नहीं जोड़ा गया.", "adding": "जोड़ा जा रहा है...", + "close": "Close", "importingModelsTitle": "मॉडल आयात करना", "copyModel": "मॉडल कॉपी करें", "removeModel": "मॉडल हटाएँ", @@ -1714,6 +1715,7 @@ "modelsPathLabel": "मॉडल समापन बिंदु पथ", "modelsPathPlaceholder": "/मॉडल", "modelsPathHint": "सत्यापन के लिए कस्टम मॉडल पथ (जैसे /v4/मॉडल)", + "modelsImported": "{count} models imported", "allModelsAlreadyImported": "Semua model sudah diimpor", "noNewModelsToImport": "Tidak ada model baru untuk diimpor — semua model sudah ada di registri atau daftar model kustom", "skippingExistingModels": "Melewatkan {count} model yang sudah ada", diff --git a/src/i18n/messages/it.json b/src/i18n/messages/it.json index fc48d97d53..1a44014e4e 100644 --- a/src/i18n/messages/it.json +++ b/src/i18n/messages/it.json @@ -1491,6 +1491,7 @@ "importFailed": "Importazione non riuscita", "noNewModelsAdded": "Non sono stati aggiunti nuovi modelli.", "adding": "Aggiunta...", + "close": "Close", "importingModelsTitle": "Importazione di modelli", "copyModel": "Copia modello", "removeModel": "Rimuovi il modello", @@ -1651,6 +1652,7 @@ "autoSyncEnabled": "Sincronizzazione automatica abilitata — i modelli verranno aggiornati periodicamente", "autoSyncDisabled": "Sincronizzazione automatica disabilitata", "autoSyncToggleFailed": "Impossibile attivare la sincronizzazione automatica", + "modelsImported": "{count} models imported", "allModelsAlreadyImported": "Tutti i modelli sono già importati", "noNewModelsToImport": "Nessun nuovo modello da importare — tutti i modelli sono già nel registro o nell'elenco dei modelli personalizzati", "skippingExistingModels": "Salto {count} modelli esistenti", diff --git a/src/i18n/messages/ja.json b/src/i18n/messages/ja.json index 4d5a12c00f..1d9c2f289c 100644 --- a/src/i18n/messages/ja.json +++ b/src/i18n/messages/ja.json @@ -1491,6 +1491,7 @@ "importFailed": "インポートに失敗しました", "noNewModelsAdded": "新しいモデルは追加されませんでした。", "adding": "追加中...", + "close": "Close", "importingModelsTitle": "モデルのインポート", "copyModel": "モデルをコピーする", "removeModel": "モデルの削除", @@ -1651,6 +1652,7 @@ "autoSyncEnabled": "自動同期有効 — モデルは定期的に更新されます", "autoSyncDisabled": "自動同期無効", "autoSyncToggleFailed": "自動同期の切り替えに失敗", + "modelsImported": "{count} models imported", "allModelsAlreadyImported": "すべてのモデルは既にインポート済みです", "noNewModelsToImport": "インポートする新しいモデルはありません — すべてのモデルは既にレジストリまたはカスタムモデルリストにあります", "skippingExistingModels": "{count}件の既存モデルをスキップ", diff --git a/src/i18n/messages/ko.json b/src/i18n/messages/ko.json index 0c5d6bec62..0928ada01c 100644 --- a/src/i18n/messages/ko.json +++ b/src/i18n/messages/ko.json @@ -1491,6 +1491,7 @@ "importFailed": "가져오기 실패", "noNewModelsAdded": "새로운 모델이 추가되지 않았습니다.", "adding": "추가 중...", + "close": "Close", "importingModelsTitle": "모델 가져오기", "copyModel": "모델 복사", "removeModel": "모델 삭제", @@ -1651,6 +1652,7 @@ "autoSyncEnabled": "자동 동기화 활성화 — 모델이 주기적으로 업데이트됩니다", "autoSyncDisabled": "자동 동기화 비활성화", "autoSyncToggleFailed": "자동 동기화 전환 실패", + "modelsImported": "{count} models imported", "allModelsAlreadyImported": "모든 모델이 이미 가져왔습니다", "noNewModelsToImport": "가져올 새 모델 없음 — 모든 모델이 이미 레지스트리 또는 사용자 정의 모델 목록에 있습니다", "skippingExistingModels": "{count}개의 기존 모델 건너뛰기", diff --git a/src/i18n/messages/ms.json b/src/i18n/messages/ms.json index 1844d05296..6072823853 100644 --- a/src/i18n/messages/ms.json +++ b/src/i18n/messages/ms.json @@ -1491,6 +1491,7 @@ "importFailed": "Import gagal", "noNewModelsAdded": "Tiada model baharu ditambahkan.", "adding": "Menambah...", + "close": "Close", "importingModelsTitle": "Mengimport Model", "copyModel": "Salin model", "removeModel": "Alih keluar model", @@ -1651,6 +1652,7 @@ "autoSyncEnabled": "Autosegerak didayakan — model akan dimuat semula secara berkala", "autoSyncDisabled": "Autosegerak dilumpuhkan", "autoSyncToggleFailed": "Gagal untuk menogol autosegerak", + "modelsImported": "{count} models imported", "allModelsAlreadyImported": "Semua model sudah diimport", "noNewModelsToImport": "Tiada model baru untuk diimport — semua model sudah ada dalam registri atau senarai model tersuai", "skippingExistingModels": "Melangkau {count} model sedia ada", diff --git a/src/i18n/messages/nl.json b/src/i18n/messages/nl.json index 22fff30409..c3d27fe132 100644 --- a/src/i18n/messages/nl.json +++ b/src/i18n/messages/nl.json @@ -1491,6 +1491,7 @@ "importFailed": "Importeren is mislukt", "noNewModelsAdded": "Er zijn geen nieuwe modellen toegevoegd.", "adding": "Toevoegen...", + "close": "Close", "importingModelsTitle": "Modellen importeren", "copyModel": "Kopieermodel", "removeModel": "Model verwijderen", @@ -1651,6 +1652,7 @@ "autoSyncEnabled": "Automatische synchronisatie ingeschakeld: modellen worden periodiek vernieuwd", "autoSyncDisabled": "Automatische synchronisatie uitgeschakeld", "autoSyncToggleFailed": "Kan automatische synchronisatie niet in- of uitschakelen", + "modelsImported": "{count} models imported", "allModelsAlreadyImported": "Alle modellen zijn al geïmporteerd", "noNewModelsToImport": "Geen nieuwe modellen om te importeren — alle modellen staan al in het register of de lijst met aangepaste modellen", "skippingExistingModels": "{count} bestaande modellen overgeslagen", diff --git a/src/i18n/messages/no.json b/src/i18n/messages/no.json index bd047acf99..5368ff75f5 100644 --- a/src/i18n/messages/no.json +++ b/src/i18n/messages/no.json @@ -1491,6 +1491,7 @@ "importFailed": "Import mislyktes", "noNewModelsAdded": "Ingen nye modeller ble lagt til.", "adding": "Legger til...", + "close": "Close", "importingModelsTitle": "Importere modeller", "copyModel": "Kopier modell", "removeModel": "Fjern modellen", @@ -1651,6 +1652,7 @@ "autoSyncEnabled": "Automatisk synkronisering aktivert – modellene oppdateres med jevne mellomrom", "autoSyncDisabled": "Automatisk synkronisering er deaktivert", "autoSyncToggleFailed": "Kunne ikke slå på automatisk synkronisering", + "modelsImported": "{count} models imported", "allModelsAlreadyImported": "Alle modeller er allerede importert", "noNewModelsToImport": "Ingen nye modeller å importere — alle modeller finnes allerede i registeret eller listen over egendefinerte modeller", "skippingExistingModels": "Hopper over {count} eksisterende modeller", diff --git a/src/i18n/messages/phi.json b/src/i18n/messages/phi.json index d4b4641534..812f9e70a5 100644 --- a/src/i18n/messages/phi.json +++ b/src/i18n/messages/phi.json @@ -1491,6 +1491,7 @@ "importFailed": "Nabigo ang pag-import", "noNewModelsAdded": "Walang naidagdag na mga bagong modelo.", "adding": "Idinaragdag...", + "close": "Close", "importingModelsTitle": "Pag-import ng mga Modelo", "copyModel": "Kopyahin ang modelo", "removeModel": "Alisin ang modelo", @@ -1651,6 +1652,7 @@ "autoSyncEnabled": "Pinagana ang auto-sync — pana-panahong magre-refresh ang mga modelo", "autoSyncDisabled": "Na-disable ang auto-sync", "autoSyncToggleFailed": "Nabigong i-toggle ang auto-sync", + "modelsImported": "{count} models imported", "allModelsAlreadyImported": "Lahat ng mga modelo ay nai-import na", "noNewModelsToImport": "Walang bagong modelo na i-import — lahat ng mga modelo ay nasa registry o custom na listahan na", "skippingExistingModels": "Pinapalampas ang {count} na umiiral na mga modelo", diff --git a/src/i18n/messages/pl.json b/src/i18n/messages/pl.json index 1d751ef00f..859e0b2e81 100644 --- a/src/i18n/messages/pl.json +++ b/src/i18n/messages/pl.json @@ -1491,6 +1491,7 @@ "importFailed": "Import nie powiódł się", "noNewModelsAdded": "Nie dodano żadnych nowych modeli.", "adding": "Dodawanie...", + "close": "Close", "importingModelsTitle": "Importowanie modeli", "copyModel": "Skopiuj model", "removeModel": "Usuń model", @@ -1651,6 +1652,7 @@ "autoSyncEnabled": "Automatyczna synchronizacja włączona — modele będą okresowo odświeżane", "autoSyncDisabled": "Automatyczna synchronizacja wyłączona", "autoSyncToggleFailed": "Nie udało się przełączyć automatycznej synchronizacji", + "modelsImported": "{count} models imported", "allModelsAlreadyImported": "Wszystkie modele są już zaimportowane", "noNewModelsToImport": "Brak nowych modeli do zaimportowania — wszystkie modele są już w rejestrze lub na liście modeli niestandardowych", "skippingExistingModels": "Pomijanie {count} istniejących modeli", diff --git a/src/i18n/messages/pt-BR.json b/src/i18n/messages/pt-BR.json index 78cf44e469..581952c3e9 100644 --- a/src/i18n/messages/pt-BR.json +++ b/src/i18n/messages/pt-BR.json @@ -1491,6 +1491,7 @@ "importFailed": "Falha na importação", "noNewModelsAdded": "Nenhum novo modelo foi adicionado.", "adding": "Adicionando...", + "close": "Close", "importingModelsTitle": "Importando Modelos", "copyModel": "Copiar modelo", "removeModel": "Remover modelo", @@ -1657,6 +1658,7 @@ "autoSyncEnabled": "Sincronização automática habilitada – os modelos serão atualizados periodicamente", "autoSyncDisabled": "Sincronização automática desativada", "autoSyncToggleFailed": "Falha ao alternar a sincronização automática", + "modelsImported": "{count} models imported", "allModelsAlreadyImported": "Todos os modelos já foram importados", "noNewModelsToImport": "Nenhum modelo novo para importar — todos os modelos já estão no registro ou na lista de modelos personalizados", "skippingExistingModels": "Ignorando {count} modelos existentes" diff --git a/src/i18n/messages/pt.json b/src/i18n/messages/pt.json index 5ba62dcc42..8015b8e0d8 100644 --- a/src/i18n/messages/pt.json +++ b/src/i18n/messages/pt.json @@ -1503,6 +1503,7 @@ "importFailed": "Falha na importação", "noNewModelsAdded": "Nenhum novo modelo foi adicionado.", "adding": "Adicionando...", + "close": "Close", "importingModelsTitle": "Importando Modelos", "copyModel": "Copiar modelo", "removeModel": "Remover modelo", @@ -1663,6 +1664,7 @@ "autoSyncEnabled": "Sincronização automática ativada — modelos serão atualizados periodicamente", "autoSyncDisabled": "Sincronização automática desativada", "autoSyncToggleFailed": "Falha ao alternar sincronização automática", + "modelsImported": "{count} models imported", "allModelsAlreadyImported": "Todos os modelos já foram importados", "noNewModelsToImport": "Nenhum modelo novo para importar — todos os modelos já estão no registo ou na lista de modelos personalizados", "skippingExistingModels": "A ignorar {count} modelos existentes", diff --git a/src/i18n/messages/ro.json b/src/i18n/messages/ro.json index 26e797cfc7..4de0c51268 100644 --- a/src/i18n/messages/ro.json +++ b/src/i18n/messages/ro.json @@ -1491,6 +1491,7 @@ "importFailed": "Importul nu a reușit", "noNewModelsAdded": "Nu au fost adăugate modele noi.", "adding": "Se adaugă...", + "close": "Close", "importingModelsTitle": "Importul modelelor", "copyModel": "Copiați modelul", "removeModel": "Eliminați modelul", @@ -1651,6 +1652,7 @@ "autoSyncEnabled": "Sincronizare automată activată — modelele se vor reîmprospăta periodic", "autoSyncDisabled": "Sincronizarea automată a fost dezactivată", "autoSyncToggleFailed": "Nu s-a putut comuta sincronizarea automată", + "modelsImported": "{count} models imported", "allModelsAlreadyImported": "Toate modelele sunt deja importate", "noNewModelsToImport": "Niciun model nou de importat — toate modelele sunt deja în registru sau în lista de modele personalizate", "skippingExistingModels": "Se omit {count} modele existente", diff --git a/src/i18n/messages/ru.json b/src/i18n/messages/ru.json index 2def40a11a..982835f761 100644 --- a/src/i18n/messages/ru.json +++ b/src/i18n/messages/ru.json @@ -1491,6 +1491,7 @@ "importFailed": "Импорт не удался", "noNewModelsAdded": "Новых моделей не добавлялось.", "adding": "Добавление...", + "close": "Close", "importingModelsTitle": "Импорт моделей", "copyModel": "Копировать модель", "removeModel": "Удалить модель", @@ -1651,6 +1652,7 @@ "autoSyncEnabled": "Автосинхронизация включена — модели будут периодически обновляться", "autoSyncDisabled": "Автосинхронизация отключена", "autoSyncToggleFailed": "Не удалось переключить автосинхронизацию", + "modelsImported": "{count} models imported", "allModelsAlreadyImported": "Все модели уже импортированы", "noNewModelsToImport": "Нет новых моделей для импорта — все модели уже есть в реестре или списке пользовательских моделей", "skippingExistingModels": "Пропуск {count} существующих моделей", diff --git a/src/i18n/messages/sk.json b/src/i18n/messages/sk.json index 188c6f4937..ead9dde3f0 100644 --- a/src/i18n/messages/sk.json +++ b/src/i18n/messages/sk.json @@ -1491,6 +1491,7 @@ "importFailed": "Import zlyhal", "noNewModelsAdded": "Neboli pridané žiadne nové modely.", "adding": "Pridáva sa...", + "close": "Close", "importingModelsTitle": "Importovanie modelov", "copyModel": "Kopírovať model", "removeModel": "Odstráňte model", @@ -1651,6 +1652,7 @@ "autoSyncEnabled": "Automatická synchronizácia povolená – modely sa budú pravidelne obnovovať", "autoSyncDisabled": "Automatická synchronizácia je zakázaná", "autoSyncToggleFailed": "Nepodarilo sa prepnúť automatickú synchronizáciu", + "modelsImported": "{count} models imported", "allModelsAlreadyImported": "Všetky modely sú už importované", "noNewModelsToImport": "Žiadne nové modely na import — všetky modely sú už v registri alebo v zozname vlastných modelov", "skippingExistingModels": "Preskakujem {count} existujúcich modelov", diff --git a/src/i18n/messages/sv.json b/src/i18n/messages/sv.json index fa7bb8a8f2..8bbd0ee012 100644 --- a/src/i18n/messages/sv.json +++ b/src/i18n/messages/sv.json @@ -1491,6 +1491,7 @@ "importFailed": "Importen misslyckades", "noNewModelsAdded": "Inga nya modeller tillkom.", "adding": "Lägger till...", + "close": "Close", "importingModelsTitle": "Importera modeller", "copyModel": "Kopiera modell", "removeModel": "Ta bort modellen", @@ -1651,6 +1652,7 @@ "autoSyncEnabled": "Automatisk synkronisering aktiverad — modeller uppdateras regelbundet", "autoSyncDisabled": "Automatisk synkronisering inaktiverad", "autoSyncToggleFailed": "Det gick inte att växla automatisk synkronisering", + "modelsImported": "{count} models imported", "allModelsAlreadyImported": "Alla modeller är redan importerade", "noNewModelsToImport": "Inga nya modeller att importera — alla modeller finns redan i registret eller listan över anpassade modeller", "skippingExistingModels": "Hoppar över {count} befintliga modeller", diff --git a/src/i18n/messages/th.json b/src/i18n/messages/th.json index 0827249b89..ab8b586662 100644 --- a/src/i18n/messages/th.json +++ b/src/i18n/messages/th.json @@ -1491,6 +1491,7 @@ "importFailed": "การนำเข้าล้มเหลว", "noNewModelsAdded": "ไม่มีการเพิ่มโมเดลใหม่", "adding": "กำลังเพิ่ม...", + "close": "Close", "importingModelsTitle": "การนำเข้าโมเดล", "copyModel": "คัดลอกโมเดล", "removeModel": "ลบโมเดล", @@ -1651,6 +1652,7 @@ "autoSyncEnabled": "เปิดใช้งานการซิงค์อัตโนมัติ — โมเดลจะรีเฟรชเป็นระยะ", "autoSyncDisabled": "ปิดใช้งานการซิงค์อัตโนมัติแล้ว", "autoSyncToggleFailed": "ไม่สามารถสลับการซิงค์อัตโนมัติ", + "modelsImported": "{count} models imported", "allModelsAlreadyImported": "นำเข้าโมเดลทั้งหมดแล้ว", "noNewModelsToImport": "ไม่มีโมเดลใหม่ที่จะนำเข้า — โมเดลทั้งหมดมีอยู่แล้วในรีจิสทรีหรือรายการโมเดลที่กำหนดเอง", "skippingExistingModels": "ข้าม {count} โมเดลที่มีอยู่", diff --git a/src/i18n/messages/tr.json b/src/i18n/messages/tr.json index 751f9ab31a..2bd2409f38 100644 --- a/src/i18n/messages/tr.json +++ b/src/i18n/messages/tr.json @@ -1560,6 +1560,7 @@ "importFailed": "İçe aktarma başarısız oldu", "noNewModelsAdded": "Yeni model eklenmedi.", "adding": "Ekleniyor...", + "close": "Close", "importingModelsTitle": "Modelleri İçe Aktarma", "copyModel": "Modeli kopyala", "removeModel": "Modeli kaldır", @@ -1714,6 +1715,7 @@ "modelsPathLabel": "Model Uç Noktası Yolu", "modelsPathPlaceholder": "/models", "modelsPathHint": "Doğrulama için özel model yolu (ör. /v4/models)", + "modelsImported": "{count} models imported", "allModelsAlreadyImported": "Tüm modeller zaten içe aktarıldı", "noNewModelsToImport": "İçe aktarılacak yeni model yok — tüm modeller zaten kayıt defterinde veya özel modeller listesinde", "skippingExistingModels": "{count} mevcut model atlanıyor", diff --git a/src/i18n/messages/uk-UA.json b/src/i18n/messages/uk-UA.json index 040ba715ef..3db9da3dd5 100644 --- a/src/i18n/messages/uk-UA.json +++ b/src/i18n/messages/uk-UA.json @@ -1491,6 +1491,7 @@ "importFailed": "Помилка імпорту", "noNewModelsAdded": "Нові моделі не додано.", "adding": "Додавання...", + "close": "Close", "importingModelsTitle": "Імпорт моделей", "copyModel": "Копія моделі", "removeModel": "Зняти модель", @@ -1651,6 +1652,7 @@ "autoSyncEnabled": "Автоматична синхронізація ввімкнена — моделі періодично оновлюватимуться", "autoSyncDisabled": "Автоматична синхронізація вимкнена", "autoSyncToggleFailed": "Не вдалося вимкнути автоматичну синхронізацію", + "modelsImported": "{count} models imported", "allModelsAlreadyImported": "Усі моделі вже імпортовано", "noNewModelsToImport": "Немає нових моделей для імпорту — усі моделі вже є в реєстрі або списку користувацьких моделей", "skippingExistingModels": "Пропуск {count} наявних моделей", diff --git a/src/i18n/messages/vi.json b/src/i18n/messages/vi.json index d31764e0f0..dd35dfc50c 100644 --- a/src/i18n/messages/vi.json +++ b/src/i18n/messages/vi.json @@ -1491,6 +1491,7 @@ "importFailed": "Nhập không thành công", "noNewModelsAdded": "Không có mô hình mới được thêm vào.", "adding": "Đang thêm...", + "close": "Close", "importingModelsTitle": "Nhập mô hình", "copyModel": "Sao chép mô hình", "removeModel": "Xóa mô hình", @@ -1651,6 +1652,7 @@ "autoSyncEnabled": "Đã bật tự động đồng bộ hóa - các mô hình sẽ làm mới định kỳ", "autoSyncDisabled": "Tự động đồng bộ hóa đã bị tắt", "autoSyncToggleFailed": "Không chuyển đổi được tính năng tự động đồng bộ hóa", + "modelsImported": "{count} models imported", "allModelsAlreadyImported": "Tất cả mô hình đã được nhập", "noNewModelsToImport": "Không có mô hình mới để nhập — tất cả mô hình đã có trong danh mục hoặc danh sách mô hình tùy chỉnh", "skippingExistingModels": "Bỏ qua {count} mô hình hiện có", diff --git a/src/i18n/messages/zh-CN.json b/src/i18n/messages/zh-CN.json index d1ee3a6dc5..f96cfab8c7 100644 --- a/src/i18n/messages/zh-CN.json +++ b/src/i18n/messages/zh-CN.json @@ -1560,6 +1560,7 @@ "importFailed": "导入失败", "noNewModelsAdded": "没有添加新模型。", "adding": "添加...", + "close": "Close", "importingModelsTitle": "导入模型", "copyModel": "复制模型", "removeModel": "删除模型", @@ -1714,6 +1715,7 @@ "modelsPathLabel": "模型端点路径", "modelsPathPlaceholder": "/models", "modelsPathHint": "为验证流程自定义模型路径(例如:/v4/models)", + "modelsImported": "{count} models imported", "allModelsAlreadyImported": "所有模型已导入", "noNewModelsToImport": "没有新模型可导入 — 所有模型已在注册表或自定义模型列表中", "skippingExistingModels": "跳过 {count} 个已有模型",