mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-07 15:52:52 +03:00
fix(i18n): add Chinese i18n support to Loading.tsx
Replace hardcoded English strings "Loading" and "Loading..." with useTranslation hook using common.loading key (already existed in en.json and zh-CN.json). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -914,26 +914,6 @@
|
||||
"when": "Use when long sessions must survive account rotation without losing the working context.",
|
||||
"avoid": "Avoid when account switching is rare or when you do not want extra summarization requests.",
|
||||
"example": "Example: Codex sessions that rotate across multiple accounts near quota exhaustion."
|
||||
},
|
||||
"fill-first": {
|
||||
"when": "Use when you want to fully exhaust one provider's quota before moving to the next.",
|
||||
"avoid": "Avoid when you need request-level load balancing between providers.",
|
||||
"example": "Example: Use up all $200 of Deepgram credits before falling back to Groq."
|
||||
},
|
||||
"auto": {
|
||||
"when": "Use when you have one preferred model and only want fallback on failure.",
|
||||
"avoid": "Avoid when you need balanced load between models.",
|
||||
"example": "Example: Primary coding model with cheaper backup for outages."
|
||||
},
|
||||
"lkgp": {
|
||||
"when": "Use when you have one preferred model and only want fallback on failure.",
|
||||
"avoid": "Avoid when you need balanced load between models.",
|
||||
"example": "Example: Primary coding model with cheaper backup for outages."
|
||||
},
|
||||
"context-optimized": {
|
||||
"when": "Use when you have one preferred model and only want fallback on failure.",
|
||||
"avoid": "Avoid when you need balanced load between models.",
|
||||
"example": "Example: Primary coding model with cheaper backup for outages."
|
||||
}
|
||||
},
|
||||
"advancedHelp": {
|
||||
@@ -1013,25 +993,6 @@
|
||||
"candidatePoolHint": "Select which providers this engine should evaluate. Leave empty to use all active providers.",
|
||||
"candidatePoolEmpty": "No active providers available yet.",
|
||||
"candidatePoolAllProviders": "All providers",
|
||||
"builderStagesDescription": "Move through the stages in order to define the combo, build the steps, choose the routing strategy and review the result.",
|
||||
"builderStepsDescription": "Build each combo step in sequence: provider, model, then account. This allows repeating the same provider and model with different accounts.",
|
||||
"selectProvider": "Select Provider",
|
||||
"selectProviderPlaceholder": "Select provider",
|
||||
"selectModel": "Select Model",
|
||||
"selectModelPlaceholder": "Select provider first",
|
||||
"selectAccount": "Select Account",
|
||||
"autoSelectAccount": "Auto-select account at runtime",
|
||||
"previewNextStep": "Choose provider and model to preview the next step.",
|
||||
"addStep": "Add Step",
|
||||
"comboReference": "Combo Reference",
|
||||
"selectComboToReference": "Select an existing combo to reference",
|
||||
"addComboReference": "Add Combo Reference",
|
||||
"browseLegacyCatalog": "Browse legacy model catalog",
|
||||
"addStepBeforeContinue": "Add at least one step before continuing to the next stage.",
|
||||
"modePackPerformance": "Performance",
|
||||
"modePackBudget": "Budget",
|
||||
"modePackBalanced": "Balanced",
|
||||
"modePackCustom": "Custom",
|
||||
"modePackLabel": "Mode Pack",
|
||||
"routerStrategyLabel": "Router Strategy",
|
||||
"strategyRules": "Rules (6-Factor Scoring)",
|
||||
@@ -1091,54 +1052,12 @@
|
||||
"tip2": "Keep a quality fallback for hard prompts.",
|
||||
"tip3": "Use for batch/background jobs where cost is the main KPI."
|
||||
},
|
||||
"fill-first": {
|
||||
"title": "Quota drain strategy",
|
||||
"description": "Exhausts one provider's quota before moving to the next in chain.",
|
||||
"tip1": "Order models by free quota size — biggest first.",
|
||||
"tip2": "Enable health checks to skip drained providers.",
|
||||
"tip3": "Ideal for free-tier stacking (Deepgram → Groq → NIM)."
|
||||
},
|
||||
"p2c": {
|
||||
"title": "Power-of-Two-Choices",
|
||||
"description": "Picks the less-loaded of two random candidates per request — low latency at scale.",
|
||||
"tip1": "Use with 4+ models for best effect.",
|
||||
"tip2": "Requires latency telemetry enabled in Settings.",
|
||||
"tip3": "Great replacement for round-robin in high-throughput combos."
|
||||
},
|
||||
"context-relay": {
|
||||
"title": "Session continuity first",
|
||||
"description": "Best when account rotation is expected and the next account must inherit a condensed task summary.",
|
||||
"tip1": "Use with providers that rotate accounts for the same model family.",
|
||||
"tip2": "Keep the handoff threshold below the hard quota cutoff to give the summary time to generate.",
|
||||
"tip3": "Set a dedicated summary model only when the primary model is too expensive or unstable."
|
||||
},
|
||||
"strict-random": {
|
||||
"title": "Shuffle deck distribution",
|
||||
"description": "Each model is used exactly once per cycle before reshuffling.",
|
||||
"tip1": "Use at least 2 models for meaningful distribution.",
|
||||
"tip2": "Works best with equivalent-performance models.",
|
||||
"tip3": "Ideal for load balancing across multiple API accounts."
|
||||
},
|
||||
"auto": {
|
||||
"title": "Fail-safe baseline",
|
||||
"description": "Use one primary model and keep fallback chain short and reliable.",
|
||||
"tip1": "Put your most reliable model first.",
|
||||
"tip2": "Keep 1-2 backup models with similar quality.",
|
||||
"tip3": "Use safe retries to absorb transient provider failures."
|
||||
},
|
||||
"lkgp": {
|
||||
"title": "Fail-safe baseline",
|
||||
"description": "Use one primary model and keep fallback chain short and reliable.",
|
||||
"tip1": "Put your most reliable model first.",
|
||||
"tip2": "Keep 1-2 backup models with similar quality.",
|
||||
"tip3": "Use safe retries to absorb transient provider failures."
|
||||
},
|
||||
"context-optimized": {
|
||||
"title": "Fail-safe baseline",
|
||||
"description": "Use one primary model and keep fallback chain short and reliable.",
|
||||
"tip1": "Put your most reliable model first.",
|
||||
"tip2": "Keep 1-2 backup models with similar quality.",
|
||||
"tip3": "Use safe retries to absorb transient provider failures."
|
||||
}
|
||||
},
|
||||
"templateFreeStack": "Free Stack ($0)",
|
||||
@@ -3399,258 +3318,5 @@
|
||||
"deduplicatedRequests": "Deduplicated Requests",
|
||||
"savedCalls": "Saved API Calls",
|
||||
"totalProcessed": "Total Requests Processed"
|
||||
},
|
||||
"proxyConfigModal": {
|
||||
"levelGlobal": "Global",
|
||||
"levelProvider": "Provider",
|
||||
"levelCombo": "Combo",
|
||||
"levelKey": "Key",
|
||||
"levelDirect": "Direct (none)",
|
||||
"titleGlobal": "Global Proxy Configuration",
|
||||
"titleLevel": "{level} Proxy — {label}",
|
||||
"loading": "Loading proxy configuration...",
|
||||
"inheritingFrom": "Inheriting from",
|
||||
"source": "Source",
|
||||
"savedProxy": "Saved Proxy",
|
||||
"custom": "Custom",
|
||||
"selectSavedProxyPlaceholder": "Select saved proxy...",
|
||||
"proxyType": "Proxy Type",
|
||||
"host": "Host",
|
||||
"hostPlaceholder": "1.2.3.4 or proxy.example.com",
|
||||
"port": "Port",
|
||||
"authOptional": "Authentication (optional)",
|
||||
"username": "Username",
|
||||
"usernamePlaceholder": "Username",
|
||||
"password": "Password",
|
||||
"passwordPlaceholder": "Password",
|
||||
"connected": "Connected",
|
||||
"ip": "IP:",
|
||||
"connectionFailed": "Connection failed",
|
||||
"testConnection": "Test Connection",
|
||||
"clear": "Clear",
|
||||
"cancel": "Cancel",
|
||||
"save": "Save",
|
||||
"errorSelectSavedProxy": "Select a saved proxy before saving.",
|
||||
"errorSelectProxyFirst": "Select a saved proxy first.",
|
||||
"errorProxyNotFound": "Selected proxy not found.",
|
||||
"errorClearSavedProxy": "Failed to clear saved proxy",
|
||||
"errorSaveProxy": "Failed to save proxy configuration",
|
||||
"errorClearProxy": "Failed to clear proxy configuration",
|
||||
"errorSocks5Hidden": "SOCKS5 is configured but hidden because NEXT_PUBLIC_ENABLE_SOCKS5_PROXY=false."
|
||||
},
|
||||
"oauthModal": {
|
||||
"title": "Connect {providerName}",
|
||||
"waiting": "Waiting for Authorization",
|
||||
"completeAuthInPopup": "Complete the authorization in the popup window.",
|
||||
"popupClosedHint": "If the popup closes without redirecting back (e.g. Qoder), this dialog will automatically switch to manual URL input mode.",
|
||||
"popupBlocked": "Popup blocked? Enter URL manually",
|
||||
"deviceCodeVisitUrl": "Visit the URL below and enter the code:",
|
||||
"deviceCodeVerificationUrl": "Verification URL",
|
||||
"deviceCodeYourCode": "Your Code",
|
||||
"deviceCodeWaiting": "Waiting for authorization...",
|
||||
"googleOAuthWarning": "Remote access + Google OAuth: The default credentials only accept redirects to <code>localhost</code>. After authorizing, your browser will try to open <code>localhost</code> — copy that full URL and paste it below. For fully remote use without this manual step, <a>configure your own OAuth credentials</a>.",
|
||||
"remoteAccessInfo": "Remote access: Since you're accessing OmniRoute remotely, after authorizing you'll see an error page (localhost not found). That's expected — just copy the full URL from your browser's address bar and paste it below.",
|
||||
"step1OpenUrl": "Step 1: Open this URL in your browser",
|
||||
"copy": "Copy",
|
||||
"step2PasteCallback": "Step 2: Paste the callback URL or auth code here",
|
||||
"step2Hint": "After authorization, paste the full callback URL. For Claude Code and Cline, you can also paste the Authentication Code directly, for example <code>code#state</code>.",
|
||||
"connect": "Connect",
|
||||
"cancel": "Cancel",
|
||||
"success": "Connected Successfully!",
|
||||
"successMessage": "Your {providerName} account has been connected.",
|
||||
"done": "Done",
|
||||
"error": "Connection Failed",
|
||||
"tryAgain": "Try Again"
|
||||
},
|
||||
"cursorAuthModal": {
|
||||
"title": "Connect Cursor IDE",
|
||||
"autoDetecting": "Auto-detecting tokens...",
|
||||
"readingFromCursor": "Reading from Cursor IDE or cursor-agent",
|
||||
"tokensAutoDetected": "Tokens auto-detected from Cursor IDE successfully!",
|
||||
"cursorNotDetected": "Cursor IDE not detected. Please paste your tokens manually.",
|
||||
"accessToken": "Access Token",
|
||||
"required": "*",
|
||||
"accessTokenPlaceholder": "Access token will be auto-filled...",
|
||||
"machineId": "Machine ID",
|
||||
"optional": "(optional)",
|
||||
"machineIdPlaceholder": "Machine ID will be auto-filled...",
|
||||
"importing": "Importing...",
|
||||
"importToken": "Import Token",
|
||||
"cancel": "Cancel",
|
||||
"errorAutoDetect": "Could not auto-detect tokens",
|
||||
"errorAutoDetectFailed": "Failed to auto-detect tokens",
|
||||
"errorEnterToken": "Please enter an access token",
|
||||
"errorImportFailed": "Import failed"
|
||||
},
|
||||
"pricingModal": {
|
||||
"title": "Pricing Configuration",
|
||||
"loading": "Loading pricing data...",
|
||||
"pricingRatesFormat": "Pricing Rates Format",
|
||||
"ratesDescription": "All rates are in <strong>dollars per million tokens</strong> ($/1M tokens). Example: Input rate of 2.50 means $2.50 per 1,000,000 input tokens.",
|
||||
"model": "Model",
|
||||
"input": "Input",
|
||||
"output": "Output",
|
||||
"cached": "Cached",
|
||||
"reasoning": "Reasoning",
|
||||
"cacheCreation": "Cache Creation",
|
||||
"noPricingData": "No pricing data available",
|
||||
"resetToDefaults": "Reset to Defaults",
|
||||
"cancel": "Cancel",
|
||||
"saving": "Saving...",
|
||||
"saveChanges": "Save Changes",
|
||||
"resetConfirm": "Reset all pricing to defaults? This cannot be undone.",
|
||||
"errorSaveFailed": "Failed to save pricing",
|
||||
"errorResetFailed": "Failed to reset pricing"
|
||||
},
|
||||
"proxyRegistry": {
|
||||
"title": "Proxy Registry",
|
||||
"description": "Store reusable proxies and track assignments.",
|
||||
"importLegacy": "Import Legacy",
|
||||
"bulkAssign": "Bulk Assign",
|
||||
"addProxy": "Add Proxy",
|
||||
"loading": "Loading proxies...",
|
||||
"noProxies": "No saved proxies yet.",
|
||||
"tableName": "Name",
|
||||
"tableEndpoint": "Endpoint",
|
||||
"tableStatus": "Status",
|
||||
"tableHealth": "Health (24h)",
|
||||
"tableUsage": "Usage",
|
||||
"tableActions": "Actions",
|
||||
"test": "Test",
|
||||
"edit": "Edit",
|
||||
"delete": "Delete",
|
||||
"modalCreateTitle": "Create Proxy",
|
||||
"modalEditTitle": "Edit Proxy",
|
||||
"labelName": "Name",
|
||||
"labelType": "Type",
|
||||
"labelHost": "Host",
|
||||
"labelPort": "Port",
|
||||
"labelUsername": "Username",
|
||||
"labelPassword": "Password",
|
||||
"labelRegion": "Region",
|
||||
"labelStatus": "Status",
|
||||
"labelNotes": "Notes",
|
||||
"usernamePlaceholderEdit": "Leave blank to keep current username",
|
||||
"passwordPlaceholderEdit": "Leave blank to keep current password",
|
||||
"statusActive": "active",
|
||||
"statusInactive": "inactive",
|
||||
"cancel": "Cancel",
|
||||
"save": "Save",
|
||||
"bulkModalTitle": "Bulk Proxy Assignment",
|
||||
"bulkLabelScope": "Scope",
|
||||
"bulkLabelProxy": "Proxy",
|
||||
"bulkClearAssignment": "(clear assignment)",
|
||||
"bulkLabelScopeIds": "Scope IDs (comma or newline)",
|
||||
"bulkScopeIdsPlaceholder": "provider-openai,provider-anthropic",
|
||||
"bulkApply": "Apply",
|
||||
"errorLoadFailed": "Failed to load proxy registry",
|
||||
"errorNameHostRequired": "Name and host are required",
|
||||
"errorSaveFailed": "Failed to save proxy",
|
||||
"errorDeleteFailed": "Failed to delete proxy",
|
||||
"errorForceDeleteConfirm": "This proxy is still assigned. Force delete and remove all assignments?",
|
||||
"errorMigrateFailed": "Failed to migrate legacy proxy config",
|
||||
"errorBulkFailed": "Failed to run bulk assignment",
|
||||
"success": "✓",
|
||||
"failure": "✗",
|
||||
"failed": "failed",
|
||||
"successRate": "{rate}% success",
|
||||
"avgLatency": "{latency} ms avg",
|
||||
"assignmentsCount": "{count} assignment(s)",
|
||||
"noData": "—",
|
||||
"testSuccess": "✓ {ip}",
|
||||
"testLatency": "{latency}ms",
|
||||
"testFailure": "✗ {error}"
|
||||
},
|
||||
"playground": {
|
||||
"title": "Model Playground",
|
||||
"description": "Test any model directly from the dashboard. Pick a provider, model, and endpoint type, then send a request to see the raw response.",
|
||||
"endpoint": "Endpoint",
|
||||
"provider": "Provider",
|
||||
"model": "Model",
|
||||
"accountKey": "Account / Key",
|
||||
"autoAccounts": "Auto ({count} accounts)",
|
||||
"noAccounts": "No accounts",
|
||||
"send": "Send",
|
||||
"cancel": "Cancel",
|
||||
"audioFile": "Audio File",
|
||||
"attachImages": "Attach Images (Vision)",
|
||||
"multipartFormData": "multipart/form-data",
|
||||
"upToImages": "up to 4 images",
|
||||
"selectAudioFile": "Select an audio file to transcribe (mp3, wav, m4a, ogg, flac…)",
|
||||
"clearAll": "Clear all",
|
||||
"request": "Request",
|
||||
"response": "Response",
|
||||
"transcription": "Transcription",
|
||||
"copy": "Copy",
|
||||
"resetToDefault": "Reset to default",
|
||||
"downloadAudio": "Download audio",
|
||||
"copyText": "Copy text",
|
||||
"transcriptionHint": "Transcription uses multipart/form-data. Upload the audio file above — JSON below controls extra params (model, language).",
|
||||
"imagesGenerated": "{count} image{count, plural, one {} other {s}} generated",
|
||||
"generatedImage": "Generated image {index}",
|
||||
"save": "Save",
|
||||
"endpointOptions": {
|
||||
"chat": "Chat Completions",
|
||||
"responses": "Responses",
|
||||
"images": "Image Generation",
|
||||
"embeddings": "Embeddings",
|
||||
"speech": "Text to Speech",
|
||||
"transcription": "Audio Transcription",
|
||||
"video": "Video Generation",
|
||||
"music": "Music Generation",
|
||||
"rerank": "Rerank",
|
||||
"search": "Web Search"
|
||||
}
|
||||
},
|
||||
"requestLogger": {
|
||||
"recording": "Recording",
|
||||
"paused": "Paused",
|
||||
"pipelineLogsOn": "Pipeline Logs On",
|
||||
"pipelineLogsOff": "Pipeline Logs Off",
|
||||
"updatingPipelineLogs": "Updating pipeline logs...",
|
||||
"searchPlaceholder": "Search model, provider, account, API key, combo...",
|
||||
"allProviders": "All Providers",
|
||||
"allModels": "All Models",
|
||||
"allAccounts": "All Accounts",
|
||||
"allApiKeys": "All API Keys",
|
||||
"total": "total",
|
||||
"ok": "OK",
|
||||
"err": "ERR",
|
||||
"combo": "combo",
|
||||
"keys": "keys",
|
||||
"shown": "shown",
|
||||
"sortNewest": "Newest",
|
||||
"sortOldest": "Oldest",
|
||||
"sortTokensDesc": "Tokens ↓",
|
||||
"sortTokensAsc": "Tokens ↑",
|
||||
"sortDurationDesc": "Duration ↓",
|
||||
"sortDurationAsc": "Duration ↑",
|
||||
"sortStatusDesc": "Status ↓",
|
||||
"sortStatusAsc": "Status ↑",
|
||||
"sortModelAsc": "Model A-Z",
|
||||
"sortModelDesc": "Model Z-A",
|
||||
"statusFilters": {
|
||||
"all": "All",
|
||||
"error": "Errors",
|
||||
"success": "Success",
|
||||
"combo": "Combo"
|
||||
},
|
||||
"columns": {
|
||||
"status": "Status",
|
||||
"model": "Model",
|
||||
"requested": "Requested",
|
||||
"provider": "Provider",
|
||||
"protocol": "Req Protocol",
|
||||
"account": "Account",
|
||||
"apiKey": "API Key",
|
||||
"combo": "Combo",
|
||||
"tokens": "Tokens",
|
||||
"duration": "Duration",
|
||||
"time": "Time"
|
||||
},
|
||||
"loadingLogs": "Loading logs...",
|
||||
"noLogs": "No logs recorded yet. Make some API calls to see them here.",
|
||||
"noMatchingLogs": "No logs match the current filters.",
|
||||
"callLogsInfo": "Call logs are also saved as JSON files to {dataDir} and rotated by {retentionDays} and {maxEntries}."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1163,6 +1163,28 @@
|
||||
"reorderHandle": "拖拽排序",
|
||||
"failedReorder": "模型重排序失败",
|
||||
"builderFlowTitle": "组合构建流程",
|
||||
"builderStage": {
|
||||
"basics": {
|
||||
"label": "基础",
|
||||
"description": "名称和起始模板"
|
||||
},
|
||||
"steps": {
|
||||
"label": "步骤",
|
||||
"description": "提供商、模型和账户选择"
|
||||
},
|
||||
"strategy": {
|
||||
"label": "策略",
|
||||
"description": "路由行为和高级设置"
|
||||
},
|
||||
"intelligent": {
|
||||
"label": "智能路由",
|
||||
"description": "自动路由候选池、预设和评分"
|
||||
},
|
||||
"review": {
|
||||
"label": "审查",
|
||||
"description": "保存前的最终验证"
|
||||
}
|
||||
},
|
||||
"builderStageVisited": "阶段已完成",
|
||||
"builderStageCurrent": "当前阶段",
|
||||
"builderStagePending": "待处理",
|
||||
|
||||
Reference in New Issue
Block a user