+
+ );
+}
diff --git a/src/app/api/conductor/ask/route.ts b/src/app/api/conductor/ask/route.ts
new file mode 100644
index 0000000000..b8d6b15823
--- /dev/null
+++ b/src/app/api/conductor/ask/route.ts
@@ -0,0 +1,37 @@
+/**
+ * POST /api/conductor/ask — proxy para o Faro (spokesperson do OmniConductor).
+ * O /ask do Faro exige credencial do hub (server-side); o browser fala só com
+ * esta rota. Resposta whitelisted {text, pending} — quando `pending` vier, a UI
+ * oferece Sim/Não (a trava de confirmação é do motor do Faro; nunca contornada).
+ */
+
+import { NextResponse } from "next/server";
+import { z } from "zod";
+
+import { createErrorResponse } from "@/lib/api/errorResponse";
+import { requireManagementAuth } from "@/lib/api/requireManagementAuth";
+import { askFaro } from "@/lib/conductor/faroProxy";
+
+const askSchema = z.object({ message: z.string().min(1).max(4000) });
+
+export async function POST(request: Request) {
+ const authError = await requireManagementAuth(request);
+ if (authError) return authError;
+
+ let raw: unknown;
+ try {
+ raw = await request.json();
+ } catch {
+ return createErrorResponse({ status: 400, message: "Invalid JSON body" });
+ }
+ const parsed = askSchema.safeParse(raw);
+ if (!parsed.success) {
+ return createErrorResponse({ status: 400, message: "Body must be { message: string (1-4000 chars) }" });
+ }
+
+ const answer = await askFaro(parsed.data.message);
+ if (!answer.ok) {
+ return createErrorResponse({ status: 503, message: "Faro (spokesperson) is offline or refused the request" });
+ }
+ return NextResponse.json({ text: answer.text, pending: answer.pending });
+}
diff --git a/src/i18n/messages/en.json b/src/i18n/messages/en.json
index 47bb050a3b..9235d89af9 100644
--- a/src/i18n/messages/en.json
+++ b/src/i18n/messages/en.json
@@ -1277,11 +1277,11 @@
"discoverySubtitle": "Scan providers for free access",
"conductor": "Conductor",
"conductorSubtitle": "CLI-agent fleet",
-"resilienceConnections": "Connection Resilience",
-"resilienceConnectionsSubtitle": "Cooldown, breaker, lockout state",
-"settingsModalityBridge": "Modality Bridge",
-"settingsModalityBridgeSubtitle": "Image/audio → text fallback for text-only models",
-"commandPalette": {
+ "resilienceConnections": "Connection Resilience",
+ "resilienceConnectionsSubtitle": "Cooldown, breaker, lockout state",
+ "settingsModalityBridge": "Modality Bridge",
+ "settingsModalityBridgeSubtitle": "Image/audio → text fallback for text-only models",
+ "commandPalette": {
"title": "Command palette",
"searchPlaceholder": "Search pages, settings, tools...",
"clearSearch": "Clear search",
@@ -6193,12 +6193,13 @@
"cline": "Connect Cline with the existing OAuth flow.",
"cursor": "Connect Cursor IDE with the existing OAuth flow.",
"github": "Connect GitHub Copilot with the existing OAuth flow.",
- "gitlab-duo": "GitLab Duo OAuth is not configured. Register an OAuth application at https://gitlab.com/-/profile/applications with redirect URI http://localhost:20128/callback and scopes \"ai_features read_user\", then set GITLAB_DUO_OAUTH_CLIENT_ID (and optionally GITLAB_DUO_OAUTH_CLIENT_SECRET) and restart.",
+ "gitlab-duo": "OAuth application with ai_features + read_user scopes. Configure GITLAB_DUO_OAUTH_CLIENT_ID and optionally GITLAB_DUO_OAUTH_CLIENT_SECRET on this OmniRoute instance.",
"kilocode": "Connect Kilo Code with the existing OAuth flow.",
"kimi-coding": "Connect Kimi Coding with the existing OAuth flow.",
"kiro": "Free tier: 50 credits/month (~25K–100K tokens). ⚠️ Kiro ToS prohibits third-party proxy/harness use.",
"codex": "Connect OpenAI Codex with the existing OAuth flow.",
- "qwen": "Connect Qwen Code with the existing OAuth flow."
+ "qwen": "Connect Qwen Code with the existing OAuth flow.",
+ "github-models": "Create a GitHub PAT with 'models: read' scope at github.com/settings/tokens"
},
"passthroughModelsDescription": "{provider} accepts provider-native model IDs. Import from /models or add custom IDs for routing.",
"bedrockModelsDescription": "Amazon Bedrock models are scoped by AWS region. Import from /models or add Bedrock model IDs enabled in the selected region.",
@@ -6248,86 +6249,87 @@
"apiProtocolHint": "Some providers publish the same models over more than one protocol. Leave the default unless you need the alternative.",
"bulkAddFormatHintCloudflare": "One key per line. Format: name|accountId|apiKey (Cloudflare account ID + API token).",
"lmarenaWebCookieHint": "Open arena.ai, sign in, then copy the full Cookie header from a Network request. Include arena-auth-prod-v1.0 and arena-auth-prod-v1.1 (and further chunks if present), preferably with cf_clearance. Do not paste only the empty arena-auth-prod-v1 cookie. Optional: providerSpecificData.recaptchaV3Token if create-evaluation still returns 403.",
- "kimiOfficialSupporterBadge": "Founding Friend",
- "kimiOfficialSupporterTooltip": "Kimi (Moonshot AI) is OmniRoute's founding Open Source Friend",
+ "kimiOfficialSupporterBadge": "Official Supporter",
+ "kimiOfficialSupporterTooltip": "Kimi (Moonshot AI) is an official OmniRoute launch partner",
"cheaperInferenceSupporterBadge": "Open Source Friend",
"cheaperInferenceSupporterTooltip": "Cheaper Inference backs OmniRoute as an Open Source Friend",
"kimiPartnerLinkNote": "Partner link — supports OmniRoute at no extra cost to you",
-"anonymousFallbackTitle": "Anonymous fallback",
-"anonymousFallbackDesc": "When all configured connections are exhausted (quota, credits, or expiry), temporarily use this provider's keyless tier. Turn off to skip this provider instead of sending anonymous requests — recommended when the keyless tier rejects them (401).",
-"anonymousFallbackEnabled": "Anonymous fallback enabled for {provider}",
-"anonymousFallbackDisabled": "Anonymous fallback disabled for {provider} — exhausted connections will skip this provider",
-"anonymousFallbackUpdateFailed": "Failed to update anonymous fallback setting",
-"batchDeleteFailed": "Batch delete failed",
-"batchDeleteNetworkError": "Network error during batch delete",
-"batchUpdateFailed": "Batch update failed",
-"batchUpdateNetworkError": "Network error during batch update",
-"categoryAudio": "Audio",
-"categoryCloudAgent": "Cloud Agent",
-"categoryIde": "IDE",
-"categoryLocal": "Local",
-"categorySearch": "Search",
-"categoryWebCookie": "Web Cookie",
-"claudeExtraUsageBlockingDisabled": "Claude extra-usage blocking disabled (extra usage is allowed)",
-"claudeExtraUsageBlockingEnabled": "Claude extra-usage blocking enabled (extra usage will be blocked)",
-"claudeRoutingPreferenceDisabled": "Unprefixed Claude models no longer prefer Claude Code",
-"claudeRoutingPreferenceEnabled": "Unprefixed Claude models now prefer Claude Code",
-"clearMediaFilter": "Clear",
-"cliproxyRoutingDisabled": "Requests now use native OmniRoute (direct)",
-"cliproxyRoutingEnabled": "Requests now route through CLIProxyAPI (deeper emulation)",
-"codexLimitPolicyUpdated": "Codex limit policy updated",
-"codexServiceModeUpdated": "Codex service mode updated",
-"codexServiceTierActive": "Codex {tier} service tier is active",
-"codexTierFastLabel": "Fast",
-"codexTierFlexLabel": "Flex",
-"commandCodeApplyFailed": "Failed to apply Command Code auth",
-"commandCodeApplyingApproval": "Browser approved, applying…",
-"commandCodeApplyingKey": "Applying browser-approved key…",
-"commandCodeApprovalInstructions": "Open the auth URL, approve access, then paste the returned key/JSON/URL below…",
-"commandCodeAuthExpired": "Command Code auth expired",
-"commandCodeConnected": "Command Code connected",
-"commandCodeConnectionAdded": "Command Code connection added",
-"commandCodeLinkExpired": "Command Code link expired",
-"commandCodeOpeningStudio": "Opening Command Code Studio…",
-"commandCodePopupBlocked": "Popup blocked. Please allow popups and try Command Code Connect again.",
-"commandCodeStartFailed": "Failed to start Command Code auth",
-"connectionDeleted": "Connection deleted",
-"connectionFallback": "connection",
-"coolingConnectionsDescription": "These connections returned a 429 (rate-limit) on their last request. OmniRoute will skip them until the timer expires — no manual disable required.",
-"coolingConnectionsTitle": "Currently cooling ({count})",
-"failedDeleteAlias": "Failed to delete alias",
-"failedDeleteConnection": "Failed to delete connection",
-"failedDistributeProxies": "Failed to distribute proxies.",
-"failedSaveModelEndpointSettings": "Failed to save model endpoint settings",
-"failedUpdateClaudeExtraUsagePolicy": "Failed to update Claude extra-usage policy",
-"failedUpdateClaudeRoutingPreference": "Failed to update Claude Code routing preference",
-"failedUpdateCliproxyRouting": "Failed to update CLIProxyAPI routing",
-"failedUpdateCodexLimitPolicy": "Failed to update Codex limit policy",
-"failedUpdateCodexServiceMode": "Failed to update Codex service mode",
-"filterByMedia": "Media",
-"freeBadge": "Free",
-"kimiCodeApiKeyLabel": "Kimi Code API Key",
-"modelTestFailed": "Model test failed",
-"modelTestNetworkError": "Network error testing model",
-"networkError": "Network error",
-"networkErrorDeletingAlias": "Network error deleting alias",
-"networkErrorSettingAlias": "Network error setting alias",
-"noProvidersMatch": "No providers match your search.",
-"noSavedProxies": "No saved proxies found. Add proxies in Settings → Proxy first.",
-"pageLoadErrorDescription": "We could not load provider data right now. Check your connection and try again.",
-"pageLoadErrorId": "Error ID: {id}",
-"pageLoadErrorRetry": "Try Again",
-"pageLoadErrorTitle": "Failed to load providers",
-"playgroundTitle": "Playground",
-"providerDetailConnectionFlexActive": "Codex flex service tier is active for this connection",
-"providerDetailConnectionPriorityActive": "Codex priority service tier is active for this connection",
-"providerDetailGlobalFlexActive": "Global Codex flex service tier is active",
-"providerDetailGlobalPriorityActive": "Global Codex priority service tier is active",
-"proxiesDistributed": "Distributed {assigned} proxy assignment(s) across {tagLabel}{total} connection(s).",
-"rerankEndpoint": "Rerank",
-"savedModelEndpointSettings": "Saved model endpoint settings",
-"searchByModelAria": "Search by model",
-"selectSupportedEndpoint": "Select at least one supported endpoint"
+ "anonymousFallbackTitle": "Anonymous fallback",
+ "anonymousFallbackDesc": "When all configured connections are exhausted (quota, credits, or expiry), temporarily use this provider's keyless tier. Turn off to skip this provider instead of sending anonymous requests — recommended when the keyless tier rejects them (401).",
+ "anonymousFallbackEnabled": "Anonymous fallback enabled for {provider}",
+ "anonymousFallbackDisabled": "Anonymous fallback disabled for {provider} — exhausted connections will skip this provider",
+ "anonymousFallbackUpdateFailed": "Failed to update anonymous fallback setting",
+ "batchDeleteFailed": "Batch delete failed",
+ "batchDeleteNetworkError": "Network error during batch delete",
+ "batchUpdateFailed": "Batch update failed",
+ "batchUpdateNetworkError": "Network error during batch update",
+ "categoryAudio": "Audio",
+ "categoryCloudAgent": "Cloud Agent",
+ "categoryIde": "IDE",
+ "categoryLocal": "Local",
+ "categorySearch": "Search",
+ "categoryWebCookie": "Web Cookie",
+ "claudeExtraUsageBlockingDisabled": "Claude extra-usage blocking disabled (extra usage is allowed)",
+ "claudeExtraUsageBlockingEnabled": "Claude extra-usage blocking enabled (extra usage will be blocked)",
+ "claudeRoutingPreferenceDisabled": "Unprefixed Claude models no longer prefer Claude Code",
+ "claudeRoutingPreferenceEnabled": "Unprefixed Claude models now prefer Claude Code",
+ "clearMediaFilter": "Clear",
+ "cliproxyRoutingDisabled": "Requests now use native OmniRoute (direct)",
+ "cliproxyRoutingEnabled": "Requests now route through CLIProxyAPI (deeper emulation)",
+ "codexLimitPolicyUpdated": "Codex limit policy updated",
+ "codexServiceModeUpdated": "Codex service mode updated",
+ "codexServiceTierActive": "Codex {tier} service tier is active",
+ "codexTierFastLabel": "Fast",
+ "codexTierFlexLabel": "Flex",
+ "commandCodeApplyFailed": "Failed to apply Command Code auth",
+ "commandCodeApplyingApproval": "Browser approved, applying…",
+ "commandCodeApplyingKey": "Applying browser-approved key…",
+ "commandCodeApprovalInstructions": "Open the auth URL, approve access, then paste the returned key/JSON/URL below…",
+ "commandCodeAuthExpired": "Command Code auth expired",
+ "commandCodeConnected": "Command Code connected",
+ "commandCodeConnectionAdded": "Command Code connection added",
+ "commandCodeLinkExpired": "Command Code link expired",
+ "commandCodeOpeningStudio": "Opening Command Code Studio…",
+ "commandCodePopupBlocked": "Popup blocked. Please allow popups and try Command Code Connect again.",
+ "commandCodeStartFailed": "Failed to start Command Code auth",
+ "connectionDeleted": "Connection deleted",
+ "connectionFallback": "connection",
+ "coolingConnectionsDescription": "These connections returned a 429 (rate-limit) on their last request. OmniRoute will skip them until the timer expires — no manual disable required.",
+ "coolingConnectionsTitle": "Currently cooling ({count})",
+ "failedDeleteAlias": "Failed to delete alias",
+ "failedDeleteConnection": "Failed to delete connection",
+ "failedDistributeProxies": "Failed to distribute proxies.",
+ "failedSaveModelEndpointSettings": "Failed to save model endpoint settings",
+ "failedUpdateClaudeExtraUsagePolicy": "Failed to update Claude extra-usage policy",
+ "failedUpdateClaudeRoutingPreference": "Failed to update Claude Code routing preference",
+ "failedUpdateCliproxyRouting": "Failed to update CLIProxyAPI routing",
+ "failedUpdateCodexLimitPolicy": "Failed to update Codex limit policy",
+ "failedUpdateCodexServiceMode": "Failed to update Codex service mode",
+ "filterByMedia": "Media",
+ "freeBadge": "Free",
+ "kimiCodeApiKeyLabel": "Kimi Code API Key",
+ "modelTestFailed": "Model test failed",
+ "modelTestNetworkError": "Network error testing model",
+ "networkError": "Network error",
+ "networkErrorDeletingAlias": "Network error deleting alias",
+ "networkErrorSettingAlias": "Network error setting alias",
+ "noProvidersMatch": "No providers match your search.",
+ "noSavedProxies": "No saved proxies found. Add proxies in Settings → Proxy first.",
+ "pageLoadErrorDescription": "We could not load provider data right now. Check your connection and try again.",
+ "pageLoadErrorId": "Error ID: {id}",
+ "pageLoadErrorRetry": "Try Again",
+ "pageLoadErrorTitle": "Failed to load providers",
+ "playgroundTitle": "Playground",
+ "providerDetailConnectionFlexActive": "Codex flex service tier is active for this connection",
+ "providerDetailConnectionPriorityActive": "Codex priority service tier is active for this connection",
+ "providerDetailGlobalFlexActive": "Global Codex flex service tier is active",
+ "providerDetailGlobalPriorityActive": "Global Codex priority service tier is active",
+ "proxiesDistributed": "Distributed {assigned} proxy assignment(s) across {tagLabel}{total} connection(s).",
+ "rerankEndpoint": "Rerank",
+ "savedModelEndpointSettings": "Saved model endpoint settings",
+ "searchByModelAria": "Search by model",
+ "selectSupportedEndpoint": "Select at least one supported endpoint",
+ "antigravityClientProfileHarness": "Harness / CLI"
},
"settings": {
"title": "Settings",
@@ -6657,78 +6659,78 @@
"NEEDS_CORE_NOT_CONFIGURED": "This subscription has nodes that need a local proxy core (SS/VMess/Trojan/VLESS); they are not routed until you configure the local-core SOCKS5 endpoint.",
"NO_USABLE_NODES": "Subscription yielded no usable nodes (http/https/socks5 or nodes with a local core endpoint)."
},
-"description": "Paste your proxy subscription link. Once enabled, traffic is routed through the proxy pool in global or rule (specified Provider) mode. Subscription nodes are automatically synced into the proxy pool and reuse existing polling, health-check, and anti-leak mechanisms.",
-"addSubscription": "Add Subscription",
-"newSubscription": "Add Subscription",
-"editSubscription": "Edit Subscription",
-"name": "Name",
-"namePlaceholder": "e.g. My Subscription A",
-"url": "Subscription URL",
-"urlPlaceholder": "https://.../subscribe?token=...",
-"mode": "Mode",
-"globalMode": "Global Mode",
-"ruleMode": "Rule Mode",
-"globalModeDesc": "All Provider traffic goes through this subscription's proxy pool.",
-"ruleModeDesc": "Only selected Providers' traffic goes through the proxy; the rest connect directly.",
-"localCoreEndpoint": "Local Core SOCKS5/HTTP Endpoint (Optional)",
-"localCoreEndpointPlaceholder": "socks5://127.0.0.1:1080",
-"localCoreEndpointDesc": "Only accepts 127.0.0.1 / localhost (SS/VMess/Trojan/VLESS require a local sing-box/clash core).",
-"routeByProvider": "Route by Provider (multi-select)",
-"loadingProviders": "Loading Provider list…",
-"autoRefreshInterval": "Auto Refresh Interval (minutes)",
-"enableAfterCreate": "Enable on creation (sync and take effect immediately)",
-"saving": "Saving…",
-"saveChanges": "Save Changes",
-"createSubscription": "Create Subscription",
-"loading": "Loading…",
-"noSubscriptions": "No subscriptions yet. Click \"Add Subscription\" to get started.",
-"statusOk": "OK",
-"statusError": "Error",
-"statusEmpty": "Empty",
-"global": "Global",
-"rule": "Rule",
-"enabled": "Enabled",
-"disabled": "Disabled",
-"nodeCount": "Nodes: {count}",
-"needsCoreCount": "{count} need local core",
-"lastSynced": "Last synced: {time}",
-"consecutiveFailures": "{count} consecutive failures",
-"lastError": "Last error: {time}",
-"coreHintTitle": "This subscription has {count} nodes that require a local proxy core (SS / VMess / Trojan / VLESS, etc.) and are currently not routed.",
-"coreHintDesc": "These protocols cannot be forwarded directly by OmniRoute. Please start a sing-box or clash (Clash.Meta) core on your machine, expose it as a SOCKS5/HTTP endpoint, and fill it in via Edit (only 127.0.0.1 / localhost is accepted).",
-"copy": "Copy",
-"goConfigure": "Configure",
-"disable": "Disable",
-"enable": "Enable",
-"refreshNodes": "Refresh Nodes",
-"edit": "Edit",
-"delete": "Delete",
-"confirmDelete": "Are you sure you want to delete subscription \"{name}\"? Associated proxy nodes will also be removed.",
-"nameRequired": "Please enter a name",
-"urlRequired": "Please enter a subscription URL",
-"ruleModeProviderRequired": "Please select at least one Provider in rule mode",
-"saveFailed": "Save failed",
-"loadFailed": "Failed to load subscription list",
-"toggleFailed": "Failed to toggle switch",
-"refreshFailed": "Failed to refresh",
-"deleteFailed": "Failed to delete",
-"add": "Add",
-"cancel": "Cancel",
-"configure": "Configure",
-"copyEndpoint": "Copy Endpoint",
-"coreEndpointHint": "Core Endpoint Hint",
-"coreNodesHint": "Core Nodes Hint",
-"create": "Create",
-"deleteConfirm": "Delete Confirm",
-"empty": "Empty",
-"globalModeDescription": "Global Mode Description",
-"localCoreHint": "Local Core Hint",
-"nodeSummary": "Node Summary",
-"providerRequired": "Provider Required",
-"providerRouting": "Provider Routing",
-"refresh": "Refresh",
-"refreshInterval": "Refresh Interval",
-"ruleModeDescription": "Rule Mode Description"
+ "description": "Paste your proxy subscription link. Once enabled, traffic is routed through the proxy pool in global or rule (specified Provider) mode. Subscription nodes are automatically synced into the proxy pool and reuse existing polling, health-check, and anti-leak mechanisms.",
+ "addSubscription": "Add Subscription",
+ "newSubscription": "Add Subscription",
+ "editSubscription": "Edit Subscription",
+ "name": "Name",
+ "namePlaceholder": "e.g. My Subscription A",
+ "url": "Subscription URL",
+ "urlPlaceholder": "https://.../subscribe?token=...",
+ "mode": "Mode",
+ "globalMode": "Global Mode",
+ "ruleMode": "Rule Mode",
+ "globalModeDesc": "All Provider traffic goes through this subscription's proxy pool.",
+ "ruleModeDesc": "Only selected Providers' traffic goes through the proxy; the rest connect directly.",
+ "localCoreEndpoint": "Local Core SOCKS5/HTTP Endpoint (Optional)",
+ "localCoreEndpointPlaceholder": "socks5://127.0.0.1:1080",
+ "localCoreEndpointDesc": "Only accepts 127.0.0.1 / localhost (SS/VMess/Trojan/VLESS require a local sing-box/clash core).",
+ "routeByProvider": "Route by Provider (multi-select)",
+ "loadingProviders": "Loading Provider list…",
+ "autoRefreshInterval": "Auto Refresh Interval (minutes)",
+ "enableAfterCreate": "Enable on creation (sync and take effect immediately)",
+ "saving": "Saving…",
+ "saveChanges": "Save Changes",
+ "createSubscription": "Create Subscription",
+ "loading": "Loading…",
+ "noSubscriptions": "No subscriptions yet. Click \"Add Subscription\" to get started.",
+ "statusOk": "OK",
+ "statusError": "Error",
+ "statusEmpty": "Empty",
+ "global": "Global",
+ "rule": "Rule",
+ "enabled": "Enabled",
+ "disabled": "Disabled",
+ "nodeCount": "Nodes: {count}",
+ "needsCoreCount": "{count} need local core",
+ "lastSynced": "Last synced: {time}",
+ "consecutiveFailures": "{count} consecutive failures",
+ "lastError": "Last error: {time}",
+ "coreHintTitle": "This subscription has {count} nodes that require a local proxy core (SS / VMess / Trojan / VLESS, etc.) and are currently not routed.",
+ "coreHintDesc": "These protocols cannot be forwarded directly by OmniRoute. Please start a sing-box or clash (Clash.Meta) core on your machine, expose it as a SOCKS5/HTTP endpoint, and fill it in via Edit (only 127.0.0.1 / localhost is accepted).",
+ "copy": "Copy",
+ "goConfigure": "Configure",
+ "disable": "Disable",
+ "enable": "Enable",
+ "refreshNodes": "Refresh Nodes",
+ "edit": "Edit",
+ "delete": "Delete",
+ "confirmDelete": "Are you sure you want to delete subscription \"{name}\"? Associated proxy nodes will also be removed.",
+ "nameRequired": "Please enter a name",
+ "urlRequired": "Please enter a subscription URL",
+ "ruleModeProviderRequired": "Please select at least one Provider in rule mode",
+ "saveFailed": "Save failed",
+ "loadFailed": "Failed to load subscription list",
+ "toggleFailed": "Failed to toggle switch",
+ "refreshFailed": "Failed to refresh",
+ "deleteFailed": "Failed to delete",
+ "add": "Add",
+ "cancel": "Cancel",
+ "configure": "Configure",
+ "copyEndpoint": "Copy Endpoint",
+ "coreEndpointHint": "Core Endpoint Hint",
+ "coreNodesHint": "Core Nodes Hint",
+ "create": "Create",
+ "deleteConfirm": "Delete Confirm",
+ "empty": "Empty",
+ "globalModeDescription": "Global Mode Description",
+ "localCoreHint": "Local Core Hint",
+ "nodeSummary": "Node Summary",
+ "providerRequired": "Provider Required",
+ "providerRouting": "Provider Routing",
+ "refresh": "Refresh",
+ "refreshInterval": "Refresh Interval",
+ "ruleModeDescription": "Rule Mode Description"
},
"bulkHealthcheck": "Bulk Healthcheck",
"bulkHealthcheckDesc": "Test all configured proxies against a target URL to find which ones work.",
@@ -6764,7 +6766,7 @@
"denoRelayOrgDomainRequired": "Organization domain is required",
"denoRelayDeployFailed": "Deno Deploy failed",
"denoRelayTokenHint": "Organization token (prefix ddo_) from console.deno.com → Organization → Settings → Organization Tokens. Used once for deploy and never stored.",
- "denoRelayOrgDomainHint": "Your Deno Deploy organization's default domain (e.g. acme.deno.net). The relay will be reachable at https://<app-name>.<org-slug>.deno.net.",
+ "denoRelayOrgDomainHint": "Your Deno Deploy organization's default domain (e.g. acme.deno.net). The relay will be reachable at https://..deno.net.",
"proxyFreePoolFilterProtocol": "Filter by protocol",
"proxyFreePoolProtocol": "Protocol",
"proxyFreePoolCountryPlaceholder": "Country (e.g. US)",
@@ -7903,9 +7905,9 @@
"resilienceEnableServerWaitDesc": "When enabled, OmniRoute waits for the first cooldown to expire and retries automatically.",
"resilienceMaxAttempts": "Maximum attempts",
"resilienceMaxWaitPerAttempt": "Maximum wait per attempt",
- "resilienceComboCooldownWaitTitle": "Combo cooldown wait",
- "resilienceComboCooldownWaitDesc": "For all combo strategies: wait out a short transient cooldown and re-dispatch instead of returning a 429 immediately. Never waits on quota_exhausted.",
- "resilienceComboCooldownWaitToggleDesc": "All combo strategies; never waits on quota_exhausted.",
+ "resilienceComboCooldownWaitTitle": "Quota-share combo cooldown wait",
+ "resilienceComboCooldownWaitDesc": "For quota-share combos only: wait out a short transient cooldown and re-dispatch instead of returning a 429 immediately. Never waits on quota_exhausted.",
+ "resilienceComboCooldownWaitToggleDesc": "Quota-share combos only; never waits on quota_exhausted.",
"resilienceComboCooldownMaxWaitMs": "Maximum wait per attempt",
"resilienceComboCooldownBudgetMs": "Total wait budget",
"resilienceQuotaShareConcurrencyTitle": "Quota-share per-connection concurrency",
@@ -8001,138 +8003,138 @@
"enableCredentialRedactionDesc": "Scrubs API keys, tokens, private keys, and JWTs from messages, tool calls, and responses.",
"pricingAutoSyncDisabled": "Automatic Sync Disabled",
"pricingAutoSyncEnabled": "Automatic Sync Enabled",
-"modalityBridgeIntro": "Bridge multimodal content to text before it reaches text-only models. Vision is live; Audio arrives with the AudioBridge; Video is on the roadmap.",
-"modalityBridgeVisionTab": "Vision",
-"modalityBridgeAudioTab": "Audio",
-"modalityBridgeVideoTab": "Video",
-"modalityBridgeSubTabsAria": "Modality Bridge sections",
-"modalityBridgeVisionTitle": "Vision Bridge",
-"modalityBridgeVisionDesc": "Describe images with a vision model and continue with the user's chosen text model.",
-"modalityBridgeMode": "Mode",
-"modalityBridgeModeAuto": "Auto (recommended)",
-"modalityBridgeModeAutoHint": "Legacy heuristic: reroute individual models without credentials; describe otherwise.",
-"modalityBridgeModeDescribe": "Always describe",
-"modalityBridgeModeDescribeHint": "The model you chose always answers; images are replaced by text descriptions.",
-"modalityBridgeModeReroute": "Always reroute",
-"modalityBridgeModeRerouteHint": "Send the whole request to the best vision-capable model (falls back to describe when none is usable).",
-"modalityBridgeVisionModel": "Vision model",
-"modalityBridgeVisionModelAuto": "Auto (best available)",
-"modalityBridgeTaskAware": "Task-aware description",
-"modalityBridgeTaskAwareDesc": "Include the user's question as focus so the vision model describes what matters and transcribes visible text.",
-"modalityBridgePrompt": "Description prompt",
-"modalityBridgeAdvanced": "Advanced",
-"modalityBridgeTimeoutMs": "Timeout (ms)",
-"modalityBridgeMaxImages": "Max images per request",
-"modalityBridgeCacheEnabled": "Cache descriptions",
-"modalityBridgeCacheEnabledDesc": "Reuse descriptions for identical images (SHA-256 keyed, in-memory).",
-"modalityBridgeCacheTtlMinutes": "Cache TTL (minutes)",
-"modalityBridgeCacheMaxEntries": "Cache max entries",
-"modalityBridgeStatsBridged": "bridged",
-"modalityBridgeStatsCacheHits": "cache hits",
-"modalityBridgeStatsFailures": "failures",
-"modalityBridgeStatsLastUsed": "last used",
-"modalityBridgeStatsNever": "never",
-"modalityBridgeTestButton": "Test with sample image",
-"modalityBridgeTestRunning": "Testing…",
-"modalityBridgeTestOk": "Bridge OK — {count} image(s) described by {model}",
-"modalityBridgeTestReroute": "Bridge rerouted the request to {model}",
-"modalityBridgeTestNoop": "Bridge did not activate (model may support vision natively or bridge is disabled)",
-"modalityBridgeTestError": "Test failed: {message}",
-"modalityBridgeAudioComingSoon": "The Audio bridge (speech → text via /v1/audio/transcriptions) ships in the next release. Its settings keys are already reserved.",
-"modalityBridgeVideoComingSoon": "Video bridging (frame sampling + captioning) is on the backlog — see issue #9760.",
-"modalityBridgeMovedTitle": "Vision Bridge moved",
-"modalityBridgeMovedBody": "Vision Bridge settings now live in the dedicated Modality Bridge page.",
-"modalityBridgeMovedCta": "Open Modality Bridge settings",
-"modalityBridgeAudioTitle": "Audio Bridge",
-"modalityBridgeAudioDesc": "Transcribe audio with a speech-to-text model before continuing with the chosen text model.",
-"modalityBridgeAudioEnabled": "Enable Audio Bridge",
-"modalityBridgeAudioEnabledDesc": "Replace audio parts with transcripts when the target model cannot process audio.",
-"modalityBridgeAudioModel": "Speech-to-text model",
-"modalityBridgeAudioModelAuto": "Auto (first connected STT provider)",
-"modalityBridgeAudioMaxClips": "Max audio clips per request",
-"modalityBridgeAudioTestButton": "Test with sample audio",
-"modalityBridgeAudioTestRunning": "Testing audio…",
-"modalityBridgeAudioTestOk": "Audio Bridge OK — {count} clip(s) transcribed by {model}",
-"modalityBridgeAudioTestNoop": "Audio Bridge did not activate (the target may support audio, no STT provider is connected, or the bridge is disabled)",
-"modalityBridgeAudioTestError": "Audio test failed: {message}",
-"modelRoutingDescriptionPlaceholder": "Route Opus models to frontier combo",
-"cliproxyapiFallbackCodes": "Cliproxyapi Fallback Codes",
-"cliproxyapiFallbackDescription": "Cliproxyapi Fallback Description",
-"cliproxyapiHealthLabel": "Cliproxyapi Health Label",
-"cliproxyapiImportFailed": "Cliproxyapi Import Failed",
-"cliproxyapiImportResult": "Cliproxyapi Import Result",
-"cliproxyapiInvalidUrl": "Cliproxyapi Invalid URL",
-"cliproxyapiLifecycleNoticeAfter": "Cliproxyapi Lifecycle Notice After",
-"cliproxyapiLifecycleNoticeBefore": "Cliproxyapi Lifecycle Notice Before",
-"cliproxyapiLifecycleNoticeLink": "Cliproxyapi Lifecycle Notice Link",
-"cliproxyapiPortLabel": "Cliproxyapi Port Label",
-"cliproxyapiStatusLabel": "Cliproxyapi Status Label",
-"cliproxyapiVersionLabel": "Cliproxyapi Version Label",
-"collection": "Collection",
-"errorPage": {
+ "modalityBridgeIntro": "Bridge multimodal content to text before it reaches text-only models. Vision is live; Audio arrives with the AudioBridge; Video is on the roadmap.",
+ "modalityBridgeVisionTab": "Vision",
+ "modalityBridgeAudioTab": "Audio",
+ "modalityBridgeVideoTab": "Video",
+ "modalityBridgeSubTabsAria": "Modality Bridge sections",
+ "modalityBridgeVisionTitle": "Vision Bridge",
+ "modalityBridgeVisionDesc": "Describe images with a vision model and continue with the user's chosen text model.",
+ "modalityBridgeMode": "Mode",
+ "modalityBridgeModeAuto": "Auto (recommended)",
+ "modalityBridgeModeAutoHint": "Legacy heuristic: reroute individual models without credentials; describe otherwise.",
+ "modalityBridgeModeDescribe": "Always describe",
+ "modalityBridgeModeDescribeHint": "The model you chose always answers; images are replaced by text descriptions.",
+ "modalityBridgeModeReroute": "Always reroute",
+ "modalityBridgeModeRerouteHint": "Send the whole request to the best vision-capable model (falls back to describe when none is usable).",
+ "modalityBridgeVisionModel": "Vision model",
+ "modalityBridgeVisionModelAuto": "Auto (best available)",
+ "modalityBridgeTaskAware": "Task-aware description",
+ "modalityBridgeTaskAwareDesc": "Include the user's question as focus so the vision model describes what matters and transcribes visible text.",
+ "modalityBridgePrompt": "Description prompt",
+ "modalityBridgeAdvanced": "Advanced",
+ "modalityBridgeTimeoutMs": "Timeout (ms)",
+ "modalityBridgeMaxImages": "Max images per request",
+ "modalityBridgeCacheEnabled": "Cache descriptions",
+ "modalityBridgeCacheEnabledDesc": "Reuse descriptions for identical images (SHA-256 keyed, in-memory).",
+ "modalityBridgeCacheTtlMinutes": "Cache TTL (minutes)",
+ "modalityBridgeCacheMaxEntries": "Cache max entries",
+ "modalityBridgeStatsBridged": "bridged",
+ "modalityBridgeStatsCacheHits": "cache hits",
+ "modalityBridgeStatsFailures": "failures",
+ "modalityBridgeStatsLastUsed": "last used",
+ "modalityBridgeStatsNever": "never",
+ "modalityBridgeTestButton": "Test with sample image",
+ "modalityBridgeTestRunning": "Testing…",
+ "modalityBridgeTestOk": "Bridge OK — {count} image(s) described by {model}",
+ "modalityBridgeTestReroute": "Bridge rerouted the request to {model}",
+ "modalityBridgeTestNoop": "Bridge did not activate (model may support vision natively or bridge is disabled)",
+ "modalityBridgeTestError": "Test failed: {message}",
+ "modalityBridgeAudioComingSoon": "The Audio bridge (speech → text via /v1/audio/transcriptions) ships in the next release. Its settings keys are already reserved.",
+ "modalityBridgeVideoComingSoon": "Video bridging (frame sampling + captioning) is on the backlog — see issue #9760.",
+ "modalityBridgeMovedTitle": "Vision Bridge moved",
+ "modalityBridgeMovedBody": "Vision Bridge settings now live in the dedicated Modality Bridge page.",
+ "modalityBridgeMovedCta": "Open Modality Bridge settings",
+ "modalityBridgeAudioTitle": "Audio Bridge",
+ "modalityBridgeAudioDesc": "Transcribe audio with a speech-to-text model before continuing with the chosen text model.",
+ "modalityBridgeAudioEnabled": "Enable Audio Bridge",
+ "modalityBridgeAudioEnabledDesc": "Replace audio parts with transcripts when the target model cannot process audio.",
+ "modalityBridgeAudioModel": "Speech-to-text model",
+ "modalityBridgeAudioModelAuto": "Auto (first connected STT provider)",
+ "modalityBridgeAudioMaxClips": "Max audio clips per request",
+ "modalityBridgeAudioTestButton": "Test with sample audio",
+ "modalityBridgeAudioTestRunning": "Testing audio…",
+ "modalityBridgeAudioTestOk": "Audio Bridge OK — {count} clip(s) transcribed by {model}",
+ "modalityBridgeAudioTestNoop": "Audio Bridge did not activate (the target may support audio, no STT provider is connected, or the bridge is disabled)",
+ "modalityBridgeAudioTestError": "Audio test failed: {message}",
+ "modelRoutingDescriptionPlaceholder": "Route Opus models to frontier combo",
+ "cliproxyapiFallbackCodes": "Cliproxyapi Fallback Codes",
+ "cliproxyapiFallbackDescription": "Cliproxyapi Fallback Description",
+ "cliproxyapiHealthLabel": "Cliproxyapi Health Label",
+ "cliproxyapiImportFailed": "Cliproxyapi Import Failed",
+ "cliproxyapiImportResult": "Cliproxyapi Import Result",
+ "cliproxyapiInvalidUrl": "Cliproxyapi Invalid URL",
+ "cliproxyapiLifecycleNoticeAfter": "Cliproxyapi Lifecycle Notice After",
+ "cliproxyapiLifecycleNoticeBefore": "Cliproxyapi Lifecycle Notice Before",
+ "cliproxyapiLifecycleNoticeLink": "Cliproxyapi Lifecycle Notice Link",
+ "cliproxyapiPortLabel": "Cliproxyapi Port Label",
+ "cliproxyapiStatusLabel": "Cliproxyapi Status Label",
+ "cliproxyapiVersionLabel": "Cliproxyapi Version Label",
+ "collection": "Collection",
+ "errorPage": {
"description": "We could not load settings right now. Please retry in a few seconds.",
"errorId": "Error ID: {id}",
"retry": "Try Again",
"title": "Failed to load settings"
},
-"host": "Host",
-"notInstalled": "Not installed",
-"oneproxyActions": "Oneproxy Actions",
-"oneproxyActive": "Oneproxy Active",
-"oneproxyAnonymity": "Oneproxy Anonymity",
-"oneproxyCountry": "Oneproxy Country",
-"oneproxyDelete": "Oneproxy Delete",
-"oneproxyEmpty": "Oneproxy Empty",
-"oneproxyHost": "Oneproxy Host",
-"oneproxyLatency": "Oneproxy Latency",
-"oneproxyProtocol": "Oneproxy Protocol",
-"oneproxyQuality": "Oneproxy Quality",
-"oneproxySyncFailed": "Sync failed: {error}",
-"oneproxySyncSuccess": "Synced {total} proxies ({added} new, {updated} updated)",
-"proxyDocumentationSocks5DescAfter": "Proxy Documentation Socks5 Desc After",
-"proxyFreePoolAddProxy": "Proxy Free Pool Add Proxy",
-"proxyFreePoolAdding": "Proxy Free Pool Adding",
-"proxyFreePoolSelectProxy": "Proxy Free Pool Select Proxy",
-"proxyStatusActive": "Proxy Status Active",
-"proxyStatusInactive": "Proxy Status Inactive",
-"routingAddEntry": "Add entry",
-"settingSaveFailed": "Setting Save Failed",
-"settingSaved": "Setting Saved",
-"skillsmpApiKeyHintAfter": ". Rate limit: {limit} requests/day.",
-"skillsmpApiKeyHintBefore": "Get your API key from",
-"syncFailed": "Sync failed",
-"unhealthy": "Unhealthy",
-"oneproxyDescription": "Fetch and rotate free validated proxies from the 1proxy community platform",
-"oneproxySyncing": "Syncing...",
-"oneproxySyncNow": "Sync Now",
-"oneproxyClearAll": "Clear All",
-"oneproxyGoogle": "Google",
-"oneproxyClearAllConfirm": "Clear all 1proxy proxies?",
-"memorySkillsSkillsmpDescription": "Connect to SkillsMP to discover and install skills from the marketplace.",
-"memorySkillsActiveProviderDescription": "Choose which provider the Skills page uses for search and install.",
-"memorySkillsSkillsmpProviderTitle": "SkillsMP Marketplace",
-"memorySkillsSkillsmpProviderDescription": "Authenticated marketplace (uses your SkillsMP API key).",
-"memorySkillsSkillsshProviderTitle": "skills.sh Directory",
-"memorySkillsSkillsshProviderDescription": "Public directory provider (no API key required).",
-"routingCcBridgeCatalogName": "Anthropic-compatible CC bridge",
-"routingClaudeProviderName": "Claude (OAuth)",
-"routingClaudeProviderDescription": "Native Claude provider with OAuth-issued tokens.",
-"routingCcBridgeName": "Claude-Code Bridge",
-"routingCcBridgeDescription": "Relay endpoints using API keys (anthropic-compatible-cc-*).",
-"routingCustomProviderDescription": "Custom provider.",
-"routingUnknownOpKind": "Unknown op kind: {kind}",
-"routingInvalidJson": "Invalid JSON: {error}",
-"routingConfigMustBeObject": "Config must be a JSON object",
-"routingEnabledMustBeBoolean": "`enabled` must be true or false",
-"routingPipelineMustBeArray": "`pipeline` must be an array of ops",
-"routingPipelineTooLong": "Pipeline cannot exceed 50 ops",
-"routingOpMissingKind": "Op #{index}: missing or invalid `kind`",
-"routingOpUnknownKind": "Op #{index}: unknown kind \"{kind}\"",
-"routingJsonEditorHide": "Hide JSON editor",
-"routingJsonEditorImportExport": "Import / export JSON",
-"routingJsonEditorLabel": "JSON (edit and apply, or paste to import)",
-"routingApplyJson": "Apply JSON",
-"routingTransformsFootnote": "All transform ops are idempotent on re-run. Changes take effect immediately on the next request."
+ "host": "Host",
+ "notInstalled": "Not installed",
+ "oneproxyActions": "Oneproxy Actions",
+ "oneproxyActive": "Oneproxy Active",
+ "oneproxyAnonymity": "Oneproxy Anonymity",
+ "oneproxyCountry": "Oneproxy Country",
+ "oneproxyDelete": "Oneproxy Delete",
+ "oneproxyEmpty": "Oneproxy Empty",
+ "oneproxyHost": "Oneproxy Host",
+ "oneproxyLatency": "Oneproxy Latency",
+ "oneproxyProtocol": "Oneproxy Protocol",
+ "oneproxyQuality": "Oneproxy Quality",
+ "oneproxySyncFailed": "Sync failed: {error}",
+ "oneproxySyncSuccess": "Synced {total} proxies ({added} new, {updated} updated)",
+ "proxyDocumentationSocks5DescAfter": "Proxy Documentation Socks5 Desc After",
+ "proxyFreePoolAddProxy": "Proxy Free Pool Add Proxy",
+ "proxyFreePoolAdding": "Proxy Free Pool Adding",
+ "proxyFreePoolSelectProxy": "Proxy Free Pool Select Proxy",
+ "proxyStatusActive": "Proxy Status Active",
+ "proxyStatusInactive": "Proxy Status Inactive",
+ "routingAddEntry": "Add entry",
+ "settingSaveFailed": "Setting Save Failed",
+ "settingSaved": "Setting Saved",
+ "skillsmpApiKeyHintAfter": ". Rate limit: {limit} requests/day.",
+ "skillsmpApiKeyHintBefore": "Get your API key from",
+ "syncFailed": "Sync failed",
+ "unhealthy": "Unhealthy",
+ "oneproxyDescription": "Fetch and rotate free validated proxies from the 1proxy community platform",
+ "oneproxySyncing": "Syncing...",
+ "oneproxySyncNow": "Sync Now",
+ "oneproxyClearAll": "Clear All",
+ "oneproxyGoogle": "Google",
+ "oneproxyClearAllConfirm": "Clear all 1proxy proxies?",
+ "memorySkillsSkillsmpDescription": "Connect to SkillsMP to discover and install skills from the marketplace.",
+ "memorySkillsActiveProviderDescription": "Choose which provider the Skills page uses for search and install.",
+ "memorySkillsSkillsmpProviderTitle": "SkillsMP Marketplace",
+ "memorySkillsSkillsmpProviderDescription": "Authenticated marketplace (uses your SkillsMP API key).",
+ "memorySkillsSkillsshProviderTitle": "skills.sh Directory",
+ "memorySkillsSkillsshProviderDescription": "Public directory provider (no API key required).",
+ "routingCcBridgeCatalogName": "Anthropic-compatible CC bridge",
+ "routingClaudeProviderName": "Claude (OAuth)",
+ "routingClaudeProviderDescription": "Native Claude provider with OAuth-issued tokens.",
+ "routingCcBridgeName": "Claude-Code Bridge",
+ "routingCcBridgeDescription": "Relay endpoints using API keys (anthropic-compatible-cc-*).",
+ "routingCustomProviderDescription": "Custom provider.",
+ "routingUnknownOpKind": "Unknown op kind: {kind}",
+ "routingInvalidJson": "Invalid JSON: {error}",
+ "routingConfigMustBeObject": "Config must be a JSON object",
+ "routingEnabledMustBeBoolean": "`enabled` must be true or false",
+ "routingPipelineMustBeArray": "`pipeline` must be an array of ops",
+ "routingPipelineTooLong": "Pipeline cannot exceed 50 ops",
+ "routingOpMissingKind": "Op #{index}: missing or invalid `kind`",
+ "routingOpUnknownKind": "Op #{index}: unknown kind \"{kind}\"",
+ "routingJsonEditorHide": "Hide JSON editor",
+ "routingJsonEditorImportExport": "Import / export JSON",
+ "routingJsonEditorLabel": "JSON (edit and apply, or paste to import)",
+ "routingApplyJson": "Apply JSON",
+ "routingTransformsFootnote": "All transform ops are idempotent on re-run. Changes take effect immediately on the next request."
},
"contextRtk": {
"title": "RTK Engine",
@@ -10482,7 +10484,8 @@
"gitlabDuoSetupTitle": "GitLab Duo OAuth setup",
"gitlabDuoSetupMessage": "GitLab Duo OAuth is not configured. Register an OAuth application at {applicationsUrl} with redirect URI {redirectUri} and scopes \"{scopes}\", then set {clientIdEnv} (and optionally {clientSecretEnv}) and restart.",
"gitlabDuoSetupDescription": "After the application is registered and the env vars are set on this OmniRoute instance, click Continue to start the OAuth login.",
- "continue": "Continue"
+ "continue": "Continue",
+ "googleOAuthWarning": "Remote access + Google OAuth: bundled credentials only accept loopback redirects like 127.0.0.1. The browser that approves Google must be able to reach OmniRoute on that local port, usually by opening OmniRoute locally or using an SSH/local-forward tunnel. Recommended for remote installs: on your own computer run npx omniroute login antigravity and paste the credential blob it prints into the field below. For fully remote use without this local callback, configure your own OAuth credentials."
},
"cursorAuthModal": {
"title": "Connect Cursor IDE",
@@ -12320,13 +12323,13 @@
"updateProviderFailed": "Failed to update provider",
"providerEnabled": "{provider} enabled",
"providerDisabled": "{provider} disabled",
-"providerAdded": "{provider} added",
-"add": "Add",
-"manualApiKey": "Use a manual API key",
-"createDahlTokenFailed": "Failed to create Dahl token",
-"providerProxy": "Proxy",
-"providerProxyConfigureHint": "Configure proxy",
-"providerProxyTitleConfigured": "Proxy configured: {host}"
+ "providerAdded": "{provider} added",
+ "add": "Add",
+ "manualApiKey": "Use a manual API key",
+ "createDahlTokenFailed": "Failed to create Dahl token",
+ "providerProxy": "Proxy",
+ "providerProxyConfigureHint": "Configure proxy",
+ "providerProxyTitleConfigured": "Proxy configured: {host}"
},
"gamification": {
"leaderboardScopes": {
@@ -13020,14 +13023,14 @@
"testFailed": "Test failed"
},
"kimiSponsorBanner": {
- "title": "Kimi (Moonshot AI) is OmniRoute's founding Open Source Friend",
+ "title": "Kimi (Moonshot AI) is now an official sponsor of OmniRoute",
"description": "Kimi K3 brings a 1M-token context window and frontier coding performance to OmniRoute at a fraction of the cost.",
"cta": "Get Kimi Code",
"partnerLinkNote": "Partner link",
"dismissAriaLabel": "Dismiss"
},
"featureFlagExposeFunctionalGatewayMirrorsDescription": "Advertise / mirror ids on /v1/models for models whose canonical owner has no active credential but a passthrough gateway with an active credential routes them. Warning: adds catalog entries for all clients when enabled globally.",
-"radarPage": {
+ "radarPage": {
"title": "Radar Catalog",
"subtitle": "Free model catalog enriched with community intelligence",
"loading": "Loading catalog...",
@@ -13083,7 +13086,7 @@
"campaignsUpsellCommunity": "Limited-time campaigns are a supporter extra. Everything on this page's fixed links stays free for everyone.",
"campaignsValidUntil": "Valid until {date}"
},
-"radarSetupPage": {
+ "radarSetupPage": {
"title": "Provider Setup",
"setupTitle": "Setup: {provider}",
"setupSubtitle": "Follow the steps below to configure this provider",
@@ -13108,7 +13111,7 @@
"addConnectionDescription": "Don't have a connection yet? Add one in the providers dashboard.",
"addConnectionLink": "Go to providers →"
},
-"resilienceConnections": {
+ "resilienceConnections": {
"title": "Connection Resilience",
"table": {
"status": "Status",
@@ -13202,12 +13205,12 @@
"degraded.source.modelLockouts": "Model Lockouts",
"degraded.source.count": "Connection Count"
},
-"featureFlagCapabilityFilterEnabledDescription": "Reject requests before dispatch when the target model lacks required capabilities (vision, tools, structured output, context window). Protects direct single-provider requests that bypass the combo-layer compatibility filter.",
-"capabilityFilter.visionMismatch": "Provider does not support vision for this image request",
-"capabilityFilter.toolsMismatch": "Provider does not support tool calling",
-"capabilityFilter.structuredOutputMismatch": "Provider does not support structured output",
-"capabilityFilter.contextWindowMismatch": "Request exceeds provider context window",
-"publicSystem": {
+ "featureFlagCapabilityFilterEnabledDescription": "Reject requests before dispatch when the target model lacks required capabilities (vision, tools, structured output, context window). Protects direct single-provider requests that bypass the combo-layer compatibility filter.",
+ "capabilityFilter.visionMismatch": "Provider does not support vision for this image request",
+ "capabilityFilter.toolsMismatch": "Provider does not support tool calling",
+ "capabilityFilter.structuredOutputMismatch": "Provider does not support structured output",
+ "capabilityFilter.contextWindowMismatch": "Request exceeds provider context window",
+ "publicSystem": {
"notFound": {
"title": "Page not found",
"description": "The page you're looking for doesn't exist or has been moved.",
@@ -13344,7 +13347,7 @@
}
}
},
-"kiroAuthModal": {
+ "kiroAuthModal": {
"title": "Connect {providerLabel}",
"chooseMethod": "Choose your authentication method:",
"builderId": "AWS Builder ID",
@@ -13386,7 +13389,7 @@
"errorApiKeyImportFailed": "API key import failed",
"errorIdcStartUrlRequired": "Please enter your IDC start URL"
},
-"kiroSocialOAuthModal": {
+ "kiroSocialOAuthModal": {
"title": "Connect {providerLabel} via {providerName}",
"errorStartAuthorization": "Failed to start authorization",
"errorAuthorizationExpired": "Authorization expired. Start the login flow again.",
@@ -13405,7 +13408,7 @@
"errorTitle": "Connection Failed",
"close": "Close"
},
-"traeAuthModal": {
+ "traeAuthModal": {
"errorAuthorizationFailed": "Authorization failed",
"errorPopupBlocked": "Popup blocked — allow popups for this site, or paste the token manually below.",
"errorPopupClosed": "Authorization window was closed before completing.",
@@ -13431,14 +13434,14 @@
"importToken": "Import Token",
"cancel": "Cancel"
},
-"sharedComponents": {
+ "sharedComponents": {
"distributeProxies": {
"distributing": "Distributing...",
"complete": "Complete",
"defaultLabel": "Distribute Proxies"
}
},
-"providerTest": {
+ "providerTest": {
"dialogLabel": "Test {provider}",
"deprecated": "deprecated",
"risk": "risk",
@@ -13473,7 +13476,7 @@
"tokens": "Tokens"
}
},
-"proxyLog": {
+ "proxyLog": {
"detailAriaLabel": "Proxy log detail",
"event": "Proxy Event",
"close": "Close proxy detail modal",
@@ -13491,7 +13494,7 @@
"error": "Error",
"configuration": "Proxy Configuration"
},
-"requestTimeline": {
+ "requestTimeline": {
"title": "Request Timeline",
"modes": {
"follow": "Follow",
@@ -13516,7 +13519,7 @@
"unknownModel": "unknown",
"pending": "pending"
},
-"metadata": {
+ "metadata": {
"compressionTitle": "Compression",
"compressionDescription": "Configure context compression settings to reduce token usage and costs.",
"relayTitle": "OmniRoute — Relay Proxies",
@@ -13553,6 +13556,25 @@
"cancelConfirmMessage": "The hub will abort the execution on the runner. This cannot be undone.",
"cancelFailed": "The hub refused the cancellation",
"close": "Close",
- "error": "Error"
+ "error": "Error",
+ "faroTitle": "Faro — fleet spokesperson",
+ "faroSubtitle": "Chat and voice, anchored in real fleet events. Destructive commands always ask for confirmation.",
+ "faroEmpty": "Ask about the fleet — e.g. \"how is the fleet?\"",
+ "faroPending": "Faro is asking for confirmation",
+ "faroPlaceholder": "talk to Faro…",
+ "faroSend": "send",
+ "faroOffline": "Faro (spokesperson) is offline",
+ "yes": "Yes",
+ "no": "No",
+ "pushToTalk": "Hold to talk",
+ "speakAnswers": "speak answers",
+ "voiceModels": "Voice models (provider/model of this OmniRoute)",
+ "voiceIdle": "talk",
+ "voiceListening": "listening…",
+ "voiceThinking": "thinking…",
+ "voiceSpeaking": "speaking…",
+ "sttFailed": "Transcription failed (check the STT model/provider)",
+ "ttsFailed": "Speech synthesis failed (check the TTS model/provider)",
+ "micDenied": "Microphone unavailable or permission denied"
}
-}
+}
\ No newline at end of file
diff --git a/src/i18n/messages/pt-BR.json b/src/i18n/messages/pt-BR.json
index 52820e2ee3..611eeb8667 100644
--- a/src/i18n/messages/pt-BR.json
+++ b/src/i18n/messages/pt-BR.json
@@ -4,7 +4,7 @@
"cancel": "Cancelar",
"delete": "Excluir",
"loading": "Carregando...",
- "selectOption": "Selecione uma opção",
+ "selectOption": "Selecionar uma opção",
"error": "Ocorreu um erro",
"success": "Sucesso",
"confirm": "Tem certeza?",
@@ -13,7 +13,7 @@
"previousPage": "Página anterior",
"nextPage": "Próxima página",
"capsLockOn": "Caps Lock está ativado",
- "dismissNotification": "Descartar notificação",
+ "dismissNotification": "Dispensar notificação",
"toggleColumns": "Alternar colunas",
"confirmTitle": "Confirmar",
"confirmAction": "Confirmar",
@@ -163,7 +163,7 @@
"effortUltra": "Ultra",
"reasoningEffort": "Esforço de raciocínio",
"wireApi": "Wire API",
- "modelAliases": "Aliases do modelo",
+ "modelAliases": "Aliases de modelo",
"combos": "Combos",
"noModelsFound": "Nenhum modelo encontrado",
"clear": "Claro",
@@ -418,7 +418,7 @@
"cloudBenefitAccess": "Cloud Benefit Access",
"maxRetries": "Max Retries",
"queueTimeout": "Queue Timeout",
- "queueDepth": "Profundidade da fila",
+ "queueDepth": "__MISSING__:Queue Depth",
"addProvider": "Add Provider",
"realtime": "Realtime",
"totalTranslations": "Total Translations",
@@ -708,7 +708,7 @@
"tokensRedeemCode": "Resgatar código",
"tokensRedeemCodePlaceholder": "Insira o código do convite",
"tokensYourActiveInvites": "Seus convites ativos",
- "tokensTransferSuccess": "Transferência bem-sucedida ({idempotencyKey})",
+ "tokensTransferSuccess": "Transferência realizada com sucesso ({idempotencyKey})",
"tokensTransferFailed": "Falha na transferência",
"tokensCreateInviteFailed": "Falha ao criar convite",
"tokensRevokeInviteFailed": "Falha ao revogar convite",
@@ -716,7 +716,7 @@
"tokensRedeemFailed": "Falha ao resgatar convite",
"tokensConnectServerFailed": "Falha ao conectar ao servidor",
"tokensDisconnectServerFailed": "Falha ao desconectar do servidor",
- "tokensAmount": "Valor",
+ "tokensAmount": "Quantia",
"tokensSending": "Enviando...",
"tokensFrom": "De",
"tokensTo": "Para",
@@ -725,7 +725,7 @@
"tokensSent": "Enviado",
"tokensReceived": "Recebido",
"tokensCreatingInvite": "Criando...",
- "tokensCreateInvite": "Criar convite",
+ "tokensCreateInvite": "Criar Convite",
"tokensInviteCreated": "Código de convite criado",
"tokensRedeeming": "Resgatando...",
"tokensRedeem": "Resgatar",
@@ -734,12 +734,12 @@
"tokensRevoke": "Revogar",
"tokensConnecting": "Conectando...",
"tokensConnectServer": "Conectar Servidor",
- "tokensNoServersConnected": "Nenhum servidor conectado. Conecte-se a um servidor da comunidade para compartilhar tabelas de classificação.",
+ "tokensNoServersConnected": "Nenhum servidor conectado. Conecte-se a um servidor da comunidade para compartilhar rankings.",
"tokensServerStatus": {
"connected": "Conectado",
"disconnected": "Desconectado",
"pending": "Pendente",
- "syncing": "Sincronizando",
+ "syncing": "Syncing",
"error": "Erro"
},
"tokensLastSync": "Última sincronização: {date}",
@@ -767,22 +767,22 @@
"batchFileDetailCopyId": "Copiar ID",
"batchFileDetailClose": "Fechar",
"batchFileDetailFailedToLoad": "Falha ao carregar o conteúdo do arquivo",
- "batchFileDetailLoadError": "Erro ao carregar o conteúdo do arquivo",
+ "batchFileDetailLoadError": "Erro ao carregar conteúdo do arquivo",
"batchFilesListSearchPlaceholder": "Pesquise por ID ou nome de arquivo…",
"batchFilesListFilesTable": "Arquivos",
"batchFilesCount": "{count, plural, one {# arquivo} other {# arquivos}}",
- "batchFilesAllPurposes": "Todas as finalidades",
+ "batchFilesAllPurposes": "Todos os propósitos",
"batchFilesFilename": "Nome do arquivo",
- "batchFilesPurpose": "Finalidade",
- "batchFilesExpires": "Expira em",
+ "batchFilesPurpose": "Propósito",
+ "batchFilesExpires": "Expira",
"batchFilesNoneFound": "Nenhum arquivo encontrado",
"batchFilesNeverExpires": "Nunca",
"batchFileInUseByActiveBatch": "Arquivo em uso por um lote ativo",
"batchFilePurpose": {
"batch": "Entrada de lote",
"batch-output": "Saída de lote",
- "fine-tune": "Ajuste fino",
- "assistants": "Assistentes"
+ "fine-tune": "Fine-tuning",
+ "assistants": "Assistants"
},
"batchPageLoadingMore": "Carregando mais…",
"recommended": "Recomendado",
@@ -829,8 +829,8 @@
"wizardValidationOk": "Todas as linhas válidas",
"wizardValidating": "Validando…",
"wizardValidationParseFailed": "Falha na validação — não foi possível analisar o conteúdo.",
- "wizardValidationSummary": "{lines} linhas · {ids} custom_ids exclusivos",
- "wizardValidationErrorCount": "{count, plural, one {# erro encontrado} other {# erros encontrados}}",
+ "wizardValidationSummary": "{lines} linhas · {ids} custom_ids únicos",
+ "wizardValidationErrorCount": "{count, plural, one {# erro} other {# erros}} encontrado(s)",
"wizardValidationDuplicateIds": "custom_ids duplicados detectados:",
"wizardValidationFirstErrors": "Erros (primeiros {count}):",
"wizardValidationLine": "Linha {line}",
@@ -965,8 +965,8 @@
"batchFileDownloadFull": "__MISSING__:Download Full File"
},
"disabled": "Desabilitado",
- "featureFlagOmnirouteEmergencyFallbackDescription": "Encaminhar solicitações com orçamento esgotado para o provedor/modelo de fallback gratuito de emergência.",
- "featureFlagArenaEloSyncEnabledDescription": "Habilitar sincronização periódica de ELO da tabela de classificação do Arena AI para rankings de inteligência de modelos.",
+ "featureFlagOmnirouteEmergencyFallbackDescription": "__MISSING__:Route budget-exhausted requests to the emergency free fallback provider/model.",
+ "featureFlagArenaEloSyncEnabledDescription": "__MISSING__:Enable periodic Arena AI leaderboard ELO sync for model intelligence rankings.",
"featureFlagExposeCcDiscoveryAliasesDescription": "Divulgar ids espelho claude/<provider>/<model> em /v1/models para que a descoberta de modelos do gateway Claude Code liste modelos não-Claude. Atenção: duplica as entradas do catálogo para todos os clientes quando ativado globalmente.",
"sidebar": {
"home": "Início",
@@ -1095,9 +1095,9 @@
"contextAggressiveSubtitle": "Resumo e envelhecimento",
"contextUltraSubtitle": "Poda heurística",
"contextOmniglyphSubtitle": "Contexto como imagens",
- "compressionStudioSubtitle": "Cascata de mecanismos em tempo real",
+ "compressionStudioSubtitle": "Cascata de engines em tempo real",
"compressionExclusionsSubtitle": "Bypass por modelo/endpoint",
- "chaosConfigSubtitle": "Execução paralela multimodelo",
+ "chaosConfigSubtitle": "Execução paralela multi-modelo",
"routingSection": "Routing",
"protocolsSection": "Protocols",
"agentsAiSection": "Agents & AI",
@@ -1111,7 +1111,7 @@
"aiFeaturesSection": "AI Features",
"mcp": "MCP",
"a2a": "A2A",
- "plugins": "Plugins",
+ "plugins": "__MISSING__:Plugins",
"apiEndpoints": "API Endpoints",
"batchFiles": "Files",
"analyticsEvals": "Evals",
@@ -1120,10 +1120,10 @@
"analyticsComboHealth": "Combo Health",
"analyticsCompression": "Compression",
"costsBudget": "Budget",
- "costsFreeTiers": "Orçamento do nível gratuito",
- "costsFreeTiersSubtitle": "Cotas mensais de tokens gratuitos",
- "freeProviderRankings": "Rankings de provedores gratuitos",
- "freeProviderRankingsSubtitle": "Melhores provedores gratuitos classificados por pontuações ELO do modelo",
+ "costsFreeTiers": "__MISSING__:Free-Tier Budget",
+ "costsFreeTiersSubtitle": "__MISSING__:Monthly free-token allowances",
+ "freeProviderRankings": "__MISSING__:Free Provider Rankings",
+ "freeProviderRankingsSubtitle": "__MISSING__:Best free providers ranked by model ELO scores",
"radar": "Catálogo Radar",
"radarSubtitle": "Catálogo de modelos gratuitos enriquecido pela comunidade",
"costsQuotaShare": "Compartilhamento de Cota",
@@ -1143,7 +1143,7 @@
"settingsAuthz": "Autorização",
"settingsRouting": "Routing",
"settingsResilience": "Resilience",
- "modelLockout": "Bloqueio de modelo",
+ "modelLockout": "__MISSING__:Model Lockout",
"settingsAdvanced": "Advanced",
"omniProxySection": "OmniProxy",
"quotaTracker": "Provider Quota",
@@ -1151,7 +1151,7 @@
"runtime": "Runtime",
"consoleLogs": "Console Logs",
"logsTimeline": "Timeline",
-"logsTimelineSubtitle": "Linha do tempo de solicitação visual",
+ "logsTimelineSubtitle": "Linha do tempo de solicitação visual",
"globalRouting": "Global Routing",
"mitmProxy": "MITM Proxy",
"oneProxy": "1Proxy",
@@ -1192,8 +1192,8 @@
"analyticsCompressionSubtitle": "Estatísticas de economia de tokens",
"analyticsSearchSubtitle": "Analytics das ferramentas de busca",
"analyticsEvalsSubtitle": "Resultados das suites de avaliação",
- "providerStats": "Estatísticas do provedor",
- "providerStatsSubtitle": "Métricas de latência e desempenho",
+ "providerStats": "__MISSING__:Provider Stats",
+ "providerStatsSubtitle": "__MISSING__:Latency and performance metrics",
"logsSubtitle": "Logs da aplicação",
"logsProxySubtitle": "Logs de tráfego do proxy",
"consoleLogsSubtitle": "Saída do console",
@@ -1213,7 +1213,7 @@
"agentSkillsSubtitle": "Registro de skills A2A",
"mcpSubtitle": "Controles do servidor MCP",
"a2aSubtitle": "Servidor do protocolo A2A",
- "pluginsSubtitle": "Marketplace e instalações de plugins",
+ "pluginsSubtitle": "__MISSING__:Plugin marketplace & installs",
"mediaSubtitle": "Arquivos de mídia em cache",
"batchFilesSubtitle": "Arquivos de entrada/saída de batch",
"settingsSubtitle": "Todas as configurações",
@@ -1251,25 +1251,25 @@
"cliAgentsSubtitle": "Agentes autônomos com CLI",
"acpAgents": "ACP Agents",
"acpAgentsSubtitle": "CLIs spawnadas pelo OmniRoute",
- "skipToContent": "Pular para o conteúdo",
+ "skipToContent": "__MISSING__:Skip to content",
"mainNavigation": "Navegação principal",
- "unpinSection": "Desafixar seção",
- "pinSectionOpen": "Fixar seção aberta",
- "reloadPage": "Recarregar Página",
- "dragReorderSection": "Arraste para reordenar a seção",
- "dragReorderItem": "Arraste para reordenar",
- "cannotHide": "Este item não pode ser ocultado",
- "alwaysVisible": "Sempre visível",
- "groupSeparatorLabel": "Separador",
+ "unpinSection": "__MISSING__:Unpin section",
+ "pinSectionOpen": "__MISSING__:Pin section open",
+ "reloadPage": "__MISSING__:Reload Page",
+ "dragReorderSection": "__MISSING__:Drag to reorder section",
+ "dragReorderItem": "__MISSING__:Drag to reorder",
+ "cannotHide": "__MISSING__:This item cannot be hidden",
+ "alwaysVisible": "__MISSING__:Always visible",
+ "groupSeparatorLabel": "__MISSING__:Separator",
"discovery": "Descoberta",
"discoverySubtitle": "Buscar acesso gratuito em provedores",
"conductor": "Conductor",
"conductorSubtitle": "Frota de agentes CLI",
-"resilienceConnections": "Resiliência de Conexão",
-"resilienceConnectionsSubtitle": "Cooldown, disjuntor, estado de bloqueio",
-"settingsModalityBridge": "Ponte de Modalidade",
-"settingsModalityBridgeSubtitle": "Fallback de imagem/áudio → texto para modelos apenas de texto",
-"commandPalette": {
+ "resilienceConnections": "Resiliência de Conexão",
+ "resilienceConnectionsSubtitle": "Cooldown, disjuntor, estado de bloqueio",
+ "settingsModalityBridge": "Ponte de Modalidade",
+ "settingsModalityBridgeSubtitle": "Fallback de imagem/áudio → texto para modelos apenas de texto",
+ "commandPalette": {
"title": "__MISSING__:Command palette",
"searchPlaceholder": "__MISSING__:Search pages, settings, tools...",
"clearSearch": "__MISSING__:Clear search",
@@ -1538,8 +1538,8 @@
"quickNavigation": "Navegação rápida",
"quickNavigationTitle": "Navegação rápida (⌘K / Ctrl+K)",
"openQuickNavigation": "Abrir navegação rápida",
- "switchToLightMode": "Alternar para o modo claro",
- "switchToDarkMode": "Alternar para o modo escuro",
+ "switchToLightMode": "Mudar para modo claro",
+ "switchToDarkMode": "Mudar para modo escuro",
"language": "Idioma",
"providers": "Provedores",
"providerDescription": "Gerencie suas conexões de provedores de IA",
@@ -1643,7 +1643,7 @@
"cloudSyncStatus": {
"synced": "Sincronizado",
"syncing": "Sincronizando...",
- "off": "Sincronização desativada",
+ "off": "Sincronização desligada",
"error": "Erro de sincronização",
"disabled": "Desativado",
"connected": "conectado",
@@ -1654,34 +1654,34 @@
"breadcrumbs": {
"ariaLabel": "Trilha de navegação",
"dashboard": "Painel",
- "providers": "Provedores",
+ "providers": "Providers",
"combos": "Combos",
"settings": "Configurações",
"general": "Geral",
- "appearance": "Aparência",
- "ai": "Configurações de IA",
- "routing": "Roteamento",
- "resilience": "Resiliência",
- "advanced": "Avançado",
- "accessTokens": "Tokens de acesso",
- "featureFlags": "Feature Flags",
+ "appearance": "Appearance",
+ "ai": "AI Settings",
+ "routing": "Routing",
+ "resilience": "Resilience",
+ "advanced": "Advanced",
+ "accessTokens": "Tokens de Acesso",
+ "featureFlags": "Sinalizadores de recursos",
"logs": "Logs",
- "auditLog": "Log de auditoria",
+ "auditLog": "Log de Auditoria",
"console": "Console",
"logger": "Logger",
"translator": "Tradutor",
"playground": "Playground",
"add": "Adicionar",
"edit": "Editar",
- "apiKeys": "Chaves de API",
+ "apiKeys": "Gerenciador API",
"models": "Modelos",
- "cliCode": "Código CLI",
- "cliAgents": "Agentes CLI",
- "acpAgents": "Agentes ACP",
- "endpoint": "Endpoint",
+ "cliCode": "CLI Code's",
+ "cliAgents": "CLI Agents",
+ "acpAgents": "ACP Agents",
+ "endpoint": "Ponto final",
"apiManager": "Gerenciador de API",
"context": "Contexto",
- "compression": "Compressão",
+ "compression": "Compression",
"services": "Serviços",
"analytics": "Análises",
"costs": "Custos",
@@ -1689,57 +1689,57 @@
"runtime": "Runtime",
"webhooks": "Webhooks",
"home": "Início",
- "activity": "Atividade",
- "agentSkills": "AgentSkills",
- "comboHealth": "Saúde do combo",
- "evals": "Avaliações",
- "search": "Busca",
- "utilization": "Utilização",
- "apiEndpoints": "Endpoints de API",
- "audit": "Auditoria",
+ "activity": "Activity",
+ "agentSkills": "Habilidades do agente",
+ "comboHealth": "Combo Health",
+ "evals": "Evals",
+ "search": "Pesquisar",
+ "utilization": "Utilization",
+ "apiEndpoints": "API Endpoints",
+ "audit": "Audit",
"a2a": "A2A",
"mcp": "MCP",
- "batch": "Lote",
+ "batch": "Batch",
"files": "Arquivos",
"media": "Mídia",
"cache": "Cache",
- "changelog": "Registro de alterações",
+ "changelog": "Changelog",
"chaos": "Caos",
- "cloudAgents": "Agentes em nuvem",
+ "cloudAgents": "Agentes de nuvem",
"live": "Ao vivo",
"studio": "Studio",
- "aggressive": "Agressivo",
- "caveman": "Homem das cavernas",
+ "aggressive": "Aggressive",
+ "caveman": "Caveman",
"ccr": "CCR",
- "headroom": "Margem",
+ "headroom": "Headroom",
"lite": "Lite",
"llmlingua": "LLMLingua",
"omniglyph": "OmniGlyph",
"rtk": "RTK",
- "sessionDedup": "Desduplicação de sessão",
+ "sessionDedup": "Session Dedup",
"ultra": "Ultra",
- "budget": "Orçamento",
- "pricing": "Preços",
- "quotaShare": "Compartilhamento de cota",
+ "budget": "Budget",
+ "pricing": "Pricing",
+ "quotaShare": "Compartilhamento de Cota",
"discovery": "Descoberta",
- "freeProviderRankings": "Ranking de provedores gratuitos",
- "freeTiers": "Níveis gratuitos",
- "gamification": "Gamificação",
- "leaderboard": "Classificação",
+ "freeProviderRankings": "Ranking de Provedores Gratuitos",
+ "freeTiers": "Níveis Gratuitos",
+ "gamification": "Gamification",
+ "leaderboard": "Leaderboard",
"limits": "Limites",
- "profile": "Perfil",
+ "profile": "Profile",
"plugins": "Plugins",
- "providerStats": "Estatísticas do provedor",
+ "providerStats": "Estatísticas do Provedor",
"new": "Novo",
"quota": "Cota",
"relay": "Relay",
- "searchTools": "Ferramentas de busca",
- "security": "Segurança",
- "sidebar": "Barra lateral",
+ "searchTools": "Search Tools",
+ "security": "Security",
+ "sidebar": "Sidebar",
"tokens": "Tokens",
"tools": "Ferramentas",
- "agentBridge": "Ponte de agentes",
- "trafficInspector": "Inspetor de tráfego",
+ "agentBridge": "Agent Bridge",
+ "trafficInspector": "Inspector de Tráfego",
"usage": "Uso"
},
"home": {
@@ -1872,15 +1872,15 @@
"activitySummary": "{active} dias ativos · {tokens} tokens · {days} dias",
"activityCellTitle": "{date}: {tokens} tokens",
"activityLess": "Menos",
- "activityMore": "Mais",
- "chartApiKeyBreakdown": "Detalhamento por chave de API",
+ "activityMore": "More",
+ "chartApiKeyBreakdown": "Detalhamento por Chave de API",
"chartApiKey": "Chave de API",
- "mostActiveDay": "Dia mais ativo",
+ "mostActiveDay": "Dia Mais Ativo",
"datedTokenCount": "{date} · {tokens} tokens",
"noDataLast7Days": "Nenhum dado nos últimos 7 dias",
- "requestTokenSummary": "{requests} requisições · {tokens} tokens",
- "chartByAccount": "Por conta",
- "chartByApiKey": "Por chave de API",
+ "requestTokenSummary": "{requests} solicitações · {tokens} tokens",
+ "chartByAccount": "Por Conta",
+ "chartByApiKey": "Por Chave de API",
"unknownApiKey": "Chave de API desconhecida",
"chartModelBreakdown": "Detalhamento por Modelo",
"chartModel": "Modelo",
@@ -1938,8 +1938,8 @@
"evals": "Avaliações",
"search": "Pesquisar",
"utilization": "Utilização",
- "routeTrace": "Rastreamento de rota",
- "sectionsAria": "Seções de análise",
+ "routeTrace": "Rastreamento de Rota",
+ "sectionsAria": "Seções de Analytics",
"utilizationDescription": "Tendências de uso de cota do provedor e rastreamento de limites de taxa",
"modelStatus": "Status do modelo",
"modelStatusCooldown": "Recarga",
@@ -1971,12 +1971,12 @@
"comboHealthUnableToLoad": "Não foi possível carregar a saúde do combo",
"comboHealthGettingStarted": "Primeiros passos",
"comboHealthForecastTitle": "Previsão de custo e cota",
- "comboHealthForecastDescription": "Projeção linear a partir do histórico de tráfego combinado e instantâneos de cota.",
- "comboHealthQuotaRisk": "Risco de cota {level}",
- "comboHealthConfidence": "Confiança {level}",
+ "comboHealthForecastDescription": "Projeção linear a partir do tráfego histórico do combo e snapshots de cota.",
+ "comboHealthQuotaRisk": "risco de cota {level}",
+ "comboHealthConfidence": "confiança {level}",
"comboHealthProjectedCost": "Custo projetado",
"comboHealthCostHistory": "histórico {total} · {daily}/dia",
- "comboHealthProjectedRequests": "Requisições projetadas",
+ "comboHealthProjectedRequests": "Solicitações projetadas",
"comboHealthRequestsInRange": "{count} no intervalo selecionado",
"comboHealthWorstProjectedQuota": "Pior cota projetada",
"comboHealthNoDepletionEstimate": "Sem estimativa de esgotamento",
@@ -1984,28 +1984,28 @@
"comboHealthTraffic": "tráfego",
"comboHealthProjectedQuota": "Cota projetada",
"comboHealthPricingCoverage": "Cobertura de preços",
- "comboHealthAutopilotTitle": "Piloto automático de saúde do combo",
+ "comboHealthAutopilotTitle": "Piloto Automático de Saúde do Combo",
"comboHealthAutopilotDescription": "Recomendações priorizadas com base na saúde do combo, previsões, cotas e saúde do provedor.",
"comboHealthIssues": "Problemas",
"comboHealthActionable": "{count} acionáveis",
- "comboHealthDown": "Inoperante",
+ "comboHealthDown": "Down",
"comboHealthDegraded": "Degradado",
- "comboHealthHealthy": "Saudável",
+ "comboHealthHealthy": "Healthy",
"comboHealthNoActiveIssues": "Nenhum problema ativo de saúde do combo detectado para o intervalo selecionado.",
"comboHealthScoringInspector": "Inspetor de pontuação inteligente",
"comboHealthReadOnlyRecompute": "Recálculo somente leitura",
- "comboHealthScoringDescription": "Explicação em nível de fator para a classificação de destinos usando a saúde atual, previsões e heurísticas de roteamento.",
+ "comboHealthScoringDescription": "Explicação por fator da classificação de alvos usando saúde atual, previsão e heurísticas de roteamento.",
"comboHealthTask": "Tarefa: {task}",
- "comboHealthSelectedRank": "Classificação nº 1 selecionada",
+ "comboHealthSelectedRank": "Posição selecionada #1",
"comboHealthFactor": {
"quota": "Cota",
"health": "Saúde",
"costInv": "Custo",
- "latencyInv": "Latência",
+ "latencyInv": "Latency",
"taskFit": "Adequação à tarefa",
- "stability": "Estabilidade",
- "tierPriority": "Nível",
- "tierAffinity": "Adequação ao nível",
+ "stability": "Stability",
+ "tierPriority": "Tier",
+ "tierAffinity": "Adequação de nível",
"specificityMatch": "Especificidade",
"contextAffinity": "Contexto",
"resetWindowAffinity": "Janela de redefinição"
@@ -2013,39 +2013,39 @@
"comboHealthQuotaValue": "Cota {value}",
"comboHealthLatencyValue": "Latência {value}ms",
"comboHealthIssueCount": "Problemas {count}",
- "comboHealthNoInspectableTargets": "Nenhum destino inspecionável para este combo.",
+ "comboHealthNoInspectableTargets": "Nenhum alvo inspecionável para este combo.",
"comboHealthAutopilotState": {
- "down": "Inoperante",
- "degraded": "Requer atenção",
- "healthy": "Saudável"
+ "down": "Down",
+ "degraded": "Precisa de atenção",
+ "healthy": "Healthy"
},
"comboHealthModelProviderCount": "{models} modelos em {providers} provedores",
"comboHealthGiniCoefficient": "Coeficiente de Gini",
- "comboHealthRequestCount": "{count} requisições",
+ "comboHealthRequestCount": "{count} solicitações",
"comboHealthQuotaHealthDescription": "Menor cota restante entre provedores com sinais de tendência curtos.",
"comboHealthRemainingQuota": "Cota restante {value}",
"comboHealthTrend": {
"improving": "Melhorando",
- "declining": "Em declínio",
+ "declining": "Piorando",
"stable": "Estável"
},
- "comboHealthUsageSkewDescription": "Participação de requisições do modelo e participação de tokens dentro deste combo.",
- "comboHealthShareSummary": "Participação de requisições {requests} · Participação de tokens {tokens}",
+ "comboHealthUsageSkewDescription": "Participação de solicitações e de tokens por modelo dentro deste combo.",
+ "comboHealthShareSummary": "Participação de solicitações {requests} · Participação de tokens {tokens}",
"comboHealthPerformance": "Desempenho",
- "comboHealthPerformanceDescription": "Confiabilidade e taxa de transferência para tráfego de combo roteado.",
- "comboHealthExecutionTargetsDescription": "Métricas de tempo de execução no nível de etapa e visibilidade de cota para alvos de combo estruturados.",
+ "comboHealthPerformanceDescription": "Confiabilidade e throughput para o tráfego de combo roteado.",
+ "comboHealthExecutionTargetsDescription": "Métricas de runtime por etapa e visibilidade de cota para alvos de combo estruturados.",
"comboHealthRequestShort": "{count} req",
"comboHealthQuotaScope": "Escopo da cota: {scope}",
"comboHealthTrendValue": "Tendência: {trend}",
- "comboHealthFetchFailed": "Falha ao buscar dados de integridade do combo",
+ "comboHealthFetchFailed": "Falha ao buscar dados de saúde do combo",
"unknownError": "Erro desconhecido",
- "comboHealthIntro": "Monitore a pressão da cota, o uso distorcido do modelo e o desempenho de entrega por combo.",
- "comboHealthForecastHorizon": "Previsão de {value}",
- "comboHealthNoData": "Nenhum dado de integridade do combo disponível",
- "comboHealthNoDataDescription": "Instantâneos de cota do combo e requisições roteadas aparecerão aqui após o início do fluxo de tráfego.",
+ "comboHealthIntro": "Monitore a pressão de cota, o uso desequilibrado de modelos e o desempenho de entrega por combo.",
+ "comboHealthForecastHorizon": "previsão de {value}",
+ "comboHealthNoData": "Nenhum dado de saúde de combo disponível",
+ "comboHealthNoDataDescription": "Snapshots de cota de combo e solicitações roteadas aparecerão aqui assim que o tráfego começar a fluir.",
"comboHealthStepCreate": "Crie combos em Combos com múltiplos provedores",
- "comboHealthStepSend": "Envie requisições para endpoints de combo para gerar dados de tráfego",
- "comboHealthStepAutomatic": "As métricas de integridade aparecerão automaticamente conforme as requisições forem roteadas",
+ "comboHealthStepSend": "Envie solicitações para endpoints de combo para gerar dados de tráfego",
+ "comboHealthStepAutomatic": "As métricas de saúde aparecerão automaticamente conforme as solicitações forem roteadas",
"comboHealthTracking": "Rastreando {count} combos para {range}",
"compressionAnalyticsTotalRequests": "Total de solicitações",
"compressionAnalyticsTokensSaved": "Tokens salvos",
@@ -2058,26 +2058,26 @@
"compressionAnalyticsTotalTokens": "Totais de fichas",
"compressionAnalyticsCacheTokens": "Tokens de cache",
"compressionAnalyticsNoDataYet": "Ainda não há dados de compactação",
- "compressionAnalyticsLoading": "Carregando análises de compressão…",
- "compressionAnalyticsNoDataDescription": "As requisições de compressão aparecerão aqui após a primeira requisição através de /v1/chat/completions com a compressão ativada.",
+ "compressionAnalyticsLoading": "Carregando analytics de compressão…",
+ "compressionAnalyticsNoDataDescription": "As solicitações de compressão aparecerão aqui após a primeira solicitação via /v1/chat/completions com compressão ativada.",
"rangeLast24h": "Últimas 24h",
"rangeLast7d": "Últimos 7d",
"rangeLast30d": "Últimos 30d",
"rangeAllTime": "Todo o período",
- "compressionAnalyticsModeStats": "{count} requisições · {tokens} tokens economizados",
- "compressionAnalyticsSkipped": " · {count} ignorados (no-op)",
+ "compressionAnalyticsModeStats": "{count} solicitações · {tokens} tokens economizados",
+ "compressionAnalyticsSkipped": " · {count} ignoradas (no-op)",
"compressionAnalyticsRealTokens": "{count} tokens reais",
"compressionAnalyticsValidationRestores": "restaurações de validação",
- "compressionAnalyticsRealUsageReceipts": "Recibos de uso real",
+ "compressionAnalyticsRealUsageReceipts": "Comprovantes de Uso Real",
"compressionAnalyticsSources": "Fontes",
- "compressionAnalyticsModeBreakdown": "Detalhamento por modo",
- "compressionAnalyticsProviderBreakdown": "Detalhamento por provedor",
- "compressionAnalyticsLast24HoursActivity": "Últimas 24 horas (Atividade)",
- "compressionAnalyticsChartPoint": "{hour}: {count} requisições, {tokens} tokens economizados",
- "compressionAnalyticsMaxRequests": "Máximo de requisições/hora: {count}",
- "compressionAnalyticsMaxTokens": "Máximo de tokens/hora: {count}",
- "compressionAnalyticsStartTracking": "Use POST /v1/chat/completions com configuração de compressão para começar a rastrear a análise de compressão.",
- "compressionAnalyticsInfo": "Análise de compressão: Economia de tokens rastreada por modo (off, lite, standard, aggressive, ultra, RTK, stacked), mecanismo, combo de compressão e provedor. Passe o mouse sobre os gráficos para obter detalhes. Use the time selector para visualizar diferentes períodos.",
+ "compressionAnalyticsModeBreakdown": "Detalhamento por Modo",
+ "compressionAnalyticsProviderBreakdown": "Detalhamento por Provedor",
+ "compressionAnalyticsLast24HoursActivity": "Últimas 24 Horas (Atividade)",
+ "compressionAnalyticsChartPoint": "{hour}: {count} solicitações, {tokens} tokens economizados",
+ "compressionAnalyticsMaxRequests": "Máx. de solicitações/hora: {count}",
+ "compressionAnalyticsMaxTokens": "Máx. de tokens/hora: {count}",
+ "compressionAnalyticsStartTracking": "Use POST /v1/chat/completions com configuração de compressão para começar a rastrear os analytics de compressão.",
+ "compressionAnalyticsInfo": "Analytics de compressão: Economia de tokens rastreada por modo (off, lite, standard, aggressive, ultra, RTK, stacked), engine, combo de compressão e provedor. Passe o mouse sobre os gráficos para ver detalhes. Use o seletor de tempo para visualizar diferentes períodos.",
"searchAnalyticsTotalSearches": "Total de pesquisas",
"searchAnalyticsCacheHitRate": "Taxa de acertos do cache",
"searchAnalyticsTotalCost": "Custo total",
@@ -2095,70 +2095,70 @@
"7d": "Últimos 7 dias",
"30d": "Últimos 30 dias"
},
- "providerUtilizationGlobalView": "Visualização Global",
+ "providerUtilizationGlobalView": "Visão Global",
"providerUtilizationAccountSplit": "Divisão por Conta",
"providerUtilizationLoading": "Carregando dados de utilização…",
"retrying": "Tentando novamente…",
- "retry": "Tentar novamente",
- "providerUtilizationNoDataDescription": "Snapshots de cota do provedor aparecerão aqui após a coleta dos dados de utilização.",
- "providerUtilizationStepConnect": "Conecte provedores por meio de OAuth ou chaves de API em Provedores",
- "providerUtilizationStepEnable": "Habilite o rastreamento de cota usando o provedor em um combo ou requisição direta",
+ "retry": "Retry",
+ "providerUtilizationNoDataDescription": "Snapshots de cota do provedor aparecerão aqui após a coleta de dados de utilização.",
+ "providerUtilizationStepConnect": "Conecte provedores via OAuth ou chaves de API em Provedores",
+ "providerUtilizationStepEnable": "Ative o rastreamento de cota usando o provedor em um combo ou solicitação direta",
"providerUtilizationStepAutomatic": "Os dados aparecerão automaticamente conforme os snapshots de cota forem coletados",
"statusExhausted": "Esgotado",
"statusLow": "Baixo",
- "statusHealthy": "Saudável",
+ "statusHealthy": "Healthy",
"remainingQuota": "Cota restante",
"routeTraceTitle": "Visualização de Rastreamento de Rota",
- "routeTraceDescription": "Inspecione o rastreamento de requisição persistido: alvo selecionado, fatores de roteamento, evidências de fallback, reprodução de pontuação atual, latência, tokens e integridade do alvo.",
- "routeTraceRequestLog": "Log de requisição",
+ "routeTraceDescription": "Inspecione o rastro de solicitação persistido: alvo selecionado, fatores de roteamento, evidências de fallback, replay da pontuação atual, latência, tokens e saúde do alvo.",
+ "routeTraceRequestLog": "Log de solicitação",
"routeWeight": "Peso {weight}%",
- "routeNoRelatedEvidence": "Nenhuma evidência de alvo relacionada persistida ainda.",
+ "routeNoRelatedEvidence": "Ainda não há evidências relacionadas ao alvo persistidas.",
"unknown": "desconhecido",
"selected": "Selecionado",
- "routeNoStepId": "sem ID de etapa",
+ "routeNoStepId": "sem id de etapa",
"routeNoStep": "sem etapa",
"routeMatchesTopTarget": "Corresponde ao alvo principal atual",
- "routeDiffersFromTop": "Diferente do principal atual",
+ "routeDiffersFromTop": "Difere do principal atual",
"routeTargetMissingNow": "Alvo ausente agora",
"routeNotComboRouted": "Não roteado por combo",
"routeWhyTarget": "Por que este alvo?",
- "routeWhyTargetSubtitle": "Metadados exatos de tempo de execução mais reprodução de pontuação somente leitura",
- "routeExactRuntimeLog": "Log exato de tempo de execução",
+ "routeWhyTargetSubtitle": "Metadados exatos de runtime mais replay de pontuação somente leitura",
+ "routeExactRuntimeLog": "Log exato de runtime",
"routeCallLogsExact": "call_logs exato",
"routeReadOnlyRecompute": "Recálculo somente leitura",
- "routeRuntimeRankNow": "Classificação em tempo de execução agora",
- "routeRuntimeScoreNow": "Pontuação em tempo de execução agora",
+ "routeRuntimeRankNow": "Posição de runtime agora",
+ "routeRuntimeScoreNow": "Pontuação de runtime agora",
"routeWouldSelectNow": "Selecionaria agora",
- "routeNoRecomputeCandidates": "Nenhuma classificação de candidato de combo pode ser recomputada para esta solicitação.",
- "runtime": "Tempo de execução",
- "routeTopNow": "Melhor agora",
+ "routeNoRecomputeCandidates": "Nenhuma classificação de candidatos de combo pode ser recalculada para esta solicitação.",
+ "runtime": "Runtime",
+ "routeTopNow": "Principal agora",
"routeFetchLogsFailed": "Falha ao buscar logs de solicitação",
"routeExplainFailed": "Falha ao explicar a rota",
- "direct": "direto",
+ "direct": "direct",
"routeUnableToLoad": "Não foi possível carregar a explicação da rota",
"routeNoRequestLogs": "Nenhum log de solicitação disponível",
- "routeNoRequestLogsDescription": "Envie tráfego pelo OmniRoute primeiro. As explicações de rota são geradas a partir de logs de chamadas estruturados persistidos.",
+ "routeNoRequestLogsDescription": "Envie tráfego pelo OmniRoute primeiro. As explicações de rota são geradas a partir de logs de chamada estruturados persistidos.",
"routeDecisionSummary": "Resumo da decisão",
- "routeConfidence": "{confidence} de confiança",
+ "routeConfidence": "confiança {confidence}",
"routeScore": "Pontuação da rota",
- "latency": "Latência",
+ "latency": "Latency",
"routeRecentSuccess": "Sucesso recente",
- "routeAvgTargetLatency": "Latência média do destino",
- "routeSelectedTarget": "Destino selecionado",
+ "routeAvgTargetLatency": "Latência média do alvo",
+ "routeSelectedTarget": "Alvo selecionado",
"provider": "Provedor",
"model": "Modelo",
"account": "Conta",
- "connection": "Conexão",
- "combo": "Combo",
+ "connection": "Por conta",
+ "combo": "Combinação",
"routeStep": "Etapa",
"tokens": "Tokens",
- "notAvailable": "n/a",
- "routeTokenCounts": "{input} de entrada · {output} de saída",
- "routeEvidence": "Evidência",
+ "notAvailable": "n/d",
+ "routeTokenCounts": "{input} entrada · {output} saída",
+ "routeEvidence": "Evidências",
"routeFactors": "Fatores de roteamento",
- "routeFactorsSubtitle": "Sinais ponderados usados para esta explicação",
- "routeFallbackTimeline": "Linha do tempo de fallback e destino",
- "routeFallbackTimelineSubtitle": "Inferido a partir de logs de chamadas persistidos em torno desta solicitação",
+ "routeFactorsSubtitle": "Sinais ponderados usados nesta explicação",
+ "routeFallbackTimeline": "Linha do tempo de fallback e alvo",
+ "routeFallbackTimelineSubtitle": "Inferido a partir de logs de chamada persistidos em torno desta solicitação",
"routeRecommendations": "Recomendações",
"routeLimitations": "Limitações",
"routeNoKnownLimitations": "Nenhuma limitação conhecida para esta explicação.",
@@ -2243,11 +2243,11 @@
"endpointsRestricted": "Restrito a {count} endpoint{count, plural, one {} other {s}}.",
"autoResolve": "Auto-Resolve",
"autoResolveDesc": "Resolve automaticamente nomes ambíguos de modelo para o provedor nativo desta API key.",
- "streamDefaultMode": "Compatibilidade padrão de stream",
- "streamDefaultModeDesc": "Controla sinalizadores `stream` omitidos para esta chave. O modo JSON retorna respostas sem streaming, a menos que o cliente solicite explicitamente SSE.",
- "streamDefaultLegacy": "Legado",
- "streamDefaultJson": "Compatível com JSON",
- "streamDefaultBadge": "Stream JSON padrão",
+ "streamDefaultMode": "__MISSING__:Stream Default Compatibility",
+ "streamDefaultModeDesc": "__MISSING__:Controls omitted `stream` flags for this key. JSON mode returns non-streaming responses unless the client explicitly requests SSE.",
+ "streamDefaultLegacy": "__MISSING__:Legacy",
+ "streamDefaultJson": "__MISSING__:JSON Compatible",
+ "streamDefaultBadge": "__MISSING__:JSON stream default",
"keyActive": "Chave Ativa",
"keyActiveDesc": "Ativa ou desativa esta API key. Chaves desativadas são bloqueadas com 403.",
"accessSchedule": "Horário de Acesso",
@@ -2295,7 +2295,7 @@
"devicesCount": "{count, plural, one {# dispositivo} other {# dispositivos}}",
"devicesTooltip": "{count, plural, one {# dispositivo distinto (IP/User-Agent) visto com esta chave (últimos 30 min)} other {# dispositivos distintos (IP/User-Agent) vistos com esta chave (últimos 30 min)}}",
"lastUsedOn": "Último: {date}",
- "viewCostsFor": "View costs for {name}",
+ "viewCostsFor": "__MISSING__:View costs for {name}",
"editPermissions": "Editar permissões",
"deleteKey": "Excluir chave",
"regenerateKey": "Chave regenerada",
@@ -2311,12 +2311,12 @@
"restrictDesc": "Esta chave pode acessar {selectedCount} de {totalModels} modelos.",
"selectedCount": "{count} selecionados",
"maxActiveSessions": "Máximo de sessões ativas",
- "maxActiveSessionsDescription": "0 = ilimitado. Retorna 429 quando esta chave exceder sessões persistentes simultâneas.",
- "throttleDelay": "Atraso de limitação",
- "throttleDelayDescription": "Adicione um atraso fixo antes que as requisições para esta chave sejam roteadas. 0 = sem lentidão.",
+ "maxActiveSessionsDescription": "0 = ilimitado. Retorna 429 quando esta chave excede o número de sessões fixas simultâneas.",
+ "throttleDelay": "Atraso de Limitação",
+ "throttleDelayDescription": "Adiciona um atraso fixo antes que as solicitações desta chave sejam roteadas. 0 = sem atraso.",
"expandClaudeCodeFamilies": "Expandir famílias do Claude Code",
"removeClaudeCodeDefault": "Remover padrão do Claude Code",
- "allowedCombos": "Combos permitidos",
+ "allowedCombos": "Combos Permitidos",
"allCombosAllowed": "Esta chave pode usar qualquer combo.",
"restrictedComboCount": "Restrito a {count, plural, one {# combo} other {# combos}}.",
"apiManagerCustomRateLimits": "Limites de taxas personalizadas",
@@ -2347,12 +2347,12 @@
"shownOf": "{shown} de {total} exibidas",
"emptyFilterTitle": "Nenhuma chave corresponde aos filtros",
"emptyFilterClear": "Limpar filtros",
- "disableNonPublicModels": "Desativar modelos não públicos",
- "disableNonPublicModelsDesc": "Rejeitar requisições para modelos que não foram descobertos ou não estão marcados como públicos no catálogo do provedor",
+ "disableNonPublicModels": "__MISSING__:Disable Non-Public Models",
+ "disableNonPublicModelsDesc": "__MISSING__:Reject requests for models that are not discovered or not marked as public in the provider catalog",
"normalKeysSection": "Chaves normais",
"quotaKeysSection": "Chaves de cota",
- "bypassProviderQuota": "Ignorar limites de cota do provedor",
- "bypassProviderQuotaDescription": "Permite que esta chave ignore a política de limite do provedor/conta upstream durante o roteamento. As cotas em USD da chave de API ainda se aplicam.",
+ "bypassProviderQuota": "Ignorar cortes de cota do provedor",
+ "bypassProviderQuotaDescription": "Permite que esta chave ignore a política de corte do provedor/conta upstream durante o roteamento. As cotas em USD da chave de API ainda se aplicam.",
"quotaPill": "QUOTA",
"quotaModeOnly": "só-qtSd"
},
@@ -2411,43 +2411,43 @@
"noConnections": "Nenhuma conexão ainda — adicione uma na página do provedor.",
"loading": "Carregando...",
"suggestedModels": "Modelos sugeridos pelo provedor",
- "imageGeneration": "Geração de imagem",
- "imageToText": "Imagem para texto",
- "imageToTextComingSoon": "O playground inline de Imagem para Texto estará disponível quando /api/v1/images/understanding for implementado.",
+ "imageGeneration": "Image Generation",
+ "imageToText": "Imagem para Texto",
+ "imageToTextComingSoon": "O playground inline de Imagem-para-Texto estará disponível quando /api/v1/images/understanding for implementado.",
"disabled": "Desativado",
- "videoGeneration": "Geração de vídeo",
- "musicGeneration": "Geração de música",
- "textToSpeech": "Texto para fala",
+ "videoGeneration": "Video Generation",
+ "musicGeneration": "Geração Musical",
+ "textToSpeech": "Texto para Fala",
"transcription": "Transcrição",
"imagePromptPlaceholder": "Uma paisagem serena com montanhas ao pôr do sol...",
"videoPromptPlaceholder": "Um timelapse de uma flor desabrochando...",
- "musicPromptPlaceholder": "Música eletrônica animada com sintetizadores...",
+ "musicPromptPlaceholder": "Música eletrônica animada com pads de synth...",
"speechTextPlaceholder": "Olá! Bem-vindo ao OmniRoute, seu gateway de IA inteligente...",
"transcriptionPlaceholder": "Envie um arquivo de áudio para transcrever...",
- "noImagesReturned": "Nenhuma imagem retornada. O provedor pode ter aceitado a requisição, mas retornou dados vazios.",
+ "noImagesReturned": "Nenhuma imagem retornada. O provedor pode ter aceitado a solicitação, mas retornou dados vazios.",
"generatedImageAlt": "Imagem gerada {index}",
"save": "Salvar",
- "enterTextToSynthesize": "Por favor, insira o texto para sintetizar.",
- "selectAudioToTranscribe": "Por favor, selecione um arquivo de áudio para transcrever.",
+ "enterTextToSynthesize": "Digite o texto a ser sintetizado.",
+ "selectAudioToTranscribe": "Selecione um arquivo de áudio para transcrever.",
"noSpeechDetected": "Nenhuma fala detectada no arquivo de áudio. Se você enviou música ou um arquivo silencioso, tente um arquivo de áudio com palavras faladas. Provedor: \"{provider}\".",
- "emptyTranscription": "A transcrição retornou um texto vazio. O áudio pode não conter fala reconhecível ou a chave de API do \"{provider}\" pode ser inválida. Verifique Painel → Logs → Proxy para obter detalhes.",
- "topazRequiresImage": "O Topaz requer uma imagem de entrada.",
- "enterPrompt": "Por favor, insira um prompt.",
- "enhanceThisImage": "Melhorar esta imagem",
+ "emptyTranscription": "A transcrição retornou texto vazio. O áudio pode não conter fala reconhecível, ou a chave de API \"{provider}\" pode ser inválida. Verifique Dashboard → Logs → Proxy para mais detalhes.",
+ "topazRequiresImage": "Topaz requer uma imagem de entrada.",
+ "enterPrompt": "Digite um prompt.",
+ "enhanceThisImage": "Aprimorar esta imagem",
"failedToReadFile": "Falha ao ler o arquivo",
"generationFailed": "Falha na geração",
- "requestFailed": "Falha na requisição ({status})",
+ "requestFailed": "Falha na solicitação ({status})",
"provider": "Provedor",
- "credentialsRequired": "Requer a chave de API do em Provedores",
+ "credentialsRequired": "Requer chave de API em Provedores",
"voice": "Voz",
"format": "Formato",
"audioVideoFile": "Arquivo de Áudio / Vídeo",
"fileTooLarge": "Arquivo muito grande ({size}). Máximo permitido: {max}.",
"audioVideoFileHint": "Suporta arquivos de áudio e vídeo de até 4 GB",
"sourceImage": "Imagem de Origem",
- "sourceImageHint": "Opcional para fluxos de trabalho de imagem para imagem, edição e upscale.",
+ "sourceImageHint": "Opcional para fluxos de imagem-para-imagem, edição e upscale.",
"maskImage": "Imagem de Máscara",
- "maskImageHint": "Opcional. Usado por modelos do estilo inpaint que suportam máscaras.",
+ "maskImageHint": "Opcional. Usado por modelos no estilo inpaint que suportam máscaras.",
"text": "Texto",
"promptOptional": "Prompt (opcional)",
"enhancementInstructionsPlaceholder": "Instruções de aprimoramento opcionais...",
@@ -2457,10 +2457,10 @@
"transcribeAudio": "Transcrever Áudio",
"generateModality": "Gerar {modality}",
"apiKeyRequired": "Chave de API Necessária",
- "configureApiKeys": "Configure as chaves de API em Provedores",
+ "configureApiKeys": "Configure chaves de API em Provedores",
"downloadFormat": "Baixar {format}",
"noTextReturned": "Nenhum texto retornado",
- "wordTimestamps": "Timestamps no nível da palavra ({count} palavras)",
+ "wordTimestamps": "Timestamps por palavra ({count} palavras)",
"providerCount": "{count} provedores",
"imageToTextBridgeAvailable": "A Ponte de Modalidade agora pode descrever imagens para modelos somente de texto. O playground inline estará disponível quando /api/v1/images/understanding for implementado.",
"imageToTextBridgeCta": "Configure a ponte Imagem→Texto nas configurações da Ponte de Modalidade",
@@ -2545,8 +2545,8 @@
"freeQuota": "Cota gratuita/mês",
"scrapeUrl": "URL para extrair",
"scrapeUrlPlaceholder": "https://exemplo.com",
- "scrapeUrlRequired": "A URL é obrigatória",
- "scrapeUrlInvalid": "URL inválida — deve começar com http:// ou https://",
+ "scrapeUrlRequired": "__MISSING__:URL is required",
+ "scrapeUrlInvalid": "__MISSING__:Invalid URL — it must start with http:// or https://",
"scrapeExtract": "Extrair",
"scrapeExtracting": "Extraindo…",
"scrapeFullPage": "Página completa",
@@ -2560,8 +2560,8 @@
"scrapeMetadata": "Metadados",
"scrapeProvider": "Provedor",
"scrapeSize": "Tamanho",
- "scrapeEmptyState": "Insira uma URL para extrair seu conteúdo",
- "scrapeProvidersAvailable": "Provedores disponíveis: Firecrawl, Jina Reader, Tavily.",
+ "scrapeEmptyState": "__MISSING__:Enter a URL to extract its content",
+ "scrapeProvidersAvailable": "__MISSING__:Available providers: Firecrawl, Jina Reader, Tavily.",
"compareRun": "Comparar",
"compareRunning": "Comparando…",
"autoProvider": "Auto (mais barato)",
@@ -2573,40 +2573,40 @@
"noneOption": "Nenhum",
"size": "Tamanho",
"configurationPane": "Painel de configuração",
- "configuration": "Configuração",
+ "configuration": "Configuration",
"status": "Status",
- "compareProviderHint": "Selecione até 4 provedores na guia Comparar para compará-los lado a lado.",
+ "compareProviderHint": "Selecione até 4 provedores na aba Comparar para compará-los lado a lado.",
"history": "Histórico",
- "historyHint": "O histórico está disponível na guia Pesquisa.",
+ "historyHint": "O histórico está disponível na aba Pesquisar.",
"noActiveProvider": "Nenhum provedor de pesquisa ativo",
"configureMoreProviders": "Configurar mais provedores",
"links": "Links",
"contentTruncated": "Conteúdo truncado para 256 KB (tamanho original: {size})",
- "viewFullRaw": "Visualizar conteúdo bruto completo",
+ "viewFullRaw": "Ver conteúdo bruto completo",
"rawScrapedContent": "Conteúdo bruto extraído",
"rawContent": "Conteúdo bruto — {size}",
"closeRawModal": "Fechar modal de conteúdo bruto",
"httpError": "Erro {status}",
- "failed": "Falhou",
- "requestFailed": "A requisição falhou",
+ "failed": "Failed",
+ "requestFailed": "Falha na requisição",
"embedding": "Embedding",
"embeddingSample": "Olá, mundo!",
- "image": "Imagem",
+ "image": "Image",
"imageSample": "Uma paisagem serena com montanhas ao pôr do sol",
"music": "Música",
"musicSample": "Piano de jazz animado com percussão leve",
- "noAudioUrl": "Nenhum URL de áudio na resposta: {response}",
- "documentUrl": "URL do documento",
- "fileTooLarge25Mb": "Arquivo muito grande — máx. 25 MB",
+ "noAudioUrl": "Nenhuma URL de áudio na resposta: {response}",
+ "documentUrl": "URL do Documento",
+ "fileTooLarge25Mb": "Arquivo muito grande — máximo de 25 MB",
"selectAudioFirst": "Selecione um arquivo de áudio primeiro.",
- "speechToText": "Conversão de voz em texto",
+ "speechToText": "Fala para Texto",
"chooseFile": "Escolher arquivo…",
- "audioFormats25Mb": "mp3, wav, m4a, ogg, flac — máx. 25 MB",
- "textToSpeech": "Conversão de texto em voz",
- "ttsSample": "Olá, este é um teste de conversão de texto em voz.",
+ "audioFormats25Mb": "mp3, wav, m4a, ogg, flac — máximo de 25 MB",
+ "textToSpeech": "Texto para Fala",
+ "ttsSample": "Olá, este é um teste de texto para fala.",
"video": "Vídeo",
- "videoSample": "Um time-lapse de nuvens sobre uma cadeia de montanhas",
- "webFetch": "Busca na Web",
+ "videoSample": "Um timelapse de nuvens sobre uma cadeia de montanhas",
+ "webFetch": "Web Fetch",
"webSearchSample": "O que é o gateway de IA OmniRoute?",
"noActiveProviderDescription": "Nenhum provedor de pesquisa ativo. Configure um em Provedores.",
"configureProviders": "Configurar provedores",
@@ -2614,44 +2614,44 @@
"compareQueryPlaceholder": "tendências de inteligência artificial 2026",
"selectedProviders": "Provedores ({count} selecionados):",
"selectAll": "Selecionar todos",
- "clear": "Limpar",
- "maxCompareProviders": "No máximo {count} provedores podem ser comparados ao mesmo tempo.",
+ "clear": "Claro",
+ "maxCompareProviders": "No máximo {count} provedores podem ser comparados por vez.",
"compareResults": "Resultados — “{query}”",
"resultCount": "{count} resultados",
"noResults": "Nenhum resultado",
"sharedResultTitle": "Em comum com outro provedor",
"sharedResult": "Em comum",
"overlapSummary": "{first} vs {second}: {overlap} em comum",
- "compareEmptyTitle": "Selecione os provedores e insira uma consulta para comparar",
- "compareEmptyDescription": "Os resultados serão exibidos lado a lado com latência, custo e sobreposição de URL"
+ "compareEmptyTitle": "Selecione provedores e digite uma consulta para comparar",
+ "compareEmptyDescription": "Os resultados serão exibidos lado a lado com latência, custo e sobreposição de URLs"
},
"cliTools": {
"title": "Ferramentas CLI",
- "classifierCompatTitle": "Compatibilidade do classificador de permissão automática",
- "classifierCompatDescription": "Curto-circuitar o classificador de segurança --permission-mode auto do Claude Code com uma resposta de permissão sintética para que as rotas de fallback não falhem fechadas. Desativado por padrão.",
- "classifierCompatCycle": "Ciclo: desativado → auto → sempre",
+ "classifierCompatTitle": "Compatibilidade do classificador de auto-permissão",
+ "classifierCompatDescription": "Curto-circuita o classificador de segurança --permission-mode auto do Claude Code com uma resposta sintética de permissão para que rotas de fallback não falhem fechadas. Desativado por padrão.",
+ "classifierCompatCycle": "Ciclo: desligado → automático → sempre",
"classifierCompatLoadFailed": "Falha ao carregar configuração",
"classifierCompatMode": {
- "off": "Desativado",
+ "off": "Off",
"auto": "Auto",
"always": "Sempre"
},
-"ccDiscoveryInfoButton": "Como habilitar a descoberta no Claude Code",
-"ccDiscoveryInfoTooltip": "Anuncie modelos não Claude sob claude/<provider>/<model> IDs de espelho para que a descoberta de modelos do gateway do Claude Code possa listá-los. Dobra as entradas do catálogo para todos os clientes quando ativado globalmente.",
-"ccDiscoveryInfoLink": "Abrir Recursos de Funcionalidade",
+ "ccDiscoveryInfoButton": "Como habilitar a descoberta no Claude Code",
+ "ccDiscoveryInfoTooltip": "Anuncie modelos não Claude sob claude/<provider>/<model> IDs de espelho para que a descoberta de modelos do gateway do Claude Code possa listá-los. Dobra as entradas do catálogo para todos os clientes quando ativado globalmente.",
+ "ccDiscoveryInfoLink": "Abrir Recursos de Funcionalidade",
"ccOnboardingTitle": "settings.json para descoberta de modelos pelo gateway",
"ccOnboardingCopy": "Copiar",
"ccOnboardingCopied": "Copiado",
"ccOnboardingKeyPlaceholder": "",
"ccOnboardingWindowNote": "O Claude Code assume uma janela de contexto de 200K para qualquer id de modelo que ele não reconhece. Para um modelo com janela real diferente, acrescente CLAUDE_CODE_AUTO_COMPACT_WINDOW logo abaixo para a compactação automática não disparar cedo demais.",
"failedSave": "Falha ao salvar",
- "profileSyncTitle": "Sincronização automática de perfil da CLI",
- "profileSyncDescription": "Após a sincronização dos modelos do provedor, regenera automaticamente os perfis de ferramentas da CLI a partir do catálogo ativo. Desativado por padrão — apenas os arquivos de perfil são gravados; a configuração ativa/padrão nunca é alterada.",
+ "profileSyncTitle": "Sincronização automática de perfis de CLI",
+ "profileSyncDescription": "Após a sincronização dos modelos do provedor, regenera automaticamente os perfis de ferramentas CLI a partir do catálogo ativo. Desativado por padrão — apenas os arquivos de perfil são gravados; a configuração ativa/padrão nunca é alterada.",
"profileSyncLoadFailed": "Falha ao carregar configurações",
"codexProfiles": "Perfis do Codex",
- "codexProfilesDescription": "Regenerar ~/.codex/*.config.toml após a descoberta de modelos.",
+ "codexProfilesDescription": "Regenera ~/.codex/*.config.toml após a descoberta de modelos.",
"claudeProfiles": "Perfis do Claude Code",
- "claudeProfilesDescription": "Regenerar cada ~/.claude/profiles/…/settings.json após a descoberta de modelos.",
+ "claudeProfilesDescription": "Regenera cada ~/.claude/profiles/…/settings.json após a descoberta de modelos.",
"noActiveProviders": "Nenhum provedor ativo",
"noActiveProvidersDesc": "Adicione e conecte provedores primeiro para configurar as ferramentas CLI.",
"mapModels": "Mapear Modelos",
@@ -2660,7 +2660,7 @@
"configureEndpoint": "Configurar Endpoint",
"instructions": "Instruções",
"modelMapping": "Mapeamento de Modelos",
- "reasoningEffort": "Esforço de raciocínio para {model}",
+ "reasoningEffort": "__MISSING__:Reasoning effort for {model}",
"effortNone": "Nenhum",
"effortLow": "Baixo",
"effortMedium": "Médio",
@@ -2728,14 +2728,14 @@
"saveMappings": "Salvar Mapeamentos",
"mappingsSaved": "Mapeamentos salvos!",
"failedSaveMappings": "Falha ao salvar mapeamentos",
- "reasoningEffortDefault": "Padrão",
- "reasoningEffortHint": "O padrão preserva o esforço de raciocínio enviado pelo agente",
+ "reasoningEffortDefault": "__MISSING__:Default",
+ "reasoningEffortHint": "__MISSING__:Default preserves the reasoning effort sent by the agent",
"reasoningEffortTier": {
- "none": "Nenhum",
- "low": "Baixo",
- "medium": "Médio",
- "high": "Alto",
- "xhigh": "Muito Alto"
+ "none": "__MISSING__:None",
+ "low": "__MISSING__:Low",
+ "medium": "__MISSING__:Medium",
+ "high": "__MISSING__:High",
+ "xhigh": "__MISSING__:XHigh"
},
"howItWorks": "Como funciona:",
"antigravityHowWorksDesc": "O Antigravity envia requisições para o endpoint do Google. O MITM intercepta e redireciona para o OmniRoute.",
@@ -2850,7 +2850,7 @@
"openclaw": "Assistente de IA Open Claw",
"cline": "CLI assistente de codificação Cline",
"kilo": "CLI assistente de IA Kilo Code",
- "qwen": "Qwen Code CLI",
+ "qwen": "CLI Alibaba Qwen Code",
"cursor": "Editor de código com IA Cursor",
"continue": "Assistente de IA Continue",
"opencode": "OpenCode AI coding agent (Terminal)",
@@ -2861,22 +2861,22 @@
"hermes": "Assistente de Terminal Hermes AI",
"hermes-agent": "Hermes Agent (by Nousresearch) - IA de terminal avançada com suporte multi-modelo (delegação, visão, compressão, etc.)",
"custom": "Gerador genérico de configuração para CLI ou SDK OpenAI-compatible",
- "aider": "CLI de programação em par Aider AI com uma URL base compatível com OpenAI",
- "forge": "CLI do agente de codificação ForgeCode com um provedor personalizado",
- "cursor-cli": "CLI do Cursor Agent no modo de agente headless",
+ "aider": "CLI de programação em par com IA Aider, com URL base compatível com OpenAI",
+ "forge": "CLI do agente de codificação ForgeCode com provedor personalizado",
+ "cursor-cli": "CLI Cursor Agent em modo agente headless",
"roo": "Assistente de IA Roo Code para o VS Code",
- "jcode": "agente de codificação de terminal jcode",
+ "jcode": "Agente de codificação de terminal jcode",
"deepseek-tui": "Agente de codificação TUI DeepSeek escrito em Rust",
- "codewhale": "Agente de codificação CodeWhale, o sucessor do DeepSeek TUI",
+ "codewhale": "Agente de codificação CodeWhale, sucessor do DeepSeek TUI",
"smelt": "CLI do agente de codificação Smelt",
- "pi": "Agente de codificação de terminal Pi leve",
- "crush": "Agente de codificação de terminal Crush da Charm",
+ "pi": "Agente de codificação de terminal Pi, leve",
+ "crush": "Agente de codificação de terminal Crush, da Charm",
"goose": "CLI do agente autônomo Goose",
"interpreter": "CLI do agente de codificação autônomo Open Interpreter",
"omp": "Agente de codificação de terminal Oh My Pi",
"letta": "Agente CLI Letta com memória persistente e uso de ferramentas",
- "warp": "Terminal Warp AI com suporte a provedor personalizado",
- "agent-deck": "Orquestrador multiagente Agent Deck"
+ "warp": "Terminal de IA Warp com suporte a provedor personalizado",
+ "agent-deck": "Orquestrador multi-agente Agent Deck"
},
"guides": {
"cursor": {
@@ -3027,22 +3027,22 @@
"customCliEndpointHint": "Aponte qualquer cliente compatível com OpenAI para a URL base OmniRoute /v1. O endpoint bruto de conclusões do chat é {endpoint}. Use o bloco JSON quando a ferramenta desejar um objeto provedor ou o script env quando ler variáveis OPENAI_*.",
"customCliEnvBlockTitle": "Fragmento de ambiente/shell",
"customCliJsonBlockTitle": "Bloco JSON do provedor",
- "networkError": "Erro de rede",
+ "networkError": "Network error",
"other": "Outro",
"preview": "Visualização",
"refreshAll": "Atualizar tudo",
"hermesRoleDefault": "Padrão (principal)",
- "hermesRoleDefaultDesc": "Modelo de conversa primário",
+ "hermesRoleDefaultDesc": "Modelo de conversa principal",
"hermesRoleDelegation": "Delegação (subagentes)",
- "hermesRoleDelegationDesc": "Modelo de orquestrador e subagente",
+ "hermesRoleDelegationDesc": "Modelo orquestrador e de subagentes",
"hermesRoleVision": "Visão",
"hermesRoleVisionDesc": "Compreensão de imagens e capturas de tela",
- "hermesRoleCompression": "Compressão",
- "hermesRoleCompressionDesc": "Compressão e sumarização de prompts",
- "hermesRoleWebExtract": "Extração da Web",
- "hermesRoleWebExtractDesc": "Extração de conteúdo de página web",
- "hermesRoleSkillsHub": "Hub de Habilidades",
- "hermesRoleSkillsHubDesc": "Raciocínio de habilidades e uso de ferramentas",
+ "hermesRoleCompression": "Compression",
+ "hermesRoleCompressionDesc": "Compressão e resumo de prompt",
+ "hermesRoleWebExtract": "Extração Web",
+ "hermesRoleWebExtractDesc": "Extração de conteúdo de páginas web",
+ "hermesRoleSkillsHub": "Hub de Skills",
+ "hermesRoleSkillsHubDesc": "Raciocínio de skills e uso de ferramentas",
"hermesRoleApproval": "Aprovação",
"hermesRoleApprovalDesc": "Decisões de segurança e aprovação",
"hermesRoleMcp": "MCP",
@@ -3067,28 +3067,28 @@
"hermesRoleMonitorDesc": "Monitoramento em segundo plano",
"hermesRoleBackgroundReview": "Revisão em Segundo Plano",
"hermesRoleBackgroundReviewDesc": "Revisão de código em segundo plano",
- "hermesSelectBeforePreview": "Selecione os modelos para as funções, ou certifique-se de que as funções estejam carregadas, antes de visualizar.",
- "hermesPreviewFailed": "Falha ao gerar visualização",
+ "hermesSelectBeforePreview": "Selecione modelos para as funções, ou garanta que as funções estejam carregadas, antes de pré-visualizar.",
+ "hermesPreviewFailed": "Falha ao gerar pré-visualização",
"hermesSavedTo": "Salvo em {path}",
"hermesFirstSetupTitle": "Configurado pela primeira vez via OmniRoute em {date}",
"hermesSinceSetup": "{time} desde a configuração",
"hermesConfiguredRoles": "{configured}/{total} funções",
"hermesQuickApply": "Aplique rapidamente o mesmo modelo a todas as funções:",
- "hermesApplyModelToAll": "Aplicar {model} a cada função",
+ "hermesApplyModelToAll": "Aplicar {model} a todas as funções",
"hermesViaOmniRoute": "{provider} (via OmniRoute)",
- "hermesNotOmniRoute": "{provider} (não OmniRoute)",
+ "hermesNotOmniRoute": "{provider} (não é OmniRoute)",
"hermesRemovePendingRole": "Remover esta função das alterações pendentes",
"hermesApply": "Aplicar ao Hermes Agent",
"hermesRolesWillUpdate": "{count, plural, one {# função será atualizada} other {# funções serão atualizadas}}",
- "hermesPreviewPath": "Visualização — gravará em ~/.hermes/config.yaml",
+ "hermesPreviewPath": "Pré-visualização — será gravado em ~/.hermes/config.yaml",
"hermesSaveDescription": "Salva o modelo selecionado para cada função em",
"copilotConfigGenerator": "Gerador de configuração do GitHub Copilot",
"copilotGeneratorDescriptionPrefix": "Gera o",
- "copilotGeneratorDescriptionSuffix": "bloco para o VS Code GitHub Copilot usando o padrão de provedor do Azure. Selecione os modelos que deseja e copie o JSON para o seu arquivo de configuração.",
- "copilotCompatibilityWarning": "Esta configuração usa a solução alternativa de provedor do Azure para listas de modelos personalizadas. Testado com VS Code ≥ 1.109 e GitHub Copilot Chat ≥ v0.37. Atualizações futuras da extensão podem alterar esse comportamento.",
+ "copilotGeneratorDescriptionSuffix": "bloco para o GitHub Copilot no VS Code usando o padrão de fornecedor Azure. Selecione os modelos desejados e copie o JSON no seu arquivo de configuração.",
+ "copilotCompatibilityWarning": "Esta configuração usa a solução alternativa do fornecedor Azure para listas de modelos personalizadas. Testada com VS Code ≥ 1.109 e GitHub Copilot Chat ≥ v0.37. Atualizações futuras da extensão podem alterar esse comportamento.",
"copilotApiKey": "Chave de API",
"copilotSelectModels": "Selecionar modelos ({selected}/{total})",
- "selectAll": "Selecionar tudo",
+ "selectAll": "Selecionar todos",
"loadingModels": "Carregando modelos...",
"advancedOptions": "Opções avançadas",
"vision": "Visão",
@@ -3100,30 +3100,30 @@
"copilotPasteInto": "Cole em:",
"copilotReloadInstruction": "Em seguida, recarregue o VS Code e defina a chave de API no prompt de entrada.",
"wireApiChatCompletions": "Conclusões de bate-papo (/chat/completions)",
-"wireApiResponses": "API de respostas (/respostas)",
-"cliproxyapiActionFailed": "__MISSING__:Action failed",
-"cliproxyapiActionSucceeded": "__MISSING__:Action succeeded",
-"cliproxyapiCheckUpdates": "__MISSING__:Check Updates",
-"cliproxyapiDescription": "__MISSING__:Upstream proxy fallback (Go-based OAuth)",
-"cliproxyapiHealth": "__MISSING__:Health",
-"cliproxyapiHealthy": "__MISSING__:Healthy",
-"cliproxyapiInstall": "__MISSING__:Install",
-"cliproxyapiNotInstalledValue": "__MISSING__:Not installed",
-"cliproxyapiPort": "__MISSING__:Port",
-"cliproxyapiRequestFailed": "__MISSING__:Request failed",
-"cliproxyapiRestart": "__MISSING__:Restart",
-"cliproxyapiStart": "__MISSING__:Start",
-"cliproxyapiStatusError": "__MISSING__:Error",
-"cliproxyapiStatusInstalled": "__MISSING__:Installed",
-"cliproxyapiStatusNotInstalled": "__MISSING__:Not Installed",
-"cliproxyapiStatusRunning": "__MISSING__:Running",
-"cliproxyapiStatusStopped": "__MISSING__:Stopped",
-"cliproxyapiStop": "__MISSING__:Stop",
-"cliproxyapiUnhealthy": "__MISSING__:Unhealthy",
-"cliproxyapiUnknown": "__MISSING__:Unknown",
-"cliproxyapiUpdate": "__MISSING__:Update",
-"cliproxyapiUpdateAvailable": "__MISSING__:Update available: v{current} → v{latest}",
-"cliproxyapiVersion": "__MISSING__:Version"
+ "wireApiResponses": "API de respostas (/respostas)",
+ "cliproxyapiActionFailed": "__MISSING__:Action failed",
+ "cliproxyapiActionSucceeded": "__MISSING__:Action succeeded",
+ "cliproxyapiCheckUpdates": "__MISSING__:Check Updates",
+ "cliproxyapiDescription": "__MISSING__:Upstream proxy fallback (Go-based OAuth)",
+ "cliproxyapiHealth": "__MISSING__:Health",
+ "cliproxyapiHealthy": "__MISSING__:Healthy",
+ "cliproxyapiInstall": "__MISSING__:Install",
+ "cliproxyapiNotInstalledValue": "__MISSING__:Not installed",
+ "cliproxyapiPort": "__MISSING__:Port",
+ "cliproxyapiRequestFailed": "__MISSING__:Request failed",
+ "cliproxyapiRestart": "__MISSING__:Restart",
+ "cliproxyapiStart": "__MISSING__:Start",
+ "cliproxyapiStatusError": "__MISSING__:Error",
+ "cliproxyapiStatusInstalled": "__MISSING__:Installed",
+ "cliproxyapiStatusNotInstalled": "__MISSING__:Not Installed",
+ "cliproxyapiStatusRunning": "__MISSING__:Running",
+ "cliproxyapiStatusStopped": "__MISSING__:Stopped",
+ "cliproxyapiStop": "__MISSING__:Stop",
+ "cliproxyapiUnhealthy": "__MISSING__:Unhealthy",
+ "cliproxyapiUnknown": "__MISSING__:Unknown",
+ "cliproxyapiUpdate": "__MISSING__:Update",
+ "cliproxyapiUpdateAvailable": "__MISSING__:Update available: v{current} → v{latest}",
+ "cliproxyapiVersion": "__MISSING__:Version"
},
"combos": {
"title": "Combos",
@@ -3151,8 +3151,8 @@
"leastLatency": "Menor Latência",
"comboName": "Nome do Combo",
"comboNamePlaceholder": "meu-combo",
- "comboDescription": "Descrição",
- "comboDescriptionPlaceholder": "Nota opcional descrevendo este combo",
+ "comboDescription": "__MISSING__:Description",
+ "comboDescriptionPlaceholder": "__MISSING__:Optional note describing this combo",
"deleteConfirm": "Excluir este combo?",
"noCombosYet": "Nenhum combo ainda",
"comboCreated": "Combo criado com sucesso",
@@ -3193,8 +3193,8 @@
"resetAwareDesc": "Equilibra a cota restante com redefinições de 5h e semanais e, em seguida, faz um round-robin de pontuações semelhantes",
"strictRandom": "Aleatório Estrito",
"strictRandomDesc": "Baralho embaralhado — usa cada modelo uma vez antes de reembaralhar",
- "fusion": "Fusão",
- "fusionDesc": "Distribui o prompt para cada modelo do painel em paralelo, então um modelo juiz sintetiza uma resposta final",
+ "fusion": "__MISSING__:Fusion",
+ "fusionDesc": "__MISSING__:Fans the prompt to every panel model in parallel, then a judge model synthesizes one final answer",
"fusionJudgeModel": "Modelo julgador",
"fusionJudgeModelHelp": "Modelo que sintetiza as respostas do painel em uma resposta final única. Deixe vazio para usar o primeiro modelo do painel.",
"fusionMinPanel": "Painel mínimo",
@@ -3225,27 +3225,27 @@
"removeModel": "Remover",
"saving": "Salvando...",
"liveNoProviders": "Nenhum provedor observado ainda.",
- "liveFleetDataHint": "Os dados da frota chegam por meio de eventos de combo ao vivo.",
+ "liveFleetDataHint": "Os dados da frota chegam por meio de eventos de combo em tempo real.",
"liveActiveCount": "Ativos ({count})",
"liveErrorCount": "Erros ({count})",
"liveInactiveCount": "Inativos ({count})",
"liveNoRun": "Nenhuma execução de combo disponível.",
- "liveDataHint": "Os dados ao vivo chegam pelo canal de combo do WebSocket.",
- "liveDisconnected": "Transmissão ao vivo desativada — WebSocket desconectado. Mostrando o último estado conhecido.",
+ "liveDataHint": "Os dados em tempo real chegam pelo canal de combo via WebSocket.",
+ "liveDisconnected": "Tempo real desativado — WebSocket desconectado. Exibindo o último estado conhecido.",
"liveSelectCombo": "Selecionar combo",
"liveSelectComboPlaceholder": "— selecionar combo —",
"liveTargetCount": "{count, plural, one {# alvo} other {# alvos}}",
- "liveSingle": "Único",
+ "liveSingle": "Solteiro",
"liveFleet": "Frota",
- "playgroundStatusAvailable": "Disponível",
- "playgroundStatusNoQuota": "Sem cota",
+ "playgroundStatusAvailable": "Available",
+ "playgroundStatusNoQuota": "Sem Cota",
"playgroundStatusDegraded": "Degradado",
"playgroundStatusError": "Erro",
"playgroundStatusUnknown": "Desconhecido",
"playgroundNetworkError": "Erro de rede durante a simulação",
- "playgroundTitle": "Combo Playground",
- "playgroundDescription": "Simule como as requisições serão roteadas pelos seus combos",
- "playgroundConfiguration": "Configuração",
+ "playgroundTitle": "Playground de Combo",
+ "playgroundDescription": "Simule como as solicitações serão roteadas pelos seus combos",
+ "playgroundConfiguration": "Configuration",
"playgroundNoCombosConfigured": "Nenhum combo configurado",
"active": "ativo",
"inactive": "inativo",
@@ -3253,9 +3253,9 @@
"playgroundSimulating": "Simulando...",
"playgroundSimulateRoute": "Simular Rota",
"playgroundRoutingPath": "Caminho de Roteamento",
- "playgroundStrategy": "Estratégia",
+ "playgroundStrategy": "Strategy",
"playgroundEstimatedCost": "Custo Est.",
- "playgroundEstimatedLatency": "Latência Est.",
+ "playgroundEstimatedLatency": "Latência Estimada",
"playgroundFallback": "fallback",
"playgroundWeight": "peso {value}",
"playgroundWarningCount": "Avisos ({count})",
@@ -3684,8 +3684,8 @@
"disableSessionStickiness": "Desabilitar fixação de sessão",
"sessionStickinessEnabled": "Fixação ativada",
"sessionStickinessDisabled": "Fixação desativada",
- "kimiPresetTitle": "Preset do Kimi Coding",
- "kimiPresetDescription": "Kimi K3 como o modelo principal (Moonshot API), com fallback automático para suas conexões do Kimi Code (kimi-coding, kimi-web) quando configurado.",
+ "kimiPresetTitle": "Preset Kimi Coding",
+ "kimiPresetDescription": "Kimi K3 como modelo primário (Moonshot API), com fallback automático para suas conexões Kimi Code (kimi-coding, kimi-web) quando configuradas.",
"kimiPresetCta": "Adicionar preset",
"intelligentComboCount": "__MISSING__:{count, plural, one {# intelligent combo} other {# intelligent combos}}",
"providersInScope": "__MISSING__:{count, plural, one {# provider in scope} other {# providers in scope}}",
@@ -3891,7 +3891,7 @@
"modelsCount": "{count, plural, one {# modelo} other {# modelos}}",
"sectionTitle": "Superfície de Integração",
"sectionDescription": "APIs compatíveis com OpenAI e endpoints operacionais de protocolos",
- "tabApis": "APIs",
+ "tabApis": "APIs compatíveis com OpenAI",
"tabProtocols": "Protocolos",
"tabsAria": "Seções de endpoint",
"protocolsTitle": "Protocolos",
@@ -3981,7 +3981,7 @@
"apiEndpointsSearchPlaceholder": "Pesquisar pontos de extremidade...",
"apiEndpointsRequiresAuth": "Requer autenticação",
"apiEndpointsNoMatch": "Nenhum endpoint corresponde ao seu filtro",
- "endpointSections": "Seções de endpoints",
+ "endpointSections": "Seções de endpoint",
"tabMcp": "MCP",
"tabA2a": "A2A",
"tabContextSources": "Fontes de Contexto",
@@ -3989,21 +3989,21 @@
"activeLocal": "Local",
"activeCloud": "Nuvem",
"copyUrlTitle": "Copiar {url}",
- "statusRunning": "Em execução",
+ "statusRunning": "Running",
"tunnels": "Túneis",
"activeTunnelCount": "{active} / {total} ativos",
"badgeLocal": "LOCAL",
"badgeProtected": "PROTEGIDO",
"badgeInternal": "INTERNO",
- "catalogLoadFailed": "A requisição do catálogo de APIs falhou com HTTP {status}",
- "catalogLoadFailedGeneric": "Falha ao carregar o catálogo de APIs",
- "apiKeysLoadFailed": "Falha ao carregar as chaves de API ({status})",
- "apiKeysLoadFailedGeneric": "Falha ao carregar as chaves de API",
- "apiKeyRevealDisabled": "A revelação da chave de API está desativada (ALLOW_API_KEY_REVEAL). Altere na página de Feature Flags ou cole uma chave de API manualmente.",
+ "catalogLoadFailed": "A solicitação do catálogo de API falhou com HTTP {status}",
+ "catalogLoadFailedGeneric": "Falha ao carregar o catálogo de API",
+ "apiKeysLoadFailed": "Falha ao carregar chaves de API ({status})",
+ "apiKeysLoadFailedGeneric": "Falha ao carregar chaves de API",
+ "apiKeyRevealDisabled": "A revelação de chave de API está desativada (ALLOW_API_KEY_REVEAL). Altere isso na página Feature Flags ou cole uma chave de API manualmente.",
"apiKeyRevealFailed": "Falha ao revelar a chave de API ({status})",
"apiKeyRevealInvalid": "A revelação da chave de API retornou uma resposta inválida",
- "apiKeyRequired": "Uma chave de API é necessária para este endpoint.",
- "requestFailed": "Falha na requisição ({status})",
+ "apiKeyRequired": "É necessária uma chave de API para este endpoint.",
+ "requestFailed": "Falha na solicitação ({status})",
"errorStatus": "Erro",
"catalogStats": "{endpoints} endpoints em {categories} categorias",
"catalogUnavailableDescription": "Não foi possível carregar a especificação OpenAPI.",
@@ -4011,20 +4011,20 @@
"all": "Todos",
"more": "+{count} mais",
"showInternalTooltip": "Mostrar ou ocultar rotas internas (ocultas por padrão)",
- "bearerAuth": "Bearer Auth",
- "requestBody": "Corpo da Requisição",
+ "bearerAuth": "Autenticação Bearer",
+ "requestBody": "Corpo da Solicitação",
"close": "Fechar",
"tryIt": "Testar",
"example": "Exemplo",
"apiKey": "Chave de API",
- "switchToSelection": "Alternar para Seleção",
+ "switchToSelection": "Mudar para Seleção",
"enterManually": "Inserir Manualmente",
"pasteApiKey": "Cole sua chave de API aqui",
- "noActiveApiKeys": "Nenhuma chave de API ativa encontrada. Alterne para a entrada manual para colar uma.",
- "requestBodyJson": "Corpo da Requisição (JSON)",
+ "noActiveApiKeys": "Nenhuma chave de API ativa encontrada. Ative a entrada manual para colar uma.",
+ "requestBodyJson": "Corpo da Solicitação (JSON)",
"sending": "Enviando...",
- "sendRequest": "Enviar Requisição",
- "dataSchemas": "Esquemas de Dados",
+ "sendRequest": "Enviar Solicitação",
+ "dataSchemas": "Schemas de Dados",
"vscodeAliasTitle": "Alias de Token do VS Code",
"vscodeAliasDescriptionReady": "URLs de compatibilidade prontas para colar usando o endpoint /api/v1/vscode/TOKEN/... .",
"vscodeAliasDescriptionError": "Mostrando URLs com placeholder porque as chaves de CLI não puderam ser carregadas nesta sessão.",
@@ -4050,11 +4050,11 @@
"customSystemPromptTitle": "Custom System Prompt",
"customSystemPromptDescription": "Inject a custom system prompt into every model request",
"customSystemPromptPlaceholder": "e.g. Always respond in pirate speak...",
- "obsidianEnterToken": "Por favor, insira um token de API do Obsidian",
+ "obsidianEnterToken": "Insira um token de API do Obsidian",
"obsidianConnectFailed": "Falha ao conectar",
"obsidianConnectionFailed": "Falha na conexão",
"obsidianDisconnectFailed": "Falha ao desconectar",
- "obsidianEnterVaultPath": "Por favor, insira o caminho do diretório do cofre",
+ "obsidianEnterVaultPath": "Insira o caminho do diretório do vault",
"obsidianWebdavEnabledMessage": "Sincronização WebDAV ativada. Configure seu dispositivo móvel abaixo.",
"obsidianEnableWebdavFailed": "Falha ao ativar o WebDAV",
"obsidianWebdavDisabledMessage": "Sincronização WebDAV desativada",
@@ -4066,23 +4066,23 @@
"obsidianRestToken": "Token da API REST Local do Obsidian",
"obsidianApiKeyPlaceholder": "Chave de API do Obsidian",
"obsidianConnect": "Conectar",
- "obsidianBaseUrlOptional": "URL base (opcional)",
- "obsidianPortWarning": "A porta 27124 é o endpoint do MCP (HTTPS, certificado autoassinado). A API REST usa HTTP na porta 27123.",
- "obsidianRemoteVaultHint": "Padrão: {defaultUrl}. Para cofres remotos, insira o IP do Tailscale + porta (ex.: http://100.x.x.x:27123). Ative o plugin Local REST API na máquina que executa o Obsidian.",
+ "obsidianBaseUrlOptional": "URL Base (opcional)",
+ "obsidianPortWarning": "A porta 27124 é o endpoint MCP (HTTPS, certificado autoassinado). A API REST usa HTTP na porta 27123.",
+ "obsidianRemoteVaultHint": "Padrão: {defaultUrl}. Para vaults remotos, insira o IP do Tailscale + porta (ex.: http://100.x.x.x:27123). Ative o plugin Local REST API na máquina que executa o Obsidian.",
"obsidianTokenConfigured": "Token configurado. As ferramentas do Obsidian estão disponíveis via MCP.",
"obsidianDisconnect": "Desconectar",
- "obsidianVaultSync": "Sincronização do cofre (WebDAV)",
- "obsidianVaultSyncDescription": "Sincronize seu cofre com o Obsidian mobile usando WebDAV via Tailscale. O Obsidian mobile tem suporte integrado a WebDAV — nenhum plugin necessário.",
- "obsidianVaultDirectoryPath": "Caminho do diretório do cofre",
+ "obsidianVaultSync": "Sincronização de Vault (WebDAV)",
+ "obsidianVaultSyncDescription": "Sincronize seu vault com o Obsidian mobile usando WebDAV via Tailscale. O Obsidian mobile tem suporte nativo a WebDAV — não são necessários plugins.",
+ "obsidianVaultDirectoryPath": "Caminho do Diretório do Vault",
"obsidianEnable": "Ativar",
"obsidianWebdavEnabled": "Sincronização WebDAV ativada",
"obsidianDisable": "Desativar",
- "obsidianConfigureMobile": "Configurar o Obsidian Mobile",
+ "obsidianConfigureMobile": "Configurar Obsidian Mobile",
"obsidianMobileInstructions": "No Obsidian mobile: Configurações → Sincronização → WebDAV → insira o seguinte:",
- "obsidianWebdavUrl": "URL do WebDAV",
+ "obsidianWebdavUrl": "URL WebDAV",
"obsidianUsername": "Nome de usuário",
"obsidianPassword": "Senha",
- "obsidianTailscaleHint": "Use seu IP do Tailscale em vez de localhost se estiver conectando de um dispositivo móvel. Ambos os dispositivos devem estar na mesma rede Tailscale.",
+ "obsidianTailscaleHint": "Use seu IP do Tailscale em vez de localhost ao conectar pelo celular. Ambos os dispositivos devem estar na mesma rede Tailscale.",
"cloudSyncNotConfigured": "__MISSING__:Cloud sync is not configured on this instance.",
"notionConnect": "__MISSING__:Connect",
"notionConnectFailed": "__MISSING__:Failed to connect",
@@ -4468,16 +4468,16 @@
"description": "Gerencie e monitore skills de IA",
"skillsTab": "Skills",
"executionsTab": "Execuções",
- "selectSkillToInspect": "Selecione uma habilidade à esquerda para inspecionar.",
- "schemaTab": "Esquema",
+ "selectSkillToInspect": "Selecione uma skill à esquerda para inspecionar.",
+ "schemaTab": "Schema",
"handlerTab": "Handler",
- "inputSchema": "Esquema de entrada",
- "outputSchema": "Esquema de saída",
- "handlerCode": "Código do handler",
+ "inputSchema": "Schema de Entrada",
+ "outputSchema": "Schema de Saída",
+ "handlerCode": "Código do Handler",
"handlerUnavailable": "Handler não disponível",
"runTestPlaceholder": "Executar teste (placeholder)",
"setModeAria": "Definir modo {mode}",
- "uninstallSkill": "Desinstalar habilidade",
+ "uninstallSkill": "Desinstalar skill",
"sandboxTab": "Sandbox",
"loading": "Carregando skills...",
"noSkills": "Nenhuma skill encontrada",
@@ -4621,27 +4621,27 @@
"throttleStatus": "Acelerador: {value}",
"lastHeaderUpdate": "Atualização do header: há {age}",
"databaseHealth": "Integridade do banco de dados",
- "databaseHealthDescription": "Diagnosticar e reparar linhas de cota/domínio obsoletas e referências de combo corrompidas.",
+ "databaseHealthDescription": "Diagnostica e repara linhas de cota/domínio desatualizadas e referências de combo quebradas.",
"status": "Status",
"attentionNeeded": "Atenção necessária",
"repairs": "Reparos",
- "repairing": "Reparando...",
- "runAutoRepair": "Executar reparo automático",
- "repairBackupCreated": "Um backup de reparo foi criado antes da mutação.",
- "sessionActivity": "Atividade da sessão",
- "activeCount": "{count} ativos",
- "requestCount": "{count, plural, one {# requisição} other {# requisições}}",
+ "repairing": "Repairing...",
+ "runAutoRepair": "Executar Auto-Reparo",
+ "repairBackupCreated": "Um backup de reparo foi criado antes da alteração.",
+ "sessionActivity": "Atividade da Sessão",
+ "activeCount": "{count} ativo",
+ "requestCount": "{count, plural, one {# solicitação} other {# solicitações}}",
"idleSeconds": "{count}s ocioso",
"ageSeconds": "{count}s de idade",
- "quotaMonitors": "Monitores de cotas",
- "alerting": "Alertas",
- "errors": "Erros",
- "degradationFull": "Completo",
+ "quotaMonitors": "Monitores de Quota",
+ "alerting": "Alertando",
+ "errors": "Errors",
+ "degradationFull": "Completa",
"degradationReduced": "Reduzido",
- "degradationMinimal": "Mínimo",
+ "degradationMinimal": "Minima",
"degradationDefault": "Padrão",
"sinceTime": "Desde {time}",
- "retryIn": "tentar novamente em {duration}",
+ "retryIn": "nova tentativa em {duration}",
"stickyBoundSessions": "Sessões fixas",
"sessionsByApiKey": "Sessões por chave API",
"noActiveSessionsTracked": "Nenhuma sessão ativa rastreada ainda.",
@@ -4824,14 +4824,14 @@
"export": "Export",
"exporting": "Exporting...",
"exportFailed": "Export failed",
- "cleanHistoryButton": "Limpar histórico",
- "cleanHistoryTitle": "Limpar histórico de logs?",
- "cleanHistoryMessage": "Isso limpa permanentemente todas as linhas de log de requisições, linhas de detalhes legadas e arquivos de artefatos locais em DATA_DIR/call_logs. A página ao vivo será atualizada após a limpeza.",
- "cleanHistoryConfirm": "Limpar histórico",
- "cleanHistoryCancel": "Cancelar",
- "cleanHistorySuccess": "Foram limpas {deleted} entradas de log, {deletedArtifacts} artefatos e {deletedDetailedLogs} linhas de detalhes legadas.",
- "cleanHistoryEmpty": "Nenhum histórico de logs de requisição foi encontrado.",
- "cleanHistoryFailed": "Falha ao limpar o histórico de logs.",
+ "cleanHistoryButton": "__MISSING__:Clean history",
+ "cleanHistoryTitle": "__MISSING__:Clean log history?",
+ "cleanHistoryMessage": "__MISSING__:This permanently clears all request log rows, legacy detail rows, and local artifact files under DATA_DIR/call_logs. The live page will refresh after cleanup.",
+ "cleanHistoryConfirm": "__MISSING__:Clean history",
+ "cleanHistoryCancel": "__MISSING__:Cancel",
+ "cleanHistorySuccess": "__MISSING__:Cleaned {deleted} log entries, {deletedArtifacts} artifacts, and {deletedDetailedLogs} legacy detail rows.",
+ "cleanHistoryEmpty": "__MISSING__:No request log history was found.",
+ "cleanHistoryFailed": "__MISSING__:Failed to clean log history.",
"timeRange": "Time Range",
"lastNHours": "Last {hours}",
"defaultRange": "default",
@@ -4848,10 +4848,10 @@
"entryCount": "{count, plural, one {# entrada} other {# entradas}}",
"lastHour": "Última 1h",
"updatedAt": "Atualizado {time}",
- "fileLoggingRequired": "Certifique-se de que o aplicativo esteja gravando logs em um arquivo (APP_LOG_TO_FILE=true)",
- "consoleAria": "Logs do console do aplicativo",
- "applicationConsole": "Console do aplicativo",
- "emptyFileLoggingHint": "Certifique-se de que APP_LOG_TO_FILE=true esteja definido no seu arquivo .env"
+ "fileLoggingRequired": "Verifique se o aplicativo está gravando logs em um arquivo (APP_LOG_TO_FILE=true)",
+ "consoleAria": "Logs do console da aplicação",
+ "applicationConsole": "Console da Aplicação",
+ "emptyFileLoggingHint": "Garanta que APP_LOG_TO_FILE=true esteja definido no seu arquivo .env"
},
"compressionLogTitle": "Compression Log",
"compressionLogEmpty": "No compressed requests yet. Compression stats will appear here when requests are processed with compression enabled.",
@@ -4859,7 +4859,7 @@
},
"onboarding": {
"welcome": "Bem-vindo",
- "tiers": "Níveis",
+ "tiers": "__MISSING__:Tiers",
"security": "Segurança",
"test": "Teste",
"ready": "Pronto!",
@@ -4942,7 +4942,7 @@
},
"providers": {
"title": "Provedores",
- "Account Deactivated": "Conta desativada",
+ "Account Deactivated": "__MISSING__:Account Deactivated",
"allProviders": "Todos os provedores",
"audioProviders": "Provedores de áudio",
"showFreeOnly": "Somente grátis",
@@ -4969,31 +4969,31 @@
"importFromFileImport": "Importar {count} provedores",
"importFromFileResult": "{success} provedores importados ({failed} falharam)",
"adaptaTutorial": {
- "title": "Como conectar o Adapta Web",
- "introPrefix": "O Adapta autentica por meio do Clerk. O token",
- "introSuffix": "é um JWT de longa duração que permite ao OmniRoute atualizar sessões automaticamente.",
- "or": "ou",
- "step1Title": "Abrir chat do Adapta",
- "step1DescPrefix": "Abrir",
- "step1DescSuffix": "e faça login com sua conta Gold ou Business.",
- "step2Title": "Abrir DevTools",
- "step2DescPrefix": "Pressione",
- "step2DescSuffix": "para abrir as Ferramentas do Desenvolvedor.",
- "step3Title": "Vá para Aplicativo → Cookies",
- "step3DescPrefix": "No",
- "step3DescMiddle": "expanda",
- "step3DescSuffix": "e clique em",
- "step4Title": "Copie o valor do cookie para",
- "step4DescPrefix": "Encontre o cookie chamado",
- "step4DescMiddle": "na lista. Clique nele e copie o conteúdo da",
- "step4DescSuffix": "coluna. Ele começa com",
- "step5Title": "Cole aqui e salve",
- "step5DescPrefix": "Clique em",
- "step5DescMiddle": "cole o",
- "step5DescSuffix": "valor no campo API Key e salve. O OmniRoute atualizará a sessão automaticamente.",
- "tipLabel": "Dica:",
- "tipPrefix": "O",
- "tipSuffix": "cookie é de longa duração, geralmente por meses. Você só precisa renová-lo se sair ou se o Adapta invalidar a sessão."
+ "title": "__MISSING__:How to connect Adapta Web",
+ "introPrefix": "__MISSING__:Adapta authenticates through Clerk. The token",
+ "introSuffix": "__MISSING__:is a long-lived JWT that lets OmniRoute refresh sessions automatically.",
+ "or": "__MISSING__:or",
+ "step1Title": "__MISSING__:Open Adapta chat",
+ "step1DescPrefix": "__MISSING__:Open",
+ "step1DescSuffix": "__MISSING__:and sign in with your Gold or Business account.",
+ "step2Title": "__MISSING__:Open DevTools",
+ "step2DescPrefix": "__MISSING__:Press",
+ "step2DescSuffix": "__MISSING__:to open Developer Tools.",
+ "step3Title": "__MISSING__:Go to Application → Cookies",
+ "step3DescPrefix": "__MISSING__:In the",
+ "step3DescMiddle": "__MISSING__:expand",
+ "step3DescSuffix": "__MISSING__:and click",
+ "step4Title": "__MISSING__:Copy the cookie value for",
+ "step4DescPrefix": "__MISSING__:Find the cookie named",
+ "step4DescMiddle": "__MISSING__:in the list. Click it and copy the content from the",
+ "step4DescSuffix": "__MISSING__:column. It starts with",
+ "step5Title": "__MISSING__:Paste it here and save",
+ "step5DescPrefix": "__MISSING__:Click",
+ "step5DescMiddle": "__MISSING__:paste the",
+ "step5DescSuffix": "__MISSING__:value into the API Key field, then save. OmniRoute will refresh the session automatically.",
+ "tipLabel": "__MISSING__:Tip:",
+ "tipPrefix": "__MISSING__:The",
+ "tipSuffix": "__MISSING__:cookie is long-lived, usually for months. You only need to renew it if you sign out or Adapta invalidates the session."
},
"editProvider": "Editar Provedor",
"deleteProvider": "Excluir Provedor",
@@ -5031,30 +5031,30 @@
"testAllFree": "Testar todas as conexões gratuitas",
"testAllApiKey": "Testar todas as conexões por chave de API",
"testAllCompatible": "Testar todas as conexões compatíveis",
- "testAllModels": "Testar todos os modelos",
- "testAllModelsConfirm": "Testar todos os modelos visíveis? Os modelos que falharem serão ocultados se a ocultação automática estiver ativada.",
- "testingAllModels": "Testando {done}/{total}...",
- "testAllResults": "{ok} de {total} modelos funcionando",
- "noModelsToTest": "Nenhum modelo corresponde ao filtro atual",
- "showAllModels": "Todos",
+ "testAllModels": "__MISSING__:Test all models",
+ "testAllModelsConfirm": "__MISSING__:Test all visible models? Failed models will be hidden if auto-hide is enabled.",
+ "testingAllModels": "__MISSING__:Testing {done}/{total}...",
+ "testAllResults": "__MISSING__:{ok} of {total} models working",
+ "noModelsToTest": "__MISSING__:No models match the current filter",
+ "showAllModels": "__MISSING__:All",
"showVisibleOnly": "Somente visíveis",
"freeFilterAll": "Todos",
"freeFilterFreeOnly": "Somente gratuitos",
"freeFilterPaidOnly": "Somente pagos",
- "sortFreeFirst": "Gratuitos primeiro",
+ "sortFreeFirst": "__MISSING__:Free first",
"showHiddenOnly": "Somente ocultos",
"filterByVisibility": "Filtrar por visibilidade",
- "autoHideFailed": "Ocultar automaticamente modelos que falharem",
- "autoHideFailedHint": "Quando ativado, o Testar todos oculta falhas não transitórias de catálogos públicos, como /v1/models. Testes de modelo único nunca são ocultados automaticamente.",
+ "autoHideFailed": "__MISSING__:Auto-hide failed models",
+ "autoHideFailedHint": "__MISSING__:When enabled, Test all hides non-transient failures from public catalogs such as /v1/models. Single-model tests never auto-hide.",
"connected": "{count} Conectado(s)",
"errorCount": "{count} Erro ({code})",
"errorCountNoCode": "{count} Erro",
- "testAllCompleted": "Testados {total} modelos: {ok} OK, {failed} falharam",
- "modelAutoHidden": "Modelo {model} ocultado automaticamente (falha no teste)",
+ "testAllCompleted": "__MISSING__:Tested {total} models: {ok} OK, {failed} failed",
+ "modelAutoHidden": "__MISSING__:Model {model} auto-hidden (test failed)",
"filterAll": "Todos",
"filterVisible": "Somente visíveis",
"filterHidden": "Somente ocultos",
- "modelsHiddenCount": "{count} ocultos",
+ "modelsHiddenCount": "__MISSING__:{count} hidden",
"warningCount": "{count} Aviso",
"noConnections": "Sem conexões",
"expiredBadge": "Expired",
@@ -5167,17 +5167,17 @@
"batchUpdateNone": "Nenhuma conexão foi atualizada (podem não existir mais)",
"batchRetestLimit": "Reteste até {max} conexões por vez",
"noConnectionsToTest": "Nenhuma conexão correspondente para testar",
- "batchDeleteConfirmTitle": "Excluir conexões",
- "batchDeleteConfirmButton": "Excluir",
+ "batchDeleteConfirmTitle": "__MISSING__:Delete connections",
+ "batchDeleteConfirmButton": "__MISSING__:Delete",
"filterActive": "Ativo",
"filterError": "Erro",
"filterBanned": "Banido",
"filterCreditsExhausted": "Créditos esgotados",
"accountSearchPlaceholder": "Search accounts…",
- "noFilteredConnections": "Nenhuma conexão corresponde ao filtro atual.",
+ "noFilteredConnections": "__MISSING__:No connections match the current filter.",
"failedSetAlias": "Falha ao definir alias",
- "setAliasSuccess": "Alias {alias} definido",
- "deleteAliasSuccess": "Alias {alias} excluído",
+ "setAliasSuccess": "__MISSING__:Alias {alias} set",
+ "deleteAliasSuccess": "__MISSING__:Alias {alias} deleted",
"failedSaveConnection": "Falha ao salvar conexão",
"failedSaveConnectionRetry": "Falha ao salvar conexão. Tente novamente.",
"failedRetestConnection": "Falha ao retestar conexão",
@@ -5214,8 +5214,8 @@
"fetchingModels": "Buscando modelos disponíveis...",
"failedFetchModels": "Falha ao buscar modelos",
"noFreeModelsFound": "Nenhum modelo gratuito encontrado para este provedor — nada importado.",
- "fetchModelsSuccess": "Encontrados {count} novos modelos",
- "fetchModelsFailed": "Não foi possível buscar os modelos automaticamente (você pode tentar novamente nas configurações)",
+ "fetchModelsSuccess": "__MISSING__:Found {count} new models",
+ "fetchModelsFailed": "__MISSING__:Could not auto-fetch models (you can retry from settings)",
"noModelsFound": "Nenhum modelo encontrado",
"importFailed": "Falha na importação",
"noNewModelsAdded": "Nenhum novo modelo foi adicionado.",
@@ -5224,8 +5224,8 @@
"importingModelsTitle": "Importando Modelos",
"copyModel": "Copiar modelo",
"filterModels": "Filtrar modelos...",
- "testAllRateLimited": "Limite de taxa atingido, interrompido antecipadamente",
- "hideFailedAuto": "Ocultar automaticamente modelos que falharem",
+ "testAllRateLimited": "__MISSING__:Rate limit reached, stopped early",
+ "hideFailedAuto": "__MISSING__:Auto-hide failed models",
"selectAllModels": "Selecionar todos",
"hideAllModels": "Ocultar todos",
"modelsActive": "ativos",
@@ -5240,9 +5240,9 @@
"quotaVisibilityUpdateFailed": "Não foi possível atualizar a visibilidade em Cotas dos Provedores",
"enableRateLimitProtection": "Clique para habilitar proteção de limite de taxa",
"disableRateLimitProtection": "Clique para desabilitar proteção de limite de taxa",
- "testAllProgress": "Testados {done}/{total}",
- "testAllFailedHidden": "{count} modelos com falha ocultos",
- "testAllDone": "Todos os modelos testados",
+ "testAllProgress": "__MISSING__:Tested {done}/{total}",
+ "testAllFailedHidden": "__MISSING__:{count} failed models hidden",
+ "testAllDone": "__MISSING__:All models tested",
"productionKey": "Chave de Produção",
"enterNewApiKey": "Insira a nova chave API",
"codexApplyModalTitle": "Inscreva-se no Codex Local",
@@ -5322,8 +5322,8 @@
"errorTypeNetworkError": "Erro de rede",
"errorTypeTestUnsupported": "Teste não suportado",
"errorTypeUpstreamError": "Erro upstream",
- "errorTypeCreditsExhausted": "Sem créditos",
- "errorTypeBanned": "403 Banido",
+ "errorTypeCreditsExhausted": "__MISSING__:No credits",
+ "errorTypeBanned": "__MISSING__:403 Banned",
"proxySourceGlobal": "Global",
"proxySourceProvider": "Provedor",
"proxySourceKey": "Chave",
@@ -5366,17 +5366,17 @@
"compatProtocolOpenAI": "OpenAI Chat Completions",
"compatProtocolOpenAIResponses": "OpenAI Responses API",
"compatProtocolClaude": "Anthropic Messages",
- "targetFormatLabel": "Formato de destino",
- "targetFormatHint": "Substitua o formato de transmissão upstream. Use 'Anthropic Messages' para rotear provedores compatíveis com a OpenAI (ex.: opencode-go) pelo endpoint /v1/messages.",
- "targetFormatAuto": "Padrão (automático)",
- "targetFormatGemini": "Gemini",
- "targetFormatAntigravity": "Antigravity",
+ "targetFormatLabel": "__MISSING__:Target Format",
+ "targetFormatHint": "__MISSING__:Override the upstream wire format. Use 'Anthropic Messages' to route OpenAI-compatible providers (e.g. opencode-go) through the /v1/messages endpoint.",
+ "targetFormatAuto": "__MISSING__:Default (auto)",
+ "targetFormatGemini": "__MISSING__:Gemini",
+ "targetFormatAntigravity": "__MISSING__:Antigravity",
"contextWindowOverrideLabel": "Substituição de Janela de Contexto",
"contextWindowOverridePlaceholder": "ex.: 131072",
"contextWindowOverrideHint": "Define manualmente a janela de contexto real (tokens) deste modelo quando o provedor a reporta incorretamente. Tem prioridade sobre os valores detectados automaticamente/do catálogo e evita que o roteamento de combo descarte o modelo.",
"contextWindowOverrideInvalid": "A substituição de janela de contexto deve ser um número inteiro positivo de tokens",
- "visionCapableLabel": "Compatível com visão",
- "visionCapableHint": "Marque manualmente este modelo como compatível com visão quando os metadados de descoberta do provedor não informarem uma modalidade de entrada de imagem (comum em backends locais/auto-hospedados).",
+ "visionCapableLabel": "__MISSING__:Vision capable",
+ "visionCapableHint": "__MISSING__:Manually flag this model as vision-capable when the provider's discovery metadata doesn't report an image input modality (common for self-hosted/local backends).",
"compatParamFiltersLabel": "Filtros de parâmetros",
"compatBlockedParamsHint": "Parâmetros bloqueados (removidos das requisições)",
"compatAllowedParamsHint": "Parâmetros permitidos (readicionados após o bloqueio)",
@@ -5404,18 +5404,18 @@
"interceptFetchHint": "Reescreve chamadas nativas de web_fetch para /v1/web/fetch da OmniRoute.",
"interceptionLoadError": "Falha ao carregar configuração de interceptação: {error}",
"interceptionSaveError": "Falha ao salvar configuração de interceptação: {error}",
-"ccAliasSectionTitle": "Expose em Claude Code (claude/…)",
-"ccAliasSectionHint": "Anuncie os modelos deste provedor sob claude/<provider>/<model> IDs de espelho para que a descoberta de modelos do gateway do Claude Code possa listá-los. Desativado por padrão — habilitar isso dobra as entradas do catálogo para todos os clientes.",
-"ccAliasProviderLevelLabel": "Provedor padrão",
-"ccAliasModelOverridesLabel": "Substituições por modelo",
-"ccAliasModelOverrideAriaLabel": "Substituição para {modelId}",
-"ccAliasStateInherit": "Herdar",
-"ccAliasStateOn": "Ligado",
-"ccAliasStateOff": "Desligado",
-"ccAliasAddModelPlaceholder": "ID do modelo (por exemplo, gpt-4o)",
-"ccAliasAddModelButton": "Adicionar substituição",
-"ccAliasLoadError": "Falha ao carregar as configurações de discovery-alias: {error}",
-"ccAliasSaveError": "Falha ao salvar a configuração de discovery-alias: {error}",
+ "ccAliasSectionTitle": "Expose em Claude Code (claude/…)",
+ "ccAliasSectionHint": "Anuncie os modelos deste provedor sob claude/<provider>/<model> IDs de espelho para que a descoberta de modelos do gateway do Claude Code possa listá-los. Desativado por padrão — habilitar isso dobra as entradas do catálogo para todos os clientes.",
+ "ccAliasProviderLevelLabel": "Provedor padrão",
+ "ccAliasModelOverridesLabel": "Substituições por modelo",
+ "ccAliasModelOverrideAriaLabel": "Substituição para {modelId}",
+ "ccAliasStateInherit": "Herdar",
+ "ccAliasStateOn": "Ligado",
+ "ccAliasStateOff": "Desligado",
+ "ccAliasAddModelPlaceholder": "ID do modelo (por exemplo, gpt-4o)",
+ "ccAliasAddModelButton": "Adicionar substituição",
+ "ccAliasLoadError": "Falha ao carregar as configurações de discovery-alias: {error}",
+ "ccAliasSaveError": "Falha ao salvar a configuração de discovery-alias: {error}",
"compatUpstreamHeadersLabel": "Extra upstream headers",
"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.",
"compatUpstreamHeaderName": "Header name",
@@ -5473,9 +5473,9 @@
"editCompatibleTitle": "Editar Compatível {type}",
"compatibleBaseUrlHint": "Root URL of your {type}-compatible API. Use Advanced Settings for custom endpoint paths.",
"apiKeyForCheck": "Chave de API (para verificação)",
- "testModelIdLabel": "ID do modelo (opcional)",
- "testModelIdPlaceholder": "ex.: my-model-id",
- "testModelIdHint": "Se o provedor não tiver um endpoint /models, insira um ID de modelo para validar via /chat/completions.",
+ "testModelIdLabel": "__MISSING__:Model ID (optional)",
+ "testModelIdPlaceholder": "__MISSING__:e.g. my-model-id",
+ "testModelIdHint": "__MISSING__:If the provider lacks a /models endpoint, enter a model ID to validate via /chat/completions instead.",
"compatibleProdPlaceholder": "{type} Compatível (Prod)",
"tokenRefreshed": "Token refreshed successfully",
"tokenRefreshFailed": "Token refresh failed",
@@ -5560,19 +5560,19 @@
"codexAuthApplyFailed": "Falha ao aplicar o auth.json do Codex localmente",
"codexAuthExported": "auth.json do Codex exportado",
"codexAuthExportFailed": "Falha ao exportar o auth.json do Codex",
- "codexCliGuideButton": "Guia da CLI do Codex",
- "codexCliGuideTitle": "Guia da CLI do Codex",
- "codexCliGuideLoading": "Carregando guia...",
- "codexCliGuideLoadFailed": "Não foi possível carregar o guia.",
- "codexExternalLinkButton": "Link externo do Codex",
- "codexExternalLinkModalTitle": "Link externo do Codex",
- "codexExternalLinkModalDescription": "Compartilhe este link de uso único com a pessoa que autenticará a conta do Codex. Ela o abrirá em seu próprio navegador, concluirá o login da OpenAI e a conexão será registrada aqui. O link expira em 15 minutos.",
- "codexExternalLinkGenerating": "Gerando link...",
- "codexExternalLinkWaiting": "Aguardando autenticação no navegador. Esta janela é atualizada automaticamente.",
- "codexExternalLinkCreateFailed": "Falha ao gerar o link.",
- "codexExternalLinkNetworkError": "Não foi possível contatar o servidor.",
- "codexExternalLinkConnected": "Conta do Codex conectada por meio do link externo.",
- "codexExternalLinkExpired": "O link expirou antes da conclusão.",
+ "codexCliGuideButton": "__MISSING__:Codex CLI Guide",
+ "codexCliGuideTitle": "__MISSING__:Codex CLI Guide",
+ "codexCliGuideLoading": "__MISSING__:Loading guide...",
+ "codexCliGuideLoadFailed": "__MISSING__:Could not load the guide.",
+ "codexExternalLinkButton": "__MISSING__:External Codex link",
+ "codexExternalLinkModalTitle": "__MISSING__:External Codex link",
+ "codexExternalLinkModalDescription": "__MISSING__:Share this single-use link with the person who will authenticate the Codex account. They open it in their own browser, complete the OpenAI login, and the connection is registered here. The link expires in 15 minutes.",
+ "codexExternalLinkGenerating": "__MISSING__:Generating link...",
+ "codexExternalLinkWaiting": "__MISSING__:Waiting for browser authentication. This window refreshes automatically.",
+ "codexExternalLinkCreateFailed": "__MISSING__:Failed to generate the link.",
+ "codexExternalLinkNetworkError": "__MISSING__:Could not contact the server.",
+ "codexExternalLinkConnected": "__MISSING__:Codex account connected through the external link.",
+ "codexExternalLinkExpired": "__MISSING__:The link expired before completion.",
"importCodexAuth": "Importar autenticação",
"codexImportModalTitle": "Importar autenticação do Codex",
"codexImportTabSingle": "Solteiro",
@@ -5642,7 +5642,7 @@
"audioProvidersHeading": "Provedores de Áudio",
"cloudAgentProviders": "Provedores de agentes em nuvem",
"audioShortLabel": "Áudio",
- "azureOpenAiBaseUrlHint": "Obrigatório: cole o endpoint do seu recurso Azure OpenAI. O OmniRoute adicionará /openai/deployments/{model}/chat/completions?api-version=....",
+ "azureOpenAiBaseUrlHint": "Obrigatório: cole o endpoint do seu recurso Azure OpenAI. O OmniRoute adicionará /openai/deployments/'{model}'/chat/completions?api-version=....",
"bailianBaseUrlHint": "Opcional: URL base customizada para o provedor bailian-coding-plan.",
"claudeWebCookieHint": "Open claude.ai → DevTools → Application → Cookies → claude.ai, copy the 'sessionKey' value. Also need cf_clearance, __cf_bm, _cfuvid for Cloudflare.",
"claudeWebCookiePlaceholder": "sessionKey=sk-ant-...",
@@ -5651,10 +5651,10 @@
"t3ChatWebCookieHint": "Abra t3.chat → DevTools → Aplicativo → Armazenamento local → https://t3.chat, copie 'convex-session-id'. Em seguida, abra DevTools → Rede, copie o cabeçalho completo do cookie de qualquer solicitação de chat. Cole os dois valores nos campos abaixo.",
"t3ChatWebCookiePlaceholder": "id-de-sessão-convexa=abc123...",
"grokWebCookieHint": "Cole o cookie sso do grok.com. Um valor completo `sso=...` também funciona.",
- "blockClaudeExtraUsageDescription": "Quando ativado, o OmniRoute marca esta conexão Claude como indisponível assim que a API de uso relata uso extra em fila, para que a alternativa mude para outra conexão em vez de continuar com a cobrança extra pay-as-you-go.",
- "blockClaudeExtraUsageLabel": "Bloquear uso extra do Claude",
- "disableCoolingDescription": "Ignore o cooldown transitório para que esta conexão permaneça qualificada mesmo após erros recuperáveis (estados terminais como banido/expirado ainda se aplicam).",
- "disableCoolingLabel": "Desativar cooldown para esta conexão",
+ "blockClaudeExtraUsageDescription": "Quando habilitado, o OmniRoute marca esta conta do Claude Code como indisponível assim que a API de usage reporta `extra_usage.queued`, para que o fallback troque para outra conta antes de continuar com cobranças extras pay-as-you-go.",
+ "blockClaudeExtraUsageLabel": "Bloquear Claude Extra Usage",
+ "disableCoolingDescription": "__MISSING__:Skip the transient cooldown so this connection stays eligible even after recoverable errors (terminal states like banned/expired still apply).",
+ "disableCoolingLabel": "__MISSING__:Disable cooldown for this connection",
"bulkPasteAdded": "{count, plural, one {1 chave adicionada} other {# chaves adicionadas}}",
"bulkPasteDuplicatesIgnored": "{count, plural, one {1 duplicata ignorada} other {# duplicatas ignoradas}}",
"bulkPasteHint": "Cole uma chave de API por linha. Linhas vazias são ignoradas e chaves duplicadas são puladas.",
@@ -5771,17 +5771,17 @@
"personalAccessTokenLabel": "Personal Access Token",
"qoderPatHint": "Fluxo suportado: PAT via qodercli. OAuth pelo navegador continua experimental.",
"qoderPatPlaceholder": "Cole seu Personal Access Token do Qoder",
- "rateLimitOverridesSection": "Substituições de limite de taxa",
- "rateLimitOverridesMaxConcurrentHint": "Substituição de máximo de solicitações simultâneas para esta conexão. Substitui o limite no nível da conta.",
- "rateLimitOverridesMaxConcurrentLabel": "Máximo simultâneo (limite de taxa)",
- "rateLimitOverridesMinTimeHint": "Tempo mínimo (ms) entre solicitações. Substitui o atraso padrão do limitador de taxa.",
- "rateLimitOverridesMinTimeLabel": "Intervalo mínimo (ms)",
- "rateLimitOverridesRpmHint": "Máximo de solicitações por minuto para esta conexão. Substitui o padrão do provedor.",
- "rateLimitOverridesRpmLabel": "RPM (Solicitações/min)",
- "rateLimitOverridesTpdHint": "Máximo de tokens por dia para esta conexão. Substitui o padrão do provedor.",
- "rateLimitOverridesTpdLabel": "TPD (Tokens/dia)",
- "rateLimitOverridesTpmHint": "Máximo de tokens por minuto para esta conexão. Substitui o padrão do provedor.",
- "rateLimitOverridesTpmLabel": "TPM (Tokens/min)",
+ "rateLimitOverridesSection": "__MISSING__:Rate Limit Overrides",
+ "rateLimitOverridesMaxConcurrentHint": "__MISSING__:Max concurrent requests override for this connection. Overrides the account-level cap.",
+ "rateLimitOverridesMaxConcurrentLabel": "__MISSING__:Max Concurrent (Rate Limit)",
+ "rateLimitOverridesMinTimeHint": "__MISSING__:Minimum time (ms) between requests. Overrides the default rate limiter delay.",
+ "rateLimitOverridesMinTimeLabel": "__MISSING__:Min Interval (ms)",
+ "rateLimitOverridesRpmHint": "__MISSING__:Max requests per minute for this connection. Overrides the provider default.",
+ "rateLimitOverridesRpmLabel": "__MISSING__:RPM (Requests/min)",
+ "rateLimitOverridesTpdHint": "__MISSING__:Max tokens per day for this connection. Overrides the provider default.",
+ "rateLimitOverridesTpdLabel": "__MISSING__:TPD (Tokens/day)",
+ "rateLimitOverridesTpmHint": "__MISSING__:Max tokens per minute for this connection. Overrides the provider default.",
+ "rateLimitOverridesTpmLabel": "__MISSING__:TPM (Tokens/min)",
"refreshOauthTokenTitle": "Atualizar token OAuth manualmente",
"regionHint": "ex.: us-central1 ou europe-west4. Modelos partner usam a região global automaticamente.",
"regionLabel": "Região",
@@ -5830,26 +5830,26 @@
"webCookieProviders": "Provedores Web / Cookie",
"weeklyShort": "Semanal",
"xiaomiMimoBaseUrlHint": "Opcional: URL base token-plan do Xiaomi MiMo. Exemplos: https://token-plan-ams.xiaomimimo.com/v1, https://token-plan-sgp.xiaomimimo.com/v1, https://token-plan-cn.xiaomimimo.com/v1. O app adicionará /chat/completions.",
- "globalCodexServiceMode": "Modo de serviço global do Codex",
+ "globalCodexServiceMode": "Modo de serviço Global Codex",
"connect": "Conectar",
"manualApiKey": "Chave de API manual",
"addPat": "Adicionar PAT",
"experimentalOauth": "OAuth experimental",
"importAuth": "Importar autenticação",
"importGrokAuth": "Importar autenticação do Grok Build",
- "zedImportTitle": "Importar do chaveiro do Zed",
- "zedImportDescription": "Descubra credenciais de provedores de IA (OpenAI, Anthropic, Google, Mistral, xAI) armazenadas pelo Zed IDE no chaveiro do SO e importe-as como conexões. O Zed IDE deve estar instalado nesta máquina.",
+ "zedImportTitle": "Importar do Zed Keychain",
+ "zedImportDescription": "Descubra credenciais de provedores de IA (OpenAI, Anthropic, Google, Mistral, xAI) armazenadas pelo Zed IDE no keychain do sistema operacional e importe-as como conexões. O Zed IDE precisa estar instalado nesta máquina.",
"zedImportButton": "Importar do Zed",
- "zedImportFailed": "Falha na importação do Zed",
+ "zedImportFailed": "Falha ao importar do Zed IDE.",
"zedImportHint": "Importar credenciais do Zed IDE",
"zedImportNetworkError": "Erro de rede ao tentar importar do Zed.",
"zedImportNone": "Nenhuma credencial OAuth suportada encontrada no Zed IDE.",
- "zedImportSuccess": "Credencial(ais) {credentials} importada(s) do Zed para o(s) provedor(es) {providers}",
- "zedImporting": "Importando…",
- "zedNoCredentials": "Nenhuma credencial do Zed encontrada no chaveiro",
- "zedUnsupportedCredentials": "Encontrada(s) {count} credencial(is) no chaveiro, mas nenhuma correspondeu aos provedores suportados",
- "zedManualTitle": "Importação manual de token",
- "zedManualDescription": "Use isso quando o OmniRoute for executado no Docker ou o chaveiro estiver indisponível. Cole a chave de API que o Zed armazenou em ~/.config/zed/settings.json ou copie-a do painel de configurações do Zed AI.",
+ "zedImportSuccess": "Importadas {count} credencial(is) do Zed IDE ({providers}).",
+ "zedImporting": "Importando...",
+ "zedNoCredentials": "Nenhuma credencial do Zed encontrada no keychain",
+ "zedUnsupportedCredentials": "{count} credencial(is) encontrada(s) no keychain, mas nenhuma correspondeu a provedores suportados",
+ "zedManualTitle": "Importação Manual de Token",
+ "zedManualDescription": "Use isto quando o OmniRoute roda em Docker ou o keychain não está disponível. Cole a chave de API que o Zed armazenou em ~/.config/zed/settings.json, ou copie-a do painel de configurações de IA do Zed.",
"zedPasteApiKey": "Colar chave de API…",
"zedSaving": "Salvando…",
"zedImportAction": "Importar",
@@ -5858,20 +5858,20 @@
"cursorAgentNudgeDismiss": "__MISSING__:Dismiss",
"zedManualImportFailed": "Falha na importação manual",
"zedManualImportSuccess": "Token do {provider} importado do Zed",
- "grokImportTitle": "Importar autenticação do Grok Build",
- "grokImportDescription": "Importe seu arquivo ~/.grok/auth.json do Grok Build. Você pode obtê-lo executando grok login no seu terminal.",
- "grokUploadFile": "Fazer upload de arquivo",
+ "grokImportTitle": "Importar Autenticação do Grok Build",
+ "grokImportDescription": "Importe seu arquivo do Grok Build ~/.grok/auth.json. Você pode obtê-lo executando grok login no seu terminal.",
+ "grokUploadFile": "Carregar arquivo",
"grokPasteJson": "Colar JSON",
- "grokInvalidAuth": "Este não é um arquivo auth.json do Grok Build válido. Esperava-se um objeto com uma chave contendo um JWT.",
+ "grokInvalidAuth": "Este não é um arquivo auth.json válido do Grok Build. Esperava-se um objeto com uma chave contendo um JWT.",
"grokParseFailed": "Não foi possível analisar o JSON",
- "grokImportFailed": "Falha ao importar a autenticação do Grok Build",
+ "grokImportFailed": "Falha ao importar autenticação do Grok Build",
"grokImportSuccess": "Conexão do Grok Build importada com sucesso",
- "grokValidToken": "Token do Grok Build válido detectado",
- "grokRefreshIncluded": "Token de atualização incluído — a renovação automática de token está ativada",
- "grokRefreshMissing": "Nenhum token de atualização encontrado — reimporte após a expiração do token",
+ "grokValidToken": "Token válido do Grok Build detectado",
+ "grokRefreshIncluded": "Refresh token incluído — a renovação automática de token está ativada",
+ "grokRefreshMissing": "Nenhum refresh token encontrado — reimporte após o token expirar",
"grokConnectionName": "Nome da conexão (opcional)",
"grokSaving": "Salvando…",
- "grokSaveConnection": "Salvar conexão",
+ "grokSaveConnection": "Salvar Conexão",
"freeTierProviders": "Provedores de nível gratuito",
"freeTierLabel": "Nível gratuito disponível",
"freeTierProvidersDesc": "Provedores com níveis gratuitos – alguns exigem uma inscrição de chave de API, outros não precisam de nenhuma credencial.",
@@ -5888,11 +5888,11 @@
"providerDetailPathAutoDetectedAllOs": "O caminho é detectado automaticamente por sistema operacional (Linux/Mac/Windows).",
"providerDetailMyClaudeAccountPlaceholder": "Minha conta Claude",
"providerDetailPathAutoDetected": "O caminho é detectado automaticamente por sistema operacional (Linux/Mac).",
- "compatBlockedParamsPlaceholder": "thinking, … (separado por vírgulas)",
- "compatAllowedParamsPlaceholder": "reasoning, … (separado por vírgulas)",
+ "compatBlockedParamsPlaceholder": "thinking, … (separados por vírgula)",
+ "compatAllowedParamsPlaceholder": "reasoning, … (separados por vírgula)",
"compatSaving": "salvando…",
- "paramFiltersBlockedPlaceholder": "thinking, reasoning_budget, … (separado por vírgulas)",
- "paramFiltersAllowedPlaceholder": "reasoning, … (separado por vírgulas)",
+ "paramFiltersBlockedPlaceholder": "thinking, reasoning_budget, … (separados por vírgula)",
+ "paramFiltersAllowedPlaceholder": "reasoning, … (separados por vírgula)",
"customGatewayNamePlaceholder": "Meu Gateway",
"inherit": "Herdar",
"claudeImportEntryName": "entrada {number}",
@@ -5985,152 +5985,152 @@
"onboardingStartOAuthFlow": "Iniciar fluxo OAuth",
"onboardingProviderDescriptions": {
"360ai": "Obtenha a chave de API em ai.360.cn",
- "agentrouter": "Ganhe $200 em créditos grátis em https://agentrouter.org/register — sem necessidade de cartão de crédito.",
+ "agentrouter": "Obtenha $200 em créditos gratuitos em https://agentrouter.org/register — sem necessidade de cartão de crédito.",
"unorouter": "Crie uma chave de API em https://unorouter.ai e cole aqui como Bearer token.",
"agnes": "Obtenha a chave de API em agnes-ai.com",
- "aimlapi": "Nível gratuito pausado (2026) — A API de IA/ML agora é apenas pague pelo que usar (recarga mínima de $20); sem créditos gratuitos recorrentes.",
- "ai21": "$10 em créditos de teste ao se cadastrar (válidos por 3 meses), sem necessidade de cartão de crédito",
- "alibaba": "Conecte o Alibaba com uma chave de API.",
- "alibaba-cn": "Conecte o Alibaba (China) com uma chave de API.",
+ "aimlapi": "Nível gratuito pausado (2026) — a AI/ML API agora é apenas pay-as-you-go (recarga mínima de $20); sem créditos gratuitos recorrentes.",
+ "ai21": "$10 em créditos de teste no cadastro (válidos por 3 meses), sem necessidade de cartão de crédito",
+ "alibaba": "Conecte a Alibaba com uma chave de API.",
+ "alibaba-cn": "Conecte a Alibaba (China) com uma chave de API.",
"bailian-coding-plan": "Conecte o Alibaba Coding Plan com uma chave de API.",
- "bedrock": "Integração nativa do Bedrock: a descoberta de modelos usa os modelos de fundação e perfis de inferência do Bedrock, enquanto o chat usa as APIs regionais Bedrock Runtime Converse/ConverseStream.",
+ "bedrock": "Integração nativa com o Bedrock: a descoberta de modelos usa os foundation models e perfis de inferência do Bedrock, enquanto o chat usa as APIs regionais Bedrock Runtime Converse/ConverseStream.",
"anthropic": "Conecte a Anthropic com uma chave de API.",
"ant-ling": "Registre-se e crie uma chave de API no console da Ant Ling (https://chat.ant-ling.com/open) e cole-a aqui. O OmniRoute envia o tráfego de chat para https://api.ant-ling.com/v1/chat/completions; o provedor é compatível com OpenAI e também expõe uma superfície compatível com Anthropic.",
"api-airforce": "Obtenha sua chave de API em https://panel.api.airforce — endpoint compatível com OpenAI em https://api.airforce/v1",
"arcee-ai": "Obtenha a chave de API em arcee.ai",
- "azure-ai": "O Foundry usa a interface v1 da OpenAI com nomes de implantação como modelos. O OmniRoute normaliza as URLs de recursos raiz para os endpoints v1 chat e /models.",
- "azure-openai": "Use sua chave de API do Azure OpenAI. A URL base deve ser o endpoint do seu recurso, por exemplo, https://my-resource.openai.azure.com.",
- "bai": "Chave de API Bearer para o gateway de LLM compatível com OpenAI da b.ai (diferente do TheB.AI). Crie uma chave em https://docs.b.ai e use https://api.b.ai/v1 como a URL base compatível com OpenAI.",
+ "azure-ai": "O Foundry usa a superfície OpenAI v1 com nomes de deployment como modelos. O OmniRoute normaliza URLs de recurso raiz para os endpoints v1 chat e /models.",
+ "azure-openai": "Use sua chave de API do Azure OpenAI. A URL base deve ser o endpoint do seu recurso, por exemplo https://my-resource.openai.azure.com.",
+ "bai": "Chave de API Bearer para o gateway de LLM compatível com OpenAI do b.ai (diferente do TheB.AI). Crie uma chave em https://docs.b.ai e use https://api.b.ai/v1 como URL base compatível com OpenAI.",
"baichuan": "Obtenha a chave de API em platform.baichuan-ai.com",
"baidu": "Obtenha a chave de API em console.bce.baidu.com",
- "qianfan": "Use uma chave de API do Qianfan da Baidu AI Cloud. O endpoint padrão é compatível com OpenAI v2.",
- "baseten": "$30 em créditos de teste gratuitos para inferência de GPU",
- "bazaarlink": "Crie uma chave de API gratuita em https://bazaarlink.ai — o modelo 'auto:free' direciona para inferência de custo zero. Todos os modelos usam o formato provedor/nome-do-modelo, ex: xiaomi/mimo-v2.5-pro.",
+ "qianfan": "Use uma chave de API Qianfan do Baidu AI Cloud. O endpoint padrão é compatível com OpenAI v2.",
+ "baseten": "$30 em créditos de teste gratuitos para inferência em GPU",
+ "bazaarlink": "Crie uma chave de API gratuita em https://bazaarlink.ai — o modelo 'auto:free' roteia para inferência de custo zero. Todos os modelos usam o formato provider/model-name, por exemplo xiaomi/mimo-v2.5-pro.",
"black-forest-labs": "Conecte o Black Forest Labs com uma chave de API.",
"blackbox": "Nível gratuito: chat básico ilimitado mais Minimax-M2.5, sem necessidade de cartão de crédito",
"bluesminds": "Obtenha sua chave de API em https://www.bluesminds.com — endpoint compatível com OpenAI em https://api.bluesminds.com/v1 com créditos diários gratuitos. Modelos VIP (Claude Opus 4.5, Gemini 2.5 Pro) consomem créditos pi.",
"byteplus": "Conecte o BytePlus ModelArk com uma chave de API.",
- "bytez": "$1 em créditos grátis, renovados a cada 4 semanas",
- "cerebras": "Teste Gratuito: 1M de tokens/dia, 30K TPM, 5 RPM — sem cartão de crédito.",
+ "bytez": "$1 em créditos gratuitos, renovados a cada 4 semanas",
+ "cerebras": "Teste gratuito: 1M tokens/dia, 30K TPM, 5 RPM — sem cartão de crédito.",
"charm-hyper": "Crie uma chave de API em https://hyper.charm.land e cole-a aqui como um token Bearer.",
- "chutes": "Chave de API Bearer para o gateway compatível com OpenAI da Chutes.",
- "clarifai": "O Clarifai expõe chat, respostas e /models compatíveis com OpenAI em /v2/ext/openai/v1. Modelos públicos/comunitários geralmente exigem um PAT; chaves com escopo de aplicativo funcionam apenas para recursos dentro desse aplicativo.",
- "cloudflare-ai": "Requer Token de API E ID da Conta (encontrado em dash.cloudflare.com)",
+ "chutes": "Chave de API Bearer para o gateway compatível com OpenAI do Chutes.",
+ "clarifai": "O Clarifai expõe chat, responses e /models compatíveis com OpenAI em /v2/ext/openai/v1. Modelos públicos/da comunidade geralmente exigem um PAT; chaves com escopo de app só funcionam para recursos dentro desse app.",
+ "cloudflare-ai": "Requer Token de API E ID de Conta (encontrados em dash.cloudflare.com)",
"clova-studio": "O CLOVA Studio (HyperCLOVA X) é compatível com OpenAI em /v1/openai. O OmniRoute sonda /v1/openai/models e roteia o tráfego de chat para /v1/openai/chat/completions. Usa o host atual clovastudio.stream.ntruss.com — o endpoint legado clovastudio.apigw.ntruss.com está sendo descontinuado.",
"codestral": "Conecte o Codestral com uma chave de API.",
- "cohere": "Teste Gratuito: 1.000 chamadas de API/mês para testes, sem necessidade de cartão de crédito",
+ "cohere": "Teste gratuito: 1.000 chamadas de API/mês para testes, sem necessidade de cartão de crédito",
"command-code": "Crie ou copie uma chave de API do Command Code e cole-a aqui como um token Bearer.",
"coze": "Obtenha a chave de API em coze.com/open/api",
"crof": "Conecte o CrofAI com uma chave de API.",
"databricks": "Conecte o Databricks com uma chave de API.",
- "datarobot": "O gateway padrão cataloga modelos ativos de /genai/llmgw/catalog/. URLs de implantação também são suportadas para solicitações diretas de chat compatíveis com OpenAI.",
- "deepinfra": "Créditos de cadastro gratuitos para testes de API e exploração de modelos",
- "deepseek": "5M tokens grátis no cadastro - sem necessidade de cartão de crédito",
- "dgrid": "Crie uma chave de API do DGrid em https://dgrid.ai e use https://api.dgrid.ai/v1 como a URL base compatível com OpenAI.",
+ "datarobot": "O gateway padrão cataloga modelos ativos a partir de /genai/llmgw/catalog/. URLs de deployment também são suportadas para solicitações de chat diretas compatíveis com OpenAI.",
+ "deepinfra": "Créditos gratuitos no cadastro para testes de API e exploração de modelos",
+ "deepseek": "5M tokens gratuitos no cadastro - sem necessidade de cartão de crédito",
+ "dgrid": "Crie uma chave de API do DGrid em https://dgrid.ai e use https://api.dgrid.ai/v1 como URL base compatível com OpenAI.",
"dify": "Obtenha a chave de API da sua instância do Dify.",
- "digitalocean": "Conecte a DigitalOcean com uma chave de API.",
- "dit": "dit.ai (Distributed Intelligence Trade) é um roteador/gateway compatível com OpenAI com precificação dinâmica por requisição, expondo /v1/chat/completions em https://api.dit.ai/v1. O OmniRoute usa o protocolo OpenAI; as análises de gastos/economia ficam no painel do dit.ai.",
+ "digitalocean": "Conecte o DigitalOcean com uma chave de API.",
+ "dit": "dit.ai (Distributed Intelligence Trade) é um roteador/gateway compatível com OpenAI com precificação dinâmica por solicitação, expondo /v1/chat/completions em https://api.dit.ai/v1. O OmniRoute usa o protocolo OpenAI; os analytics de gasto/economia ficam no dashboard do dit.ai.",
"doubao": "Obtenha a chave de API em console.volcengine.com",
- "empower": "O Empower expõe chat compatível com OpenAI em https://app.empower.dev/api/v1 com suporte a chamadas de ferramentas em empower-functions.",
- "factory": "Obtenha sua chave de API da Factory em https://app.factory.ai/settings/api-keys e cole-a como um token Bearer. Endpoint compatível com OpenAI em https://api.factory.ai/v1.",
+ "empower": "O Empower expõe chat compatível com OpenAI em https://app.empower.dev/api/v1 com suporte a tool-calling em empower-functions.",
+ "factory": "Obtenha sua chave de API do Factory em https://app.factory.ai/settings/api-keys e cole-a como um token Bearer. Endpoint compatível com OpenAI em https://api.factory.ai/v1.",
"fal-ai": "Conecte o Fal.ai com uma chave de API.",
- "featherless-ai": "Plano gratuito disponível — sem necessidade de cartão de crédito",
- "fenayai": "Chave de API Bearer para o gateway compatível com OpenAI da FenayAI.",
+ "featherless-ai": "Nível gratuito disponível — sem necessidade de cartão de crédito",
+ "fenayai": "Chave de API Bearer para o gateway compatível com OpenAI do FenayAI.",
"firecrawl": "Conecte o Firecrawl com uma chave de API.",
- "fireworks": "$1 em créditos iniciais grátis no cadastro para testes de API",
+ "fireworks": "$1 em créditos iniciais gratuitos no cadastro para testes de API",
"freeaiapikey": "Proxy de API com desconto para mais de 40 modelos, incluindo GPT-5, Claude Opus 4.6, Claude Sonnet 4.6, Qwen 3.5. Obtenha sua chave de API em https://freeaiapikey.com/dashboard. URL base: https://freeaiapikey.com/v1.",
- "freemodel-dev": "Obtenha $300 em créditos de API grátis em https://freemodel.dev — sem necessidade de informações de pagamento. Endpoint compatível com OpenAI. Modelos GPT-5.4 e GPT-5.5 disponíveis.",
- "friendliai": "Plano gratuito para inferência serverless — sem necessidade de cartão de crédito",
- "gemini": "Grátis para sempre: 1.500 req/dia para o Gemini 2.5 Flash — sem cartão de crédito, obtenha a chave em aistudio.google.com",
+ "freemodel-dev": "Obtenha $300 em créditos de API gratuitos em https://freemodel.dev — sem necessidade de dados de pagamento. Endpoint compatível com OpenAI. Modelos GPT-5.4 e GPT-5.5 disponíveis.",
+ "friendliai": "Nível gratuito para inferência serverless — sem necessidade de cartão de crédito",
+ "gemini": "Gratuito para sempre: 1.500 solicitações/dia para o Gemini 2.5 Flash — sem cartão de crédito, obtenha a chave em aistudio.google.com",
"gigachat": "Conecte o GigaChat (Sber) com uma chave de API.",
"github-models": "Crie um PAT do GitHub com o escopo 'models: read' em github.com/settings/tokens",
- "gitlab": "Token de acesso pessoal do GitLab para a API pública de Code Suggestions. Configure uma URL base auto-hospedada quando não estiver usando o gitlab.com.",
- "gitlawb-gmi": "Obtenha sua chave de API no painel do Gitlawb Opengateway.",
- "gitlawb": "Obtenha sua chave de API no painel do Gitlawb Opengateway.",
+ "gitlab": "Token de acesso pessoal do GitLab para a API pública de Code Suggestions. Configure uma URL base self-hosted quando não estiver usando gitlab.com.",
+ "gitlawb-gmi": "Obtenha sua chave de API no dashboard do Gitlawb Opengateway.",
+ "gitlawb": "Obtenha sua chave de API no dashboard do Gitlawb Opengateway.",
"glm": "Conecte o GLM Coding com uma chave de API.",
"glm-cn": "Conecte o GLM Coding (China) com uma chave de API.",
- "glmt": "Perfil GLM predefinido com maior limite de tokens, pensamento ativado e tempo limite mais longo.",
+ "glmt": "Perfil GLM pré-configurado com orçamento de tokens maior, thinking ativado e timeout mais longo.",
"getgoapi": "Conecte o GoAPI com uma chave de API.",
- "groq": "Plano gratuito: 30 RPM / 14,4K RPD — sem cartão de crédito",
- "hackclub": "Faça login com sua conta do Hack Club em ai.hackclub.com.",
+ "groq": "Nível gratuito: 30 RPM / 14,4K RPD — sem cartão de crédito",
+ "hackclub": "Entre com sua conta Hack Club em ai.hackclub.com.",
"haiper": "Obtenha a chave de API em haiper.ai/haiper-api",
"heroku": "Conecte o Heroku AI com uma chave de API.",
"hcnsec": "Obtenha a chave de API em api.hcnsec.cn",
- "huggingface": "API de inferência gratuita para milhares de modelos (Whisper, VITS, SDXL…)",
+ "huggingface": "API de Inferência gratuita para milhares de modelos (Whisper, VITS, SDXL…)",
"hyperbolic": "$1-5 em créditos de teste no cadastro para inferência serverless",
- "watsonx": "O gateway de modelos do watsonx expõe /chat/completions e /models compatíveis com OpenAI sob /ml/gateway/v1.",
+ "watsonx": "O gateway de modelos do watsonx expõe /chat/completions e /models compatíveis com OpenAI em /ml/gateway/v1.",
"ideogram": "Obtenha a chave de API em ideogram.ai/docs/api",
"iflytek": "Obtenha a chave de API em console.xfyun.cn",
"inception": "A Inception Labs é compatível com OpenAI em https://api.inceptionlabs.ai/v1. O mercury-2 é o primeiro LLM de difusão (dLLM) do catálogo — geração 5-10x mais rápida que modelos autoregressivos comparáveis, com chamadas de ferramentas, json_mode e saídas estruturadas.",
- "inference-net": "$25 em créditos grátis no cadastro, além de bolsas de pesquisa disponíveis",
+ "inference-net": "$25 em créditos gratuitos no cadastro, além de bolsas de pesquisa disponíveis",
"internlm": "Cota mensal gratuita de ~1M tokens de entrada / 3M de saída (~10 RPM)",
- "jina-ai": "Chave de API Bearer para a API de rerank da Jina AI.",
+ "jina-ai": "Chave de API Bearer para a API de rerank do Jina AI.",
"jina-reader": "Conecte o Jina Reader com uma chave de API.",
- "kenari": "O Kenari expõe um endpoint de chat completions compatível com OpenAI em https://kenari.id/v1/chat/completions, além de um catálogo ativo de /v1/models cobrindo Claude, GPT, DeepSeek, GLM, Kimi e mais. O OmniRoute usa o protocolo OpenAI e lista os modelos via passthrough.",
+ "kenari": "O Kenari expõe um endpoint de chat completions compatível com OpenAI em https://kenari.id/v1/chat/completions, além de um catálogo /v1/models ao vivo cobrindo Claude, GPT, DeepSeek, GLM, Kimi e outros. O OmniRoute usa o protocolo OpenAI e lista modelos via passthrough.",
"kie": "Conecte o KIE.AI com uma chave de API.",
"kilo-gateway": "Conecte o Kilo Gateway com uma chave de API.",
"kimi": "Conecte o Kimi com uma chave de API.",
- "kimi-coding-apikey": "Conecte o Kimi Coding (API Key) com uma chave de API.",
+ "kimi-coding-apikey": "Conecte o Kimi Coding (Chave de API) com uma chave de API.",
"lambda-ai": "Conecte o Lambda AI com uma chave de API.",
"laozhang": "Conecte o LaoZhang AI com uma chave de API.",
"leonardo": "Obtenha a chave de API em leonardo.ai/developer",
"liquid": "Obtenha a chave de API em liquid.ai",
"llamagate": "Conecte o LlamaGate com uma chave de API.",
- "llm7": "Funciona sem chave de API (use 'unused' como chave). Obtenha um token gratuito em token.llm7.io para limites maiores.",
- "longcat": "Gratuito: concessão única de 10M de tokens após o cadastro da conta + verificação KYC (LongCat-2.0). Apenas uma vez — não é uma franquia diária/mensal recorrente.",
+ "llm7": "Funciona sem chave de API (use 'unused' como chave). Obtenha um token gratuito em token.llm7.io para limites mais altos.",
+ "longcat": "Gratuito: concessão única de 10M tokens após cadastro de conta + verificação KYC (LongCat-2.0). Apenas uma vez — não é uma cota diária/mensal recorrente.",
"maritalk": "Conecte o Maritalk com uma chave de API.",
- "meta-llama": "Conecte o Meta Llama API com uma chave de API.",
+ "meta-llama": "Conecte a Meta Llama API com uma chave de API.",
"minimax-cn": "Conecte o Minimax (China) com uma chave de API.",
"minimax": "Conecte o Minimax Coding com uma chave de API.",
- "mistral": "Nível de Experimento Gratuito: acesso com limite de taxa a todos os modelos, sem necessidade de cartão de crédito",
- "modal": "O Modal geralmente serve aplicativos compatíveis com OpenAI hospedados pelo usuário em /v1. O OmniRoute investigará /v1/models e roteará o tráfego de chat para /v1/chat/completions.",
- "modelscope": "Nível gratuito via ModelScope API-Inference — conta Alibaba necessária.",
+ "mistral": "Nível gratuito Experiment: acesso com limite de taxa a todos os modelos, sem necessidade de cartão de crédito",
+ "modal": "O Modal geralmente serve aplicativos hospedados pelo usuário compatíveis com OpenAI em /v1. O OmniRoute vai sondar /v1/models e rotear o tráfego de chat para /v1/chat/completions.",
+ "modelscope": "Nível gratuito via ModelScope API-Inference — requer conta Alibaba.",
"monsterapi": "Obtenha a chave de API em monsterapi.ai",
- "moonshot": "Conecte o Moonshot AI com uma chave de API.",
+ "moonshot": "Conecte o Kimi com uma chave de API.",
"morph": "Nível gratuito: 250K créditos/mês, $0",
"nanogpt": "Conecte o NanoGPT com uma chave de API.",
"nebius": "~$1 em créditos de teste no cadastro para testes de API",
- "nlpcloud": "O NLP Cloud usa uma API de chatbot proprietária em vez de chat/completions da OpenAI. O OmniRoute adapta as mensagens da OpenAI para entrada/contexto/histórico e expõe um catálogo local de modelos de chatbot suportados.",
+ "nlpcloud": "O NLP Cloud usa uma API de chatbot proprietária em vez de chat/completions da OpenAI. O OmniRoute adapta mensagens OpenAI para input/context/history e expõe um catálogo local dos modelos de chatbot suportados.",
"nomic": "Obtenha a chave de API em atlas.nomic.ai",
- "nous-research": "O Nous expõe uma superfície /v1 compatível com OpenAI com um grande catálogo remoto de /models. O endpoint /chat/completions requer uma chave de API válida para inferência programática.",
+ "nous-research": "O Nous expõe uma superfície /v1 compatível com OpenAI com um grande catálogo remoto /models. O endpoint /chat/completions requer uma chave de API válida para inferência programática.",
"novita": "$0,50 em créditos de teste no cadastro (válidos por cerca de 1 ano)",
"nscale": "$5 em créditos gratuitos no cadastro para testes de inferência",
"nube": "Conecte o Nube.sh com uma chave de API.",
"nvidia": "Acesso gratuito para desenvolvedores: ~40 RPM, mais de 70 modelos (Kimi K2.5, GLM 4.7, DeepSeek V3.2...)",
- "oci": "O OCI expõe endpoints de chat e respostas compatíveis com a OpenAI. O Project ID é opcional no OmniRoute, mas pode ser necessário para Responses e fluxos de trabalho de agentes.",
+ "oci": "A OCI expõe endpoints de chat e responses compatíveis com OpenAI. O Project ID é opcional no OmniRoute, mas pode ser necessário para Responses e fluxos agênticos.",
"ollama-cloud": "Conecte o Ollama Cloud com uma chave de API.",
- "openadapter": "O OpenAdapter expõe um endpoint de chat completions compatível com a OpenAI em https://api.openadapter.in/v1/chat/completions, agregando mais de 70 modelos de código aberto (DeepSeek, Qwen, Kimi, MiniMax, GLM, Llama, Mistral, …). O OmniRoute usa o protocolo da OpenAI.",
+ "openadapter": "O OpenAdapter expõe um endpoint de chat completions compatível com OpenAI em https://api.openadapter.in/v1/chat/completions, agregando mais de 70 modelos open-source (DeepSeek, Qwen, Kimi, MiniMax, GLM, Llama, Mistral, …). O OmniRoute usa o protocolo OpenAI.",
"openai": "Conecte a OpenAI com uma chave de API.",
"opencode-go": "Conecte o OpenCode Go com uma chave de API.",
"opencode-zen": "Conecte o OpenCode Zen com uma chave de API.",
"openrouter": "Modelos gratuitos a $0/token com o sufixo :free - 20 RPM / 200 RPD",
"openvecta": "Créditos gratuitos no cadastro para inferência compatível com OpenAI em LLMs, embeddings e modelos de raciocínio",
- "orcarouter": "Crie uma chave de API (começa com sk-orca-) em https://www.orcarouter.ai e, em seguida, cole-a como um token Bearer. Endpoint compatível com OpenAI em https://api.orcarouter.ai/v1.",
+ "orcarouter": "Crie uma chave de API (começa com sk-orca-) em https://www.orcarouter.ai e cole-a como um token Bearer. Endpoint compatível com OpenAI em https://api.orcarouter.ai/v1.",
"ovhcloud": "Conecte o OVHcloud AI com uma chave de API.",
"perplexity": "Conecte o Perplexity com uma chave de API.",
"piapi": "Conecte o PiAPI com uma chave de API.",
- "pioneer": "$75 em créditos de uso gratuito — sem necessidade de cartão de crédito",
+ "pioneer": "$75 em créditos de uso gratuitos — sem necessidade de cartão de crédito",
"plamo": "O PLaMo é compatível com OpenAI em https://api.platform.preferredai.jp/v1. Desenvolvido pela Preferred Networks e otimizado para o japonês. A documentação está principalmente em japonês.",
- "poe": "O Poe expõe chat e respostas compatíveis com OpenAI em https://api.poe.com/v1, com verificações de saldo autenticadas em /usage/current_balance.",
- "pollinations": "Nível gratuito sem chave: openai, openai-fast, openai-large, qwen-coder, mistral, deepseek, grok, gemini-flash-lite-3.1, perplexity-fast, perplexity-reasoning. Modelos premium (claude, gemini, midijourney) exigem uma chave de API do Pollinations de enter.pollinations.ai.",
- "publicai": "Requer uma chave de API — crédito único de inscrição, depois pago",
- "puter": "Obtenha o token em puter.com/dashboard → Copiar Auth Token",
- "qiniu": "Crie uma chave de API de inferência de IA da Qiniu em https://portal.qiniu.com/ai-inference/api-key e cole-a aqui como um token Bearer. Endpoint compatível com OpenAI em https://api.qnaigc.com/v1, fazendo proxy de DeepSeek, Claude, Kimi e outros sob uma única chave.",
+ "poe": "O Poe expõe chat e responses compatíveis com OpenAI em https://api.poe.com/v1, com verificação autenticada de saldo em /usage/current_balance.",
+ "pollinations": "Nível gratuito sem chave: openai, openai-fast, openai-large, qwen-coder, mistral, deepseek, grok, gemini-flash-lite-3.1, perplexity-fast, perplexity-reasoning. Modelos premium (claude, gemini, midijourney) requerem uma chave de API do Pollinations em enter.pollinations.ai.",
+ "publicai": "Requer uma chave de API — crédito único no cadastro, depois pago",
+ "puter": "Obtenha o token em puter.com/dashboard → Copy Auth Token",
+ "qiniu": "Crie uma chave de API de inferência Qiniu AI em https://portal.qiniu.com/ai-inference/api-key e cole-a aqui como um token Bearer. Endpoint compatível com OpenAI em https://api.qnaigc.com/v1, fazendo proxy de DeepSeek, Claude, Kimi e outros por trás de uma única chave.",
"recraft": "Conecte o Recraft com uma chave de API.",
"reka": "O Reka Chat é compatível com OpenAI em /v1. O OmniRoute sonda /v1/models e roteia o tráfego de chat para /v1/chat/completions.",
- "requesty": "Crie uma chave de API em https://app.requesty.ai e cole-a aqui como um token Bearer. Endpoint compatível com OpenAI em https://router.requesty.ai/v1, com um catálogo /v1/models ativo.",
- "runwayml": "A geração de vídeo do Runway é baseada em tarefas. O OmniRoute envia trabalhos de texto para vídeo ou imagem para vídeo, consulta /v1/tasks/[id] e normaliza as saídas de vídeo concluídas de volta na resposta /v1/videos/generations semelhante à da OpenAI.",
- "sambanova": "$5 em créditos gratuitos ao se inscrever (validade de 30 dias), sem necessidade de cartão de crédito",
- "sap": "A descoberta de modelos usa /v2/lm/scenarios/foundation-models/models em AI_API_URL. As solicitações de chat usam deploymentUrl/chat/completions e exigem AI-Resource-Group.",
+ "requesty": "Crie uma chave de API em https://app.requesty.ai e cole-a aqui como um token Bearer. Endpoint compatível com OpenAI em https://router.requesty.ai/v1, com um catálogo /v1/models ao vivo.",
+ "runwayml": "A geração de vídeo do Runway é baseada em tarefas. O OmniRoute envia jobs de texto-para-vídeo ou imagem-para-vídeo, consulta /v1/tasks/[id] periodicamente e normaliza as saídas de vídeo concluídas de volta para a resposta /v1/videos/generations no estilo OpenAI.",
+ "sambanova": "$5 em créditos gratuitos no cadastro (validade de 30 dias), sem necessidade de cartão de crédito",
+ "sap": "A descoberta de modelos usa /v2/lm/scenarios/foundation-models/models em AI_API_URL. As solicitações de chat usam deploymentUrl/chat/completions e requerem AI-Resource-Group.",
"sarvam": "O Sarvam AI é compatível com OpenAI em /v1. O OmniRoute sonda /v1/models e roteia o tráfego de chat para /v1/chat/completions. Os modelos são ajustados para línguas indianas.",
- "scaleway": "1M de tokens gratuitos para novas contas — em conformidade com a UE/GDPR (Paris), Qwen3 235B e Llama 70B",
+ "scaleway": "1M tokens gratuitos para novas contas — compatível com UE/GDPR (Paris), Qwen3 235B e Llama 70B",
"sensenova": "Obtenha a chave de API em platform.sensenova.cn",
- "siliconflow": "$1 em créditos gratuitos mais modelos permanentemente gratuitos após verificação de identidade",
+ "siliconflow": "$1 em créditos gratuitos, além de modelos permanentemente gratuitos após verificação de identidade",
"snowflake": "Conecte o Snowflake Cortex com uma chave de API.",
"sparkdesk": "Obtenha a chave de API em console.xfyun.cn",
- "stability-ai": "Conecte o Stability AI com uma chave de API.",
+ "stability-ai": "Conecte a Stability AI com uma chave de API.",
"stepfun": "Obtenha a chave de API em platform.stepfun.com",
- "sumopod": "O SumoPod expõe um endpoint de chat completions compatível com OpenAI em https://ai.sumopod.com/v1/chat/completions, além de um catálogo /v1/models ativo. O OmniRoute usa o protocolo OpenAI e lista modelos via passthrough.",
+ "sumopod": "O SumoPod expõe um endpoint de chat completions compatível com OpenAI em https://ai.sumopod.com/v1/chat/completions, além de um catálogo /v1/models ao vivo. O OmniRoute usa o protocolo OpenAI e lista modelos via passthrough.",
"suno": "Cole o cookie de sessão do suno.ai (autenticação Clerk)",
"synthetic": "Conecte o Synthetic com uma chave de API.",
"tencent": "Obtenha a chave de API em console.cloud.tencent.com",
@@ -6141,47 +6141,47 @@
"topaz": "Conecte o Topaz com uma chave de API.",
"typhoon": "O Typhoon é compatível com OpenAI em /v1. Desenvolvido pela SCB 10X (Tailândia); o typhoon-v2.5-30b-a3b-instruct é um modelo multilíngue com foco no idioma tailandês.",
"udio": "Cole o cookie de sessão do udio.com (autenticação Supabase)",
- "uncloseai": "Nenhuma autenticação necessária. A API aceita qualquer string não vazia como chave para identificação.",
+ "uncloseai": "Não requer autenticação. A API aceita qualquer string não vazia como chave para identificação.",
"upstage": "Conecte o Upstage com uma chave de API.",
"v0-vercel": "Conecte o v0 (Vercel) com uma chave de API.",
"venice": "Conecte o Venice.ai com uma chave de API.",
"vercel-ai-gateway": "Conecte o Vercel AI Gateway com uma chave de API.",
- "vertex": "Forneça o JSON da Conta de Serviço ou o access_token do OAuth",
- "vertex-partner": "Forneça o mesmo JSON da Conta de Serviço usado para os modelos parceiros do Vertex AI.",
+ "vertex": "Forneça o JSON da Service Account ou um access_token OAuth",
+ "vertex-partner": "Forneça o mesmo JSON de Service Account usado para os modelos parceiros do Vertex AI.",
"volcengine": "Conecte o Volcengine com uma chave de API.",
- "voyage-ai": "Chave de API Bearer para as APIs de embeddings e rerank da Voyage AI.",
+ "voyage-ai": "Chave de API Bearer para as APIs de embeddings e rerank do Voyage AI.",
"wafer": "Chave de API de https://wafer.ai",
"wandb": "Conecte o Weights & Biases Inference com uma chave de API.",
"writer": "O Writer Palmyra é compatível com OpenAI em https://api.writer.com/v1. O palmyra-x5 oferece uma janela de contexto de 1M de tokens.",
- "x5lab": "O X5Lab expõe um endpoint de chat completions compatível com a OpenAI em https://api.x5lab.dev/v1/chat/completions, além de um catálogo de modelos /v1/models ativo. O OmniRoute usa o protocolo da OpenAI e lista os modelos via passthrough.",
- "xai": "Conecte o xAI (Grok) com uma chave de API.",
+ "x5lab": "O X5Lab expõe um endpoint de chat completions compatível com OpenAI em https://api.x5lab.dev/v1/chat/completions, além de um catálogo /v1/models ao vivo. O OmniRoute usa o protocolo OpenAI e lista modelos via passthrough.",
+ "xai": "Conecte a xAI (Grok) com uma chave de API.",
"xiaomi-mimo": "Conecte o Xiaomi MiMo com uma chave de API.",
"yi": "Obtenha a chave de API em platform.lingyiwanwu.com",
"zai": "Chave de API de https://open.bigmodel.cn/usercenter/apikeys",
- "zenmux": "O ZenMux expõe um endpoint de chat completions compatível com a OpenAI em /api/v1/chat/completions, além das superfícies de protocolo Anthropic Messages (/api/anthropic/v1/messages) e Google Gemini (/api/vertex-ai). O OmniRoute usa o protocolo da OpenAI.",
+ "zenmux": "O ZenMux expõe um endpoint de chat completions compatível com OpenAI em /api/v1/chat/completions, além de superfícies de protocolo Anthropic Messages (/api/anthropic/v1/messages) e Google Gemini (/api/vertex-ai). O OmniRoute usa o protocolo OpenAI.",
"galadriel": "Conecte o Galadriel com uma chave de API.",
- "predibase": "$25 em créditos de teste gratuito (validade de 30 dias)",
- "chenzk": "Gateway compatível com a OpenAI com um catálogo de modelos ativo em chenzk.top.",
- "freepik": "Gere imagens com a Mystic API do Freepik.",
- "freetheai": "Gateway gratuito compatível com a OpenAI com suporte a modelos via passthrough.",
- "g4f-gemini": "Proxy reverso gratuito sem chave do g4f.space para o Gemini, limitado a 5 requisições por minuto.",
- "g4f-groq": "Proxy reverso gratuito sem chave do g4f.space para o Groq, limitado a 5 requisições por minuto.",
- "g4f-nvidia": "Proxy reverso gratuito sem chave do g4f.space para o NVIDIA NIM, limitado a 5 requisições por minuto.",
- "g4f-ollama": "Gateway Ollama hospedado gratuito sem chave do g4f.space, limitado a 5 requisições por minuto.",
- "g4f-pollinations": "Proxy reverso gratuito sem chave do g4f.space para o Pollinations, limitado a 5 requisições por minuto.",
+ "predibase": "$25 em créditos de teste gratuitos (validade de 30 dias)",
+ "chenzk": "Gateway compatível com OpenAI com um catálogo de modelos ao vivo em chenzk.top.",
+ "freepik": "Gere imagens com a API Mystic do Freepik.",
+ "freetheai": "Gateway gratuito compatível com OpenAI com suporte a modelos via passthrough.",
+ "g4f-gemini": "Proxy reverso gratuito e sem chave do g4f.space para o Gemini, limitado a 5 solicitações por minuto.",
+ "g4f-groq": "Proxy reverso gratuito e sem chave do g4f.space para o Groq, limitado a 5 solicitações por minuto.",
+ "g4f-nvidia": "Proxy reverso gratuito e sem chave do g4f.space para o NVIDIA NIM, limitado a 5 solicitações por minuto.",
+ "g4f-ollama": "Gateway Ollama hospedado, gratuito e sem chave, do g4f.space, limitado a 5 solicitações por minuto.",
+ "g4f-pollinations": "Proxy reverso gratuito e sem chave do g4f.space para o Pollinations, limitado a 5 solicitações por minuto.",
"mixedbread": "Crie embeddings com a API do Mixedbread.",
- "segmind": "Gere imagens e vídeos com os modelos hospedados da Segmind.",
+ "segmind": "Gere imagens e vídeos com os modelos hospedados do Segmind.",
"amazon-q": "Usa o mesmo AWS Builder ID ou fluxo de refresh-token importado do Kiro, mas mantém as conexões do Amazon Q separadas.",
"antigravity": "Conecte o Antigravity com o fluxo OAuth existente.",
- "agy": "Importe seu login da CLI do Antigravity (`agy`) (cole/carregue seu arquivo de token), detecte automaticamente um login de CLI local ou faça login com o Google. Compartilha o backend do Antigravity (incl. modelos Claude).",
+ "agy": "Importe seu login da Antigravity CLI (`agy`) (cole/envie o arquivo de token), detecte automaticamente um login local da CLI, ou entre com o Google. Compartilha o backend do Antigravity (incluindo modelos Claude).",
"claude": "Conecte o Claude Code com o fluxo OAuth existente.",
"cline": "Conecte o Cline com o fluxo OAuth existente.",
"cursor": "Conecte o Cursor IDE com o fluxo OAuth existente.",
"github": "Conecte o GitHub Copilot com o fluxo OAuth existente.",
- "gitlab-duo": "Aplicativo OAuth com escopos ai_features + read_user. Configure GITLAB_DUO_OAUTH_CLIENT_ID e opcionalmente GITLAB_DUO_OAUTH_CLIENT_SECRET nesta instância do OmniRoute.",
+ "gitlab-duo": "Aplicação OAuth com os escopos ai_features + read_user. Configure GITLAB_DUO_OAUTH_CLIENT_ID e, opcionalmente, GITLAB_DUO_OAUTH_CLIENT_SECRET nesta instância do OmniRoute.",
"kilocode": "Conecte o Kilo Code com o fluxo OAuth existente.",
"kimi-coding": "Conecte o Kimi Coding com o fluxo OAuth existente.",
- "kiro": "Nível gratuito: 50 créditos/mês (~25K–100K tokens). ⚠️ Os Termos de Serviço (ToS) do Kiro proíbem o uso de proxy/harness de terceiros.",
+ "kiro": "Nível gratuito: 50 créditos/mês (~25K–100K tokens). ⚠️ Os Termos de Serviço do Kiro proíbem o uso de proxy/harness de terceiros.",
"codex": "Conecte o OpenAI Codex com o fluxo OAuth existente.",
"qwen": "Conecte o Qwen Code com o fluxo OAuth existente."
},
@@ -6214,18 +6214,18 @@
"webSessionCredentialValidationFailed": "Falha na validação da credencial da sessão. Faça login novamente, copie uma nova credencial e tente novamente.",
"checkCookie": "Verifique o cookie",
"checkWebToken": "Verifique o token",
- "huggingchatLabel": "HuggingChat (Gratuito)",
- "huggingchatDesc": "Chat de LLM gratuito via huggingface.co/chat",
- "poeWebLabel": "Poe Web",
- "poeWebDesc": "Chat multimodelo via poe.com",
- "veniceWebLabel": "Venice Web",
- "veniceWebDesc": "Chat de IA focado em privacidade",
- "v0VercelWebLabel": "v0 Vercel Web",
- "v0VercelWebDesc": "Geração de código por IA via v0.dev",
- "kimiWebLabel": "Kimi Web",
- "kimiWebDesc": "Chat de consumidor da Moonshot AI via www.kimi.com (internacional, API Connect-RPC)",
- "doubaoWebLabel": "Doubao Web",
- "doubaoWebDesc": "Chat de IA da ByteDance via doubao.com",
+ "huggingchatLabel": "__MISSING__:HuggingChat (Free)",
+ "huggingchatDesc": "__MISSING__:Free LLM chat via huggingface.co/chat",
+ "poeWebLabel": "__MISSING__:Poe Web",
+ "poeWebDesc": "__MISSING__:Multi-model chat via poe.com",
+ "veniceWebLabel": "__MISSING__:Venice Web",
+ "veniceWebDesc": "__MISSING__:Privacy-focused AI chat",
+ "v0VercelWebLabel": "__MISSING__:v0 Vercel Web",
+ "v0VercelWebDesc": "__MISSING__:AI code generation via v0.dev",
+ "kimiWebLabel": "__MISSING__:Kimi Web",
+ "kimiWebDesc": "__MISSING__:Moonshot AI consumer chat via www.kimi.com (international, Connect-RPC API)",
+ "doubaoWebLabel": "__MISSING__:Doubao Web",
+ "doubaoWebDesc": "__MISSING__:ByteDance AI chat via doubao.com",
"overrideBaseUrlAdvanced": "Avançado: sobrescrever URL base",
"overrideBaseUrlHint": "Avançado: aponta este provedor embutido para um endpoint personalizado. Deixe em branco para usar o padrão.",
"apiProtocolLabel": "Protocolo da API",
@@ -6233,86 +6233,87 @@
"apiProtocolHint": "Alguns provedores publicam os mesmos modelos em mais de um protocolo. Mantenha o padrão a menos que precise da alternativa.",
"bulkAddFormatHintCloudflare": "Uma chave por linha. Formato: nome|accountId|apiKey (ID de conta Cloudflare + token de API).",
"lmarenaWebCookieHint": "Abra arena.ai, faça login e depois copie o cabeçalho Cookie completo de uma requisição de rede. Inclua arena-auth-prod-v1.0 e arena-auth-prod-v1.1 (e outros fragmentos, se houver), preferencialmente com cf_clearance. Não cole apenas o cookie vazio arena-auth-prod-v1. Opcional: providerSpecificData.recaptchaV3Token se create-evaluation ainda retornar 403.",
- "kimiOfficialSupporterBadge": "Amigo Fundador",
- "kimiOfficialSupporterTooltip": "A Kimi (Moonshot AI) é a amiga fundadora de código aberto do OmniRoute",
+ "kimiOfficialSupporterBadge": "Apoiador Oficial",
+ "kimiOfficialSupporterTooltip": "A Kimi (Moonshot AI) é parceira oficial de lançamento do OmniRoute",
"cheaperInferenceSupporterBadge": "Amigo do Código Aberto",
"cheaperInferenceSupporterTooltip": "A Cheaper Inference apoia o OmniRoute como amiga do código aberto",
- "kimiPartnerLinkNote": "Link de parceiro — apoia o OmniRoute sem custo extra para você",
-"anonymousFallbackTitle": "Fallback anônimo",
-"anonymousFallbackDesc": "Quando todas as conexões configuradas estiverem esgotadas (cota, créditos ou expiração), use temporariamente a camada sem chave deste provedor. Desative para ignorar este provedor em vez de enviar solicitações anônimas — recomendado quando a camada sem chave as rejeita (401).",
-"anonymousFallbackEnabled": "Fallback anônimo ativado para {provider}",
-"anonymousFallbackDisabled": "Fallback anônimo desativado para {provider} — conexões esgotadas ignorarão este provedor",
-"anonymousFallbackUpdateFailed": "Falha ao atualizar a configuração de fallback anônimo",
-"batchDeleteFailed": "__MISSING__:Batch delete failed",
-"batchDeleteNetworkError": "__MISSING__:Network error during batch delete",
-"batchUpdateFailed": "__MISSING__:Batch update failed",
-"batchUpdateNetworkError": "__MISSING__:Network error during batch update",
-"categoryAudio": "__MISSING__:Audio",
-"categoryCloudAgent": "__MISSING__:Cloud Agent",
-"categoryIde": "__MISSING__:IDE",
-"categoryLocal": "__MISSING__:Local",
-"categorySearch": "__MISSING__:Search",
-"categoryWebCookie": "__MISSING__:Web Cookie",
-"claudeExtraUsageBlockingDisabled": "__MISSING__:Claude extra-usage blocking disabled (extra usage is allowed)",
-"claudeExtraUsageBlockingEnabled": "__MISSING__:Claude extra-usage blocking enabled (extra usage will be blocked)",
-"claudeRoutingPreferenceDisabled": "__MISSING__:Unprefixed Claude models no longer prefer Claude Code",
-"claudeRoutingPreferenceEnabled": "__MISSING__:Unprefixed Claude models now prefer Claude Code",
-"clearMediaFilter": "__MISSING__:Clear",
-"cliproxyRoutingDisabled": "__MISSING__:Requests now use native OmniRoute (direct)",
-"cliproxyRoutingEnabled": "__MISSING__:Requests now route through CLIProxyAPI (deeper emulation)",
-"codexLimitPolicyUpdated": "__MISSING__:Codex limit policy updated",
-"codexServiceModeUpdated": "__MISSING__:Codex service mode updated",
-"codexServiceTierActive": "__MISSING__:Codex {tier} service tier is active",
-"codexTierFastLabel": "__MISSING__:Fast",
-"codexTierFlexLabel": "__MISSING__:Flex",
-"commandCodeApplyFailed": "__MISSING__:Failed to apply Command Code auth",
-"commandCodeApplyingApproval": "__MISSING__:Browser approved, applying…",
-"commandCodeApplyingKey": "__MISSING__:Applying browser-approved key…",
-"commandCodeApprovalInstructions": "__MISSING__:Open the auth URL, approve access, then paste the returned key/JSON/URL below…",
-"commandCodeAuthExpired": "__MISSING__:Command Code auth expired",
-"commandCodeConnected": "__MISSING__:Command Code connected",
-"commandCodeConnectionAdded": "__MISSING__:Command Code connection added",
-"commandCodeLinkExpired": "__MISSING__:Command Code link expired",
-"commandCodeOpeningStudio": "__MISSING__:Opening Command Code Studio…",
-"commandCodePopupBlocked": "__MISSING__:Popup blocked. Please allow popups and try Command Code Connect again.",
-"commandCodeStartFailed": "__MISSING__:Failed to start Command Code auth",
-"connectionDeleted": "__MISSING__:Connection deleted",
-"connectionFallback": "__MISSING__:connection",
-"coolingConnectionsDescription": "__MISSING__:These connections returned a 429 (rate-limit) on their last request. OmniRoute will skip them until the timer expires — no manual disable required.",
-"coolingConnectionsTitle": "__MISSING__:Currently cooling ({count})",
-"failedDeleteAlias": "__MISSING__:Failed to delete alias",
-"failedDeleteConnection": "__MISSING__:Failed to delete connection",
-"failedDistributeProxies": "__MISSING__:Failed to distribute proxies.",
-"failedSaveModelEndpointSettings": "__MISSING__:Failed to save model endpoint settings",
-"failedUpdateClaudeExtraUsagePolicy": "__MISSING__:Failed to update Claude extra-usage policy",
-"failedUpdateClaudeRoutingPreference": "__MISSING__:Failed to update Claude Code routing preference",
-"failedUpdateCliproxyRouting": "__MISSING__:Failed to update CLIProxyAPI routing",
-"failedUpdateCodexLimitPolicy": "__MISSING__:Failed to update Codex limit policy",
-"failedUpdateCodexServiceMode": "__MISSING__:Failed to update Codex service mode",
-"filterByMedia": "__MISSING__:Media",
-"freeBadge": "__MISSING__:Free",
-"kimiCodeApiKeyLabel": "__MISSING__:Kimi Code API Key",
-"modelTestFailed": "__MISSING__:Model test failed",
-"modelTestNetworkError": "__MISSING__:Network error testing model",
-"networkError": "__MISSING__:Network error",
-"networkErrorDeletingAlias": "__MISSING__:Network error deleting alias",
-"networkErrorSettingAlias": "__MISSING__:Network error setting alias",
-"noProvidersMatch": "__MISSING__:No providers match your search.",
-"noSavedProxies": "__MISSING__:No saved proxies found. Add proxies in Settings → Proxy first.",
-"pageLoadErrorDescription": "__MISSING__:We could not load provider data right now. Check your connection and try again.",
-"pageLoadErrorId": "__MISSING__:Error ID: {id}",
-"pageLoadErrorRetry": "__MISSING__:Try Again",
-"pageLoadErrorTitle": "__MISSING__:Failed to load providers",
-"playgroundTitle": "__MISSING__:Playground",
-"providerDetailConnectionFlexActive": "__MISSING__:Codex flex service tier is active for this connection",
-"providerDetailConnectionPriorityActive": "__MISSING__:Codex priority service tier is active for this connection",
-"providerDetailGlobalFlexActive": "__MISSING__:Global Codex flex service tier is active",
-"providerDetailGlobalPriorityActive": "__MISSING__:Global Codex priority service tier is active",
-"proxiesDistributed": "__MISSING__:Distributed {assigned} proxy assignment(s) across {tagLabel}{total} connection(s).",
-"rerankEndpoint": "__MISSING__:Rerank",
-"savedModelEndpointSettings": "__MISSING__:Saved model endpoint settings",
-"searchByModelAria": "__MISSING__:Search by model",
-"selectSupportedEndpoint": "__MISSING__:Select at least one supported endpoint"
+ "kimiPartnerLinkNote": "Link de parceria — apoia o OmniRoute sem custo extra para você",
+ "anonymousFallbackTitle": "Fallback anônimo",
+ "anonymousFallbackDesc": "Quando todas as conexões configuradas estiverem esgotadas (cota, créditos ou expiração), use temporariamente a camada sem chave deste provedor. Desative para ignorar este provedor em vez de enviar solicitações anônimas — recomendado quando a camada sem chave as rejeita (401).",
+ "anonymousFallbackEnabled": "Fallback anônimo ativado para {provider}",
+ "anonymousFallbackDisabled": "Fallback anônimo desativado para {provider} — conexões esgotadas ignorarão este provedor",
+ "anonymousFallbackUpdateFailed": "Falha ao atualizar a configuração de fallback anônimo",
+ "batchDeleteFailed": "__MISSING__:Batch delete failed",
+ "batchDeleteNetworkError": "__MISSING__:Network error during batch delete",
+ "batchUpdateFailed": "__MISSING__:Batch update failed",
+ "batchUpdateNetworkError": "__MISSING__:Network error during batch update",
+ "categoryAudio": "__MISSING__:Audio",
+ "categoryCloudAgent": "__MISSING__:Cloud Agent",
+ "categoryIde": "__MISSING__:IDE",
+ "categoryLocal": "__MISSING__:Local",
+ "categorySearch": "__MISSING__:Search",
+ "categoryWebCookie": "__MISSING__:Web Cookie",
+ "claudeExtraUsageBlockingDisabled": "__MISSING__:Claude extra-usage blocking disabled (extra usage is allowed)",
+ "claudeExtraUsageBlockingEnabled": "__MISSING__:Claude extra-usage blocking enabled (extra usage will be blocked)",
+ "claudeRoutingPreferenceDisabled": "__MISSING__:Unprefixed Claude models no longer prefer Claude Code",
+ "claudeRoutingPreferenceEnabled": "__MISSING__:Unprefixed Claude models now prefer Claude Code",
+ "clearMediaFilter": "__MISSING__:Clear",
+ "cliproxyRoutingDisabled": "__MISSING__:Requests now use native OmniRoute (direct)",
+ "cliproxyRoutingEnabled": "__MISSING__:Requests now route through CLIProxyAPI (deeper emulation)",
+ "codexLimitPolicyUpdated": "__MISSING__:Codex limit policy updated",
+ "codexServiceModeUpdated": "__MISSING__:Codex service mode updated",
+ "codexServiceTierActive": "__MISSING__:Codex {tier} service tier is active",
+ "codexTierFastLabel": "__MISSING__:Fast",
+ "codexTierFlexLabel": "__MISSING__:Flex",
+ "commandCodeApplyFailed": "__MISSING__:Failed to apply Command Code auth",
+ "commandCodeApplyingApproval": "__MISSING__:Browser approved, applying…",
+ "commandCodeApplyingKey": "__MISSING__:Applying browser-approved key…",
+ "commandCodeApprovalInstructions": "__MISSING__:Open the auth URL, approve access, then paste the returned key/JSON/URL below…",
+ "commandCodeAuthExpired": "__MISSING__:Command Code auth expired",
+ "commandCodeConnected": "__MISSING__:Command Code connected",
+ "commandCodeConnectionAdded": "__MISSING__:Command Code connection added",
+ "commandCodeLinkExpired": "__MISSING__:Command Code link expired",
+ "commandCodeOpeningStudio": "__MISSING__:Opening Command Code Studio…",
+ "commandCodePopupBlocked": "__MISSING__:Popup blocked. Please allow popups and try Command Code Connect again.",
+ "commandCodeStartFailed": "__MISSING__:Failed to start Command Code auth",
+ "connectionDeleted": "__MISSING__:Connection deleted",
+ "connectionFallback": "__MISSING__:connection",
+ "coolingConnectionsDescription": "__MISSING__:These connections returned a 429 (rate-limit) on their last request. OmniRoute will skip them until the timer expires — no manual disable required.",
+ "coolingConnectionsTitle": "__MISSING__:Currently cooling ({count})",
+ "failedDeleteAlias": "__MISSING__:Failed to delete alias",
+ "failedDeleteConnection": "__MISSING__:Failed to delete connection",
+ "failedDistributeProxies": "__MISSING__:Failed to distribute proxies.",
+ "failedSaveModelEndpointSettings": "__MISSING__:Failed to save model endpoint settings",
+ "failedUpdateClaudeExtraUsagePolicy": "__MISSING__:Failed to update Claude extra-usage policy",
+ "failedUpdateClaudeRoutingPreference": "__MISSING__:Failed to update Claude Code routing preference",
+ "failedUpdateCliproxyRouting": "__MISSING__:Failed to update CLIProxyAPI routing",
+ "failedUpdateCodexLimitPolicy": "__MISSING__:Failed to update Codex limit policy",
+ "failedUpdateCodexServiceMode": "__MISSING__:Failed to update Codex service mode",
+ "filterByMedia": "__MISSING__:Media",
+ "freeBadge": "__MISSING__:Free",
+ "kimiCodeApiKeyLabel": "__MISSING__:Kimi Code API Key",
+ "modelTestFailed": "__MISSING__:Model test failed",
+ "modelTestNetworkError": "__MISSING__:Network error testing model",
+ "networkError": "__MISSING__:Network error",
+ "networkErrorDeletingAlias": "__MISSING__:Network error deleting alias",
+ "networkErrorSettingAlias": "__MISSING__:Network error setting alias",
+ "noProvidersMatch": "__MISSING__:No providers match your search.",
+ "noSavedProxies": "__MISSING__:No saved proxies found. Add proxies in Settings → Proxy first.",
+ "pageLoadErrorDescription": "__MISSING__:We could not load provider data right now. Check your connection and try again.",
+ "pageLoadErrorId": "__MISSING__:Error ID: {id}",
+ "pageLoadErrorRetry": "__MISSING__:Try Again",
+ "pageLoadErrorTitle": "__MISSING__:Failed to load providers",
+ "playgroundTitle": "__MISSING__:Playground",
+ "providerDetailConnectionFlexActive": "__MISSING__:Codex flex service tier is active for this connection",
+ "providerDetailConnectionPriorityActive": "__MISSING__:Codex priority service tier is active for this connection",
+ "providerDetailGlobalFlexActive": "__MISSING__:Global Codex flex service tier is active",
+ "providerDetailGlobalPriorityActive": "__MISSING__:Global Codex priority service tier is active",
+ "proxiesDistributed": "__MISSING__:Distributed {assigned} proxy assignment(s) across {tagLabel}{total} connection(s).",
+ "rerankEndpoint": "__MISSING__:Rerank",
+ "savedModelEndpointSettings": "__MISSING__:Saved model endpoint settings",
+ "searchByModelAria": "__MISSING__:Search by model",
+ "selectSupportedEndpoint": "__MISSING__:Select at least one supported endpoint",
+ "antigravityClientProfileHarness": "Harness / CLI"
},
"settings": {
"title": "Configurações",
@@ -6434,7 +6435,7 @@
"memoryDesc": "Memória conversacional persistente entre sessões",
"memoryEnabled": "Ativar Memória",
"memoryEnabledDesc": "Quando ativado, injetará o contexto passado relevante de forma dinâmica.",
- "memoryTokenCostWarning": "Atenção: com a memória ativada, o OmniRoute injeta até {tokens} tokens de contexto recuperado em cada solicitação de chat — isso aumenta o uso de tokens e o custo. Para ignorar a injeção em uma solicitação específica, envie o cabeçalho \"x-omniroute-no-memory: true\" .",
+ "memoryTokenCostWarning": "__MISSING__:Heads up: with memory enabled, OmniRoute injects up to {tokens} tokens of retrieved context into every chat request — this increases token usage and cost. To skip injection for a specific request, send the \"x-omniroute-no-memory: true\" header.",
"maxTokens": "Tokens Máximos",
"retentionDays": "Retenção",
"recent": "Recente",
@@ -6476,27 +6477,27 @@
"logToolSourcesToggle": "Registrar fontes de ferramentas",
"logToolSourcesDescription": "Emite uma linha de log de diagnóstico por requisição resumindo a contagem de ferramentas e a origem MCP/hospedada/cliente.",
"homePinProviderQuotaToHome": "Fixar informações na página inicial",
- "homePinnedSectionsDesc": "Escolha quais seções fixar no topo da página inicial.",
+ "homePinnedSectionsDesc": "Escolha quais seções fixar no topo da página Início.",
"homeProviderQuotaLimits": "Limites de cota dos provedores",
"homeProviderQuotaLimitsDesc": "Fixe o painel de status de cotas dos provedores (com botão Atualizar tudo) no topo da página inicial.",
"homeQuickStart": "Início rápido",
"homeQuickStartDesc": "Mostrar o painel de início rápido na página inicial.",
"homeProviderTopology": "Topologia dos provedores",
"homeProviderTopologyDesc": "Mostrar a topologia dos provedores na página inicial.",
- "accountEmailVisibility": "Visibilidade do e-mail da conta",
- "accountEmailVisibilityDesc": "Mostrar e-mails completos da conta nas telas de provedores, combos, logs, cotas e playground. Desative isso para mascará-los por padrão.",
+ "accountEmailVisibility": "__MISSING__:Account email visibility",
+ "accountEmailVisibilityDesc": "__MISSING__:Show full account emails across providers, combos, logs, quota, and playground screens. Turn this off to mask them by default.",
"comboConfigMode": "Modo de configuração de combo",
- "comboConfigModeDesc": "Escolha como a caixa de diálogo de criação e edição de combo é organizada.",
+ "comboConfigModeDesc": "Escolha como o diálogo de criação e edição de combo é organizado.",
"comboConfigModeGuided": "Guiado",
"comboConfigModeGuidedDesc": "Use o construtor de combo passo a passo atual.",
"comboConfigModeExpert": "Especialista",
- "comboConfigModeExpertDesc": "Mostrar todas as opções de combo em uma página e habilitar a inserção direta de modelos.",
- "providerQuotaAutoRefresh": "Atualização automática de cota do provedor",
- "providerQuotaAutoRefreshDesc": "Atualizar a visualização de Limites do Provedor automaticamente enquanto ela permanecer aberta.",
+ "comboConfigModeExpertDesc": "Mostra todas as opções de combo em uma página e permite a entrada direta de modelo.",
+ "providerQuotaAutoRefresh": "Atualização automática da Cota do Provedor",
+ "providerQuotaAutoRefreshDesc": "Atualiza automaticamente a visualização de Limites do Provedor enquanto ela permanece aberta.",
"providerQuotaAutoRefreshToggle": "Atualização automática",
- "providerQuotaAutoRefreshToggleDesc": "Atualizar a visualização de cotas a cada poucos minutos enquanto a página estiver visível.",
+ "providerQuotaAutoRefreshToggleDesc": "Atualiza a visualização de cota a cada poucos minutos enquanto a página está visível.",
"providerQuotaAutoRefreshInterval": "Intervalo de atualização",
- "providerQuotaAutoRefreshIntervalDesc": "Com que frequência a visualização de cotas deve ser atualizada, em segundos.",
+ "providerQuotaAutoRefreshIntervalDesc": "Com que frequência a visualização de cota deve atualizar, em segundos.",
"seconds": "segundos",
"sidebarVisibilityToggle": "Show Sidebar Items",
"enableCache": "Ativar Cache",
@@ -6531,17 +6532,17 @@
"autoDisableDescription": "Marca permanentemente conexões de provedor como desativadas quando retornam sinais terminais de banimento (ex.: HTTP 403 'verify your account'). Isso remove a conexão da rotação de combos.",
"autoDisableThreshold": "Limite de banimento",
"autoDisableThresholdDesc": "Quantidade de sinais consecutivos de banimento antes da desativação permanente.",
- "customBannedSignals": "Palavras-chave banidas",
- "customBannedSignalsDesc": "Palavras-chave adicionais que acionam a detecção de banimento permanente da conta. As palavras-chave integradas sempre se aplicam.",
- "customBannedSignalsPlaceholder": "ex: api key revoked",
- "noCustomBannedSignals": "Nenhuma palavra-chave personalizada. Apenas as palavras-chave integradas estão ativas.",
+ "customBannedSignals": "__MISSING__:Banned Keywords",
+ "customBannedSignalsDesc": "__MISSING__:Additional keywords that trigger permanent account ban detection. Built-in keywords always apply.",
+ "customBannedSignalsPlaceholder": "__MISSING__:e.g. api key revoked",
+ "noCustomBannedSignals": "__MISSING__:No custom keywords. Only built-in keywords are active.",
"resilienceStructureTitle": "Estrutura de resiliência",
"resilienceStructureDesc": "Esta página configura apenas o comportamento. O estado ao vivo de circuit breaker aparece na página Saúde. Controle de retry específico por combo e slot de round-robin continuam nas configurações de combos.",
"enableThinking": "Ativar Raciocínio",
"maxThinkingTokens": "Máximo de Tokens de Raciocínio",
"enableProxy": "Ativar Proxy",
- "perKeyProxyEnabled": "Habilitar atribuição de proxy por chave",
- "perKeyProxyEnabledDesc": "Quando ativado, cada conexão de provedor pode usar sua própria atribuição de proxy",
+ "perKeyProxyEnabled": "__MISSING__:Enable per-key proxy assignment",
+ "perKeyProxyEnabledDesc": "__MISSING__:When enabled, each provider connection can use its own proxy assignment",
"proxyUrl": "URL do Proxy",
"pricingRates": "Formato de Taxas de Preço",
"currentPricing": "Visão Geral de Preços Atual",
@@ -6612,13 +6613,13 @@
"uploadFavicon": "Upload Favicon",
"resetFavicon": "Reset Favicon",
"faviconPreview": "Favicon Preview",
- "logoFileTooLarge": "O arquivo do logotipo deve ter menos de 500KB",
- "faviconFileTooLarge": "O arquivo do favicon deve ter menos de 50KB",
- "invalidLogoFileType": "Tipo de arquivo inválido. Carregue PNG, JPG, SVG, GIF ou WebP.",
- "invalidFaviconFileType": "Tipo de arquivo inválido. Carregue PNG, ICO, SVG, GIF ou WebP.",
+ "logoFileTooLarge": "O arquivo de logo deve ter menos de 500KB",
+ "faviconFileTooLarge": "O arquivo de favicon deve ter menos de 50KB",
+ "invalidLogoFileType": "Tipo de arquivo inválido. Envie PNG, JPG, SVG, GIF ou WebP.",
+ "invalidFaviconFileType": "Tipo de arquivo inválido. Envie PNG, ICO, SVG, GIF ou WebP.",
"failedToReadFile": "Falha ao ler o arquivo",
- "startOnLogin": "Iniciar ao fazer login",
- "startOnLoginDesc": "Iniciar automaticamente o OmniRoute na inicialização do sistema e executá-lo silenciosamente na bandeja do sistema.",
+ "startOnLogin": "Iniciar no Login",
+ "startOnLoginDesc": "Inicia automaticamente o OmniRoute na inicialização do sistema e executa silenciosamente na bandeja em segundo plano.",
"flushCache": "Limpar Cache",
"flushing": "Limpando…",
"size": "Tamanho",
@@ -6642,78 +6643,78 @@
"NEEDS_CORE_NOT_CONFIGURED": "Esta assinatura tem nós que precisam de um core local (SS/VMess/Trojan/VLESS); eles não são roteados até você configurar o endpoint SOCKS5 do core local.",
"NO_USABLE_NODES": "A assinatura não retornou nós utilizáveis (http/https/socks5 ou nós com endpoint de core local)."
},
-"description": "Cole o link de assinatura do seu proxy. Uma vez ativado, o tráfego é roteado através do pool de proxy no modo global ou de regra (Provedor especificado). Os nós de assinatura são sincronizados automaticamente no pool de proxy e reutilizam mecanismos existentes de pesquisa, verificação de integridade e antivazamento.",
-"addSubscription": "Adicionar assinatura",
-"newSubscription": "Adicionar assinatura",
-"editSubscription": "Editar assinatura",
-"name": "Nome",
-"namePlaceholder": "por exemplo Minha assinatura A",
-"url": "URL de assinatura",
-"urlPlaceholder": "https://.../subscribe?token=...",
-"mode": "Modo",
-"globalMode": "Modo Global",
-"ruleMode": "Modo de regra",
-"globalModeDesc": "Todo o tráfego do Provedor passa pelo pool de proxy desta assinatura.",
-"ruleModeDesc": "Apenas o tráfego dos Provedores selecionados passa pelo proxy; o resto se conecta diretamente.",
-"localCoreEndpoint": "Ponto final SOCKS5/HTTP de núcleo local (opcional)",
-"localCoreEndpointPlaceholder": "meias5://127.0.0.1:1080",
-"localCoreEndpointDesc": "Aceita apenas 127.0.0.1 / localhost (SS/VMess/Trojan/VLESS requerem um núcleo sing-box/clash local).",
-"routeByProvider": "Rota por provedor (seleção múltipla)",
-"loadingProviders": "Carregando lista de provedores…",
-"autoRefreshInterval": "Intervalo de atualização automática (minutos)",
-"enableAfterCreate": "Ativar na criação (sincronizar e entrar em vigor imediatamente)",
-"saving": "Salvando…",
-"saveChanges": "Salvar alterações",
-"createSubscription": "Criar assinatura",
-"loading": "Carregando…",
-"noSubscriptions": "Ainda não há assinaturas. Clique em \"Adicionar assinatura\" para começar.",
-"statusOk": "OK",
-"statusError": "Erro",
-"statusEmpty": "Vazio",
-"global": "Globais",
-"rule": "Regra",
-"enabled": "Habilitado",
-"disabled": "Desativado",
-"nodeCount": "Nós: {count}",
-"needsCoreCount": "{count} precisa de núcleo local",
-"lastSynced": "Última sincronização: {time}",
-"consecutiveFailures": "{count} falhas consecutivas",
-"lastError": "Último erro: {time}",
-"coreHintTitle": "Esta assinatura possui nós {count} que requerem um núcleo de proxy local (SS/VMess/Trojan/VLESS, etc.) e atualmente não são roteados.",
-"coreHintDesc": "Esses protocolos não podem ser encaminhados diretamente pelo OmniRoute. Por favor, inicie um núcleo sing-box ou Clash (Clash.Meta) em sua máquina, exponha-o como um endpoint SOCKS5/HTTP e preencha-o via Editar (apenas 127.0.0.1/localhost é aceito).",
-"copy": "Copiar",
-"goConfigure": "Configurar",
-"disable": "Desativar",
-"enable": "Habilitar",
-"refreshNodes": "Atualizar nós",
-"edit": "Editar",
-"delete": "Excluir",
-"confirmDelete": "Tem certeza de que deseja excluir a assinatura \"{name}\"? Os nós proxy associados também serão removidos.",
-"nameRequired": "Por favor insira um nome",
-"urlRequired": "Insira um URL de assinatura",
-"ruleModeProviderRequired": "Selecione pelo menos um provedor no modo de regra",
-"saveFailed": "Falha ao salvar",
-"loadFailed": "Falha ao carregar a lista de assinaturas",
-"toggleFailed": "Falha ao alternar o interruptor",
-"refreshFailed": "Falha ao atualizar",
-"deleteFailed": "Falha ao excluir",
-"add": "__MISSING__:Add",
-"cancel": "__MISSING__:Cancel",
-"configure": "__MISSING__:Configure",
-"copyEndpoint": "__MISSING__:Copy Endpoint",
-"coreEndpointHint": "__MISSING__:Core Endpoint Hint",
-"coreNodesHint": "__MISSING__:Core Nodes Hint",
-"create": "__MISSING__:Create",
-"deleteConfirm": "__MISSING__:Delete Confirm",
-"empty": "__MISSING__:Empty",
-"globalModeDescription": "__MISSING__:Global Mode Description",
-"localCoreHint": "__MISSING__:Local Core Hint",
-"nodeSummary": "__MISSING__:Node Summary",
-"providerRequired": "__MISSING__:Provider Required",
-"providerRouting": "__MISSING__:Provider Routing",
-"refresh": "__MISSING__:Refresh",
-"refreshInterval": "__MISSING__:Refresh Interval",
-"ruleModeDescription": "__MISSING__:Rule Mode Description"
+ "description": "Cole o link de assinatura do seu proxy. Uma vez ativado, o tráfego é roteado através do pool de proxy no modo global ou de regra (Provedor especificado). Os nós de assinatura são sincronizados automaticamente no pool de proxy e reutilizam mecanismos existentes de pesquisa, verificação de integridade e antivazamento.",
+ "addSubscription": "Adicionar assinatura",
+ "newSubscription": "Adicionar assinatura",
+ "editSubscription": "Editar assinatura",
+ "name": "Nome",
+ "namePlaceholder": "por exemplo Minha assinatura A",
+ "url": "URL de assinatura",
+ "urlPlaceholder": "https://.../subscribe?token=...",
+ "mode": "Modo",
+ "globalMode": "Modo Global",
+ "ruleMode": "Modo de regra",
+ "globalModeDesc": "Todo o tráfego do Provedor passa pelo pool de proxy desta assinatura.",
+ "ruleModeDesc": "Apenas o tráfego dos Provedores selecionados passa pelo proxy; o resto se conecta diretamente.",
+ "localCoreEndpoint": "Ponto final SOCKS5/HTTP de núcleo local (opcional)",
+ "localCoreEndpointPlaceholder": "meias5://127.0.0.1:1080",
+ "localCoreEndpointDesc": "Aceita apenas 127.0.0.1 / localhost (SS/VMess/Trojan/VLESS requerem um núcleo sing-box/clash local).",
+ "routeByProvider": "Rota por provedor (seleção múltipla)",
+ "loadingProviders": "Carregando lista de provedores…",
+ "autoRefreshInterval": "Intervalo de atualização automática (minutos)",
+ "enableAfterCreate": "Ativar na criação (sincronizar e entrar em vigor imediatamente)",
+ "saving": "Salvando…",
+ "saveChanges": "Salvar alterações",
+ "createSubscription": "Criar assinatura",
+ "loading": "Carregando…",
+ "noSubscriptions": "Ainda não há assinaturas. Clique em \"Adicionar assinatura\" para começar.",
+ "statusOk": "OK",
+ "statusError": "Erro",
+ "statusEmpty": "Vazio",
+ "global": "Globais",
+ "rule": "Regra",
+ "enabled": "Habilitado",
+ "disabled": "Desativado",
+ "nodeCount": "Nós: {count}",
+ "needsCoreCount": "{count} precisa de núcleo local",
+ "lastSynced": "Última sincronização: {time}",
+ "consecutiveFailures": "{count} falhas consecutivas",
+ "lastError": "Último erro: {time}",
+ "coreHintTitle": "Esta assinatura possui nós {count} que requerem um núcleo de proxy local (SS/VMess/Trojan/VLESS, etc.) e atualmente não são roteados.",
+ "coreHintDesc": "Esses protocolos não podem ser encaminhados diretamente pelo OmniRoute. Por favor, inicie um núcleo sing-box ou Clash (Clash.Meta) em sua máquina, exponha-o como um endpoint SOCKS5/HTTP e preencha-o via Editar (apenas 127.0.0.1/localhost é aceito).",
+ "copy": "Copiar",
+ "goConfigure": "Configurar",
+ "disable": "Desativar",
+ "enable": "Habilitar",
+ "refreshNodes": "Atualizar nós",
+ "edit": "Editar",
+ "delete": "Excluir",
+ "confirmDelete": "Tem certeza de que deseja excluir a assinatura \"{name}\"? Os nós proxy associados também serão removidos.",
+ "nameRequired": "Por favor insira um nome",
+ "urlRequired": "Insira um URL de assinatura",
+ "ruleModeProviderRequired": "Selecione pelo menos um provedor no modo de regra",
+ "saveFailed": "Falha ao salvar",
+ "loadFailed": "Falha ao carregar a lista de assinaturas",
+ "toggleFailed": "Falha ao alternar o interruptor",
+ "refreshFailed": "Falha ao atualizar",
+ "deleteFailed": "Falha ao excluir",
+ "add": "__MISSING__:Add",
+ "cancel": "__MISSING__:Cancel",
+ "configure": "__MISSING__:Configure",
+ "copyEndpoint": "__MISSING__:Copy Endpoint",
+ "coreEndpointHint": "__MISSING__:Core Endpoint Hint",
+ "coreNodesHint": "__MISSING__:Core Nodes Hint",
+ "create": "__MISSING__:Create",
+ "deleteConfirm": "__MISSING__:Delete Confirm",
+ "empty": "__MISSING__:Empty",
+ "globalModeDescription": "__MISSING__:Global Mode Description",
+ "localCoreHint": "__MISSING__:Local Core Hint",
+ "nodeSummary": "__MISSING__:Node Summary",
+ "providerRequired": "__MISSING__:Provider Required",
+ "providerRouting": "__MISSING__:Provider Routing",
+ "refresh": "__MISSING__:Refresh",
+ "refreshInterval": "__MISSING__:Refresh Interval",
+ "ruleModeDescription": "__MISSING__:Rule Mode Description"
},
"bulkHealthcheck": "Verificação de integridade em massa",
"bulkHealthcheckDesc": "Teste todos os proxies configurados contra uma URL de destino para encontrar quais funcionam.",
@@ -6745,11 +6746,11 @@
"vercelRelayTokenRequired": "Token obrigatório",
"vercelRelayDeployFailed": "Falha no deploy",
"vercelRelayTokenHint": "O token é usado apenas durante o deploy e nunca é armazenado.",
- "denoRelayTokenRequired": "O token do Deno Deploy é obrigatório",
- "denoRelayOrgDomainRequired": "O domínio da organização é obrigatório",
- "denoRelayDeployFailed": "Falha no Deno Deploy",
- "denoRelayTokenHint": "Token da organização (prefixo ddo_) de console.deno.com → Organization → Settings → Organization Tokens. Usado uma vez para o deploy e nunca armazenado.",
- "denoRelayOrgDomainHint": "O domínio padrão da sua organização no Deno Deploy (ex: acme.deno.net). O relay estará acessível em https://<app-name>.<org-slug>.deno.net.",
+ "denoRelayTokenRequired": "__MISSING__:Deno Deploy token is required",
+ "denoRelayOrgDomainRequired": "__MISSING__:Organization domain is required",
+ "denoRelayDeployFailed": "__MISSING__:Deno Deploy failed",
+ "denoRelayTokenHint": "__MISSING__:Organization token (prefix ddo_) from console.deno.com → Organization → Settings → Organization Tokens. Used once for deploy and never stored.",
+ "denoRelayOrgDomainHint": "__MISSING__:Your Deno Deploy organization's default domain (e.g. acme.deno.net). The relay will be reachable at https://..deno.net.",
"proxyFreePoolFilterProtocol": "Filtrar por protocolo",
"proxyFreePoolProtocol": "Protocolo",
"proxyFreePoolCountryPlaceholder": "País (ex.: US)",
@@ -7065,7 +7066,7 @@
"systemStorage": "Sistema e Armazenamento",
"allDataLocal": "Todos os dados armazenados localmente na sua máquina",
"databasePath": "Caminho do Banco de Dados",
- "export": "Exportar",
+ "export": "__MISSING__:Export",
"exportDatabase": "Exportar Banco de Dados",
"exportAll": "Exportar Tudo (.tar.gz)",
"importDatabase": "Importar Banco de Dados",
@@ -7144,7 +7145,7 @@
"howPricingWorks": "Como os Preços Funcionam",
"cacheWrite": "Escrita em Cache",
"unsaved": "não salvo",
- "resetDefaults": "Restaurar padrões",
+ "resetDefaults": "Restaurar Padrões",
"saveProvider": "Salvar Provedor",
"model": "Modelo",
"models": "modelos",
@@ -7181,11 +7182,11 @@
"adaptiveVolumeRoutingDesc": "Escala conexões dinamicamente com base no volume e pressão na taxa de transferência.",
"lkgpToggleTitle": "Last Known Good Provider (LKGP)",
"lkgpToggleDesc": "When enabled, the router remembers which provider last served a successful response and tries it first on subsequent requests.",
- "echoRequestedModelTitle": "Ecoar nome do modelo solicitado nas respostas",
- "echoRequestedModelDesc": "Quando ativado, o campo `model` da resposta ecoa o alias ou nome do combo que o cliente solicitou em vez do nome do modelo upstream. Corrige clientes estritos (por exemplo, Claude Desktop) que rejeitam uma resposta cujo modelo não corresponde à solicitação.",
- "webSearchRouteTitle": "Roteamento de pesquisa na web",
- "webSearchRouteDesc": "Quando uma solicitação inclui uma ferramenta nativa web_search, roteia toda a solicitação para este modelo em vez do padrão — útil para provedores que não implementam a ferramenta de servidor web_search da Anthropic. Deixe em branco para desativar.",
- "webSearchRoutePlaceholder": "ex.: openrouter,anthropic/claude-3.5-sonnet",
+ "echoRequestedModelTitle": "__MISSING__:Echo requested model name in responses",
+ "echoRequestedModelDesc": "__MISSING__:When enabled, the response `model` field echoes the alias or combo name the client requested instead of the upstream model name. Fixes strict clients (e.g. Claude Desktop) that reject a response whose model does not match the request.",
+ "webSearchRouteTitle": "__MISSING__:Web search routing",
+ "webSearchRouteDesc": "__MISSING__:When a request includes a native web_search tool, route the whole request to this model instead of the default — useful for providers that don't implement Anthropic's web_search server tool. Leave blank to disable.",
+ "webSearchRoutePlaceholder": "__MISSING__:e.g. openrouter,anthropic/claude-3.5-sonnet",
"paidModelPatternWarning": "Este padrão corresponde apenas a modelos pagos — habilite modelos pagos ou ajuste o padrão.",
"clearLkgpCache": "Clear LKGP Cache",
"lkgpCacheCleared": "LKGP cache cleared successfully",
@@ -7198,7 +7199,7 @@
"purgeLogsFailed": "Falha ao purgar logs",
"logsDeleted": "{count, plural, =0 {Nenhum log expirado removido} one {# log expirado removido} other {# logs expirados removidos}}",
"resetUsageData": "Redefinir dados de uso",
- "resetUsageDataDesc": "Selecione até onde você deseja excluir dados de uso, logs de solicitação e dados de análise. A configuração do provedor, conexões, chaves de API, combinações e configurações são preservadas. Esta ação não pode ser desfeita.",
+ "resetUsageDataDesc": "Selecione quanto tempo no passado você deseja excluir dados de uso. Esta ação não pode ser desfeita.",
"resetUsagePeriod_5m": "5 minutos",
"resetUsagePeriod_1h": "1 hora",
"resetUsagePeriod_3h": "3 horas",
@@ -7274,16 +7275,16 @@
"compressionGuidanceHide": "Ocultar detalhes",
"compressionGuidanceSafeDefault": "Padrão seguro",
"compressionGuidanceCacheImpact": "Impacto no cache",
- "tokenSaverTitle": "Economizador de Tokens",
- "tokenSaverSubtitle": "Gaste menos tokens em cada solicitação.",
- "tokenSaverToolOutput": "Saída da ferramenta",
- "tokenSaverToolOutputDesc": "Limpar a saída de git, grep, ls, tree e log antes que ela chegue ao provedor.",
- "tokenSaverLlmOutput": "Saída do LLM",
- "tokenSaverLlmOutputDesc": "Injetar instruções de resposta concisas sem reescrever a saída do provedor.",
- "tokenSaverInputCompression": "Compressão de entrada",
- "tokenSaverInputCompressionDesc": "Reescrever o histórico de chat elegível preservando o código, URLs e a intenção.",
- "tokenSaverFineTunePrefix": "Fazer ajuste fino de cada mecanismo em",
- "tokenSaverFineTuneSuffix": "ou combinar mecanismos por solicitação em",
+ "tokenSaverTitle": "__MISSING__:Token Saver",
+ "tokenSaverSubtitle": "__MISSING__:Spend fewer tokens on every request.",
+ "tokenSaverToolOutput": "__MISSING__:Tool output",
+ "tokenSaverToolOutputDesc": "__MISSING__:Clean git, grep, ls, tree, and log output before it reaches the provider.",
+ "tokenSaverLlmOutput": "__MISSING__:LLM output",
+ "tokenSaverLlmOutputDesc": "__MISSING__:Inject terse response instructions without rewriting provider output.",
+ "tokenSaverInputCompression": "__MISSING__:Input compression",
+ "tokenSaverInputCompressionDesc": "__MISSING__:Rewrite eligible chat history while preserving code, URLs, and intent.",
+ "tokenSaverFineTunePrefix": "__MISSING__:Fine-tune each engine on",
+ "tokenSaverFineTuneSuffix": "__MISSING__:or combine engines per request on",
"compressionMode": "Compression Mode",
"compressionModeOff": "Off",
"compressionModeOffDesc": "No compression applied",
@@ -7303,11 +7304,11 @@
"compressionUltraMinScore": "Minimum Score Threshold",
"compressionUltraSlmFallback": "Fallback to Aggressive",
"compressionUltraModelPath": "SLM Model Path",
- "compressionUltraEngine": "Nível Ultra",
- "compressionUltraEngineHeuristic": "Heuristic (Tier-A, default)",
- "compressionUltraEngineSlm": "SLM (LLMLingua-2, opt-in)",
- "compressionUltraSlmHint": "SLM downloads a small ONNX model on first use (cold-start) and transparently falls back to the heuristic on timeout or if unavailable.",
- "compressionUltraSlmPrewarm": "Pre-warm SLM model on enable",
+ "compressionUltraEngine": "__MISSING__:Ultra tier",
+ "compressionUltraEngineHeuristic": "__MISSING__:Heuristic (Tier-A, default)",
+ "compressionUltraEngineSlm": "__MISSING__:SLM (LLMLingua-2, opt-in)",
+ "compressionUltraSlmHint": "__MISSING__:SLM downloads a small ONNX model on first use (cold-start) and transparently falls back to the heuristic on timeout or if unavailable.",
+ "compressionUltraSlmPrewarm": "__MISSING__:Pre-warm SLM model on enable",
"compressionSummarizerEnabled": "Enable Summarizer",
"compressionMaxTokensPerMessage": "Max Tokens Per Message",
"compressionMinSavings": "Min Savings Threshold",
@@ -7512,81 +7513,81 @@
"resilienceNo": "Não",
"resilienceDefault": "Default",
"storageDatabaseBackupRetention": "Retenção de backup de banco de dados",
- "storageDatabaseBackups": "Database backups",
- "storageBackupRetentionDescription": "Automatic SQLite backups are stored in",
- "storageBackupRetentionHelp": "Configure how many snapshots to keep and optionally delete backups older than a chosen number of days.",
+ "storageDatabaseBackups": "__MISSING__:Database backups",
+ "storageBackupRetentionDescription": "Os backups automáticos do SQLite são armazenados em",
+ "storageBackupRetentionHelp": "Configure quantos snapshots manter e, opcionalmente, exclua backups mais antigos que um número escolhido de dias.",
"storageBackupCount": "{count} backups",
- "storageBackupMaximum": "Max {count}",
- "storageBackupAgeRetention": "{count}d retention",
- "storageBackupAgeRetentionOff": "Age retention off",
- "storageBackupKeepLatest": "Keep latest backups",
- "storageBackupDeleteOlderThan": "Delete older than days",
- "storageBackupSaveRetention": "Save retention",
- "storageBackupCleanOld": "Clean old backups",
- "storageDatabaseStatistics": "Database Statistics",
- "storageIntegrityNotChecked": "Not checked",
- "backupRetentionSaved": "Backup retention saved.",
- "backupRetentionSaveFailed": "Failed to save backup retention",
- "backupCleanupSuccess": "Deleted {backups} backup set(s) and {files} file(s).",
- "backupCleanupFailed": "Failed to clean database backups",
- "purgeQuotaSnapshotsSuccess": "Purged {count} quota snapshots",
- "purgeQuotaSnapshotsFailed": "Failed to purge quota snapshots",
- "purgeCallLogsSuccess": "Purged {count} call logs",
- "purgeCallLogsFailed": "Failed to purge call logs",
- "purgeDetailedLogsSuccess": "Purged {count} detailed logs",
- "purgeDetailedLogsFailed": "Failed to purge detailed logs",
- "vacuumCompleted": "VACUUM completed",
- "vacuumFailed": "VACUUM failed",
- "jsonExportFailed": "JSON export failed",
- "invalidJsonFileType": "Invalid file type. Only .json files are allowed.",
- "legacyJsonImportSuccess": "Legacy JSON imported successfully!",
- "jsonImportFailed": "Failed to import JSON",
- "jsonImportError": "Error during JSON import",
+ "storageBackupMaximum": "Máx. {count}",
+ "storageBackupAgeRetention": "retenção de {count}d",
+ "storageBackupAgeRetentionOff": "Retenção por idade desligada",
+ "storageBackupKeepLatest": "Manter os backups mais recentes",
+ "storageBackupDeleteOlderThan": "Excluir mais antigos que (dias)",
+ "storageBackupSaveRetention": "Salvar retenção",
+ "storageBackupCleanOld": "Limpar backups antigos",
+ "storageDatabaseStatistics": "Estatísticas do Banco de Dados",
+ "storageIntegrityNotChecked": "Não verificado",
+ "backupRetentionSaved": "Retenção de backup salva.",
+ "backupRetentionSaveFailed": "Falha ao salvar retenção de backup",
+ "backupCleanupSuccess": "Excluído(s) {backups} conjunto(s) de backup e {files} arquivo(s).",
+ "backupCleanupFailed": "Falha ao limpar backups do banco de dados",
+ "purgeQuotaSnapshotsSuccess": "{count} snapshots de cota removidos",
+ "purgeQuotaSnapshotsFailed": "Falha ao remover snapshots de cota",
+ "purgeCallLogsSuccess": "{count} logs de chamadas removidos",
+ "purgeCallLogsFailed": "Falha ao remover logs de chamadas",
+ "purgeDetailedLogsSuccess": "{count} logs detalhados removidos",
+ "purgeDetailedLogsFailed": "Falha ao remover logs detalhados",
+ "vacuumCompleted": "VACUUM concluído",
+ "vacuumFailed": "Falha no VACUUM",
+ "jsonExportFailed": "Falha na exportação de JSON",
+ "invalidJsonFileType": "Tipo de arquivo inválido. Apenas arquivos .json são permitidos.",
+ "legacyJsonImportSuccess": "JSON legado importado com sucesso!",
+ "jsonImportFailed": "Falha ao importar JSON",
+ "jsonImportError": "Erro durante a importação de JSON",
"storagePurgeData": "Limpar dados",
- "storagePurgeDataDesc": "Immediately delete all records without applying retention checks. Use with caution.",
- "storageRetentionCleanup": "Retention Settings",
- "storageRetentionCleanupDesc": "Configure operational record retention and database backup cleanup.",
- "retentionCallDays": "Call {count}d",
- "retentionAppDays": "App {count}d",
- "retentionRows": "{count} rows",
+ "storagePurgeDataDesc": "__MISSING__:Immediately delete all records without applying retention checks. Use with caution.",
+ "storageRetentionCleanup": "__MISSING__:Retention Settings",
+ "storageRetentionCleanupDesc": "__MISSING__:Configure operational record retention and database backup cleanup.",
+ "retentionCallDays": "__MISSING__:Call {count}d",
+ "retentionAppDays": "__MISSING__:App {count}d",
+ "retentionRows": "__MISSING__:{count} rows",
"retentionQuotaSnapshots": "Instantâneos de cota (dias)",
- "retentionCompressionAnalytics": "Análise de compressão (dias)",
+ "retentionCompressionAnalytics": "__MISSING__:Compression Analytics (days)",
"retentionMcpAudit": "Auditoria MCP (dias)",
"retentionA2aEvents": "Eventos A2A (dias)",
"retentionCallLogs": "Registros de chamadas (dias)",
"retentionUsageHistory": "Histórico de uso (dias)",
"retentionMemoryEntries": "Entradas de memória (dias)",
"retentionXpAuditLog": "Log de Auditoria de XP (dias)",
- "saveRetentionSettings": "Salvar configurações de retenção",
+ "saveRetentionSettings": "__MISSING__:Save retention settings",
"storageAutoVacuumMode": "Modo de vácuo automático",
"storageScheduledVacuum": "Vácuo programado",
"storageVacuumHour": "Hora de Vácuo (0-23)",
"storagePageSize": "Tamanho da página (bytes)",
- "storageOptimizationSettings": "Configurações de otimização",
+ "storageOptimizationSettings": "Configurações de Otimização",
"storageJournalModeNone": "Nenhum",
- "storageJournalModeFull": "Completo",
+ "storageJournalModeFull": "Completa",
"storageJournalModeIncremental": "Incremental",
"storageVacuumNever": "Nunca",
"storageVacuumDaily": "Diário",
"storageVacuumWeekly": "Semanal",
"storageVacuumMonthly": "Mensal",
- "storageCacheSizeKb": "Tamanho do cache (KB)",
- "storageOptimizeOnStartup": "Otimizar na inicialização",
- "storageSaveOptimization": "Salvar configurações de otimização",
- "storageCompressionAggregation": "Configurações de compressão e agregação",
- "storageEnableAggregation": "Ativar agregação de dados",
- "storageRawDataRetention": "Retenção de dados brutos (dias)",
+ "storageCacheSizeKb": "Tamanho do Cache (KB)",
+ "storageOptimizeOnStartup": "Otimizar na Inicialização",
+ "storageSaveOptimization": "Salvar Configurações de Otimização",
+ "storageCompressionAggregation": "Configurações de Compressão e Agregação",
+ "storageEnableAggregation": "Ativar Agregação de Dados",
+ "storageRawDataRetention": "Retenção de Dados Brutos (dias)",
"storageGranularity": "Granularidade",
"storageHourly": "Por hora",
"storageDaily": "Diário",
"storageWeekly": "Semanal",
- "storageSaveAggregation": "Salvar configurações de agregação",
+ "storageSaveAggregation": "Salvar Configurações de Agregação",
"exportJson": "Exportar JSON",
"importJson": "Importar JSON",
- "manualVacuum": "VACUUM manual",
- "purgeQuotaSnapshots": "Limpar snapshots de cota",
- "purgeCallLogs": "Limpar logs de chamadas",
- "purgeDetailedLogs": "Limpar logs detalhados",
+ "manualVacuum": "VACUUM Manual",
+ "purgeQuotaSnapshots": "Remover Snapshots de Cota",
+ "purgeCallLogs": "Remover Logs de Chamadas",
+ "purgeDetailedLogs": "Remover Logs Detalhados",
"storageDatabaseSize": "Tamanho do banco de dados",
"storagePageCount": "Contagem de páginas",
"storageFreelistCount": "Contagem de lista livre",
@@ -7596,9 +7597,9 @@
"storageIntegrityOk": "✓ OK",
"storageIntegrityError": "✗ Erro",
"storageUsageTokenBuffer": "Buffer de token de uso",
- "storageUsageTokenBufferDesc": "Tokens extras adicionados ao uso relatado para compensar a sobrecarga do prompt do sistema.",
- "storageUsageTokenBufferHint": "Defina como 0 para relatar a contagem bruta de tokens do provedor. Padrão: 2000.",
- "storageUsageTokenBufferCurrent": "Atual: {value}",
+ "storageUsageTokenBufferDesc": "__MISSING__:Extra tokens added to reported usage to account for system prompt overhead.",
+ "storageUsageTokenBufferHint": "__MISSING__:Set to 0 to report raw provider token counts. Default: 2000.",
+ "storageUsageTokenBufferCurrent": "__MISSING__:Current: {value}",
"redisLauncherTitle": "Redis local",
"redisLauncherDesc": "Inicie com um clique um contêiner Redis 7 (Podman ou Docker) para cache de resposta, controle de cota e limitação de taxa.",
"redisLauncherRefresh": "Atualizar",
@@ -7612,35 +7613,35 @@
"redisLauncherHint": "Equivalente a executar `omniroute redis up`. O contêiner é chamado `omniroute-redis` e escuta em 127.0.0.1:6379.",
"compressionSettingsAutoTriggerMode": "Modo de disparo automático",
"compressionSettingsMcpDescriptionCompression": "Compressão de descrição MCP",
- "mcpAccessibilityTitle": "Saída de acessibilidade do MCP",
+ "mcpAccessibilityTitle": "__MISSING__:MCP accessibility output",
"compressionSettingsCavemanIntensity": "Intensidade do homem das cavernas",
"compressionSettingsCavemanOutputMode": "Modo de saída do homem das cavernas",
- "compressionSettingsOutputStyles": "Estilos de saída",
- "compressionStylesTileTitle": "Estilos de saída",
+ "compressionSettingsOutputStyles": "__MISSING__:Output styles",
+ "compressionStylesTileTitle": "__MISSING__:Output styles",
"compressionSettingsOutputIntensity": "Intensidade de saída",
"compressionSettingsAutoClarityBypass": "Desvio de clareza automática",
"compressionEffectivePipeline": "Pipeline efetivo:",
- "compressionDerivedOff": "desativado",
- "compressionDerivedRuns": "execuções: {pipeline}",
+ "compressionDerivedOff": "desligado",
+ "compressionDerivedRuns": "executa: {pipeline}",
"compressionDerivedMode": "modo: {mode}",
- "compressionAdaptiveOff": "Orçamento de contexto adaptativo: desativado (acionamento automático legado)",
- "compressionAdaptiveTarget": "Adaptativo ({mode}, política: {policy}) — meta ≈ {target, number} tokens (para uma janela de {contextLimit, number} tokens)",
- "compressionOutputStylesDescription": "Injete instruções de modelagem de resposta sem reescrever a saída do provedor. Combine livremente.",
- "mcpAccessibilityDescription": "Define o escopo das saídas de ferramentas MCP (armazenamento separado).",
+ "compressionAdaptiveOff": "Orçamento de contexto adaptativo: desligado (auto-gatilho legado)",
+ "compressionAdaptiveTarget": "Adaptativo ({mode}, política: {policy}) — alvo ≈ {target, number} tokens (para uma janela de {contextLimit, number} tokens)",
+ "compressionOutputStylesDescription": "Injeta instruções de modelagem de resposta sem reescrever a saída do provedor. Combine livremente.",
+ "mcpAccessibilityDescription": "Delimita o escopo das saídas de ferramentas MCP (armazenamento separado).",
"compressionStylesTileSummary": "{tokens, number} tokens economizados · {runs, plural, one {# execução estilizada} other {# execuções estilizadas}}",
- "compressionStylesTileEmpty": "Nenhuma execução estilizada ainda.",
+ "compressionStylesTileEmpty": "Ainda não há execuções estilizadas.",
"compressionLevel": {
- "minimal": "Mínimo",
+ "minimal": "Minima",
"standard": "Padrão",
- "aggressive": "Agressivo",
+ "aggressive": "Aggressive",
"lite": "Lite",
- "full": "Completo",
+ "full": "Completa",
"ultra": "Ultra"
},
"compressionEngine": {
"session-dedup": {
- "label": "Desduplicação de sessão",
- "description": "Desduplicação de blocos entre turnos."
+ "label": "Session Dedup",
+ "description": "Deduplicação de blocos entre turnos."
},
"ccr": {
"label": "CCR (Recuperação)",
@@ -7652,7 +7653,7 @@
},
"rtk": {
"label": "RTK",
- "description": "Filtragem de saída de comandos."
+ "description": "Filtragem de saída de comando."
},
"codex-responses": {
"label": "Responses Tool Output",
@@ -7660,18 +7661,18 @@
},
"headroom": {
"label": "Headroom",
- "description": "Compactação de JSON tabular."
+ "description": "Compactação tabular de JSON."
},
"relevance": {
"label": "Relevância",
- "description": "Pontuação extrativa de sentenças em relação à última consulta do usuário."
+ "description": "Pontuação extrativa de frases em relação à última consulta do usuário."
},
"caveman": {
"label": "Caveman",
"description": "Compressão de prosa baseada em regras."
},
"aggressive": {
- "label": "Agressivo",
+ "label": "Aggressive",
"description": "Resume e envelhece turnos antigos."
},
"llmlingua": {
@@ -7690,11 +7691,11 @@
"compressionOutputStyle": {
"terse-prose": {
"label": "Prosa concisa",
- "description": "Remove preenchimentos, artigos e rodeios mantendo a substância técnica exata."
+ "description": "Remove enchimento, artigos e ressalvas, mantendo a substância técnica exata."
},
"less-code": {
"label": "Menos código",
- "description": "Escada YAGNI: menor alteração funcional, sem abstrações não solicitadas."
+ "description": "Escada YAGNI: menor mudança funcional, sem abstrações não solicitadas."
},
"ponytail": {
"label": "Ponytail (lazy senior dev)",
@@ -7702,7 +7703,7 @@
},
"terse-cjk": {
"label": "CJK conciso (文言)",
- "description": "Estilo ultraconciso em chinês clássico (disponível apenas para chinês)."
+ "description": "Estilo ultra-conciso em chinês clássico (disponível apenas para chinês)."
}
},
"resilienceWaitForCooldown": "Aguarde o resfriamento",
@@ -7718,9 +7719,9 @@
"cliproxyapiUrl": "URL CLIProxyAPI",
"cliproxyapiStatus": "Status CLIProxyAPI",
"cliproxyapiNotDetected": "Não detectado",
- "cliproxyapiImportAuthTitle": "Importar contas do CLIProxyAPI",
- "cliproxyapiImportAuthDesc": "Importe as contas OAuth que o CLIProxyAPI já salvou em ~/.cli-proxy-api/ como conexões do OmniRoute, para que você não precise fazer login em cada conta novamente. Os tipos de conta compatíveis (Gemini, Codex, Claude, Antigravity, Qwen, Kimi) são importados; os outros são ignorados.",
- "cliproxyapiImportAuthButton": "Importar contas",
+ "cliproxyapiImportAuthTitle": "__MISSING__:Import accounts from CLIProxyAPI",
+ "cliproxyapiImportAuthDesc": "__MISSING__:Import the OAuth accounts CLIProxyAPI already saved in ~/.cli-proxy-api/ as OmniRoute connections, so you don't have to log in to each account again. Supported account types (Gemini, Codex, Claude, Antigravity, Qwen, Kimi) are imported; others are skipped.",
+ "cliproxyapiImportAuthButton": "__MISSING__:Import accounts",
"payloadRulesTitle": "Regras de carga útil",
"payloadRulesDesc": "Configure mutações de carga útil de solicitação por modelo e protocolo. As alterações são persistidas nas configurações e recarregadas no runtime imediatamente após o salvamento.",
"payloadRuleDefaultTitle": "padrão (default)",
@@ -7753,7 +7754,7 @@
"maxResponseTokensDesc": "Total máximo de tokens permitidos em uma única resposta.",
"modelCooldownsTitle": "Modelos em espera",
"modelCooldownsEmpty": "Nenhum modelo em espera no momento.",
- "modelCooldownsDescription": "Modelos temporariamente isolados após uma falha. Quando o cooldown expirar, eles voltam automaticamente.",
+ "modelCooldownsDescription": "Modelos temporariamente isolados após uma falha. Quando o cooldown expira, eles voltam automaticamente.",
"modelCooldownsLoadFailed": "Falha ao carregar cooldowns",
"modelCooldownReactivated": "Modelo reativado: {model}",
"modelCooldownClearFailed": "Falha ao limpar cooldown",
@@ -7762,14 +7763,14 @@
"modelCooldownsReactivateAll": "Reativar todos",
"modelCooldownsReasonRemaining": "motivo: {reason} • restante: {remaining}",
"modelCooldownsReactivate": "Reativar",
- "responsesStateTitle": "Estado de Responses",
- "responsesStateDesc": "Controle como o OmniRoute encaminha o previous_response_id.",
- "responsesStateModeLabel": "Tratamento de previous_response_id",
- "responsesStateModeAuto": "Auto",
- "responsesStateModeStrip": "Remover",
- "responsesStateModePreserve": "Preservar",
- "responsesStateHint": "Auto remove o previous_response_id a menos que uma conexão habilite explicitamente o armazenamento do OpenAI Responses. Remover é o mais seguro para clientes sem estado, como o VS Code Custom Endpoint; o contexto então depende do envio do histórico completo pelo cliente.",
- "responsesStateSaveError": "Falha ao atualizar a configuração de estado de Responses",
+ "responsesStateTitle": "__MISSING__:Responses State",
+ "responsesStateDesc": "__MISSING__:Control how OmniRoute forwards previous_response_id.",
+ "responsesStateModeLabel": "__MISSING__:previous_response_id handling",
+ "responsesStateModeAuto": "__MISSING__:Auto",
+ "responsesStateModeStrip": "__MISSING__:Strip",
+ "responsesStateModePreserve": "__MISSING__:Preserve",
+ "responsesStateHint": "__MISSING__:Auto strips previous_response_id unless a connection explicitly enables OpenAI Responses storage. Strip is safest for stateless clients such as VS Code Custom Endpoint; context then depends on the client sending full history.",
+ "responsesStateSaveError": "__MISSING__:Failed to update Responses state setting",
"codexFastTierTitle": "Camada rápida do Codex",
"codexFastTierDesc": "Injete globalmente service_tier=priority para solicitações do OpenAI Codex.",
"codexFastTierHint": "Quando habilitado, o OmniRoute adiciona service_tier=priority às solicitações de saída do Codex para conexões que ainda não especificam uma camada. O nível de prioridade requer uma chave de API OpenAI Enterprise ou o caminho ChatGPT-auth Codex; outros tipos de chave receberão um erro relacionado ao nível do OpenAI. As configurações por conexão na página do provedor Codex têm precedência.",
@@ -7888,23 +7889,23 @@
"resilienceEnableServerWaitDesc": "Quando ativado, o OmniRoute aguarda o primeiro resfriamento expirar e tenta novamente automaticamente.",
"resilienceMaxAttempts": "Máximo de tentativas",
"resilienceMaxWaitPerAttempt": "Espera máxima por tentativa",
- "resilienceComboCooldownWaitTitle": "Tempo de espera do cooldown do combo",
- "resilienceComboCooldownWaitDesc": "Para todas as estratégias de combo: aguarde um curto tempo de espera transitório e reenvie em vez de retornar um 429 imediatamente. Nunca aguarda em quota_exhausted.",
- "resilienceComboCooldownWaitToggleDesc": "Todas as estratégias de combo; nunca espera pelo quota_exhausted.",
+ "resilienceComboCooldownWaitTitle": "Espera de cooldown do combo de cota compartilhada",
+ "resilienceComboCooldownWaitDesc": "Somente para combos de cota compartilhada: aguarda um cooldown transitório curto e reenvia em vez de retornar um 429 imediatamente. Nunca espera em quota_exhausted.",
+ "resilienceComboCooldownWaitToggleDesc": "Somente combos de cota compartilhada; nunca espera em quota_exhausted.",
"resilienceComboCooldownMaxWaitMs": "Espera máxima por tentativa",
"resilienceComboCooldownBudgetMs": "Orçamento total de espera",
"resilienceQuotaShareConcurrencyTitle": "Concorrência por conexão de cota compartilhada",
"resilienceQuotaShareConcurrencyDesc": "Somente para combos de cota compartilhada: quando uma conexão define um limite de Concorrência Máxima, serializa as requisições concorrentes para essa conta de assinatura para que nunca seja inundada além do teto. Requisições excedentes esperam na fila em vez de receber um 429. O limite vem do campo Concorrência Máxima de cada conexão; este botão apenas habilita ou desabilita seu respeito.",
"resilienceQuotaShareConcurrencyToggleDesc": "Somente combos de cota compartilhada; respeita o limite de Concorrência Máxima de cada conexão.",
- "resilienceProviderCooldownTitle": "Cooldown do provedor",
- "resilienceProviderCooldownScope": "Todas as requisições combo",
- "resilienceProviderCooldownTrigger": "Quando um provedor/conexão falha",
- "resilienceProviderCooldownEffect": "Ignora o provedor com falha por um período de cooldown antes de tentar novamente",
- "resilienceProviderCooldownDesc": "Evita que requisições subsequentes percorram novamente os mesmos provedores com falha. O cooldown aumenta exponencialmente com falhas consecutivas.",
- "resilienceProviderCooldownEnabled": "Ativar cooldown global de provedores",
- "resilienceProviderCooldownEnabledDesc": "Quando ativado, os provedores com falha são rastreados globalmente e ignorados por um período de cooldown.",
- "resilienceProviderCooldownMin": "Cooldown mínimo",
- "resilienceProviderCooldownMax": "Cooldown máximo",
+ "resilienceProviderCooldownTitle": "__MISSING__:Provider Cooldown",
+ "resilienceProviderCooldownScope": "__MISSING__:All combo requests",
+ "resilienceProviderCooldownTrigger": "__MISSING__:When a provider/connection fails",
+ "resilienceProviderCooldownEffect": "__MISSING__:Skips the failed provider for a cooldown period before retrying",
+ "resilienceProviderCooldownDesc": "__MISSING__:Prevents subsequent requests from re-walking the same failing providers. Cooldown scales exponentially with consecutive failures.",
+ "resilienceProviderCooldownEnabled": "__MISSING__:Enable global provider cooldown",
+ "resilienceProviderCooldownEnabledDesc": "__MISSING__:When enabled, failed providers are tracked globally and skipped for a cooldown period.",
+ "resilienceProviderCooldownMin": "__MISSING__:Minimum cooldown",
+ "resilienceProviderCooldownMax": "__MISSING__:Maximum cooldown",
"forcedFingerprintTitle": "Sempre ativado para {provider} — necessário para a segurança da conta OAuth; não pode ser desativado.",
"forcedFingerprintBadge": "Obrigatório",
"sessionAffinityTitle": "Afinidade de sessão",
@@ -7926,198 +7927,198 @@
"vercelRelayFreeTierNote": "Relays são endpoints de proxy leves implantados no plano gratuito da Vercel para contornar limitações de rede local/região.",
"vercelRelayDeploying": "Implantando...",
"vercelRelayDeploy": "Implantar",
- "deployRelayButton": "Implantar Relay",
- "denoRelayButton": "Implantar Deno Relay",
- "denoRelayModalTitle": "Implantar Deno Relay",
- "denoRelayWarning": "Aviso: É necessário um token de organização do Deno Deploy. Este token será usado apenas para criar o aplicativo de relay e nunca será armazenado pelo OmniRoute.",
- "denoRelayTokenLabel": "Token de organização do Deno Deploy",
- "denoRelayOrgDomainLabel": "Domínio da organização",
- "denoRelayProjectNameLabel": "Nome do aplicativo Deno",
- "denoRelayFreeTierNote": "O Deno Deploy v2 é executado em uma rede edge global. Nível gratuito: 1M de requisições e 100GiB de tráfego de saída por mês, sem limites de CPU por requisição, até 20 aplicativos ativos e 50 domínios personalizados.",
- "denoRelayDeploying": "Implantando...",
- "denoRelayDeploy": "Implantar",
- "cloudflareRelaySuccess": "Cloudflare Relay implantado com sucesso",
- "cloudflareRelayButton": "Implantar Cloudflare Relay",
- "cloudflareRelayModalTitle": "Implantar Cloudflare Worker Relay",
- "cloudflareRelayWarning": "Implanta um Cloudflare Worker que faz proxy de requisições de LLM através da rede edge da Cloudflare — mascarando o IP do host atrás de endereços dinâmicos da Cloudflare. O Worker impõe um segredo de autenticação de uso único para que a URL pública workers.dev não possa ser reutilizada como um relay aberto.",
- "cloudflareRelayTokenHowto": "Crie o token de API em Meu perfil -> Tokens de API -> Criar token -> Token personalizado -> Conta / Scripts do Workers / Editar.",
- "cloudflareRelayAccountIdLabel": "ID da conta Cloudflare",
- "cloudflareRelayAccountIdHint": "Encontrado no lado direito da página de visão geral do painel da Cloudflare.",
- "cloudflareRelayApiTokenLabel": "Token de API da Cloudflare",
- "cloudflareRelayApiTokenHint": "Requer a permissão 'Workers Scripts: Edit'. O token é usado apenas no momento da implantação e nunca é armazenado.",
- "cloudflareRelayProjectNameLabel": "Nome do Worker",
- "cloudflareRelayFreeTierNote": "Plano gratuito: 100.000 requisições/dia por conta Cloudflare.",
- "cloudflareRelayDeploying": "Implantando...",
- "cloudflareRelayDeploy": "Implantar",
- "cloudflareRelayCredsRequired": "O ID da conta e o Token de API são obrigatórios",
- "cloudflareRelayDeployFailed": "Falha na implantação",
- "modelLockout": "Bloqueio de modelo",
- "modelLockoutPageDescription": "Configure quais códigos de erro HTTP acionam o bloqueio por modelo e controle o comportamento do cooldown.",
- "modelLockoutLoadFailed": "Falha ao carregar as configurações de bloqueio de modelo",
- "modelLockoutSaveFailed": "Falha ao salvar as configurações de bloqueio de modelo",
+ "deployRelayButton": "__MISSING__:Deploy Relay",
+ "denoRelayButton": "__MISSING__:Deploy Deno Relay",
+ "denoRelayModalTitle": "__MISSING__:Deploy Deno Relay",
+ "denoRelayWarning": "__MISSING__:Warning: A Deno Deploy organization token is required. This token will only be used to create the relay app and will never be stored by OmniRoute.",
+ "denoRelayTokenLabel": "__MISSING__:Deno Deploy Organization Token",
+ "denoRelayOrgDomainLabel": "__MISSING__:Organization Domain",
+ "denoRelayProjectNameLabel": "__MISSING__:Deno App Name",
+ "denoRelayFreeTierNote": "__MISSING__:Deno Deploy v2 runs on a global edge network. Free tier: 1M requests & 100GiB outbound traffic per month, no per-request CPU limits, up to 20 active apps & 50 custom domains.",
+ "denoRelayDeploying": "__MISSING__:Deploying...",
+ "denoRelayDeploy": "__MISSING__:Deploy",
+ "cloudflareRelaySuccess": "__MISSING__:Cloudflare Relay deployed successfully",
+ "cloudflareRelayButton": "__MISSING__:Deploy Cloudflare Relay",
+ "cloudflareRelayModalTitle": "__MISSING__:Deploy Cloudflare Worker Relay",
+ "cloudflareRelayWarning": "__MISSING__:Deploys a Cloudflare Worker that proxies LLM requests through Cloudflare's edge network — masking the host IP behind dynamic Cloudflare addresses. The Worker enforces a one-time auth secret so the public workers.dev URL cannot be reused as an open relay.",
+ "cloudflareRelayTokenHowto": "__MISSING__:Create the API token under My Profile -> API Tokens -> Create Token -> Custom Token -> Account / Workers Scripts / Edit.",
+ "cloudflareRelayAccountIdLabel": "__MISSING__:Cloudflare Account ID",
+ "cloudflareRelayAccountIdHint": "__MISSING__:Found on the right side of the Cloudflare dashboard overview page.",
+ "cloudflareRelayApiTokenLabel": "__MISSING__:Cloudflare API Token",
+ "cloudflareRelayApiTokenHint": "__MISSING__:Requires 'Workers Scripts: Edit' permission. The token is used only at deploy time and is never stored.",
+ "cloudflareRelayProjectNameLabel": "__MISSING__:Worker Name",
+ "cloudflareRelayFreeTierNote": "__MISSING__:Free tier: 100,000 requests/day per Cloudflare account.",
+ "cloudflareRelayDeploying": "__MISSING__:Deploying...",
+ "cloudflareRelayDeploy": "__MISSING__:Deploy",
+ "cloudflareRelayCredsRequired": "__MISSING__:Account ID and API Token are required",
+ "cloudflareRelayDeployFailed": "__MISSING__:Deploy failed",
+ "modelLockout": "__MISSING__:Model Lockout",
+ "modelLockoutPageDescription": "__MISSING__:Configure which HTTP error codes trigger per-model lockout and control the cooldown behavior.",
+ "modelLockoutLoadFailed": "Falha ao carregar configurações de bloqueio de modelo",
+ "modelLockoutSaveFailed": "Falha ao salvar configurações de bloqueio de modelo",
"modelLockoutLoading": "Carregando configurações de bloqueio de modelo...",
- "modelLockoutBaseRangeError": "O Cooldown base deve estar entre 5.000ms e 600.000ms",
- "modelLockoutMaxRangeError": "O Cooldown máximo deve estar entre 5.000ms e 3.600.000ms",
- "modelLockoutOrderError": "O Cooldown máximo deve ser maior ou igual ao Cooldown base",
- "modelLockoutStepsRangeError": "As Etapas máximas de backoff devem estar entre 0 e 20",
+ "modelLockoutBaseRangeError": "O Cooldown Base deve estar entre 5.000ms e 600.000ms",
+ "modelLockoutMaxRangeError": "O Cooldown Máximo deve estar entre 5.000ms e 3.600.000ms",
+ "modelLockoutOrderError": "O Cooldown Máximo deve ser maior ou igual ao Cooldown Base",
+ "modelLockoutStepsRangeError": "As Etapas Máximas de Backoff devem estar entre 0 e 20",
"removeErrorCode": "Remover {code}",
"addErrorCode": "Adicionar código de erro...",
"suggestions": "Sugestões:",
- "modelLockoutMaxCooldownHint": "≥ Cooldown base — 3.600.000ms",
- "modelLockoutEnabled": "Ativar bloqueio de modelo",
- "modelLockoutEnabledDescription": "Quando ativado, os modelos que falharem com os códigos de erro configurados serão bloqueados temporariamente para evitar loops de repetição.",
- "modelLockoutErrorCodes": "Códigos de erro",
- "modelLockoutErrorCodesDescription": "Códigos de status HTTP que acionam o bloqueio do modelo. Digite um código e clique em Adicionar ou selecione a partir das sugestões.",
- "modelLockoutBaseCooldown": "Cooldown base (ms)",
- "modelLockoutBaseCooldownDescription": "Duração inicial do cooldown em milissegundos antes que uma nova tentativa possa ser feita no modelo.",
- "modelLockoutMaxCooldown": "Cooldown máximo (ms)",
- "modelLockoutMaxCooldownDescription": "Duração máxima do cooldown em milissegundos. Evita bloqueios excessivamente longos.",
- "modelLockoutExponentialBackoff": "Backoff exponencial",
- "modelLockoutExponentialBackoffDescription": "Quando ativado, cada falha consecutiva aumenta a duração do cooldown exponencialmente.",
- "modelLockoutMaxBackoffSteps": "Etapas máximas de backoff",
- "modelLockoutMaxBackoffStepsDescription": "Número máximo de etapas de backoff antes que o cooldown pare de aumentar. O limite do Cooldown máximo é atingido primeiro na maioria das configurações, tornando este um teto de segurança para quando o Cooldown máximo for aumentado.",
+ "modelLockoutMaxCooldownHint": "≥ Cooldown Base — 3.600.000ms",
+ "modelLockoutEnabled": "__MISSING__:Enable Model Lockout",
+ "modelLockoutEnabledDescription": "__MISSING__:When enabled, models that fail with configured error codes are temporarily locked to prevent retry loops.",
+ "modelLockoutErrorCodes": "__MISSING__:Error Codes",
+ "modelLockoutErrorCodesDescription": "__MISSING__:HTTP status codes that trigger model lockout. Type a code and click Add, or select from suggestions.",
+ "modelLockoutBaseCooldown": "__MISSING__:Base Cooldown (ms)",
+ "modelLockoutBaseCooldownDescription": "__MISSING__:Initial cooldown duration in milliseconds before a model can be retried.",
+ "modelLockoutMaxCooldown": "__MISSING__:Max Cooldown (ms)",
+ "modelLockoutMaxCooldownDescription": "__MISSING__:Maximum cooldown duration in milliseconds. Prevents excessively long lockouts.",
+ "modelLockoutExponentialBackoff": "__MISSING__:Exponential Backoff",
+ "modelLockoutExponentialBackoffDescription": "__MISSING__:When enabled, each consecutive failure increases the cooldown duration exponentially.",
+ "modelLockoutMaxBackoffSteps": "__MISSING__:Max Backoff Steps",
+ "modelLockoutMaxBackoffStepsDescription": "__MISSING__:Maximum number of backoff steps before the cooldown stops growing. The Max Cooldown cap is reached first in most configurations, making this a safety ceiling for when Max Cooldown is raised.",
"disableSessionStickiness": "Desabilitar fixação de sessão",
"disableSessionStickinessDesc": "Combos round-robin e aleatórios alternam para uma conexão diferente a cada requisição, em vez de fixar toda a conversa em uma conexão pelo hash da primeira mensagem. Deixe desativado para preservar acertos de cache de prompt em conversas com múltiplos turnos. Sobrescritas por combo têm prioridade.",
"promptCacheAffinity": "Prompt-cache locality routing",
"promptCacheAffinityDesc": "Prefer the same provider account for matching prompt-cache keys while preserving health and quota failover.",
- "credentialRedaction": "Ocultação de credenciais",
- "credentialRedactionDesc": "Oculte chaves de API, tokens e segredos do contexto enviado aos provedores e das respostas.",
- "enableCredentialRedaction": "Ativar ocultação de credenciais",
- "enableCredentialRedactionDesc": "Remove chaves de API, tokens, chaves privadas e JWTs de mensagens, chamadas de ferramentas e respostas.",
+ "credentialRedaction": "__MISSING__:Credential Redaction",
+ "credentialRedactionDesc": "__MISSING__:Redact API keys, tokens, and secrets from context sent to providers and from responses.",
+ "enableCredentialRedaction": "__MISSING__:Enable credential redaction",
+ "enableCredentialRedactionDesc": "__MISSING__:Scrubs API keys, tokens, private keys, and JWTs from messages, tool calls, and responses.",
"pricingAutoSyncDisabled": "Sincronização automática desativada",
"pricingAutoSyncEnabled": "Sincronização automática ativada",
-"modalityBridgeIntro": "Conecte conteúdo multimodal ao texto antes que ele chegue a modelos apenas de texto. A visão está ativa; o áudio chega com o AudioBridge; o vídeo está no roadmap.",
-"modalityBridgeVisionTab": "Visão",
-"modalityBridgeAudioTab": "Áudio",
-"modalityBridgeVideoTab": "Vídeo",
-"modalityBridgeSubTabsAria": "Seções da Ponte de Modalidade",
-"modalityBridgeVisionTitle": "Ponte de Visão",
-"modalityBridgeVisionDesc": "Descreva imagens com um modelo de visão e continue com o modelo de texto escolhido pelo usuário.",
-"modalityBridgeMode": "Modo",
-"modalityBridgeModeAuto": "Automático (recomendado)",
-"modalityBridgeModeAutoHint": "Heurística legada: redirecionar modelos individuais sem credenciais; descreva de outra forma.",
-"modalityBridgeModeDescribe": "Sempre descreva",
-"modalityBridgeModeDescribeHint": "O modelo que você escolheu sempre responde; imagens são substituídas por descrições de texto.",
-"modalityBridgeModeReroute": "Sempre redirecionar",
-"modalityBridgeModeRerouteHint": "Envie toda a solicitação para o melhor modelo com capacidade de visão (retorna para descrever quando nenhum é utilizável).",
-"modalityBridgeVisionModel": "Modelo de Visão",
-"modalityBridgeVisionModelAuto": "Automático (melhor disponível)",
-"modalityBridgeTaskAware": "Descrição ciente da tarefa",
-"modalityBridgeTaskAwareDesc": "Inclua a pergunta do usuário como foco para que o modelo de visão descreva o que importa e transcreva o texto visível.",
-"modalityBridgePrompt": "Prompt de descrição",
-"modalityBridgeAdvanced": "Avançado",
-"modalityBridgeTimeoutMs": "Tempo Limite (ms)",
-"modalityBridgeMaxImages": "Máx. de imagens por solicitação",
-"modalityBridgeCacheEnabled": "Descrições de cache",
-"modalityBridgeCacheEnabledDesc": "Reutilizar descrições para imagens idênticas (chaveadas por SHA-256, em memória).",
-"modalityBridgeCacheTtlMinutes": "Cache TTL (minutos)",
-"modalityBridgeCacheMaxEntries": "Máximo de entradas em cache",
-"modalityBridgeStatsBridged": "conectado",
-"modalityBridgeStatsCacheHits": "acertos de cache",
-"modalityBridgeStatsFailures": "falhas",
-"modalityBridgeStatsLastUsed": "último usado",
-"modalityBridgeStatsNever": "nunca",
-"modalityBridgeTestButton": "Teste com imagem de amostra",
-"modalityBridgeTestRunning": "Testando…",
-"modalityBridgeTestOk": "Bridge OK — {count} imagem(ns) descrita(s) por {model}",
-"modalityBridgeTestReroute": "O Bridge redirecionou a solicitação para {model}",
-"modalityBridgeTestNoop": "A ponte não foi ativada (o modelo pode suportar visão nativamente ou a ponte está desativada)",
-"modalityBridgeTestError": "Teste falhou: {message}",
-"modalityBridgeAudioComingSoon": "A ponte de áudio (fala → texto via /v1/audio/transcriptions) será lançada na próxima versão. As chaves de configuração já estão reservadas.",
-"modalityBridgeVideoComingSoon": "A ponte de vídeo (amostragem de quadros + legendagem) está no backlog — veja a issue #9760.",
-"modalityBridgeMovedTitle": "Vision Bridge movido",
-"modalityBridgeMovedBody": "As configurações do Vision Bridge agora estão na página dedicada do Modality Bridge.",
-"modalityBridgeMovedCta": "Abra as configurações do Modality Bridge",
-"modalityBridgeAudioTitle": "Ponte de Áudio",
-"modalityBridgeAudioDesc": "Transcreva o áudio com um modelo de reconhecimento de fala antes de continuar com o modelo de texto escolhido.",
-"modalityBridgeAudioEnabled": "Ativar Ponte de Áudio",
-"modalityBridgeAudioEnabledDesc": "Substitua as partes de áudio por transcrições quando o modelo de destino não puder processar áudio.",
-"modalityBridgeAudioModel": "Modelo de fala para texto",
-"modalityBridgeAudioModelAuto": "Automático (primeiro provedor STT conectado)",
-"modalityBridgeAudioMaxClips": "Máx. de clipes de áudio por solicitação",
-"modalityBridgeAudioTestButton": "Teste com áudio de amostra",
-"modalityBridgeAudioTestRunning": "Testando áudio…",
-"modalityBridgeAudioTestOk": "Audio Bridge OK — {count} clipe(s) transcrito(s) por {model}",
-"modalityBridgeAudioTestNoop": "O Audio Bridge não foi ativado (o destino pode suportar áudio, nenhum provedor de STT está conectado ou a ponte está desativada)",
-"modalityBridgeAudioTestError": "Teste de áudio falhou: {message}",
-"modelRoutingDescriptionPlaceholder": "__MISSING__:Route Opus models to frontier combo",
-"cliproxyapiFallbackCodes": "__MISSING__:Cliproxyapi Fallback Codes",
-"cliproxyapiFallbackDescription": "__MISSING__:Cliproxyapi Fallback Description",
-"cliproxyapiHealthLabel": "__MISSING__:Cliproxyapi Health Label",
-"cliproxyapiImportFailed": "__MISSING__:Cliproxyapi Import Failed",
-"cliproxyapiImportResult": "__MISSING__:Cliproxyapi Import Result",
-"cliproxyapiInvalidUrl": "__MISSING__:Cliproxyapi Invalid URL",
-"cliproxyapiLifecycleNoticeAfter": "__MISSING__:Cliproxyapi Lifecycle Notice After",
-"cliproxyapiLifecycleNoticeBefore": "__MISSING__:Cliproxyapi Lifecycle Notice Before",
-"cliproxyapiLifecycleNoticeLink": "__MISSING__:Cliproxyapi Lifecycle Notice Link",
-"cliproxyapiPortLabel": "__MISSING__:Cliproxyapi Port Label",
-"cliproxyapiStatusLabel": "__MISSING__:Cliproxyapi Status Label",
-"cliproxyapiVersionLabel": "__MISSING__:Cliproxyapi Version Label",
-"collection": "__MISSING__:Collection",
-"errorPage": {
+ "modalityBridgeIntro": "Conecte conteúdo multimodal ao texto antes que ele chegue a modelos apenas de texto. A visão está ativa; o áudio chega com o AudioBridge; o vídeo está no roadmap.",
+ "modalityBridgeVisionTab": "Visão",
+ "modalityBridgeAudioTab": "Áudio",
+ "modalityBridgeVideoTab": "Vídeo",
+ "modalityBridgeSubTabsAria": "Seções da Ponte de Modalidade",
+ "modalityBridgeVisionTitle": "Ponte de Visão",
+ "modalityBridgeVisionDesc": "Descreva imagens com um modelo de visão e continue com o modelo de texto escolhido pelo usuário.",
+ "modalityBridgeMode": "Modo",
+ "modalityBridgeModeAuto": "Automático (recomendado)",
+ "modalityBridgeModeAutoHint": "Heurística legada: redirecionar modelos individuais sem credenciais; descreva de outra forma.",
+ "modalityBridgeModeDescribe": "Sempre descreva",
+ "modalityBridgeModeDescribeHint": "O modelo que você escolheu sempre responde; imagens são substituídas por descrições de texto.",
+ "modalityBridgeModeReroute": "Sempre redirecionar",
+ "modalityBridgeModeRerouteHint": "Envie toda a solicitação para o melhor modelo com capacidade de visão (retorna para descrever quando nenhum é utilizável).",
+ "modalityBridgeVisionModel": "Modelo de Visão",
+ "modalityBridgeVisionModelAuto": "Automático (melhor disponível)",
+ "modalityBridgeTaskAware": "Descrição ciente da tarefa",
+ "modalityBridgeTaskAwareDesc": "Inclua a pergunta do usuário como foco para que o modelo de visão descreva o que importa e transcreva o texto visível.",
+ "modalityBridgePrompt": "Prompt de descrição",
+ "modalityBridgeAdvanced": "Avançado",
+ "modalityBridgeTimeoutMs": "Tempo Limite (ms)",
+ "modalityBridgeMaxImages": "Máx. de imagens por solicitação",
+ "modalityBridgeCacheEnabled": "Descrições de cache",
+ "modalityBridgeCacheEnabledDesc": "Reutilizar descrições para imagens idênticas (chaveadas por SHA-256, em memória).",
+ "modalityBridgeCacheTtlMinutes": "Cache TTL (minutos)",
+ "modalityBridgeCacheMaxEntries": "Máximo de entradas em cache",
+ "modalityBridgeStatsBridged": "conectado",
+ "modalityBridgeStatsCacheHits": "acertos de cache",
+ "modalityBridgeStatsFailures": "falhas",
+ "modalityBridgeStatsLastUsed": "último usado",
+ "modalityBridgeStatsNever": "nunca",
+ "modalityBridgeTestButton": "Teste com imagem de amostra",
+ "modalityBridgeTestRunning": "Testando…",
+ "modalityBridgeTestOk": "Bridge OK — {count} imagem(ns) descrita(s) por {model}",
+ "modalityBridgeTestReroute": "O Bridge redirecionou a solicitação para {model}",
+ "modalityBridgeTestNoop": "A ponte não foi ativada (o modelo pode suportar visão nativamente ou a ponte está desativada)",
+ "modalityBridgeTestError": "Teste falhou: {message}",
+ "modalityBridgeAudioComingSoon": "A ponte de áudio (fala → texto via /v1/audio/transcriptions) será lançada na próxima versão. As chaves de configuração já estão reservadas.",
+ "modalityBridgeVideoComingSoon": "A ponte de vídeo (amostragem de quadros + legendagem) está no backlog — veja a issue #9760.",
+ "modalityBridgeMovedTitle": "Vision Bridge movido",
+ "modalityBridgeMovedBody": "As configurações do Vision Bridge agora estão na página dedicada do Modality Bridge.",
+ "modalityBridgeMovedCta": "Abra as configurações do Modality Bridge",
+ "modalityBridgeAudioTitle": "Ponte de Áudio",
+ "modalityBridgeAudioDesc": "Transcreva o áudio com um modelo de reconhecimento de fala antes de continuar com o modelo de texto escolhido.",
+ "modalityBridgeAudioEnabled": "Ativar Ponte de Áudio",
+ "modalityBridgeAudioEnabledDesc": "Substitua as partes de áudio por transcrições quando o modelo de destino não puder processar áudio.",
+ "modalityBridgeAudioModel": "Modelo de fala para texto",
+ "modalityBridgeAudioModelAuto": "Automático (primeiro provedor STT conectado)",
+ "modalityBridgeAudioMaxClips": "Máx. de clipes de áudio por solicitação",
+ "modalityBridgeAudioTestButton": "Teste com áudio de amostra",
+ "modalityBridgeAudioTestRunning": "Testando áudio…",
+ "modalityBridgeAudioTestOk": "Audio Bridge OK — {count} clipe(s) transcrito(s) por {model}",
+ "modalityBridgeAudioTestNoop": "O Audio Bridge não foi ativado (o destino pode suportar áudio, nenhum provedor de STT está conectado ou a ponte está desativada)",
+ "modalityBridgeAudioTestError": "Teste de áudio falhou: {message}",
+ "modelRoutingDescriptionPlaceholder": "__MISSING__:Route Opus models to frontier combo",
+ "cliproxyapiFallbackCodes": "__MISSING__:Cliproxyapi Fallback Codes",
+ "cliproxyapiFallbackDescription": "__MISSING__:Cliproxyapi Fallback Description",
+ "cliproxyapiHealthLabel": "__MISSING__:Cliproxyapi Health Label",
+ "cliproxyapiImportFailed": "__MISSING__:Cliproxyapi Import Failed",
+ "cliproxyapiImportResult": "__MISSING__:Cliproxyapi Import Result",
+ "cliproxyapiInvalidUrl": "__MISSING__:Cliproxyapi Invalid URL",
+ "cliproxyapiLifecycleNoticeAfter": "__MISSING__:Cliproxyapi Lifecycle Notice After",
+ "cliproxyapiLifecycleNoticeBefore": "__MISSING__:Cliproxyapi Lifecycle Notice Before",
+ "cliproxyapiLifecycleNoticeLink": "__MISSING__:Cliproxyapi Lifecycle Notice Link",
+ "cliproxyapiPortLabel": "__MISSING__:Cliproxyapi Port Label",
+ "cliproxyapiStatusLabel": "__MISSING__:Cliproxyapi Status Label",
+ "cliproxyapiVersionLabel": "__MISSING__:Cliproxyapi Version Label",
+ "collection": "__MISSING__:Collection",
+ "errorPage": {
"description": "__MISSING__:We could not load settings right now. Please retry in a few seconds.",
"errorId": "__MISSING__:Error ID: {id}",
"retry": "__MISSING__:Try Again",
"title": "__MISSING__:Failed to load settings"
},
-"host": "__MISSING__:Host",
-"notInstalled": "__MISSING__:Not installed",
-"oneproxyActions": "__MISSING__:Oneproxy Actions",
-"oneproxyActive": "__MISSING__:Oneproxy Active",
-"oneproxyAnonymity": "__MISSING__:Oneproxy Anonymity",
-"oneproxyCountry": "__MISSING__:Oneproxy Country",
-"oneproxyDelete": "__MISSING__:Oneproxy Delete",
-"oneproxyEmpty": "__MISSING__:Oneproxy Empty",
-"oneproxyHost": "__MISSING__:Oneproxy Host",
-"oneproxyLatency": "__MISSING__:Oneproxy Latency",
-"oneproxyProtocol": "__MISSING__:Oneproxy Protocol",
-"oneproxyQuality": "__MISSING__:Oneproxy Quality",
-"oneproxySyncFailed": "__MISSING__:Sync failed: {error}",
-"oneproxySyncSuccess": "__MISSING__:Synced {total} proxies ({added} new, {updated} updated)",
-"proxyDocumentationSocks5DescAfter": "__MISSING__:Proxy Documentation Socks5 Desc After",
-"proxyFreePoolAddProxy": "__MISSING__:Proxy Free Pool Add Proxy",
-"proxyFreePoolAdding": "__MISSING__:Proxy Free Pool Adding",
-"proxyFreePoolSelectProxy": "__MISSING__:Proxy Free Pool Select Proxy",
-"proxyStatusActive": "__MISSING__:Proxy Status Active",
-"proxyStatusInactive": "__MISSING__:Proxy Status Inactive",
-"routingAddEntry": "__MISSING__:Add entry",
-"settingSaveFailed": "__MISSING__:Setting Save Failed",
-"settingSaved": "__MISSING__:Setting Saved",
-"skillsmpApiKeyHintAfter": "__MISSING__:. Rate limit: {limit} requests/day.",
-"skillsmpApiKeyHintBefore": "__MISSING__:Get your API key from",
-"syncFailed": "__MISSING__:Sync failed",
-"unhealthy": "__MISSING__:Unhealthy",
-"oneproxyDescription": "__MISSING__:Fetch and rotate free validated proxies from the 1proxy community platform",
-"oneproxySyncing": "__MISSING__:Syncing...",
-"oneproxySyncNow": "__MISSING__:Sync Now",
-"oneproxyClearAll": "__MISSING__:Clear All",
-"oneproxyGoogle": "Google",
-"oneproxyClearAllConfirm": "__MISSING__:Clear all 1proxy proxies?",
-"memorySkillsSkillsmpDescription": "__MISSING__:Connect to SkillsMP to discover and install skills from the marketplace.",
-"memorySkillsActiveProviderDescription": "__MISSING__:Choose which provider the Skills page uses for search and install.",
-"memorySkillsSkillsmpProviderTitle": "__MISSING__:SkillsMP Marketplace",
-"memorySkillsSkillsmpProviderDescription": "__MISSING__:Authenticated marketplace (uses your SkillsMP API key).",
-"memorySkillsSkillsshProviderTitle": "__MISSING__:skills.sh Directory",
-"memorySkillsSkillsshProviderDescription": "__MISSING__:Public directory provider (no API key required).",
-"routingCcBridgeCatalogName": "__MISSING__:Anthropic-compatible CC bridge",
-"routingClaudeProviderName": "__MISSING__:Claude (OAuth)",
-"routingClaudeProviderDescription": "__MISSING__:Native Claude provider with OAuth-issued tokens.",
-"routingCcBridgeName": "__MISSING__:Claude-Code Bridge",
-"routingCcBridgeDescription": "__MISSING__:Relay endpoints using API keys (anthropic-compatible-cc-*).",
-"routingCustomProviderDescription": "__MISSING__:Custom provider.",
-"routingUnknownOpKind": "__MISSING__:Unknown op kind: {kind}",
-"routingInvalidJson": "__MISSING__:Invalid JSON: {error}",
-"routingConfigMustBeObject": "__MISSING__:Config must be a JSON object",
-"routingEnabledMustBeBoolean": "__MISSING__:`enabled` must be true or false",
-"routingPipelineMustBeArray": "__MISSING__:`pipeline` must be an array of ops",
-"routingPipelineTooLong": "__MISSING__:Pipeline cannot exceed 50 ops",
-"routingOpMissingKind": "__MISSING__:Op #{index}: missing or invalid `kind`",
-"routingOpUnknownKind": "__MISSING__:Op #{index}: unknown kind \"{kind}\"",
-"routingJsonEditorHide": "__MISSING__:Hide JSON editor",
-"routingJsonEditorImportExport": "__MISSING__:Import / export JSON",
-"routingJsonEditorLabel": "__MISSING__:JSON (edit and apply, or paste to import)",
-"routingApplyJson": "__MISSING__:Apply JSON",
-"routingTransformsFootnote": "__MISSING__:All transform ops are idempotent on re-run. Changes take effect immediately on the next request."
+ "host": "__MISSING__:Host",
+ "notInstalled": "__MISSING__:Not installed",
+ "oneproxyActions": "__MISSING__:Oneproxy Actions",
+ "oneproxyActive": "__MISSING__:Oneproxy Active",
+ "oneproxyAnonymity": "__MISSING__:Oneproxy Anonymity",
+ "oneproxyCountry": "__MISSING__:Oneproxy Country",
+ "oneproxyDelete": "__MISSING__:Oneproxy Delete",
+ "oneproxyEmpty": "__MISSING__:Oneproxy Empty",
+ "oneproxyHost": "__MISSING__:Oneproxy Host",
+ "oneproxyLatency": "__MISSING__:Oneproxy Latency",
+ "oneproxyProtocol": "__MISSING__:Oneproxy Protocol",
+ "oneproxyQuality": "__MISSING__:Oneproxy Quality",
+ "oneproxySyncFailed": "__MISSING__:Sync failed: {error}",
+ "oneproxySyncSuccess": "__MISSING__:Synced {total} proxies ({added} new, {updated} updated)",
+ "proxyDocumentationSocks5DescAfter": "__MISSING__:Proxy Documentation Socks5 Desc After",
+ "proxyFreePoolAddProxy": "__MISSING__:Proxy Free Pool Add Proxy",
+ "proxyFreePoolAdding": "__MISSING__:Proxy Free Pool Adding",
+ "proxyFreePoolSelectProxy": "__MISSING__:Proxy Free Pool Select Proxy",
+ "proxyStatusActive": "__MISSING__:Proxy Status Active",
+ "proxyStatusInactive": "__MISSING__:Proxy Status Inactive",
+ "routingAddEntry": "__MISSING__:Add entry",
+ "settingSaveFailed": "__MISSING__:Setting Save Failed",
+ "settingSaved": "__MISSING__:Setting Saved",
+ "skillsmpApiKeyHintAfter": "__MISSING__:. Rate limit: {limit} requests/day.",
+ "skillsmpApiKeyHintBefore": "__MISSING__:Get your API key from",
+ "syncFailed": "__MISSING__:Sync failed",
+ "unhealthy": "__MISSING__:Unhealthy",
+ "oneproxyDescription": "__MISSING__:Fetch and rotate free validated proxies from the 1proxy community platform",
+ "oneproxySyncing": "__MISSING__:Syncing...",
+ "oneproxySyncNow": "__MISSING__:Sync Now",
+ "oneproxyClearAll": "__MISSING__:Clear All",
+ "oneproxyGoogle": "Google",
+ "oneproxyClearAllConfirm": "__MISSING__:Clear all 1proxy proxies?",
+ "memorySkillsSkillsmpDescription": "__MISSING__:Connect to SkillsMP to discover and install skills from the marketplace.",
+ "memorySkillsActiveProviderDescription": "__MISSING__:Choose which provider the Skills page uses for search and install.",
+ "memorySkillsSkillsmpProviderTitle": "__MISSING__:SkillsMP Marketplace",
+ "memorySkillsSkillsmpProviderDescription": "__MISSING__:Authenticated marketplace (uses your SkillsMP API key).",
+ "memorySkillsSkillsshProviderTitle": "__MISSING__:skills.sh Directory",
+ "memorySkillsSkillsshProviderDescription": "__MISSING__:Public directory provider (no API key required).",
+ "routingCcBridgeCatalogName": "__MISSING__:Anthropic-compatible CC bridge",
+ "routingClaudeProviderName": "__MISSING__:Claude (OAuth)",
+ "routingClaudeProviderDescription": "__MISSING__:Native Claude provider with OAuth-issued tokens.",
+ "routingCcBridgeName": "__MISSING__:Claude-Code Bridge",
+ "routingCcBridgeDescription": "__MISSING__:Relay endpoints using API keys (anthropic-compatible-cc-*).",
+ "routingCustomProviderDescription": "__MISSING__:Custom provider.",
+ "routingUnknownOpKind": "__MISSING__:Unknown op kind: {kind}",
+ "routingInvalidJson": "__MISSING__:Invalid JSON: {error}",
+ "routingConfigMustBeObject": "__MISSING__:Config must be a JSON object",
+ "routingEnabledMustBeBoolean": "__MISSING__:`enabled` must be true or false",
+ "routingPipelineMustBeArray": "__MISSING__:`pipeline` must be an array of ops",
+ "routingPipelineTooLong": "__MISSING__:Pipeline cannot exceed 50 ops",
+ "routingOpMissingKind": "__MISSING__:Op #{index}: missing or invalid `kind`",
+ "routingOpUnknownKind": "__MISSING__:Op #{index}: unknown kind \"{kind}\"",
+ "routingJsonEditorHide": "__MISSING__:Hide JSON editor",
+ "routingJsonEditorImportExport": "__MISSING__:Import / export JSON",
+ "routingJsonEditorLabel": "__MISSING__:JSON (edit and apply, or paste to import)",
+ "routingApplyJson": "__MISSING__:Apply JSON",
+ "routingTransformsFootnote": "__MISSING__:All transform ops are idempotent on re-run. Changes take effect immediately on the next request."
},
"contextRtk": {
"title": "Motor RTK",
@@ -8169,20 +8170,20 @@
"tooltipDedup": "Quão agressivamente remover linhas repetidas.",
"tooltipMaxChars": "Máximo de caracteres por bloco de saída.",
"tooltipMaxLines": "Máximo de linhas a serem mantidas na saída do comando. O excesso é truncado.",
- "learnDiscoverTitle": "Aprender & Descobrir filtros",
- "learnDiscoverDesc": "Mine a saída de comando capturada (a retenção de Raw Output deve estar ativada) para sugerir novos filtros RTK. Apenas sugestões — você as revisa e salva.",
- "discoverHeading": "Descobrir ruído repetido",
- "discoverButton": "Escanear amostras",
- "discoverScanning": "Escaneando…",
- "discoverEmpty": "Nenhum ruído repetido encontrado. Ative a retenção de Raw Output e execute alguns comandos primeiro.",
- "discoverSamples": "{count} amostra(s) escaneada(s)",
- "discoverHits": "{hits}× nas amostras",
- "learnHeading": "Aprender um filtro para um comando",
- "learnCommandPlaceholder": "ex.: npm install",
- "learnButton": "Sugerir filtro",
- "learnEmpty": "Nenhuma sugestão ainda. Digite um comando que você executou e escaneie.",
- "learnSamplesUsed": "Aprendido a partir de {count} amostra(s) correspondente(s)",
- "suggestionError": "Não foi possível carregar as sugestões. Verifique a autenticação de gerenciamento e tente novamente.",
+ "learnDiscoverTitle": "__MISSING__:Learn & Discover filters",
+ "learnDiscoverDesc": "__MISSING__:Mine your captured command output (Raw Output retention must be on) to suggest new RTK filters. Suggestions only — you review and save them.",
+ "discoverHeading": "__MISSING__:Discover repeated noise",
+ "discoverButton": "__MISSING__:Scan samples",
+ "discoverScanning": "__MISSING__:Scanning…",
+ "discoverEmpty": "__MISSING__:No repeated noise found. Enable Raw Output retention and run a few commands first.",
+ "discoverSamples": "__MISSING__:{count} sample(s) scanned",
+ "discoverHits": "__MISSING__:{hits}× across samples",
+ "learnHeading": "__MISSING__:Learn a filter for a command",
+ "learnCommandPlaceholder": "__MISSING__:e.g. npm install",
+ "learnButton": "__MISSING__:Suggest filter",
+ "learnEmpty": "__MISSING__:No suggestion yet. Type a command you have run and scan.",
+ "learnSamplesUsed": "__MISSING__:Learned from {count} matching sample(s)",
+ "suggestionError": "__MISSING__:Could not load suggestions. Check management auth and try again.",
"tomlImportTitle": "Importar filtros TOML do RTK",
"tomlImportDesc": "Valide os filtros do esquema TOML v1 do RTK e instale-os globalmente. A instalação grava em DATA_DIR/rtk/filters.toml; arquivos existentes só são substituídos após confirmação explícita.",
"tomlChooseFile": "Escolher um arquivo TOML",
@@ -8205,22 +8206,22 @@
},
"compressionEngineConfig": {
"loading": "Carregando…",
- "loadFailed": "Falha ao carregar as informações do mecanismo.",
- "engineNotFound": "Mecanismo \"{engine}\" não encontrado.",
- "saveFailed": "Falha ao salvar a configuração.",
+ "loadFailed": "Falha ao carregar informações da engine.",
+ "engineNotFound": "Engine \"{engine}\" não encontrada.",
+ "saveFailed": "Falha ao salvar configuração.",
"previewFailed": "Falha na pré-visualização.",
"panelPointerPrefix": "Ative ou desative esta camada e defina seu nível em",
- "compressionSettings": "Configurações de compressão",
+ "compressionSettings": "Compression Settings",
"panelPointerSuffix": ". Esta página edita apenas sua configuração detalhada.",
- "configuration": "Configuração",
+ "configuration": "Configuration",
"noAdditionalConfiguration": "Nenhuma configuração adicional.",
"save": "Salvar",
"saving": "Salvando…",
- "globalSettingsOnly": "Esta camada é configurada pelas configurações globais; ainda não há substituição por mecanismo para salvar aqui.",
- "preview": "Pré-visualização",
- "previewInput": "Entrada da pré-visualização",
+ "globalSettingsOnly": "Esta camada é configurada pelas configurações globais; ainda não há substituição por engine para salvar aqui.",
+ "preview": "Visualização",
+ "previewInput": "Entrada de pré-visualização",
"processing": "Processando…",
- "previewSample": "A rápida raposa marrom salta sobre o cão preguiçoso. Esta é uma mensagem de exemplo usada para pré-visualizar a compressão. Ela contém texto suficiente para mostrar uma economia significativa de tokens.",
+ "previewSample": "The quick brown fox jumps over the lazy dog. Esta é uma mensagem de exemplo usada para pré-visualizar a compressão. Ela contém texto suficiente para mostrar uma economia de tokens significativa.",
"originalTokens": "Tokens originais",
"compressedTokens": "Tokens comprimidos",
"savings": "Economia",
@@ -8228,9 +8229,9 @@
"compressed": "Comprimido",
"diff": "Diff",
"last7Days": "Últimos 7 dias",
- "noDataYet": "Nenhum dado ainda",
+ "noDataYet": "Sem dados ainda",
"runs": "Execuções",
- "tokensSaved": "Tokens economizados",
+ "tokensSaved": "Tokens salvos",
"averageSavings": "Economia média",
"diffLabels": {
"change": "Alteração",
@@ -8244,7 +8245,7 @@
"description": "Compactação tabular sem perdas de arrays JSON homogêneos com marcadores explícitos de contagem de linhas."
},
"session-dedup": {
- "name": "Deduplicação de sessão",
+ "name": "Session Dedup",
"description": "Deduplicação de blocos entre turnos com marcadores de conteúdo recuperáveis."
},
"ccr": {
@@ -8252,44 +8253,44 @@
"description": "Marcadores de recuperação endereçados por conteúdo para blocos de contexto repetidos."
},
"llmlingua": {
- "name": "LLMLingua-2 (Poda semântica)",
- "description": "Classificação semântica de tokens baseada em ONNX. Comprime apenas prosa; blocos de código e construções preservadas são protegidos. Falha em modo aberto em caso de erros de modelo ou worker."
+ "name": "LLMLingua-2 (Poda Semântica)",
+ "description": "Classificação semântica de tokens baseada em ONNX. Comprime apenas prosa; blocos de código e construções preservadas são protegidos. Falha aberta em caso de erros de modelo ou worker."
},
"lite": {
- "name": "Leve",
- "description": "Redução rápida de espaços em branco, resultados de ferramentas e URLs de imagens."
+ "name": "Lite",
+ "description": "Redução rápida de espaços em branco, resultados de ferramentas e URLs de imagem."
},
"aggressive": {
- "name": "Agressivo",
- "description": "Sumarização, compressão de resultados de ferramentas e envelhecimento progressivo."
+ "name": "Aggressive",
+ "description": "Resumo, compressão de resultados de ferramentas e envelhecimento progressivo."
},
"ultra": {
"name": "Ultra",
- "description": "Poda heurística de tokens com fallback opcional para SLM local."
+ "description": "Poda heurística de tokens com fallback opcional para um SLM local."
}
},
"fields": {
"minBlockChars": {
- "label": "Mínimo de caracteres do bloco",
- "description": "Contagem mínima de caracteres para que um bloco de sufixo seja um candidato à deduplicação."
+ "label": "Caracteres mínimos por bloco",
+ "description": "Contagem mínima de caracteres para que um bloco de sufixo seja candidato à deduplicação."
},
"fuzzy": {
- "label": "Deduplicação difusa de quase duplicados",
- "description": "Ative para substituir mensagens inteiras que sejam pelo menos cerca de 85% semelhantes a uma mensagem anterior por um marcador CCR recuperável."
+ "label": "Deduplicação difusa de quase-duplicatas",
+ "description": "Opte por substituir mensagens inteiras com pelo menos cerca de 85% de similaridade a uma mensagem anterior por um marcador CCR recuperável."
},
"minChars": {
- "label": "Mínimo de caracteres do bloco",
- "description": "Contagem mínima de caracteres para que um bloco seja um candidato a CCR."
+ "label": "Caracteres mínimos por bloco",
+ "description": "Contagem mínima de caracteres para que um bloco seja candidato a CCR."
},
"retrievalRampFactor": {
"label": "Fator de rampa de recuperação (H8)",
- "description": "Controla com que intensidade blocos recuperados frequentemente resistem à compressão. Cada recuperação anterior aumenta o tamanho mínimo efetivo do bloco linearmente; 1 desativa a rampa."
+ "description": "Controla o quanto blocos recuperados com frequência resistem à compressão. Cada recuperação anterior aumenta linearmente o tamanho mínimo efetivo do bloco; 1 desativa a rampa."
},
"model": {
"label": "Modelo"
},
"minTokens": {
- "label": "Mínimo de tokens (piso)"
+ "label": "Tokens mínimos (piso)"
},
"compressionRate": {
"label": "Taxa de compressão"
@@ -8298,14 +8299,14 @@
"label": "Caminho do modelo"
},
"minRows": {
- "label": "Mínimo de linhas para compactar",
- "description": "Mínimo de linhas em um array JSON homogêneo necessárias para acionar a compactação tabular. Padrão: 8."
+ "label": "Linhas mínimas para compactar",
+ "description": "Número mínimo de linhas em um array JSON homogêneo necessário para acionar a compactação tabular. Padrão: 8."
},
"preserveSystemPrompt": {
- "label": "Preservar prompt do sistema"
+ "label": "Preservar prompt de sistema"
},
"summarizerEnabled": {
- "label": "Ativar sumarizador"
+ "label": "Ativar resumidor"
},
"maxTokensPerMessage": {
"label": "Máximo de tokens por mensagem"
@@ -8317,7 +8318,7 @@
"label": "Limite mínimo de pontuação"
},
"slmFallbackToAggressive": {
- "label": "Recorrer ao Agressivo"
+ "label": "Recorrer ao modo Aggressive"
},
"intensity": {
"label": "Intensidade"
@@ -8333,10 +8334,10 @@
"engineFields": {
"llmlingua": {
"compressionRate": {
- "label": "Taxa de compressão (proporção a manter)"
+ "label": "Taxa de compressão (proporção de retenção)"
},
"modelPath": {
- "label": "Caminho do modelo (sobrescrever offline)"
+ "label": "Caminho do modelo (substituição offline)"
}
}
},
@@ -8347,7 +8348,7 @@
},
"intensity": {
"lite": "Lite",
- "full": "Completo",
+ "full": "Completa",
"ultra": "Ultra"
}
},
@@ -8384,63 +8385,63 @@
"enabled": "Ativo",
"loading": "Carregando…",
"hubTitle": "Hub de Compressão",
- "hubDescription": "Escolha qual perfil de compressão será executado globalmente.",
+ "hubDescription": "Escolha qual perfil de compressão é executado globalmente.",
"hideExplanation": "Ocultar explicação",
"howItWorks": "Como funciona",
- "saveSettingsFailed": "Falha ao salvar as configurações.",
- "explanationIntro": "A compressão reduz tokens e custos reescrevendo o histórico antes de ser enviado ao provedor, preservando o significado.",
- "explanationActiveProfile": "Perfil ativo: escolhe qual perfil de compressão é executado globalmente — o Padrão derivado do painel ou uma de suas combinações nomeadas salvas.",
- "explanationDefault": "Padrão (do painel): derivado da chave mestra e das alternâncias por mecanismo que você configura nas Configurações de Compressão.",
- "explanationNamedCombos": "Combinações nomeadas: pipelines salvos que você cria no editor de combinações nomeadas. Selecionar um o torna o perfil ativo para cada solicitação.",
- "explanationPreview": "Visualização: mostra quais mecanismos o perfil ativo executa, em ordem.",
+ "saveSettingsFailed": "Falha ao salvar configurações.",
+ "explanationIntro": "A compressão reduz tokens e custo reescrevendo o histórico antes de enviá-lo ao provedor, preservando o significado.",
+ "explanationActiveProfile": "Perfil ativo: escolhe qual perfil de compressão é executado globalmente — o Padrão derivado do painel ou um dos seus combos nomeados salvos.",
+ "explanationDefault": "Padrão (do painel): derivado do interruptor mestre e das alternâncias por engine que você configura em Configurações de Compressão.",
+ "explanationNamedCombos": "Combos nomeados: pipelines salvos que você cria no editor de combos nomeados. Selecionar um o torna o perfil ativo para cada solicitação.",
+ "explanationPreview": "Pré-visualização: mostra quais engines o perfil ativo executa, em ordem.",
"activeProfile": "Perfil ativo",
- "activeProfileDescription": "Escolha qual perfil de compressão é executado globalmente — o Padrão derivado do painel ou uma combinação nomeada salva.",
+ "activeProfileDescription": "Escolha qual perfil de compressão é executado globalmente — o Padrão derivado do painel ou um combo nomeado salvo.",
"defaultFromPanel": "Padrão (do painel)",
"runs": "Executa:",
"defaultConfiguredPrefix": "Padrão — configurado em",
- "compressionSettings": "Configurações de Compressão",
+ "compressionSettings": "Compression Settings",
"providerDelegated": "Compressão delegada ao provedor",
"contextEditingClaude": "Edição de Contexto (Claude)",
"contextEditingDescription": "Permite que o provedor limpe blocos antigos de uso de ferramentas no lado do servidor, sem reescrever a mensagem.",
"contextEditingAria": "Edição de Contexto",
- "contextEditingNote": "Atualmente disponível apenas para o Claude (Anthropic). É um modo delegado: o provedor limpa blocos antigos de uso de ferramentas no lado do servidor — nós não reescrevemos a mensagem. Não afeta outros provedores.",
- "namedCombos": "Combinações nomeadas",
- "namedCombosDescription": "Salve pipelines diferentes e atribua-os a combinações de roteamento específicas.",
- "comboNamePlaceholder": "Nome da combinação",
- "descriptionPlaceholder": "Descrição",
- "nameRequired": "Insira um nome para a combinação antes de salvar.",
+ "contextEditingNote": "Atualmente disponível apenas para Claude (Anthropic). É um modo delegado: o provedor limpa blocos antigos de uso de ferramentas no lado do servidor — não reescrevemos a mensagem. Não afeta outros provedores.",
+ "namedCombos": "Combos nomeados",
+ "namedCombosDescription": "Salve pipelines diferentes e atribua-os a combos de roteamento específicos.",
+ "comboNamePlaceholder": "Nome do combo",
+ "descriptionPlaceholder": "Description",
+ "nameRequired": "Digite um nome de combo antes de salvar.",
"pipelineRequired": "Adicione pelo menos uma etapa de pipeline antes de salvar.",
- "saveComboFailed": "Falha ao salvar a combinação (HTTP {status}).",
- "deleteNamedConfirm": "Excluir combinação “{name}”?",
+ "saveComboFailed": "Falha ao salvar combo (HTTP {status}).",
+ "deleteNamedConfirm": "Excluir combo “{name}”?",
"intensityLite": "Lite",
- "intensityFull": "Completo",
+ "intensityFull": "Completa",
"intensityUltra": "Ultra",
"active": "Ativo",
"languagePacksList": "Pacotes de idioma: {packs}",
"dragToReorder": "Arraste para reordenar a etapa",
- "engine": "Mecanismo",
+ "engine": "Engine",
"intensity": "Intensidade"
},
"compressionStudio": {
"noRun": "Nenhuma execução de compressão disponível.",
- "liveDataHint": "Os dados em tempo real chegam pelo canal de compressão WebSocket.",
- "cockpitView": "Visualização do cockpit",
+ "liveDataHint": "Os dados em tempo real chegam pelo canal de compressão via WebSocket.",
+ "cockpitView": "Visão de cockpit",
"canvas": "Canvas",
- "waterfall": "Cascata",
+ "waterfall": "Waterfall",
"replayDone": "Replay concluído",
"pauseReplay": "Pausar replay",
"playReplay": "Reproduzir replay",
"pause": "Pausar",
"replay": "Replay",
- "resetReplay": "Reiniciar replay",
+ "resetReplay": "Redefinir replay",
"stepProgress": "etapa {current}/{total}",
"inlineView": "Inline",
- "splitComingSoon": "Visualização dividida (em breve)",
+ "splitComingSoon": "Visão dividida (em breve)",
"inputPlaceholder": "Cole um prompt, saída de ferramenta ou contexto…",
"activeCombined": "Ativo no fluxo combinado",
"requiresOnnx": "requer um modelo ONNX",
"verifyFidelity": "Verificar fidelidade (rejeitar qualquer camada que corrompa o conteúdo)",
- "fuzzyDedup": "Deduplicação difusa (quase duplicado → CCR)",
+ "fuzzyDedup": "Deduplicação difusa (quase-duplicata → CCR)",
"protectSensitive": "Proteger conteúdo sensível (gate de risco)",
"quantumLock": "QuantumLock (estabilizar o prefixo do cache)",
"saliencyHeatmap": "Mapa de calor de saliência",
@@ -8452,86 +8453,86 @@
"eachLayer": "Cada camada separadamente",
"diff": "Diferença",
"combined": "combinado",
- "skipped": "pular",
+ "skipped": "ignorado",
"input": "ENTRADA",
"output": "SAÍDA",
"tokenCount": "{count, number} tokens",
"tokenShort": "tok",
"provider": "Provedor",
- "judgeModel": "Modelo juiz",
+ "judgeModel": "Modelo julgador",
"judgeModelPlaceholder": "ex.: claude-haiku",
- "maxCostUsd": "Limite em USD",
- "enterJudgeModel": "Insira um modelo juiz",
+ "maxCostUsd": "Teto em USD",
+ "enterJudgeModel": "Informe um modelo juiz",
"verifying": "Verificando…",
- "verifyAll": "Verificar todos",
+ "verifyAll": "Verificar tudo",
"spent": "gasto ${spent} / ${cap}",
- "capReached": "limite atingido",
+ "capReached": "teto atingido",
"loadAb": "Carregar A/B",
- "engine": "Motor",
+ "engine": "Engine",
"savings": "Economia",
"retention": "Retenção",
"outputTokensShort": "Tokens de saída",
"fidelity": "Fidelidade",
- "playTab": "Executar",
+ "playTab": "Reproduzir",
"compareTab": "Comparar",
- "encoderComparison": "Codificador A/B — {count} array(s)",
+ "encoderComparison": "Encoder A/B — {count} array(s)",
"encoderWinner": "vencedor: {winner}",
- "encoder": "codificador",
+ "encoder": "encoder",
"bytes": "bytes",
"tokensCl100k": "tokens (cl100k)"
},
"omniglyph": {
"preview": "Visualização",
- "description": "Compressão de contexto como imagem. Renderiza o prompt do sistema, a documentação da ferramenta e o histórico denso como páginas PNG compactas que o Claude Fable 5 lê em vez de texto. Os tokens de imagem são cobrados por dimensões em vez de caracteres, portanto, o bloco convertido custa cerca de 10× menos. Apenas rota direta da Anthropic.",
- "economicsTitle": "Aspectos econômicos",
+ "description": "Compressão de contexto como imagem. Renderiza o prompt de sistema, a documentação de ferramentas e o histórico denso como páginas PNG compactas que o Claude Fable 5 lê em vez de texto. Os tokens de imagem são cobrados por dimensões em vez de caracteres, então o bloco convertido custa cerca de 10× menos. Somente na rota direta da Anthropic.",
+ "economicsTitle": "A economia",
"economics": {
"fewerTokens": "menos tokens no bloco convertido",
"savings": "economia de ponta a ponta (medida)",
- "imageTokens": "tokens de imagem para uma página de 1568×728 (cerca de 28k caracteres)",
+ "imageTokens": "tokens de imagem para uma página de 1568×728 (cerca de 28 mil caracteres)",
"accuracy": "precisão de leitura no Fable 5 (n=30)"
},
"beforeAfterTitle": "Antes → depois",
- "blockSavings": "−{percent}% tokens neste bloco",
- "realRender": "Uma renderização real de {characters, number} caracteres de documentação densa de ferramentas — não um mockup.",
+ "blockSavings": "−{percent}% de tokens neste bloco",
+ "realRender": "Uma renderização real de {characters, number} caracteres de documentação densa de ferramentas — não é um mockup.",
"textTokens": "Texto · ≈ {tokens, number} tokens",
"renderedTokens": "Página renderizada · ≈ {tokens, number} tokens",
"renderedImageAlt": "Página densa renderizada, {width}×{height}px",
"gatesTitle": "Quando é acionado",
- "gatesDescription": "Falha fechada: todos os gates devem passar, ou a requisição passa inalterada (cada desvio é registrado como skip:<reason>).",
+ "gatesDescription": "Fail-closed: todo gate precisa passar, ou a solicitação passa intacta (cada omissão é registrada como skip:<reason>).",
"gates": {
"model": {
"label": "Modelo",
"pass": "claude-fable-5",
- "why": "Apenas o Fable 5 lê páginas densas com 100% de precisão (medido, n=30). GPT-5.5 e Gemini 2.5 Flash estão bloqueados."
+ "why": "Somente o Fable 5 lê páginas densas com 100% de precisão (medido, n=30). GPT-5.5 e Gemini 2.5 Flash são bloqueados."
},
"transport": {
"label": "Transporte",
- "pass": "Anthropic direto",
- "why": "Agregadores reamostram imagens e destroem a legibilidade — apenas a rota direta é autoritativa."
+ "pass": "direto Anthropic",
+ "why": "Agregadores reamostram imagens e destroem a legibilidade — apenas a rota direta é confiável."
},
"format": {
"label": "Formato",
"pass": "Claude nativo",
- "why": "O corpo deve usar o formato Claude e nunca deve colocar uma função de sistema dentro das mensagens."
+ "why": "O corpo deve usar o formato Claude e nunca colocar um papel system dentro de messages."
},
"profitable": {
- "label": "Lucrativo",
+ "label": "Rentável",
"pass": "denso o suficiente",
- "why": "O limite de custo exato do patch de 28px decide por solicitação; textos pequenos ou esparsos passam sem alterações."
+ "why": "O gate exato de custo por patch de 28px decide por solicitação; texto pequeno ou esparso passa intacto."
}
},
- "enableTitle": "Habilitar o mecanismo",
- "enableDescription": "Executa por último na pilha (após o RTK/Caveman limpar o texto, o OmniGlyph converte o restante em imagens) e também executa de forma autônoma através do modo omniglyph. Esta é uma prévia e permanece desativada por padrão até que a validação de ponta a ponta seja concluída.",
+ "enableTitle": "Ativar a engine",
+ "enableDescription": "Executa por último na pilha (depois que RTK/Caveman limpa o texto, o OmniGlyph converte o restante em imagens) e também roda de forma independente pelo modo omniglyph. Este é um preview e permanece desativado por padrão até que a validação de ponta a ponta seja concluída.",
"saved": "Salvo.",
"saveFailed": "Não foi possível salvar.",
- "enableAria": "Habilitar o mecanismo OmniGlyph"
+ "enableAria": "Ativar a engine OmniGlyph"
},
"embeddedServices": {
- "title": "Serviços incorporados",
- "description": "Mecanismos locais gerenciados sob demanda — CLIProxyAPI, 9Router, Mux e Bifrost. Acessíveis apenas em loopback.",
- "stateRunning": "Em execução",
- "stateStopped": "Parado",
- "stateStarting": "Iniciando",
+ "title": "Serviços Embarcados",
+ "description": "Engines locais gerenciadas sob demanda — CLIProxyAPI, 9Router, Mux e Bifrost. Acessíveis apenas via loopback.",
+ "stateRunning": "Running",
+ "stateStopped": "Stopped",
+ "stateStarting": "Starting",
"stateStopping": "Parando",
"stateError": "Erro",
"stateNotInstalled": "Não instalado",
@@ -8539,10 +8540,10 @@
"port": "porta {port}",
"externalBadge": "Gerenciado externamente",
"externalTitle": "9Router externo detectado",
- "externalDescription": "O OmniRoute encontrou o 9Router em {host}:{port}. Seu ciclo de vida, logs, atualizações e chave de serviço permanecem gerenciados pela instalação externa.",
- "start": "Iniciar",
+ "externalDescription": "O OmniRoute encontrou o 9Router em {host}:{port}. Seu ciclo de vida, logs, atualizações e chave de serviço continuam gerenciados pela instalação externa.",
+ "start": "Início",
"starting": "Iniciando…",
- "stop": "Parar",
+ "stop": "Pare",
"stopping": "Parando…",
"restart": "Reiniciar",
"restarting": "Reiniciando…",
@@ -8550,33 +8551,33 @@
"updating": "Atualizando…",
"install": "Instalar",
"installing": "Instalando…",
- "autoStart": "Iniciar automaticamente",
- "autoStartDescription": "Iniciar {name} automaticamente quando o OmniRoute iniciar",
+ "autoStart": "Início automático",
+ "autoStartDescription": "Inicia {name} automaticamente quando o OmniRoute é iniciado",
"apiKey": "Chave de API",
- "apiKeyDescription": "Chave usada pelo OmniRoute para se autenticar com o {name}",
- "keyRotated": "Chave rotacionada — {name} reiniciado para aplicar a nova chave",
+ "apiKeyDescription": "Chave usada pelo OmniRoute para autenticar com {name}",
+ "keyRotated": "Chave rotacionada — {name} foi reiniciado para aplicar a nova chave",
"keyRotateFailed": "Falha ao rotacionar a chave",
"keyRevealFailed": "Falha ao revelar a chave",
- "keyRevealEmpty": "Falha ao revelar: chave não retornada",
+ "keyRevealEmpty": "Falha na revelação: chave não retornada",
"reveal": "Revelar",
"revealing": "Revelando…",
- "hide": "Ocultar",
+ "hide": "Hide",
"rotateKey": "Rotacionar chave",
"rotating": "Rotacionando…",
"keyAutoHide": "A chave será ocultada automaticamente em 30 segundos.",
- "revealTitle": "Revelar chave de API",
+ "revealTitle": "Revelar Chave de API",
"revealConfirm": "Revelar a chave de API será registrado na trilha de auditoria. Continuar?",
"cancel": "Cancelar",
"install9Router": "Instalar 9Router",
"install9RouterDescription": "Baixa e instala o 9Router via npm. Requer aproximadamente 500 MB de espaço em disco.",
- "version": "Versão",
- "versionHint": "Insira “latest” ou uma versão específica (por exemplo, 1.2.3).",
+ "version": "Version",
+ "versionHint": "Digite “latest” ou uma versão específica (por exemplo, 1.2.3).",
"servicePort": "Porta",
- "servicePortHint": "O OmniRoute e o 9Router devem usar portas diferentes. A porta padrão do 9Router é 20130.",
+ "servicePortHint": "O OmniRoute e o 9Router precisam usar portas diferentes. A porta padrão do 9Router é 20130.",
"installationFailed": "Falha na instalação (HTTP {status})",
"installationSucceeded": "9Router instalado com sucesso. Iniciando…",
"networkInstallFailed": "Erro de rede — não foi possível alcançar o endpoint de instalação",
- "availableModels": "Modelos disponíveis",
+ "availableModels": "Modelos Disponíveis",
"modelsLoading": "Carregando…",
"modelsDiscovered": "{count, plural, one {# modelo descoberto} other {# modelos descobertos}}",
"modelsLoadFailed": "Falha ao carregar modelos",
@@ -8587,37 +8588,37 @@
"pageOf": "Página {page} de {total}",
"previous": "Anterior",
"next": "Próximo",
- "providerExposure": "Exposição do provedor",
- "providerExposureDescription": "Expor modelos do 9Router como um destino de roteamento sob o prefixo 9router/.",
+ "providerExposure": "Exposição do Provedor",
+ "providerExposureDescription": "Expõe os modelos do 9Router como alvo de roteamento sob o prefixo 9router/.",
"providerExposureLabel": "Expor como 9router/…",
- "providerExposureHint": "Quando ativado, os modelos descobertos aparecem nos seletores de provedores em todo o OmniRoute.",
+ "providerExposureHint": "Quando ativado, os modelos descobertos aparecem nos seletores de provedor em todo o OmniRoute.",
"providerExposureUpdateFailed": "Falha ao atualizar (HTTP {status})",
"providerExposureNetworkFailed": "Erro de rede — não foi possível atualizar a configuração de exposição do provedor",
- "webUi": "9Router Web UI",
- "openNewTab": "Abrir em nova guia",
+ "webUi": "Interface Web do 9Router",
+ "openNewTab": "Abrir em nova aba",
"filterLogs": "Filtrar logs…",
"resume": "Retomar",
"pause": "Pausar",
- "clear": "Limpar",
+ "clear": "Claro",
"download": "Baixar",
- "noLogs": "Nenhuma saída de log ainda.",
+ "noLogs": "Ainda não há saída de log.",
"logStreamFailed": "Não foi possível transmitir os logs de {name}. Verifique o acesso local e o status do serviço.",
"fallbackRouting": "Roteamento de Fallback",
- "fallbackRoutingDescription": "Tentar novamente requisições de provedor com falha através da CLIProxyAPI",
- "enableFallback": "Habilitar fallback",
- "cliproxyUrl": "URL da CLIProxyAPI",
+ "fallbackRoutingDescription": "Tenta novamente solicitações de provedor com falha por meio do CLIProxyAPI",
+ "enableFallback": "Ativar fallback",
+ "cliproxyUrl": "URL CLIProxyAPI",
"fallbackCodes": "Códigos de status de fallback (separados por vírgula)",
"invalidUrl": "URL inválida — deve começar com http:// ou https://",
"saved": "Salvo",
"saveFailed": "Falha ao salvar configuração",
"modelMapping": "Mapeamento de Modelos",
- "modelMappingDescription": "Mapear IDs de modelo do OmniRoute para IDs de modelo da CLIProxyAPI (por exemplo, \"gpt-4o\": \"openai-gpt-4o\")",
+ "modelMappingDescription": "Mapeie IDs de modelo do OmniRoute para IDs de modelo do CLIProxyAPI (por exemplo, \"gpt-4o\": \"openai-gpt-4o\")",
"modelMappingEditor": "Editor JSON de mapeamento de modelos",
"mappingSaved": "Mapeamento salvo",
"mappingSaveFailed": "Falha ao salvar mapeamento",
"mappingInvalidJson": "JSON inválido.",
"mappingMustBeObject": "O mapeamento deve ser um objeto JSON, não um array ou valor primitivo.",
- "mappingValueMustBeString": "O valor para a chave “{key}” deve ser uma string.",
+ "mappingValueMustBeString": "O valor da chave “{key}” deve ser uma string.",
"save": "Salvar"
},
"contextCaveman": {
@@ -8645,7 +8646,7 @@
"inputCompressionDesc": "Reescreve o histórico do chat com termos mais curtos. Reduz os tokens de entrada em aproximadamente 50%.",
"analyticsTitle": "Analytics de Compressao",
"noAnalytics": "Sem analytics de compressao ainda.",
- "masterDisabledWarning": "A chave mestra do Token Saver está DESLIGADA — estas configurações não afetarão as requisições até que você a ative nas Configurações de Compressão ou a altere aqui.",
+ "masterDisabledWarning": "O interruptor mestre do Token Saver está DESLIGADO — essas configurações não afetarão as solicitações até que você o ative em Configurações de Compressão ou o altere aqui.",
"outputMode": "Modo de saída",
"outputModeDesc": "Instrui o LLM a responder em formato curto e compacto.",
"outputModeTitle": "Output Mode",
@@ -8825,8 +8826,8 @@
"translationPipeline": "Pipeline de Tradução",
"loading": "Carregando…",
"compressionOriginal": "Original",
- "compressionCompressed": "Compactado",
- "compressionSaved": "Economizado",
+ "compressionCompressed": "Comprimido",
+ "compressionSaved": "Salvo",
"compressionDuration": "Duração",
"pipelineStepsAria": "Etapas do pipeline",
"copyIntermediateJson": "Copiar JSON intermediário",
@@ -8965,18 +8966,18 @@
"conceptDiagramHubTooltip": "Hub intermediário usado pelo translator para converter entre formatos que não têm mapeamento direto.",
"conceptDiagramSourceTooltip": "O formato de API que sua app fala (ex: SDK Anthropic = claude).",
"conceptDiagramTargetTooltip": "O provider para onde a requisição será realmente enviada.",
- "compressionEmptyHint": "Preencha o campo de entrada na guia Traduzir (Controles Simples ou JSON Bruto) para habilitar a visualização.",
- "compressionModeLabel": "Modo de compressão",
- "compressionPreviewButton": "Visualizar Compressão",
- "compressionPreviewing": "Pré-visualizando…",
+ "compressionEmptyHint": "__MISSING__:Fill in the input field on the Translate tab (Simple Controls or Raw JSON) to enable the preview.",
+ "compressionModeLabel": "__MISSING__:Compression mode",
+ "compressionPreviewButton": "__MISSING__:Preview Compression",
+ "compressionPreviewing": "__MISSING__:Previewing…",
"compressionPreviewFailed": "Falha na pré-visualização da compressão",
- "tokens": "tokens",
+ "tokens": "fichas",
"pauseAutoRefresh": "Pausar atualização automática",
"resumeAutoRefresh": "Retomar atualização automática",
"live": "Ao vivo",
"copyInput": "Copiar entrada",
"copyOutput": "Copiar saída",
- "streamTransformFailed": "Falha ao transformar stream"
+ "streamTransformFailed": "Falha ao transformar o stream"
},
"usage": {
"title": "Uso",
@@ -9133,10 +9134,10 @@
"loadingQuotas": "Carregando...",
"showMoreQuotas": "Mostrar mais {count}",
"showLessQuotas": "Mostrar menos",
- "hideQuotaRow": "Ocultar esta linha de cota",
- "showQuotaRow": "Mostrar esta linha de cota",
- "hiddenQuotaRowsLabel": "Oculto:",
- "quotaVisibilityUpdateFailed": "Falha ao atualizar a visibilidade da cota",
+ "hideQuotaRow": "__MISSING__:Hide this quota row",
+ "showQuotaRow": "__MISSING__:Show this quota row",
+ "hiddenQuotaRowsLabel": "__MISSING__:Hidden:",
+ "quotaVisibilityUpdateFailed": "__MISSING__:Failed to update quota visibility",
"account": "Conta",
"modelQuotas": "Cotas de Modelo",
"lastUsed": "Last Refreshed",
@@ -9337,21 +9338,21 @@
"budgetKpiBlocked": "Bloqueado",
"budgetKpiAtRisk": "Em risco",
"budgetKpiActiveKeys": "Chaves ativas",
- "budgetPageTitle": "Orçamento",
+ "budgetPageTitle": "Budget",
"budgetPageDescription": "Defina limites de gastos diários, semanais e mensais para cada chave de API.",
- "budgetTemplateStorageHint": "{count, plural, one {# modelo} other {# modelos}} · editar via localStorage:",
+ "budgetTemplateStorageHint": "{count, plural, one {# modelo} other {# modelos}} · edite via localStorage:",
"budgetAboveLimitShort": "acima do limite ⚠",
"budgetOnTrackShort": "dentro do esperado",
- "budgetAtOrAboveWarning": "≥ limiar de alerta",
+ "budgetAtOrAboveWarning": "≥ limite de aviso",
"budgetTemplates": "Modelos",
"budgetSelectKeysFirst": "Selecione as chaves primeiro para aplicar",
"budgetApplyToSelected": "Aplicar a {count, plural, one {# chave selecionada} other {# chaves selecionadas}}",
- "budgetSelectedTemplateHint": "{count, plural, one {# selecionada} other {# selecionadas}} · clique em um modelo para aplicar",
+ "budgetSelectedTemplateHint": "{count, plural, one {# selecionado} other {# selecionados}} · clique em um modelo para aplicar",
"budgetTemplateMonthlyAmount": "${amount}/mês",
"budgetTemplateDailyAmount": "${amount}/dia",
"budgetNoKeysSelected": "Nenhuma chave selecionada",
- "budgetTemplateApplied": "Aplicado \"{template}\" a {count, plural, one {# chave} other {# chaves}}",
- "budgetTemplateApplyFailed": "Falha ao aplicar o modelo",
+ "budgetTemplateApplied": "\"{template}\" aplicado a {count, plural, one {# chave} other {# chaves}}",
+ "budgetTemplateApplyFailed": "Falha ao aplicar modelo",
"budgetTemplateNames": {
"tpl-prod": "Produção",
"tpl-dev": "Desenvolvimento",
@@ -9363,7 +9364,7 @@
"alerting": "Alertando",
"warning": "Aviso",
"safe": "Seguro",
- "no-limit": "Sem limite"
+ "no-limit": "No limit"
},
"budgetColumnKey": "Chave",
"budgetColumnToday": "Hoje",
@@ -9377,7 +9378,7 @@
"budgetColDailyLim": "Limite diário",
"budgetColMonthlyLim": "Limite mensal",
"budgetColUsedPct": "% usado",
- "percentUsed": "{pct}% usado",
+ "percentUsed": "__MISSING__:{pct}% used",
"budgetLoading": "Carregando…",
"budgetNoKeysMatch": "Nenhuma chave corresponde aos filtros",
"budgetLinearExtrapolation": "extrapolação linear",
@@ -9386,13 +9387,13 @@
"budgetByProvider": "por provedor",
"budgetProjection": "Projeção",
"budgetAboveMonthlyLimit": "⚠ acima de {limit}/mês",
- "budgetCostBreakdown30d": "Detalhamento de custos (30 dias)",
+ "budgetCostBreakdown30d": "Detalhamento de custo (30 dias)",
"budgetLimits": "Limites",
"budgetResetDaily": "Diário",
"budgetResetWeekly": "Semanal",
"budgetResetMonthly": "Mensal",
"budgetNextReset": "Próxima redefinição",
- "budgetHardCapComingSoon": "A política de limite rígido e os alertas por e-mail estarão disponíveis em breve",
+ "budgetHardCapComingSoon": "A política de limite rígido e alertas por e-mail estão chegando em breve",
"unknownProvider": "Provedor desconhecido",
"budgetDailyDollar": "Diariamente $",
"budgetWeeklyDollar": "Semanal $",
@@ -10165,8 +10166,8 @@
"agentDescriptions": {
"jules": "Agente de codificação autônomo do Google",
"devin": "Engenheiro de software de IA da Cognition",
- "codexCloud": "Agente de codificação baseado em nuvem da OpenAI",
- "cursorCloud": "Agentes de Nuvem / Segundo Plano do Cursor (chave de API oficial)"
+ "codexCloud": "Agente de codificação em nuvem da OpenAI",
+ "cursorCloud": "Agentes em segundo plano / nuvem do Cursor (chave de API oficial)"
},
"activityTypes": {
"plan": "Plano",
@@ -10467,7 +10468,8 @@
"gitlabDuoSetupTitle": "__MISSING__:GitLab Duo OAuth setup",
"gitlabDuoSetupMessage": "__MISSING__:GitLab Duo OAuth is not configured. Register an OAuth application at {applicationsUrl} with redirect URI {redirectUri} and scopes \"{scopes}\", then set {clientIdEnv} (and optionally {clientSecretEnv}) and restart.",
"gitlabDuoSetupDescription": "__MISSING__:After the application is registered and the env vars are set on this OmniRoute instance, click Continue to start the OAuth login.",
- "continue": "__MISSING__:Continue"
+ "continue": "__MISSING__:Continue",
+ "googleOAuthWarning": "Acesso remoto + Google OAuth: as credenciais padrão aceitam apenas redirecionamentos para localhost. Após a autorização, seu navegador tentará abrir localhost — copie o URL completo e cole-o abaixo. Para uso totalmente remoto sem esta etapa manual, configure suas próprias credenciais OAuth."
},
"cursorAuthModal": {
"title": "Conecte o Cursor IDE",
@@ -10532,11 +10534,11 @@
"modalEditTitle": "Modal Edit Title",
"labelName": "Label Name",
"labelType": "Tipo",
- "labelFamily": "Família de IP",
- "familyAuto": "Automático (dual-stack)",
- "familyIpv4": "Apenas IPv4",
- "familyIpv6": "Apenas IPv6",
- "familyHint": "Família de endereços de saída. Automático mantém dual-stack; IPv4/IPv6 fixam este proxy nessa família (evita vazamento de v4 sob um proxy apenas IPv6).",
+ "labelFamily": "__MISSING__:IP family",
+ "familyAuto": "__MISSING__:Auto (dual-stack)",
+ "familyIpv4": "__MISSING__:IPv4 only",
+ "familyIpv6": "__MISSING__:IPv6 only",
+ "familyHint": "__MISSING__:Egress address family. Auto keeps dual-stack; IPv4/IPv6 pin this proxy to that family (prevents a v4 leak under an IPv6-only proxy).",
"labelHost": "Anfitrião",
"labelPort": "Porto",
"labelUsername": "Nome de usuário",
@@ -10654,7 +10656,7 @@
"audioFile": "Arquivo de áudio",
"attachImages": "Anexar imagens",
"multipartFormData": "Multipart Form Data",
- "upToImages": "Até {count} imagens",
+ "upToImages": "Até 4 imagens",
"selectAudioFile": "Selecionar arquivo de áudio",
"clearAll": "Limpar tudo",
"request": "Requisição",
@@ -10671,17 +10673,17 @@
"endpointOptions": {
"chat": "Chat",
"responses": "Responses",
- "completions": "Conclusões",
+ "completions": "Completions",
"images": "Images",
"embeddings": "Embeddings",
"speech": "Speech",
"transcription": "Transcription",
"video": "Video",
"music": "Music",
- "moderations": "Moderações",
+ "moderations": "Moderations",
"rerank": "Rerank",
"search": "Search",
- "webFetch": "Busca na web"
+ "webFetch": "Busca na Web"
},
"conversationalChat": "Bate-papo conversacional",
"clearChat": "Limpar bate-papo",
@@ -10721,10 +10723,10 @@
"improvePromptTitle": "Melhorar seu prompt com IA",
"setModelFirst": "Defina um modelo primeiro",
"setModelInConfigFirst": "Defina um modelo no painel de Configuração primeiro.",
- "improvePromptFailed": "Falha ao melhorar o prompt.",
- "improvePromptAria": "Melhorar prompt usando IA",
- "confirmImprovePrompt": "Confirmar melhoria do prompt",
- "improvePromptDescription": "Isso enviará seu prompt do sistema atual para para gerar uma versão melhorada.",
+ "improvePromptFailed": "Falha ao aprimorar o prompt.",
+ "improvePromptAria": "Aprimorar prompt usando IA",
+ "confirmImprovePrompt": "Confirmar aprimoramento de prompt",
+ "improvePromptDescription": "Isto enviará seu prompt de sistema atual para para gerar uma versão aprimorada.",
"improveQuotaWarning": "Isso consumirá cota do modelo configurado no painel Config.",
"improveConfirm": "Melhorar",
"exportCode": "Exportar código",
@@ -10754,9 +10756,9 @@
"done": "concluído",
"error": "erro"
},
- "cancelStream": "Cancelar transmissão",
+ "cancelStream": "Cancelar stream",
"removeColumn": "Remover coluna",
- "removeModelColumn": "Remover coluna para {model}",
+ "removeModelColumn": "Remover coluna de {model}",
"readyToRun": "Pronto para executar.",
"errorLabel": "Erro",
"unknownError": "Ocorreu um erro desconhecido.",
@@ -10767,9 +10769,9 @@
"tokensLabel": "Tokens",
"costLabel": "Custo",
"costEstimated": "(estimado)",
- "ttftTitle": "Tempo até o primeiro token (estimativa do lado do cliente)",
- "tpsTitle": "Tokens por segundo (estimativa do lado do cliente)",
- "tokenCountsTitle": "Tokens do prompt ↑ / Tokens de conclusão ↓",
+ "ttftTitle": "Tempo até o primeiro token (estimativa no cliente)",
+ "tpsTitle": "Tokens por segundo (estimativa no cliente)",
+ "tokenCountsTitle": "Tokens de prompt ↑ / Tokens de conclusão ↓",
"estimatedCostTitle": "Custo estimado (precisão não garantida)",
"toolsLabel": "Ferramentas",
"toolsCount": "Ferramentas ({count})",
@@ -10779,8 +10781,8 @@
"toolNamePlaceholder": "Nome da função",
"toolNameRequiredPlaceholder": "Nome da função *",
"toolDescPlaceholder": "Descrição (opcional)",
- "toolParamsLabel": "Parâmetros (esquema JSON)",
- "toolParamsJsonSchema": "Esquema JSON para parâmetros",
+ "toolParamsLabel": "Parâmetros (schema JSON)",
+ "toolParamsJsonSchema": "Schema JSON para parâmetros",
"toolParamsInvalid": "Parâmetros devem ser JSON válido",
"structuredOutputLabel": "Saída Estruturada",
"enableJsonMode": "Ativar modo JSON",
@@ -10788,20 +10790,20 @@
"invalidJson": "JSON inválido",
"jsonMode": "Modo JSON",
"jsonModeDescription": "Força response_format: json_schema",
- "schemaName": "Nome do esquema",
- "jsonSchema": "Esquema JSON",
- "jsonSchemaEditor": "Editor de esquema JSON",
- "schemaValidated": "Esquema validado",
- "validateSchema": "Validar esquema",
- "seed": "Semente",
+ "schemaName": "Nome do schema",
+ "jsonSchema": "Schema JSON",
+ "jsonSchemaEditor": "Editor de schema JSON",
+ "schemaValidated": "Schema validado",
+ "validateSchema": "Validar schema",
+ "seed": "Seed",
"stopSequences": "Sequências de parada",
"stopSequencesPlaceholder": "ex.: \"\\n\\n\" ou \"END\"",
- "autoProvider": "Automático",
+ "autoProvider": "Auto",
"httpError": "Erro {status}",
"requestCancelled": "Solicitação cancelada",
- "networkError": "Erro de rede",
- "regenerateLastResponse": "Regerar última resposta",
- "regenerate": "Regerar",
+ "networkError": "Network error",
+ "regenerateLastResponse": "Regenerar última resposta",
+ "regenerate": "Regenerar",
"startConversation": "Inicie uma conversa — digite uma mensagem abaixo",
"role": {
"system": "sistema",
@@ -10810,8 +10812,8 @@
},
"generating": "Gerando…",
"typeMessageWithShortcut": "Digite uma mensagem... (Enter para enviar, Shift+Enter para nova linha)",
- "stop": "Parar",
- "noResponseBody": "Nenhum corpo de resposta",
+ "stop": "Pare",
+ "noResponseBody": "Sem corpo de resposta",
"comparePromptPlaceholder": "Digite seu prompt aqui…",
"userPrompt": "Prompt do usuário",
"cancelAllStreams": "Cancelar todos os streams",
@@ -10820,7 +10822,7 @@
"addColumn": "Adicionar coluna",
"addModelColumn": "Adicionar coluna de modelo",
"columnCount": "{count}/{max} colunas",
- "addModelToCompare": "Adicionar uma coluna de modelo para comparar",
+ "addModelToCompare": "Adicione uma coluna de modelo para comparar",
"modelsSimultaneously": "Até {max} modelos simultaneamente",
"running": "Executando…",
"runLabel": "Executar",
@@ -10882,24 +10884,24 @@
"audioFile": "Arquivo de áudio",
"fileTooLarge25Mb": "O arquivo é muito grande. Tamanho máximo: 25 MB.",
"selectAudioFirst": "Selecione um arquivo de áudio primeiro.",
- "speechToText": "Fala para texto",
+ "speechToText": "Fala para Texto",
"chooseFile": "Escolher arquivo",
- "audioFormats25Mb": "MP3, WAV, M4A, OGG ou FLAC · Máximo de 25 MB",
- "musicSample": "Uma faixa ambiente calma com piano acolhedor e cordas suaves",
+ "audioFormats25Mb": "MP3, WAV, M4A, OGG ou FLAC · Máximo 25 MB",
+ "musicSample": "Uma faixa ambiente calma com piano quente e cordas suaves",
"noAudioUrl": "A resposta não incluiu uma URL de áudio: {response}",
"music": "Música",
- "embeddingSample": "O OmniRoute roteia solicitações de IA entre vários provedores.",
+ "embeddingSample": "O OmniRoute roteia solicitações de IA entre múltiplos provedores.",
"embedding": "Embedding",
"imageSample": "Uma cidade futurista ao pôr do sol, iluminação cinematográfica",
- "image": "Imagem",
+ "image": "Image",
"ttsSample": "Olá do OmniRoute. Este é um teste de texto para fala.",
- "textToSpeech": "Texto para fala",
+ "textToSpeech": "Texto para Fala",
"videoSample": "Um avião de papel voando sobre uma cidade futurista",
"video": "Vídeo",
- "webFetch": "Busca na Web",
+ "webFetch": "Web Fetch",
"webSearchSample": "O que é o OmniRoute?",
- "webSearch": "Pesquisa na Web",
- "documentUrl": "URL do documento",
+ "webSearch": "Web Search",
+ "documentUrl": "URL do Documento",
"browserAudioUnsupported": "Seu navegador não suporta áudio.",
"browserVideoUnsupported": "Seu navegador não suporta vídeo.",
"searchResultFallback": "Resultado {number}",
@@ -10908,14 +10910,14 @@
"latency": "{ms}ms",
"statsLine": "{ms}ms · {tokensIn} entrada / {tokensOut} saída tokens",
"defaultKey": "(padrão)",
- "clear": "Limpar",
+ "clear": "Claro",
"emptyConversation": "Envie uma mensagem para iniciar a conversa",
"sendHint": "Shift+Enter para nova linha · Enter para enviar",
"you": "Você",
- "assistant": "Assistente",
+ "assistant": "Assistant",
"errorLabel": "Erro",
"requestFailed": "Falha na requisição",
- "stop": "Parar"
+ "stop": "Pare"
},
"requestLogger": {
"recording": "Recording",
@@ -10983,8 +10985,8 @@
"noLogs": "No logs yet. Make some API calls to see them here.",
"noMatchingLogs": "No logs matching current filters.",
"callLogsInfo": "Call logs are also saved as JSON files to {dataDir} and rotated based on {retentionDays} and {maxEntries}.",
- "loadMore": "Carregar mais",
- "loadingMore": "Carregando mais...",
+ "loadMore": "__MISSING__:Load More",
+ "loadingMore": "__MISSING__:Loading more...",
"correlationId": "__MISSING__:Correlation ID",
"group": {
"showAllRows": "__MISSING__:Show all rows",
@@ -11093,7 +11095,7 @@
"colProvider": "Provider",
"colTarget": "Target",
"colLatency": "Latency",
- "colClientIp": "IP do cliente",
+ "colClientIp": "__MISSING__:Client IP",
"colTime": "Time",
"recording": "Recording",
"paused": "Paused",
@@ -11377,17 +11379,17 @@
"status": "Status",
"enabled": "Enabled",
"disabled": "Disabled",
- "installedTab": "Instalado",
- "marketplaceTab": "Marketplace",
- "marketplaceUrlLabel": "URL personalizada do marketplace",
- "marketplaceUrlPlaceholder": "Deixe em branco para o registro oficial do Omniroute",
- "saveMarketplaceUrl": "Salvar e recarregar",
- "marketplaceUrlSaved": "URL do marketplace atualizada",
- "marketplaceEmpty": "Nenhum plugin encontrado no marketplace.",
+ "installedTab": "__MISSING__:Installed",
+ "marketplaceTab": "__MISSING__:Marketplace",
+ "marketplaceUrlLabel": "__MISSING__:Custom Marketplace URL",
+ "marketplaceUrlPlaceholder": "__MISSING__:Leave empty for official Omniroute registry",
+ "saveMarketplaceUrl": "__MISSING__:Save & Reload",
+ "marketplaceUrlSaved": "__MISSING__:Marketplace URL updated",
+ "marketplaceEmpty": "__MISSING__:No plugins found in marketplace.",
"marketplaceInstallComingSoon": "Instalações via marketplace em breve.",
- "verified": "Verificado",
- "install": "Instalar",
- "installedFromMarketplace": "Plugin {name} instalado!",
+ "verified": "__MISSING__:Verified",
+ "install": "__MISSING__:Install",
+ "installedFromMarketplace": "__MISSING__:Plugin {name} installed!",
"hooks": "Hooks"
},
"quotaPlans": {
@@ -11438,10 +11440,10 @@
"filterSystem": "Sistema",
"filterAria": "Filtrar por tipo de evento",
"refresh": "Atualizar",
- "refreshAria": "Atualizar feed de atividades",
+ "refreshAria": "Atualizar feed de atividade",
"loading": "Carregando",
- "loadingActivity": "Carregando atividades…",
- "fetchFailed": "Falha ao buscar atividades",
+ "loadingActivity": "Carregando atividade…",
+ "fetchFailed": "Falha ao buscar atividade",
"relative": {
"justNow": "agora há pouco",
"minutesAgo": "há {n} min",
@@ -11593,28 +11595,28 @@
"quickLinkProviders": "Configurar provedores",
"quickLinkInspector": "Ver tráfego no Traffic Inspector",
"unknownError": "Erro desconhecido",
- "maintenanceTitle": "Manutenção e diagnósticos",
- "maintenanceSubtitle": "Faça o autoteste do pipeline de captura, desfaça o estado residual do sistema e mova sua configuração entre máquinas.",
- "orphanedStateWarning": "Uma sessão anterior deixou resíduos no estado do sistema (DNS spoof, CA ou proxy do sistema). Execute Reparar para limpá-lo.",
- "diagnose": "Diagnosticar",
- "diagnosing": "Diagnosticando…",
- "diagnoseHealthy": "O pipeline de captura está saudável.",
- "diagnoseUnhealthy": "O pipeline de captura tem problemas:",
- "repair": "Reparar",
- "repairing": "Reparando…",
- "repairDone": "Reparado: {items}",
- "repairNothing": "Nada a reparar — o estado do sistema está limpo.",
- "removeCa": "Remover CA",
- "removeCaConfirm": "Remover CA?",
- "removeCaDone": "CA raiz MITM removida do repositório de confiança do SO.",
- "removing": "Removendo…",
- "confirm": "Confirmar",
- "exportConfig": "Exportar configuração",
- "exporting": "Exportando…",
- "importConfig": "Importar configuração",
- "importing": "Importando…",
- "importInvalidJson": "O arquivo selecionado não é um JSON válido.",
- "importDone": "Importados {bypass} bypass · {hosts} hosts · {agents} agentes",
+ "maintenanceTitle": "__MISSING__:Maintenance & Diagnostics",
+ "maintenanceSubtitle": "__MISSING__:Self-test the capture pipeline, undo leftover system state, and move your setup between machines.",
+ "orphanedStateWarning": "__MISSING__:A previous session left system state behind (DNS spoof, CA, or system proxy). Run Repair to clean it up.",
+ "diagnose": "__MISSING__:Diagnose",
+ "diagnosing": "__MISSING__:Diagnosing…",
+ "diagnoseHealthy": "__MISSING__:Capture pipeline is healthy.",
+ "diagnoseUnhealthy": "__MISSING__:Capture pipeline has problems:",
+ "repair": "__MISSING__:Repair",
+ "repairing": "__MISSING__:Repairing…",
+ "repairDone": "__MISSING__:Repaired: {items}",
+ "repairNothing": "__MISSING__:Nothing to repair — system state is clean.",
+ "removeCa": "__MISSING__:Remove CA",
+ "removeCaConfirm": "__MISSING__:Remove CA?",
+ "removeCaDone": "__MISSING__:MITM root CA removed from the OS trust store.",
+ "removing": "__MISSING__:Removing…",
+ "confirm": "__MISSING__:Confirm",
+ "exportConfig": "__MISSING__:Export config",
+ "exporting": "__MISSING__:Exporting…",
+ "importConfig": "__MISSING__:Import config",
+ "importing": "__MISSING__:Importing…",
+ "importInvalidJson": "__MISSING__:The selected file is not valid JSON.",
+ "importDone": "__MISSING__:Imported {bypass} bypass · {hosts} hosts · {agents} agents",
"save": "Salvar",
"saving": "Salvando…",
"cancel": "Cancelar",
@@ -11634,35 +11636,35 @@
"unknownError": "Erro desconhecido",
"loading": "Carregando estatísticas do provedor...",
"loadFailed": "Falha ao carregar estatísticas do provedor: {error}",
- "retry": "Tentar novamente",
+ "retry": "Retry",
"updated": "Atualizado {time}",
"refresh": "Atualizar",
- "totalRequests": "Total de requisições",
- "avgLatency": "Latência média",
- "successRate": "Taxa de sucesso",
- "activeProviders": "Provedores ativos",
- "providerBreakdown": "Detalhamento por provedor",
+ "totalRequests": "Total Requests",
+ "avgLatency": "Avg Latency",
+ "successRate": "Taxa de Sucesso",
+ "activeProviders": "Active Providers",
+ "providerBreakdown": "Detalhamento por Provedor",
"providerCount": "{count} provedores",
"provider": "Provedor",
"requests": "Requisições",
"success": "Sucesso",
"rate": "Taxa",
- "tokensIn": "Tokens de entrada",
- "tokensOut": "Tokens de saída",
- "ttftAfterTool": "TTFT após ferramenta",
- "gapAfterTool": "Intervalo após ferramenta",
+ "tokensIn": "Tokens de Entrada",
+ "tokensOut": "Tokens de Saída",
+ "ttftAfterTool": "TTFT Após Ferramenta",
+ "gapAfterTool": "Intervalo Após Ferramenta",
"model": "Modelo",
"noProviderData": "Nenhum dado de provedor registrado ainda.",
- "comboMetrics": "Métricas de combo",
- "comboMetricsDescription": "Latência e taxa de transferência por combo a partir do streaming",
- "avgTtft": "TTFT médio",
- "avgTotal": "Total médio",
- "requestTelemetry": "Telemetria de requisições",
+ "comboMetrics": "Métricas de Combo",
+ "comboMetricsDescription": "Latência e throughput por combo a partir do streaming",
+ "avgTtft": "TTFT Médio",
+ "avgTotal": "Total Médio",
+ "requestTelemetry": "Telemetria de Solicitações",
"requestTelemetryDescription": "Detalhamento do pipeline de 7 fases (últimos 5 minutos)"
},
"relay": {
"title": "Proxies de Relay Serverless",
- "description": "Crie endpoints de API públicos que façam proxy para o OmniRoute com limitação de taxa e controle de acesso",
+ "description": "Crie endpoints de API públicos que fazem proxy para o OmniRoute com limitação de taxa e controle de acesso",
"created": "Token de relay criado",
"createFailed": "Falha ao criar token",
"toggleFailed": "Falha ao alternar token",
@@ -11673,17 +11675,17 @@
"newToken": "Novo Token de Relay",
"createTitle": "Criar Token de Relay",
"nameRequired": "Nome *",
- "tokenDescription": "Descrição",
+ "tokenDescription": "Description",
"descriptionPlaceholder": "Para minhas funções serverless",
- "maxPerMinute": "Máx. de Requisições/Minuto",
- "maxPerDay": "Máx. de Requisições/Dia",
+ "maxPerMinute": "Máx. de Solicitações/Minuto",
+ "maxPerDay": "Máx. de Solicitações/Dia",
"createButton": "Criar Token",
- "createdTitle": "Token Criado — Copie-o agora!",
+ "createdTitle": "Token Criado — Copie agora!",
"tokenFor": "Token para {name}:",
- "shownOnce": "Este token não será exibido novamente. Armazene-o com segurança.",
+ "shownOnce": "Este token não será exibido novamente. Guarde-o com segurança.",
"dismiss": "Dispensar",
"usage": "Uso",
- "usageDescription": "Envie requisições para o seu endpoint de relay:",
+ "usageDescription": "Envie solicitações para o seu endpoint de relay:",
"tokenCount": "Tokens de Relay ({count})",
"loading": "Carregando...",
"empty": "Nenhum token de relay configurado. Crie um para começar.",
@@ -11703,8 +11705,8 @@
"httpProxyModeDesc": "Usar variável de ambiente HTTP_PROXY",
"systemWideMode": "Sistema inteiro",
"systemWideModeDesc": "Interceptar todo o tráfego do sistema (avançado)",
- "tproxyMode": "Descriptografia TPROXY",
- "tproxyModeUnavailable": "A descriptografia TPROXY requer Linux + root + o addon nativo",
+ "tproxyMode": "__MISSING__:TPROXY Decrypt",
+ "tproxyModeUnavailable": "__MISSING__:TPROXY decrypt requires Linux + root + the native addon",
"filterBarTitle": "Filtros",
"profileLlmOnly": "Apenas LLM",
"profileCustom": "Personalizado",
@@ -11761,7 +11763,7 @@
"httpProxyTitle": "Snippet de Proxy HTTP — porta {port}",
"notRecording": "Sem gravação",
"anyStatus": "Qualquer status",
- "liveOnly": "Ao vivo",
+ "liveOnly": "__MISSING__:Live",
"viewingRecordedSession": "Visualizando sessão gravada",
"backToLive": "Voltar ao live",
"untitledSession": "Sessão sem nome",
@@ -11787,24 +11789,24 @@
"timingResponseSize": "Tamanho da resposta",
"pausedNewBadge": "{count} novos",
"clearContextFilter": "limpar",
- "invalidHostname": "Hostname inválido",
+ "invalidHostname": "Nome de host inválido",
"invalidHost": "Host inválido",
"addHostFailed": "Falha ao adicionar host",
- "networkError": "Erro de rede",
+ "networkError": "Network error",
"close": "Fechar",
"removeHost": "Remover {host}",
- "requestDetails": "Detalhes da requisição",
+ "requestDetails": "Detalhes da solicitação",
"filterByContext": "Filtrar por este contexto",
"filteringContext": "Filtrando: contexto {context}",
"clear": "limpar",
"trafficProfile": "Perfil de tráfego",
"roleSystem": "Sistema",
- "roleUser": "Usuário",
- "roleAssistant": "Assistente",
+ "roleUser": "User",
+ "roleAssistant": "Assistant",
"roleTool": "Ferramenta",
"expand": "Expandir",
"collapse": "Recolher",
- "systemPromptHidden": "Prompt do sistema oculto — clique para expandir",
+ "systemPromptHidden": "Prompt de sistema oculto — clique para expandir",
"sessionName": "Sessão {id}",
"sessions": "Sessões",
"requestCountShort": "{count} reqs",
@@ -11812,14 +11814,14 @@
"saving": "Salvando…",
"sensitiveHeaders": "Cabeçalhos sensíveis",
"show": "Mostrar",
- "hide": "Ocultar",
+ "hide": "Hide",
"name": "Nome",
- "value": "Valor",
+ "value": "Value",
"noSseEvents": "Nenhum evento SSE",
- "noRequestBody": "Nenhum corpo de requisição.",
- "noResponseBody": "Nenhum corpo de resposta.",
- "formatted": "Formatado",
- "raw": "Bruto"
+ "noRequestBody": "Sem corpo de solicitação.",
+ "noResponseBody": "Sem corpo de resposta.",
+ "formatted": "Formatted",
+ "raw": "Raw"
},
"cliCommon": {
"concept": {
@@ -11845,7 +11847,7 @@
"comparison": {
"title": "Entenda os 3 tipos de CLI no OmniRoute",
"thisPage": "[Esta página ✓]",
- "open": "Abrir →",
+ "open": "__MISSING__:Open →",
"code": {
"title": "Ferramenta de código",
"desc": "Aponta para o Omni",
@@ -11876,11 +11878,11 @@
"manualConfig": "Manual config",
"installGuide": "Install guide",
"endpointLabel": "Endpoint",
- "baseUrlFull": "URL Base Completa",
+ "baseUrlFull": "__MISSING__:Full Base URL",
"baseUrlPartial": "Base URL parcial",
"refreshDetection": "Atualizar detecção",
"alsoAcp": "também ACP",
- "connectProviderHint": "Conecte um provedor em Provedores"
+ "connectProviderHint": "__MISSING__:Connect a provider in Providers"
},
"detail": {
"back": "Voltar",
@@ -11961,187 +11963,187 @@
"catalog": {
"omni-auth": {
"name": "Autenticação",
- "description": "Gerencie a autenticação por chave de API e tokens de sessão. Comece aqui para autenticar requisições via token Bearer, obter cookies de sessão e configurar requisitos de login para a API do OmniRoute."
+ "description": "Gerencie a autenticação por chave de API e tokens de sessão. Comece aqui para autenticar solicitações via token Bearer, obter cookies de sessão e configurar requisitos de login para a API do OmniRoute."
},
"omni-providers": {
- "name": "Provedores",
- "description": "Gerencie conexões de provedores, chaves de API, fluxos OAuth e testes de conexão via API REST. Liste, adicione, atualize, remova e teste integrações de provedores de IA (OpenAI, Anthropic, Gemini e mais de 160)."
+ "name": "Providers",
+ "description": "Gerencie conexões de provedor, chaves de API, fluxos OAuth e testes de conexão via API REST. Liste, adicione, atualize, remova e teste integrações de provedores de IA (OpenAI, Anthropic, Gemini e mais de 160)."
},
"omni-models": {
"name": "Modelos",
- "description": "Consulte modelos de IA disponíveis em todos os provedores configurados. Liste modelos, resolva aliases de modelos e navegue pelo catálogo completo de modelos, incluindo variantes específicas de provedores."
+ "description": "Consulte os modelos de IA disponíveis em todos os provedores configurados. Liste modelos, resolva aliases de modelo e navegue pelo catálogo completo, incluindo variantes específicas de provedor."
},
"omni-combos-routing": {
- "name": "Combos & Roteamento",
- "description": "Crie e gerencie combos de roteamento com 14 estratégias (prioridade, ponderada, round-robin, Auto-combo, etc.). Configure cadeias de fallback, teste resultados de roteamento e obtenha métricas de combos."
+ "name": "Combos e Roteamento",
+ "description": "Crie e gerencie combos de roteamento com 14 estratégias (priority, weighted, round-robin, Auto-combo, etc.). Configure cadeias de fallback, teste resultados de roteamento e obtenha métricas de combo."
},
"omni-api-keys": {
- "name": "Chaves de API",
+ "name": "Gerenciador API",
"description": "Crie, liste, rotacione e revogue chaves de API do OmniRoute. Controle escopos por chave, limites de gastos e expiração. As chaves controlam o acesso a todos os endpoints de proxy e gerenciamento."
},
"omni-usage-logs": {
"name": "Uso e Logs",
- "description": "Acesse logs de chamadas detalhados e análises de uso. Filtre por provedor, modelo, intervalo de tempo, status e custo. Exporte logs e agregue o uso de tokens em todas as conexões."
+ "description": "Acesse logs detalhados de chamadas e análises de uso. Filtre por provedor, modelo, período, status e custo. Exporte logs e agregue o uso de tokens em todas as conexões."
},
"omni-budget": {
"name": "Orçamento e Limites de Taxa",
- "description": "Configure limites de gastos, cotas de tokens e políticas de limite de taxa por chave de API ou globalmente. Inspecione o consumo atual e aplique controles de custos entre provedores."
+ "description": "Configure limites de gastos, cotas de tokens e políticas de limite de taxa por chave de API ou globalmente. Inspecione o consumo atual e aplique controles de custo entre provedores."
},
"omni-settings": {
"name": "Configurações",
- "description": "Leia e atualize as configurações globais do aplicativo: prompts do sistema, orçamento de pensamento, filtros de IP, regras de payload, padrões de combo e configuração de require-login."
+ "description": "Leia e atualize as configurações globais da aplicação: prompts de sistema, orçamento de raciocínio, filtros de IP, regras de payload, padrões de combo e configuração de exigência de login."
},
"omni-proxies": {
"name": "Configuração de Proxy",
- "description": "Configure proxies HTTP/HTTPS/SOCKS para requisições a provedores upstream. Defina regras de proxy globais ou por provedor, teste a conectividade e gerencie a rotação de proxies."
+ "description": "Configure proxies HTTP/HTTPS/SOCKS para solicitações ao provedor upstream. Defina regras de proxy por provedor ou globais, teste a conectividade e gerencie a rotação de proxies."
},
"omni-cache": {
"name": "Cache",
- "description": "Gerencie o cache de respostas de LLM. Visualize estatísticas de cache, limpe entradas, configure políticas de TTL e controle limites de cache por similaridade semântica."
+ "description": "Gerencie o cache de respostas de LLM. Veja estatísticas do cache, limpe entradas, configure políticas de TTL e controle os limites de cache por similaridade semântica."
},
"omni-compression": {
- "name": "Compressão",
- "description": "Configure os modos de compressão RTK (saída de comando), Caveman (prosa) e empilhada. Gerencie pacotes de idiomas, regras personalizadas e teste a compressão de prompts reduzindo tokens em 60–90%."
+ "name": "Compression",
+ "description": "Configure os modos de compressão RTK (saída de comando), Caveman (prosa) e empilhados. Gerencie pacotes de idioma, regras personalizadas e teste a compressão de prompt, reduzindo tokens em 60–90%."
},
"omni-context-rtk": {
"name": "Contexto e RTK",
- "description": "Configure filtros RTK, regras de engenharia de contexto e configurações de relay de contexto. Teste a compressão com amostras reais de prompts e gerencie pipelines de transformação de contexto."
+ "description": "Configure filtros RTK, regras de engenharia de contexto e configurações de context relay. Teste a compressão com amostras reais de prompt e gerencie pipelines de transformação de contexto."
},
"omni-resilience": {
"name": "Resiliência e Monitoramento",
- "description": "Monitore a integridade do provedor, estados de circuit-breaker, métricas de latência p50/p95/p99 e alertas de proteção de orçamento. Inspecione cooldowns de conexão e bloqueios de modelos em tempo real."
+ "description": "Monitore a saúde do provedor, estados do circuit breaker, métricas de latência p50/p95/p99 e alertas de guarda de orçamento. Inspecione cooldowns de conexão e bloqueios de modelo em tempo real."
},
"omni-cli-tools": {
- "name": "Ferramentas de CLI",
- "description": "Gerencie integrações de ferramentas de CLI expostas via API. Liste, configure e invoque plugins de ferramentas de CLI que estendem a superfície de automação do OmniRoute."
+ "name": "Ferramentas CLI",
+ "description": "Gerencie integrações de ferramentas CLI expostas via API. Liste, configure e invoque plugins de ferramentas CLI que estendem a superfície de automação do OmniRoute."
},
"omni-tunnels": {
"name": "Túneis",
"description": "Crie e gerencie túneis seguros (ngrok, Cloudflare Tunnel, personalizado) para expor o OmniRoute à internet ou compartilhar acesso com agentes remotos e pipelines de CI."
},
"omni-sync-cloud": {
- "name": "Sincronização na Nuvem",
- "description": "Sincronize a configuração do OmniRoute, conexões de provedores e definições de/para o armazenamento em nuvem. Gerencie a autenticação de workers na nuvem e destinos de backup remoto."
+ "name": "Sincronização em Nuvem",
+ "description": "Sincronize a configuração do OmniRoute, conexões de provedor e configurações com armazenamento em nuvem. Gerencie a autenticação do cloud worker e destinos de backup remoto."
},
"omni-db-backups": {
"name": "Banco de Dados e Backups",
- "description": "Acione backups do sistema, restaure a partir de arquivos de backup e gerencie o ciclo de vida do banco de dados SQLite. Suporta estratégias de exportação, importação e snapshots incrementais."
+ "description": "Acione backups do sistema, restaure a partir de arquivos de backup e gerencie o ciclo de vida do banco de dados SQLite. Suporta estratégias de exportação, importação e snapshot incremental."
},
"omni-webhooks": {
"name": "Webhooks",
"description": "Registre, liste, teste e remova endpoints de webhook. Configure assinaturas de eventos (request.completed, provider.error, budget.exceeded, etc.) e gerencie novas tentativas de entrega."
},
"omni-mcp": {
- "name": "Servidor MCP",
+ "name": "MCP",
"description": "Conecte-se ao servidor MCP do OmniRoute (37 ferramentas, 3 transportes: SSE/stdio/HTTP). Abrange ferramentas de roteamento, cache, compressão, memória, skills, provedores e auditoria em 16 escopos de permissão."
},
"omni-agents-a2a": {
"name": "Agentes e Protocolo A2A",
- "description": "Interaja com o OmniRoute via protocolo agente-a-agente JSON-RPC 2.0. 6 skills A2A integradas: smart-routing, quota-management, provider-discovery, cost-analysis, health-report, list-capabilities."
+ "description": "Interaja com o OmniRoute via protocolo agent-to-agent JSON-RPC 2.0. 6 skills A2A integradas: smart-routing, quota-management, provider-discovery, cost-analysis, health-report, list-capabilities."
},
"omni-version-manager": {
"name": "Gerenciador de Versões",
- "description": "Instale, inicie, pare, reinicie e atualize serviços incorporados (9Router, CLIProxyAPI). Monitore o status do serviço, recupere logs e configure o início automático para endpoints de serviço exclusivamente locais."
+ "description": "Instale, inicie, pare, reinicie e atualize serviços embutidos (9Router, CLIProxyAPI). Monitore o status do serviço, obtenha logs e configure o início automático para endpoints de serviço somente locais."
},
"omni-inference": {
"name": "Inferência (compatível com OpenAI)",
- "description": "Os principais endpoints de inferência compatíveis com OpenAI: chat completions, embeddings, imagens, áudio (TTS/STT), moderações, rerank e a Responses API. A principal superfície de integração para agentes de IA."
+ "description": "Os endpoints de inferência principais compatíveis com OpenAI: chat completions, embeddings, imagens, áudio (TTS/STT), moderações, rerank e a Responses API. A principal superfície de integração para agentes de IA."
},
"cli-serve": {
"name": "CLI: Serve",
- "description": "Inicie, pare e reinicie o servidor OmniRoute a partir da CLI. Gerencie o modo daemon, configuração de portas, recuperação automática, integração com a bandeja do sistema e o atalho para abrir o painel."
+ "description": "Inicie, pare e reinicie o servidor OmniRoute a partir da CLI. Gerencie o modo daemon, configuração de porta, recuperação automática, integração com a bandeja do sistema e o atalho para abrir o dashboard."
},
"cli-health": {
"name": "CLI: Health",
- "description": "Verifique a integridade do servidor, o status dos componentes e métricas em tempo real a partir da CLI. Execute `health`, `health components` e `health watch` para obter um painel em tempo real de circuit breakers e status dos provedores."
+ "description": "Verifique a saúde do servidor, o status dos componentes e métricas em tempo real a partir da CLI. Execute `health`, `health components` e `health watch` para um dashboard em tempo real dos circuit breakers e do status dos provedores."
},
"cli-providers": {
"name": "CLI: Providers",
- "description": "Gerencie conexões de provedores a partir da CLI: liste provedores disponíveis/configurados, adicione, teste, test-all, valide, rotacione chaves de API e visualize métricas por provedor."
+ "description": "Gerencie conexões de provedor a partir da CLI: liste provedores disponíveis/configurados, adicione, teste, test-all, valide, rotacione chaves de API e veja métricas por provedor."
},
"cli-keys": {
- "name": "CLI: Chaves de API",
- "description": "Crie, liste, rotacione e revogue chaves de API do OmniRoute a partir da CLI. Gerencie fluxos OAuth para autenticação de provedores e inspecione escopos e expiração de chaves."
+ "name": "CLI: API Keys",
+ "description": "Crie, liste, rotacione e revogue chaves de API do OmniRoute a partir da CLI. Gerencie fluxos OAuth para autenticação de provedor e inspecione escopos e expiração de chave."
},
"cli-models": {
- "name": "CLI: Modelos",
- "description": "Consulte modelos de IA disponíveis, liste aliases de modelos e navegue pelo catálogo completo de modelos a partir da CLI. Filtre por provedor, pesquise por capacidade e resolva variantes de nomes de modelos."
+ "name": "CLI: Models",
+ "description": "Consulte os modelos de IA disponíveis, liste aliases de modelo e navegue pelo catálogo completo a partir da CLI. Filtre por provedor, pesquise por capacidade e resolva variantes de nome de modelo."
},
"cli-chat": {
"name": "CLI: Chat",
- "description": "Envie conclusões de chat, transmita respostas e inicie uma sessão REPL interativa a partir da CLI. Suporta todos os provedores do OmniRoute, roteamento de combos e configuração de prompt do sistema."
+ "description": "Envie chat completions, transmita respostas e inicie uma sessão REPL interativa a partir da CLI. Suporta todos os provedores do OmniRoute, roteamento por combo e configuração de prompt de sistema."
},
"cli-routing": {
"name": "CLI: Roteamento e Combos",
- "description": "Crie, liste, atualize e exclua combos de roteamento a partir da CLI. Teste estratégias de roteamento, inspecione métricas de combos e configure cadeias de fallback interativamente."
+ "description": "Crie, liste, atualize e exclua combos de roteamento a partir da CLI. Teste estratégias de roteamento, inspecione métricas de combo e configure cadeias de fallback interativamente."
},
"cli-resilience": {
"name": "CLI: Resiliência e Cotas",
- "description": "Inspecione e gerencie estados de circuit-breaker, cooldowns de conexão, limites de cotas e níveis de backoff a partir da CLI. Reinicie provedores travados e configure limites de resiliência."
+ "description": "Inspecione e gerencie estados do circuit breaker, cooldowns de conexão, limites de cota e níveis de backoff a partir da CLI. Redefina provedores travados e configure limites de resiliência."
},
"cli-compression": {
- "name": "CLI: Compressão",
- "description": "Configure e teste a compressão de prompts a partir da CLI. Gerencie filtros RTK, regras Caveman, modos de compressão empilhados e visualize a saída da compressão com prompts reais."
+ "name": "CLI: Compression",
+ "description": "Configure e teste a compressão de prompt a partir da CLI. Gerencie filtros RTK, regras Caveman, modos de compressão empilhados e pré-visualize a saída da compressão com prompts reais."
},
"cli-contexts": {
"name": "CLI: Contextos e Sessões",
- "description": "Gerencie configurações de engenharia de contexto, conjuntos de filtros RTK e sessões de conversa a partir da CLI. Aplique configurações de context-relay e inspecione pipelines de contexto ativos."
+ "description": "Gerencie configurações de engenharia de contexto, conjuntos de filtros RTK e sessões de conversa a partir da CLI. Aplique configurações de context relay e inspecione pipelines de contexto ativos."
},
"cli-cost-usage": {
"name": "CLI: Custo e Uso",
- "description": "Visualize detalhamentos de custos, uso de tokens e logs de chamadas a partir da CLI. Filtre por provedor, modelo ou intervalo de datas. Exporte relatórios de uso e inspecione os gastos por conexão."
+ "description": "Veja detalhamentos de custo, uso de tokens e logs de chamadas a partir da CLI. Filtre por provedor, modelo ou período. Exporte relatórios de uso e inspecione gastos por conexão."
},
"cli-mcp": {
"name": "CLI: MCP",
- "description": "Inspecione o status do servidor MCP, liste ferramentas e escopos registrados, execute invocações de ferramentas e gerencie logs de auditoria do MCP a partir da CLI."
+ "description": "Inspecione o status do servidor MCP, liste ferramentas e escopos registrados, execute invocações de ferramentas e gerencie logs de auditoria MCP a partir da CLI."
},
"cli-a2a": {
"name": "CLI: Protocolo A2A",
- "description": "Interaja com o servidor A2A do OmniRoute a partir da CLI. Envie tarefas, inspecione o histórico de execução de habilidades e teste o protocolo agente a agente JSON-RPC 2.0 interativamente."
+ "description": "Interaja com o servidor A2A do OmniRoute a partir da CLI. Envie tarefas, inspecione o histórico de execução de skills e teste o protocolo agent-to-agent JSON-RPC 2.0 interativamente."
},
"cli-tunnel": {
"name": "CLI: Túneis",
- "description": "Inicie e pare conexões de túnel (ngrok, Cloudflare, personalizado) a partir da CLI. Inspecione URLs de túneis ativos, configure a autenticação e teste a acessibilidade externa."
+ "description": "Inicie e pare conexões de túnel (ngrok, Cloudflare, personalizado) a partir da CLI. Inspecione URLs de túnel ativas, configure a autenticação e teste a alcançabilidade externa."
},
"cli-backup-sync": {
"name": "CLI: Backup e Sincronização",
- "description": "Faça backup e restaure dados do OmniRoute a partir da CLI. Dispare snapshots incrementais, sincronize com o armazenamento em nuvem, gerencie cronogramas de backup e restaure a partir de arquivos de backup."
+ "description": "Faça backup e restaure dados do OmniRoute a partir da CLI. Acione snapshots incrementais, sincronize com armazenamento em nuvem, gerencie agendamentos de backup e restaure a partir de arquivos de arquivamento."
},
"cli-policy-audit": {
"name": "CLI: Política e Auditoria",
- "description": "Inspecione logs de auditoria, gerencie políticas de acesso, visualize dados de telemetria e revise o histórico de solicitações a partir da CLI. Filtre por tipo de evento, usuário ou intervalo de tempo para fluxos de trabalho de conformidade."
+ "description": "Inspecione logs de auditoria, gerencie políticas de acesso, veja dados de telemetria e revise o histórico de solicitações a partir da CLI. Filtre por tipo de evento, usuário ou período para fluxos de conformidade."
},
"cli-batches": {
"name": "CLI: Lotes e Arquivos",
- "description": "Envie e monitore trabalhos de inferência em lote a partir da CLI. Faça upload e gerencie arquivos para processamento em lote, recupere resultados e integre pipelines de lote com fluxos de trabalho de CI/CD."
+ "description": "Envie e monitore jobs de inferência em lote a partir da CLI. Envie e gerencie arquivos para processamento em lote, obtenha resultados e integre pipelines de lote com fluxos de CI/CD."
},
"cli-eval": {
"name": "CLI: Evals",
- "description": "Crie e execute suítes de avaliação, acompanhe o progresso de benchmarks ao vivo, visualize scorecards, compare o desempenho de modelos e integre execuções de avaliação com fluxos de trabalho de CI a partir da CLI."
+ "description": "Crie e execute suítes de avaliação, acompanhe o progresso de benchmarks em tempo real, veja scorecards, compare o desempenho de modelos e integre execuções de eval com fluxos de CI a partir da CLI."
},
"cli-plugins-skills": {
- "name": "CLI: Plugins, Habilidades e Memória",
+ "name": "CLI: Plugins, Skills e Memória",
"description": "Gerencie Omni Skills (listar, instalar, testar, remover), plugins (criar, configurar) e memória persistente (pesquisar, adicionar, limpar) a partir da CLI."
},
"cli-setup": {
"name": "CLI: Setup e Configuração",
- "description": "Execute a configuração inicial, defina as configurações globais da CLI, gerencie variáveis de ambiente, verifique atualizações e configure a inicialização automática por meio dos comandos de setup e config da CLI."
+ "description": "Execute a configuração inicial, configure as opções globais da CLI, gerencie variáveis de ambiente, verifique atualizações e configure o início automático via os comandos setup e config da CLI."
},
"cli-skill-collector": {
- "name": "CLI: Coletor de Habilidades de Agente",
- "description": "Detecte ferramentas de codificação de CLI instaladas (Claude Code, Codex, Cursor, Copilot, Cline e mais), pesquise no GitHub por habilidades de agente correspondentes e instale-as nas ferramentas detectadas por meio das APIs integradas do OmniRoute."
+ "name": "CLI: Coletor de Agent Skills",
+ "description": "Detecte ferramentas de codificação CLI instaladas (Claude Code, Codex, Cursor, Copilot, Cline e outras), pesquise no GitHub agent skills correspondentes e instale-as nas ferramentas detectadas via as APIs integradas do OmniRoute."
},
"config-codex-cli": {
- "name": "Configuração: Codex CLI",
- "description": "Fluxo de trabalho passo a passo do agente para configurar a CLI do OpenAI Codex em qualquer máquina (Linux, macOS, Windows) para usar o OmniRoute como um backend compatível com a OpenAI. Detecta o SO e o shell, grava o arquivo config.toml e 7 perfis nomeados, define variáveis de ambiente e verifica a configuração."
+ "name": "Config: Codex CLI",
+ "description": "Fluxo de trabalho passo a passo para configurar a Codex CLI da OpenAI em qualquer máquina (Linux, macOS, Windows) para usar o OmniRoute como backend compatível com OpenAI. Detecta o SO e o shell, grava config.toml e 7 perfis nomeados, define variáveis de ambiente e verifica a configuração."
},
"omni-github-skills": {
- "name": "Descoberta de Habilidades do GitHub",
- "description": "Pesquise, pontue, escaneie e importe habilidades de agente de repositórios do GitHub que contenham SKILL.md, CLAUDE.md, .cursorrules e arquivos de habilidades de agente semelhantes. Descubra habilidades da comunidade em mais de 160 categorias de provedores, avalie a relevância com pontuação heurística, verifique a presença de malware ou segredos codificados diretamente no código e instale nos diretórios de agentes do Hermes, Claude Code, Gemini CLI ou OpenCode."
+ "name": "Descoberta de Skills no GitHub",
+ "description": "Pesquise, pontue, escaneie e importe agent skills de repositórios do GitHub que contenham arquivos SKILL.md, CLAUDE.md, .cursorrules e similares. Descubra skills da comunidade em mais de 160 categorias de provedor, avalie a relevância com pontuação heurística, verifique malware ou segredos codificados, e instale nos diretórios de agente do Hermes, Claude Code, Gemini CLI ou OpenCode."
}
},
"pageTitle": "Agent Skills",
- "pageSubtitle": "Ensine seu agente a operar o OmniRoute — 23 áreas de API + 21 famílias de CLI",
+ "pageSubtitle": "Ensine seu agente a operar o OmniRoute — 22 áreas de API + 20 famílias de CLI",
"conceptCard": {
"agent": {
"title": "Agent Skills — Saída",
@@ -12195,8 +12197,8 @@
"coverageLabel": "Cobertura",
"mcpUrl": "URL MCP",
"a2aLink": "A2A",
- "mcpPrompt": "Adicione este endpoint MCP ao seu agente para fornecer a ele 37 ferramentas OmniRoute.",
- "a2aPrompt": "Registre este Agent Card com seu orquestrador para habilitar a delegação de tarefas A2A.",
+ "mcpPrompt": "Adicione este endpoint MCP ao seu agente para dar a ele 37 ferramentas do OmniRoute.",
+ "a2aPrompt": "Registre este Agent Card no seu orquestrador para habilitar a delegação de tarefas A2A.",
"refresh": "Atualizar",
"copyUrl": "Copiar URL",
"viewOnGithub": "Ver no GitHub",
@@ -12215,25 +12217,25 @@
"regenerateError": "Falha ao regenerar skills."
},
"freeProviderRankingsPage": {
- "title": "Classificações de Provedores Gratuitos",
- "subtitle": "Melhores provedores gratuitos classificados pelas pontuações de ELO dos modelos dos rankings da Arena AI",
- "loading": "Carregando classificações...",
- "errorLoading": "Falha ao carregar classificações",
- "emptyState": "Nenhuma classificação disponível ainda. Os dados de ELO da Arena são sincronizados na inicialização (diariamente) — volte em breve ou acione uma sincronização manual. Desative a Sincronização de ELO da Arena em Feature Flags ou defina ARENA_ELO_SYNC_ENABLED=false para desativar.",
- "bestModel": "Melhores",
- "allCategories": "Todas as Categorias",
- "categoryDefault": "Padrão",
- "categoryCoding": "Programação",
- "categoryReview": "Revisão",
- "categoryDocumentation": "Documentação",
- "categoryDebugging": "Depuração",
- "colRank": "Posição",
- "colProvider": "Provedor",
- "colTopModel": "Melhor Modelo",
- "colScore": "Pontuação",
- "colAvgScore": "Pontuação Média",
- "colModels": "Modelos",
- "colType": "Tipo",
+ "title": "__MISSING__:Free Provider Rankings",
+ "subtitle": "__MISSING__:Best free providers ranked by model ELO scores from Arena AI leaderboards",
+ "loading": "__MISSING__:Loading rankings...",
+ "errorLoading": "__MISSING__:Failed to load rankings",
+ "emptyState": "__MISSING__:No rankings available yet. Arena ELO data syncs on startup (daily) — check back shortly, or trigger a manual sync. Disable Arena ELO Sync in Feature Flags or set ARENA_ELO_SYNC_ENABLED=false to opt out.",
+ "bestModel": "__MISSING__:Best",
+ "allCategories": "__MISSING__:All Categories",
+ "categoryDefault": "__MISSING__:Default",
+ "categoryCoding": "__MISSING__:Coding",
+ "categoryReview": "__MISSING__:Review",
+ "categoryDocumentation": "__MISSING__:Documentation",
+ "categoryDebugging": "__MISSING__:Debugging",
+ "colRank": "__MISSING__:Rank",
+ "colProvider": "__MISSING__:Provider",
+ "colTopModel": "__MISSING__:Top Model",
+ "colScore": "__MISSING__:Score",
+ "colAvgScore": "__MISSING__:Avg Score",
+ "colModels": "__MISSING__:Models",
+ "colType": "__MISSING__:Type",
"filterConfiguredOnly": "Somente configurados",
"filterAvailableOnly": "Somente disponíveis",
"filterAvailableOnlyHelp": "Ocultar provedores cujas conexões estão todas limitadas por taxa ou sem cota.",
@@ -12241,13 +12243,13 @@
"configuredOnlyHint": "Mostrar apenas provedores com conexões ativas",
"noConfiguredProviders": "Nenhum provedor configurado encontrado. Adicione uma conexão de provedor primeiro.",
"colConfigured": "Status",
- "typeAll": "Todos os Tipos",
- "typeNoauth": "Sem Cadastro",
- "typeOauth": "Login via OAuth",
- "typeApikey": "Chave de API",
- "sortTypeFirst": "Mais fáceis primeiro",
- "sortTypeFirstHelp": "Agrupar por esforço de cadastro (Sem Cadastro → Login via OAuth → Chave de API), mantendo a ordem de qualidade dentro de cada grupo",
- "typeLegend": "Sem Cadastro = configuração zero · Login via OAuth = entre com sua própria conta · Chave de API = use sua própria chave ou o nível gratuito daquele provedor"
+ "typeAll": "__MISSING__:All Types",
+ "typeNoauth": "__MISSING__:No Signup",
+ "typeOauth": "__MISSING__:OAuth Login",
+ "typeApikey": "__MISSING__:API Key",
+ "sortTypeFirst": "__MISSING__:Easiest first",
+ "sortTypeFirstHelp": "__MISSING__:Group by signup effort (No Signup → OAuth Login → API Key), keeping quality order within each group",
+ "typeLegend": "__MISSING__:No Signup = zero setup · OAuth Login = sign in with your own account · API Key = bring your own key or that provider's free tier"
},
"discovery": {
"title": "Descoberta de provedores",
@@ -12275,11 +12277,11 @@
"models": "Modelos"
},
"noAuthProvider": {
- "title": "Nenhuma autenticação necessária",
- "description": "Este provedor está pronto para uso imediato — sem necessidade de cadastro ou chave de API.",
- "accountDescription": "Pronto para usar — sem necessidade de cadastro. Adicione contas para rotação de limite de taxa.",
+ "title": "Não requer autenticação",
+ "description": "Este provedor está pronto para uso imediato — não requer cadastro nem chave de API.",
+ "accountDescription": "Pronto para uso — não requer cadastro. Adicione contas para rotação de limite de taxa.",
"addAccount": "Adicionar Conta",
- "accountName": "Conta {provider} {number}",
+ "accountName": "Conta {number} do {provider}",
"accounts": "Contas ({count})",
"adding": "Adicionando...",
"autoGeneratedAccount": "Usando uma conta gerada automaticamente. Selecione “{addLabel}” para rotação de limite de taxa.",
@@ -12288,12 +12290,12 @@
"removeAccount": "Remover conta",
"proxyForAccount": "Proxy para a Conta {number}",
"saved": "Salvo",
- "custom": "Personalizado",
+ "custom": "Custom",
"noSavedProxies": "Nenhum proxy salvo — adicione um em Configurações → Proxy",
"directConnection": "Direto (sem proxy)",
- "host": "Host",
+ "host": "Anfitrião",
"port": "Porta",
- "usernameOptional": "Nome de usuário (opcional)",
+ "usernameOptional": "Usuário (opcional)",
"passwordOptional": "Senha (opcional)",
"cancel": "Cancelar",
"saving": "Salvando...",
@@ -12305,29 +12307,29 @@
"updateProviderFailed": "Falha ao atualizar provedor",
"providerEnabled": "{provider} ativado",
"providerDisabled": "{provider} desativado",
-"providerAdded": "{provider} adicionado",
-"add": "Adicionar",
-"manualApiKey": "Usar uma chave de API manual",
-"createDahlTokenFailed": "__MISSING__:Failed to create Dahl token",
-"providerProxy": "__MISSING__:Proxy",
-"providerProxyConfigureHint": "__MISSING__:Configure proxy",
-"providerProxyTitleConfigured": "__MISSING__:Proxy configured: {host}"
+ "providerAdded": "{provider} adicionado",
+ "add": "Adicionar",
+ "manualApiKey": "Usar uma chave de API manual",
+ "createDahlTokenFailed": "__MISSING__:Failed to create Dahl token",
+ "providerProxy": "__MISSING__:Proxy",
+ "providerProxyConfigureHint": "__MISSING__:Configure proxy",
+ "providerProxyTitleConfigured": "__MISSING__:Proxy configured: {host}"
},
"gamification": {
"leaderboardScopes": {
- "allTime": "Todo o período",
+ "allTime": "Tudo",
"weekly": "Semanal",
"monthly": "Mensal",
- "tokensShared": "Tokens compartilhados"
+ "tokensShared": "Tokens Compartilhados"
},
- "leaderboardLoadFailed": "Falha ao carregar a tabela de classificação (HTTP {status})",
+ "leaderboardLoadFailed": "Falha ao carregar ranking (HTTP {status})",
"scope": "Escopo",
"tokensShared": "tokens compartilhados",
"points": "pontos",
- "rank": "Classificação",
+ "rank": "Posição",
"name": "Nome",
"score": "Pontuação",
- "leaderboardEmpty": "Nenhuma entrada ainda para este escopo. Comece a usar o OmniRoute para aparecer na tabela de classificação!",
+ "leaderboardEmpty": "Ainda não há entradas para este escopo. Comece a usar o OmniRoute para aparecer no ranking!",
"profileLoadFailed": "Falha ao carregar dados do perfil",
"levelTitles": {
"beginner": "Iniciante",
@@ -12343,13 +12345,13 @@
"platinum": "Platina",
"diamond": "Diamante"
},
- "tierLabel": "Tier: {tier}",
- "dayStreak": "Sequência de {count} dias",
+ "tierLabel": "Nível: {tier}",
+ "dayStreak": "sequência de {count} dias",
"levelProgress": "Nível {current} → {next}",
- "totalXpEarned": "{count} XP total ganho",
+ "totalXpEarned": "{count} de XP total ganho",
"maintainStreak": "Continue usando o OmniRoute todos os dias para manter sua sequência!",
"badgesTitle": "Emblemas ({earned}/{total})",
- "noBadges": "Nenhum emblema disponível ainda.",
+ "noBadges": "Ainda não há emblemas disponíveis.",
"hiddenBadge": "Conquista oculta",
"earnedDate": "Conquistado em {date}",
"earnedOn": "Conquistado em {date}",
@@ -12371,23 +12373,23 @@
"badges": {
"first-token": {
"name": "Primeiro Token",
- "description": "Fez sua primeira requisição de API",
- "criteria": "Complete sua primeira requisição de API através do OmniRoute."
+ "description": "Fez sua primeira solicitação de API",
+ "criteria": "Complete sua primeira solicitação de API pelo OmniRoute."
},
"token-consumer": {
"name": "Consumidor de Tokens",
- "description": "Fez 1.000 requisições de API",
- "criteria": "Complete 1.000 requisições de API através do OmniRoute."
+ "description": "Fez 1.000 solicitações de API",
+ "criteria": "Complete 1.000 solicitações de API pelo OmniRoute."
},
"token-machine": {
"name": "Máquina de Tokens",
- "description": "Fez 10.000 requisições de API",
- "criteria": "Complete 10.000 requisições de API através do OmniRoute."
+ "description": "Fez 10.000 solicitações de API",
+ "criteria": "Complete 10.000 solicitações de API pelo OmniRoute."
},
"token-whale": {
"name": "Baleia de Tokens",
- "description": "Fez 100.000 requisições de API",
- "criteria": "Complete 100.000 requisições de API através do OmniRoute."
+ "description": "Fez 100.000 solicitações de API",
+ "criteria": "Complete 100.000 solicitações de API pelo OmniRoute."
},
"generous": {
"name": "Generoso",
@@ -12421,18 +12423,18 @@
},
"architect": {
"name": "Arquiteto",
- "description": "Criou 3 rotas combo",
- "criteria": "Crie 3 rotas combo."
+ "description": "Criou 3 rotas de combo",
+ "criteria": "Crie 3 rotas de combo."
},
"speedster": {
"name": "Velocista",
- "description": "Manteve a latência média abaixo de 500 ms em 100 requisições",
- "criteria": "Mantenha a latência média abaixo de 500 ms em 100 requisições."
+ "description": "Manteve latência média abaixo de 500 ms em 100 solicitações",
+ "criteria": "Mantenha a latência média abaixo de 500 ms em 100 solicitações."
},
"resilient": {
"name": "Resiliente",
- "description": "Manteve 100% de uptime por 7 dias",
- "criteria": "Mantenha 100% de uptime por 7 dias consecutivos."
+ "description": "Manteve 100% de disponibilidade por 7 dias",
+ "criteria": "Mantenha 100% de disponibilidade por 7 dias consecutivos."
},
"daily-user": {
"name": "Usuário Diário",
@@ -12455,41 +12457,41 @@
"criteria": "Use o OmniRoute por 365 dias consecutivos."
},
"early-adopter": {
- "name": "Pioneiro",
- "description": "Entrou no primeiro mês da gamificação",
- "criteria": "Participe no primeiro mês após o lançamento da gamificação."
+ "name": "Adotante Pioneiro",
+ "description": "Entrou no primeiro mês de gamificação",
+ "criteria": "Entre no primeiro mês após o lançamento da gamificação."
},
"bug-hunter": {
"name": "Caçador de Bugs",
- "description": "Relatou 5 problemas",
- "criteria": "Relate 5 problemas válidos."
+ "description": "Reportou 5 issues",
+ "criteria": "Reporte 5 issues válidas."
},
"contributor": {
- "name": "Colaborador",
- "description": "Mesclou 1 pull request",
- "criteria": "Ter 1 pull request mesclado no OmniRoute."
+ "name": "Contribuidor",
+ "description": "Teve 1 pull request mesclado",
+ "criteria": "Tenha 1 pull request mesclado no OmniRoute."
},
"community-leader": {
"name": "Líder da Comunidade",
"description": "Alcançou o top 10 em qualquer ranking",
- "criteria": "Alcançar o top 10 em qualquer ranking."
+ "criteria": "Alcance o top 10 em qualquer ranking."
},
"secret-badge": {
"name": "???",
- "description": "Uma conquista oculta aguarda...",
+ "description": "Uma conquista oculta espera...",
"criteria": "Complete a conquista oculta para revelar este emblema."
}
}
},
"featureFlags": {
- "title": "Feature Flags",
- "activeCount": "{count} ativas",
- "inactiveCount": "{count} inativas",
- "dbOverrideCount": "{count} substituições no BD",
- "searchPlaceholder": "Buscar flags...",
+ "title": "Sinalizadores de recursos",
+ "activeCount": "{count} ativo",
+ "inactiveCount": "{count} inativo",
+ "dbOverrideCount": "{count} Substituições de banco de dados",
+ "searchPlaceholder": "Pesquisar sinalizadores...",
"categories": {
- "all": "Todas",
- "security": "Segurança",
+ "all": "Todos",
+ "security": "Security",
"network": "Rede",
"policies": "Políticas",
"runtime": "Runtime",
@@ -12498,38 +12500,38 @@
"requiresRestart": "Requer Reinicialização"
},
"categoryLabel": "Categoria: {category}",
- "caution": "Atenção",
+ "caution": "Cuidado",
"danger": "Perigo",
"requiresRestart": "Requer reinicialização",
- "source": "Origem",
-"ccDiscoveryAliasesEnvWarning": "Ativo via variável de ambiente (EXPOSE_CC_DISCOVERY_ALIASES) — isso substitui qualquer alternância de painel abaixo.",
+ "source": "Source",
+ "ccDiscoveryAliasesEnvWarning": "Ativo via variável de ambiente (EXPOSE_CC_DISCOVERY_ALIASES) — isso substitui qualquer alternância de painel abaixo.",
"resetFlag": "Redefinir {label} para o padrão",
- "reset": "Redefinir",
- "loadFailed": "Falha ao carregar as feature flags",
- "updateFailedHttp": "Falha ao atualizar a flag: HTTP {status}",
- "updateFailed": "Falha ao atualizar a flag",
- "restartFailedHttp": "Falha ao reiniciar: HTTP {status}",
- "restartFailed": "Falha ao reiniciar",
- "resetOverridesFailedHttp": "Falha ao redefinir as substituições: HTTP {status}",
- "resetOverridesFailed": "Falha ao redefinir as substituições",
- "restartRequiredCount": "{count, plural, one {# alteração requer} other {# alterações requerem}} a reinicialização do servidor para entrar em vigor.",
- "restartRequiredDescription": "Essas flags só se aplicam após o recarregamento do processo. Reinicie agora ou continue editando — as flags pendentes permanecerão na fila até que você confirme.",
+ "reset": "Resetar",
+ "loadFailed": "Falha ao carregar feature flags",
+ "updateFailedHttp": "Falha ao atualizar flag: HTTP {status}",
+ "updateFailed": "Falha ao atualizar sinalizador",
+ "restartFailedHttp": "Falha na reinicialização: HTTP {status}",
+ "restartFailed": "Falha na reinicialização",
+ "resetOverridesFailedHttp": "Falha ao redefinir substituições: HTTP {status}",
+ "resetOverridesFailed": "Falha ao redefinir substituições",
+ "restartRequiredCount": "{count, plural, one {# alteração requer} other {# alterações requerem}} reiniciar o servidor para ter efeito.",
+ "restartRequiredDescription": "Essas flags só entram em vigor depois que o processo é recarregado. Reinicie agora ou continue editando — as flags pendentes ficam na fila até você confirmar.",
"restartServer": "Reiniciar Servidor",
"cancel": "Cancelar",
"restarting": "Reiniciando…",
- "confirmRestart": "Confirmar reinicialização",
- "restartViewDescription": "Essas flags só entram em vigor após a reinicialização do servidor. Alterne-as como qualquer outra flag — a alteração é mantida imediatamente, mas o novo valor só é lido na inicialização do processo. Use o banner Reiniciar servidor acima para aplicar.",
- "retry": "Tentar novamente",
- "noSearchResults": "Nenhuma flag corresponde à sua pesquisa",
+ "confirmRestart": "Confirmar Reinicialização",
+ "restartViewDescription": "Essas flags só entram em vigor após a reinicialização do servidor. Alterne-as como qualquer outra flag — a alteração é persistida imediatamente, mas o novo valor só é lido na inicialização do processo. Use o banner Reiniciar Servidor acima para aplicar.",
+ "retry": "Retry",
+ "noSearchResults": "Nenhuma sinalização corresponde à sua pesquisa",
"resetAllOverrides": "Redefinir todas as substituições",
- "confirmResetOverrides": "Redefinir todas as {count} substituições de banco de dados?",
- "resetting": "Redefinindo...",
- "confirmReset": "Confirmar redefinição",
+ "confirmResetOverrides": "Redefinir todas as {count} substituição(ões) do banco de dados?",
+ "resetting": "Resetando...",
+ "confirmReset": "Confirmar Redefinição",
"enumValues": {
- "off": "Desativado",
+ "off": "Off",
"warn": "Avisar",
"block": "Bloquear",
- "redact": "Ocultar",
+ "redact": "Redigir",
"disabled": "Desativado",
"dual": "Dual",
"alias": "Alias",
@@ -12537,198 +12539,198 @@
},
"definitions": {
"REQUIRE_API_KEY": {
- "description": "Exigir uma chave de API para todas as solicitações de entrada."
+ "description": "Exige uma chave de API para todas as solicitações recebidas."
},
"INPUT_SANITIZER_ENABLED": {
- "description": "Habilitar a sanitização de entrada para todas as solicitações."
+ "description": "Ativa a sanitização de entrada para todas as solicitações."
},
"INJECTION_GUARD_MODE": {
- "description": "Definir o modo de proteção contra injeção de prompt."
+ "description": "Define o modo de proteção contra injeção de prompt."
},
"PII_REDACTION_ENABLED": {
- "description": "Ocultar informações de identificação pessoal das solicitações."
+ "description": "Redige informações de identificação pessoal das solicitações."
},
"PII_RESPONSE_SANITIZATION": {
- "description": "Sanitizar informações de identificação pessoal nas respostas do provedor."
+ "description": "Sanitiza informações de identificação pessoal nas respostas do provedor."
},
"PII_RESPONSE_SANITIZATION_MODE": {
- "description": "Escolha como a PII da resposta é tratada: ocultar a substitui, avisar apenas a registra, bloquear rejeita a resposta e desativado desabilita a sanitização."
+ "description": "Escolha como as PII da resposta são tratadas: redact as substitui, warn apenas as registra, block rejeita a resposta, e off desativa a sanitização."
},
"OUTBOUND_SSRF_GUARD_ENABLED": {
- "description": "Bloquear solicitações de saída para intervalos de IP privados ou internos."
+ "description": "Bloqueia solicitações de saída para faixas de IP privadas ou internas."
},
"ALLOW_API_KEY_REVEAL": {
- "description": "Permitir que usuários autenticados do painel revelem chaves de API armazenadas em vez de ver apenas valores mascarados."
+ "description": "Permite que usuários autenticados do dashboard revelem chaves de API armazenadas em vez de ver apenas valores mascarados."
},
"ENABLE_TLS_FINGERPRINT": {
- "description": "Habilitar o modo furtivo de impressão digital TLS."
+ "description": "Ativa o modo furtivo de fingerprint TLS."
},
"ONEPROXY_ENABLED": {
- "description": "Habilitar o proxy de solicitações por meio do 1proxy."
+ "description": "Ativa o proxy de solicitações via 1proxy."
},
"PROXY_AUTO_SELECT_ENABLED": {
- "description": "Quando nenhum proxy for atribuído a uma conexão, selecionar automaticamente o primeiro proxy de registro em funcionamento. Desativado por padrão porque, caso contrário, um proxy de registro se torna um fallback global para todo o tráfego (#3332)."
+ "description": "Quando nenhum proxy é atribuído a uma conexão, seleciona automaticamente o primeiro proxy funcional do registro. Desativado por padrão porque, caso contrário, um proxy do registro se torna um fallback global para todo o tráfego (#3332)."
},
"OMNIROUTE_CONTROL_PLANE_PROXY_DIRECT_FALLBACK": {
- "description": "Permitir que os fluxos de OAuth e validação de provedor ignorem um proxy fixado quando as verificações de acessibilidade do proxy falharem. Desativado por padrão porque isso pode alterar o IP de saída da conta."
+ "description": "Permite que fluxos de OAuth e validação de provedor ignorem um proxy fixado quando as verificações de alcançabilidade do proxy falham. Desativado por padrão porque isso pode alterar o IP de saída da conta."
},
"MITM_DISABLE_TLS_VERIFY": {
- "description": "Desativar a verificação de certificado TLS para o proxy MITM."
+ "description": "Desativa a verificação de certificado TLS para o proxy MITM."
},
"OMNIROUTE_ALLOW_PRIVATE_PROVIDER_URLS": {
- "description": "Permitir URLs de provedores que apontam para redes privadas ou internas."
+ "description": "Permite URLs de provedor que apontam para redes privadas ou internas."
},
"OMNIROUTE_ALLOW_LOCAL_PROVIDER_URLS": {
- "description": "Permitir provedores em localhost, LAN e intervalos de IP privados. Isso é necessário para modelos locais compatíveis com a OpenAI e vem habilitado por padrão. Endpoints de metadados de nuvem, como 169.254.169.254, permanecem bloqueados."
+ "description": "Permite provedores em localhost, LAN e faixas de IP privadas. Isso é necessário para modelos locais compatíveis com OpenAI e está ativado por padrão. Endpoints de metadados de nuvem como 169.254.169.254 permanecem bloqueados."
},
"ENABLE_CC_COMPATIBLE_PROVIDER": {
- "description": "Habilitar o modo de provedor compatível com o Claude Code."
+ "description": "Ativa o modo de provedor compatível com o Claude Code."
},
"TOOL_POLICY_MODE": {
- "description": "Definir o modo de aplicação da política de uso de ferramentas."
+ "description": "Define o modo de aplicação da política de uso de ferramentas."
},
"RATE_LIMIT_AUTO_ENABLE": {
- "description": "Habilitar automaticamente o limite de taxa com base nos padrões de uso."
+ "description": "Ativa automaticamente a limitação de taxa com base em padrões de uso."
},
"ALLOW_MULTI_CONNECTIONS_PER_COMPAT_NODE": {
- "description": "Permitir várias conexões para cada nó de compatibilidade."
+ "description": "Permite múltiplas conexões para cada nó de compatibilidade."
},
"RESPONSES_PASSTHROUGH_DROP_COMMENTARY": {
- "description": "Remover itens de saída internos da fase de comentário dos fluxos de passagem da API de Respostas antes de encaminhá-los aos clientes. Desative esta flag para receber comentários brutos de upstream."
+ "description": "Remove itens de saída da fase de comentário interno dos streams de passthrough da Responses API antes de encaminhá-los aos clientes. Desative esta flag para receber o comentário bruto do upstream."
},
"OMNIROUTE_MCP_ENFORCE_SCOPES": {
- "description": "Impor restrições de escopo para o acesso a ferramentas MCP."
+ "description": "Aplica restrições de escopo para o acesso a ferramentas MCP."
},
"OMNIROUTE_MCP_COMPRESS_DESCRIPTIONS": {
- "description": "Comprimir as descrições das ferramentas MCP para reduzir o uso de tokens."
+ "description": "Comprime as descrições de ferramentas MCP para reduzir o uso de tokens."
},
"OMNIROUTE_ENABLE_RUNTIME_BACKGROUND_TASKS": {
- "description": "Habilitar o processamento de tarefas em segundo plano em tempo de execução."
+ "description": "Ativa o processamento de tarefas em segundo plano em runtime."
},
"OMNIROUTE_DISABLE_BACKGROUND_SERVICES": {
- "description": "Desativar todos os serviços em segundo plano, incluindo atualização de cota e sincronização."
+ "description": "Desativa todos os serviços em segundo plano, incluindo atualização de cota e sincronização."
},
"OMNIROUTE_RTK_TRUST_PROJECT_FILTERS": {
- "description": "Confiar nos filtros RTK no nível do projeto sem validação."
+ "description": "Confia em filtros RTK de nível de projeto sem validação."
},
"OMNIROUTE_ENABLE_LIVE_WS": {
- "description": "Iniciar o servidor WebSocket do painel em tempo real na importação na porta de loopback 20132. Defina a flag como 0 ou false para desativá-lo. A exposição à LAN também requer LIVE_WS_HOST=0.0.0.0 e LIVE_WS_ALLOWED_ORIGINS."
+ "description": "Inicia o servidor WebSocket do dashboard em tempo real na importação, na porta loopback 20132. Defina a flag como 0 ou false para desativá-lo. A exposição na LAN também requer LIVE_WS_HOST=0.0.0.0 e LIVE_WS_ALLOWED_ORIGINS."
},
"OMNIROUTE_CODEX_WS_ENABLED": {
- "description": "Permitir que o Codex use Responses via WebSocket. Quando desativado, o Codex recorre a HTTP Responses."
+ "description": "Permite que o Codex use Responses via WebSocket. Quando desativado, o Codex recorre a Responses via HTTP."
},
"OMNIROUTE_EMERGENCY_FALLBACK": {
- "description": "Rotear requisições com orçamento esgotado para o provedor e modelo de fallback gratuito de emergência."
+ "description": "Roteia solicitações com orçamento esgotado para o provedor e modelo de fallback gratuito de emergência."
},
"STREAM_RECOVERY_ENABLED": {
- "description": "Tentar novamente fluxos SSE upstream truncados de forma transparente antes que qualquer byte de resposta chegue ao cliente."
+ "description": "Tenta novamente streams SSE truncados do upstream de forma transparente antes que qualquer byte de resposta chegue ao cliente."
},
"STREAM_RECOVERY_MIDSTREAM_ENABLED": {
- "description": "Permitir que a recuperação de fluxo solicite a resposta novamente e a costure após os bytes já terem chegado ao cliente."
+ "description": "Permite que a recuperação de stream solicite a resposta novamente e a costure depois que bytes já chegaram ao cliente."
},
"MODEL_CATALOG_INCLUDE_NAMES": {
- "description": "Incluir campos de nome amigáveis para exibição nas respostas de /v1/models. Desative isso para clientes que aceitam apenas IDs de modelo."
+ "description": "Inclui campos de nome amigável para exibição nas respostas de /v1/models. Desative isso para clientes que aceitam apenas IDs de modelo."
},
"MODELS_CATALOG_PREFIX_MODE": {
- "description": "Controlar prefixos de ID de modelo em /v1/models: dual emite prefixos alias e canônicos, alias emite apenas prefixos curtos e canonical emite apenas IDs de provedor completos."
+ "description": "Controla os prefixos de ID de modelo em /v1/models: dual emite prefixos de alias e canônicos, alias emite apenas prefixos curtos, e canonical emite apenas IDs completos de provedor."
},
"ARENA_ELO_SYNC_ENABLED": {
- "description": "Sincronizar periodicamente os dados de ELO da tabela de classificação da Arena AI para classificações de inteligência de modelo."
+ "description": "Sincroniza periodicamente os dados de ELO do ranking Arena AI para classificações de inteligência de modelo."
},
"CLI_COMPAT_ALL": {
- "description": "Habilitar o modo de compatibilidade para todos os clientes CLI."
+ "description": "Ativa o modo de compatibilidade para todos os clientes CLI."
},
"MODEL_ALIAS_COMPAT_ENABLED": {
- "description": "Habilitar a camada de compatibilidade de alias de modelo."
+ "description": "Ativa a camada de compatibilidade de alias de modelo."
},
"PRICING_SYNC_ENABLED": {
- "description": "Sincronizar dados de preços automaticamente. A variável de ambiente PRICING_SYNC_ENABLED também deve ser true."
+ "description": "Sincroniza automaticamente os dados de preços. A variável de ambiente PRICING_SYNC_ENABLED também deve ser true."
},
"OMNIROUTE_AUTO_SYNC_CODEX_PROFILES": {
- "description": "Após a sincronização do provedor-modelo, regenerar os perfis ~/.codex/*.config.toml a partir do catálogo ativo. Isso nunca altera a configuração ativa ou padrão do Codex e fica desativado por padrão."
+ "description": "Após a sincronização de modelos do provedor, regenera os perfis ~/.codex/*.config.toml a partir do catálogo ativo. Isso nunca altera a configuração ativa ou padrão do Codex e está desativado por padrão."
},
"OMNIROUTE_AUTO_SYNC_CLAUDE_PROFILES": {
- "description": "Após a sincronização do provedor-modelo, regenerar os perfis ~/.claude/profiles//settings.json a partir do catálogo ativo. Isso nunca altera a configuração ativa ou padrão do Claude e fica desativado por padrão."
+ "description": "Após a sincronização de modelos do provedor, regenera os perfis ~/.claude/profiles//settings.json a partir do catálogo ativo. Isso nunca altera a configuração ativa ou padrão do Claude e está desativado por padrão."
},
"OMNIROUTE_DISABLE_LOCAL_HEALTHCHECK": {
- "description": "Desativar o endpoint de verificação de integridade da instância local."
+ "description": "Desativa o endpoint de verificação de saúde da instância local."
},
"OMNIROUTE_DISABLE_TOKEN_HEALTHCHECK": {
- "description": "Desativar a verificação de integridade de validação de token."
+ "description": "Desativa a verificação de saúde de validação de token."
},
"SKILLS_SANDBOX_NETWORK_ENABLED": {
- "description": "Habilitar acesso à rede no sandbox de habilidades."
+ "description": "Ativa o acesso à rede no sandbox de skills."
}
}
},
"comboControl": {
- "title": "Central de Controle de Combos",
- "unavailable": "Central de Controle de Combos indisponível",
+ "title": "Central de Controle de Combo",
+ "unavailable": "Central de Controle de Combo indisponível",
"backToCombos": "Voltar para Combos",
- "loadFailed": "Falha ao carregar a central de controle de combos",
+ "loadFailed": "Falha ao carregar a central de controle de combo",
"state": {
- "healthy": "Saudável",
+ "healthy": "Healthy",
"warning": "Precisa de atenção",
"critical": "Crítico",
"idle": "Ocioso"
},
"active": "Ativo",
"disabled": "Desativado",
- "description": "Visualização central somente leitura para comportamento de roteamento, integridade, cota, métricas de tempo de execução e decisões recentes para .",
+ "description": "Visão central somente leitura do comportamento de roteamento, saúde, cota, métricas de runtime e decisões recentes para .",
"refresh": "Atualizar",
"editInCombos": "Editar em Combos",
"requests": "Requisições",
"success": "Sucesso",
- "latency": "Latência",
+ "latency": "Latency",
"quota": "Cota",
- "rangeWindow": "Janela de {range}",
- "runtimeHealthBlend": "combinação de runtime/health",
+ "rangeWindow": "janela de {range}",
+ "runtimeHealthBlend": "combinação runtime/saúde",
"averageResponseTime": "tempo médio de resposta",
"worstQuota": "Pior cota",
"providerAccountTelemetry": "telemetria de provedor/conta",
"overview": "Visão geral",
"overviewDescription": "Estratégia, status de runtime e links de controle para este combo.",
- "strategy": "Estratégia",
+ "strategy": "Strategy",
"targets": "Alvos",
- "providers": "Provedores",
+ "providers": "Providers",
"targetCounts": "{configured} configurados · {resolved} resolvidos",
- "healthReasons": "Motivos de integridade",
+ "healthReasons": "Motivos de saúde",
"healthReason": {
- "noRecentTraffic": "Nenhum tráfego recente do combo",
- "lowSuccessRate": "Baixa taxa de sucesso",
+ "noRecentTraffic": "Nenhum tráfego recente de combo",
+ "lowSuccessRate": "Taxa de sucesso baixa",
"successBelowTarget": "Taxa de sucesso abaixo da meta",
- "highFallbackRate": "Alta taxa de fallback",
+ "highFallbackRate": "Taxa de fallback alta",
"elevatedFallbackRate": "Taxa de fallback elevada",
"quotaExhausted": "Pelo menos uma cota está esgotada",
"quotaNearlyExhausted": "A cota está quase esgotada",
"quotaGettingLow": "A cota está ficando baixa",
- "trafficHighlySkewed": "A distribuição de tráfego está altamente desequilibrada",
+ "trafficHighlySkewed": "A distribuição de tráfego está muito desequilibrada",
"comboHealthy": "O combo parece saudável"
},
"configuredTargets": "Alvos configurados",
- "configuredTargetsDescription": "As etapas salvas do combo, enriquecidas com dados de integridade correspondentes quando disponíveis.",
+ "configuredTargetsDescription": "As etapas salvas do combo, enriquecidas com dados de saúde correspondentes quando disponíveis.",
"noConfiguredTargets": "Nenhum alvo configurado.",
"runtimeConfig": "Configuração de runtime",
"runtimeConfigDescription": "Configurações avançadas selecionadas para este combo.",
"noRuntimeConfig": "Nenhuma configuração de runtime personalizada.",
"resolvedTargets": "Alvos de runtime resolvidos",
- "resolvedTargetsDescription": "Alvos achatados após a resolução de combos aninhados e métricas no nível do alvo.",
- "noResolvedTargetHealth": "Nenhuma integridade de alvo resolvida ainda.",
+ "resolvedTargetsDescription": "Alvos achatados após a resolução de combos aninhados e métricas por alvo.",
+ "noResolvedTargetHealth": "Ainda não há saúde de alvo resolvida.",
"quotaDistribution": "Cota e distribuição",
- "noQuotaSnapshots": "Nenhum snapshot de cota para esta janela de combo.",
- "usageSkew": "Desequilíbrio de uso",
+ "noQuotaSnapshots": "Nenhum snapshot de cota para esta janela do combo.",
+ "usageSkew": "Distorção de uso",
"recentDecisions": "Decisões de roteamento recentes",
- "recentDecisionsDescription": "Logs de chamadas recentes filtrados por este nome de combo. Abra o Analytics para explicabilidade total.",
- "noRecentLogs": "Nenhum log de chamada de combo recente encontrado.",
- "quickLinks": "Links rápidos",
- "comboHealth": "Integridade do combo",
- "callLogs": "Logs de chamadas",
+ "recentDecisionsDescription": "Logs de chamadas recentes filtrados pelo nome deste combo. Abra Analytics para explicabilidade completa.",
+ "noRecentLogs": "Nenhum log de chamada recente encontrado para este combo.",
+ "quickLinks": "Atalhos",
+ "comboHealth": "Combo Health",
+ "callLogs": "Logs de Chamadas",
"costs": "Custos",
"playground": "Playground",
"nestedCombo": "Combo aninhado",
- "modelTarget": "Alvo do modelo",
- "weight": "{value}% de peso",
- "comboReference": "Referência do combo",
+ "modelTarget": "Alvo de modelo",
+ "weight": "peso de {value}%",
+ "comboReference": "Referência de combo",
"accountShort": "conta {id}",
"keyShort": "chave {id}",
"stepShort": "etapa {id}",
@@ -12740,27 +12742,27 @@
},
"usageLimits": {
"usdUsageQuota": "Cota de uso em USD",
- "usdUsageQuotaDescription": "Bloqueia esta chave com um erro de API 400 após o gasto local em USD atingir a cota diária ou semanal configurada.",
+ "usdUsageQuotaDescription": "Bloqueia esta chave com um erro de API 400 depois que o gasto local em USD atinge a cota diária ou semanal configurada.",
"dailyQuotaUsd": "Cota diária (USD)",
"weeklyQuotaUsd": "Cota semanal (USD)",
- "quotaWindowDescription": "A cota semanal segue a redefinição semanal em cache do Claude quando disponível; caso contrário, recorre a uma janela móvel de 7 dias. A cota diária usa o dia do calendário de Fortaleza.",
+ "quotaWindowDescription": "A cota semanal segue a redefinição semanal em cache do Claude quando disponível; caso contrário, recorre a uma janela contínua de 7 dias. A cota diária usa o dia de calendário de Fortaleza.",
"apiKeyUsdQuota": "Cota em USD da chave de API",
- "apiKeyUsdQuotaDescription": "Quando ativado, @@om-usage retorna cota diária, cota semanal, gasto diário e gasto semanal em USD. O semanal segue a redefinição em cache do Claude quando disponível.",
+ "apiKeyUsdQuotaDescription": "Quando ativado, @@om-usage retorna cota diária, cota semanal, gasto diário e gasto semanal em USD. A semanal segue a redefinição em cache do Claude quando disponível.",
"enabled": "Ativado",
"disabled": "Desativado",
"dailySpend": "Gasto diário",
"weeklySpend": "Gasto semanal",
"dailyQuota": "Cota diária",
"weeklyQuota": "Cota semanal",
- "fallbackRollingDays": "fallback: {days} dias móveis",
- "fallbackRollingDaysShort": "Fallback de {days}d móveis",
- "resetDueNow": "redefinição pendente agora",
+ "fallbackRollingDays": "fallback: janela contínua de {days} dias",
+ "fallbackRollingDaysShort": "Fallback contínuo {days}d",
+ "resetDueNow": "redefinição prevista para agora",
"resetsInHours": "redefine em {count}h",
"resetsInDays": "redefine em {count}d",
- "saveFailed": "Falha ao salvar os limites de uso",
+ "saveFailed": "Falha ao salvar limites de uso",
"saving": "Salvando...",
"saveQuota": "Salvar cota",
- "loadUsdCostsFailed": "Falha ao carregar os custos em USD",
+ "loadUsdCostsFailed": "Falha ao carregar custos em USD",
"usdCost": "Custo em USD",
"close": "Fechar",
"loadingUsdCosts": "Carregando custos em USD",
@@ -12770,53 +12772,53 @@
"rows": "Linhas",
"window": "Janela",
"unknown": "desconhecido",
- "fromRecordedReset": "A partir do reset de {quota} registrado",
- "fromObservedReset": "A partir do reset de {quota} observado",
- "fromReset": "A partir do reset de {quota}",
+ "fromRecordedReset": "A partir da redefinição {quota} registrada",
+ "fromObservedReset": "A partir da redefinição {quota} observada",
+ "fromReset": "A partir da redefinição {quota}",
"quotaEstimator": "Estimador de cota",
"noApiKeyUsage": "Nenhum uso de chave de API nesta janela do provedor.",
- "requestTokenCounts": "{requests} requisições · {tokens} tokens",
- "noUsdLimit": "Sem limite de USD"
+ "requestTokenCounts": "{requests} solicitações · {tokens} tokens",
+ "noUsdLimit": "Sem limite em USD"
},
"freeBudget": {
"title": "Orçamento de tokens gratuitos",
"remaining": "{remaining} restantes · {percent}% de {total}",
- "steadyMonth": "Estável / mês",
+ "steadyMonth": "Constante / mês",
"firstMonth": "Primeiro mês (+ créditos)",
"usedThisMonth": "Usado este mês",
- "segmentHint": "Cada segmento = um pool gratuito · pool com deduplicação, contagem honesta (sem tetos inflados de limite de taxa).",
- "boost": "Desbloqueie mais ~{tokens}/mês com uma recarga única de $10 no OpenRouter (50 → 1000 req/dia)",
- "uncapped": "Permanentemente gratuito, sem limite publicado (com limite de taxa) — acesso real, não contabilizado no destaque:",
- "tosRestricted": "{count, plural, one {# modelo marcado como restrito por ToS} other {# modelos marcados como restritos por ToS}} — você decide",
+ "segmentHint": "Cada segmento = um pool gratuito · deduplicado por pool, contagem honesta (sem tetos de limite de taxa inflados).",
+ "boost": "Desbloqueie ~{tokens} a mais/mês com uma recarga única de $10 na OpenRouter (50 → 1000 solicitações/dia)",
+ "uncapped": "Permanentemente gratuito, sem teto publicado (limitado por taxa) — acesso real, não contabilizado no total principal:",
+ "tosRestricted": "{count, plural, one {# modelo} other {# modelos}} sinalizado(s) como restrito(s) pelos Termos de Serviço — você decide",
"provider": "Provedor",
"model": "Modelo",
"modelName": "Nome do modelo",
"type": "Tipo",
"tokensMonth": "Tokens/mês",
"credit": "{tokens} de crédito",
- "hideTosRestricted": "Ocultar restritos por ToS",
+ "hideTosRestricted": "Ocultar restritos pelos Termos de Serviço",
"sort": "Ordenar",
"freeType": {
"daily": "diário",
"monthly": "mensal",
"creditMonthly": "crédito/mês",
- "uncapped": "sem limite",
+ "uncapped": "sem teto",
"signupCredit": "crédito de cadastro",
"keyless": "sem chave",
"discontinued": "descontinuado"
},
"tosTitle": {
- "avoid": "Restrito por ToS — revise os termos",
- "caution": "Atenção — cláusulas de uso pessoal / proxy",
+ "avoid": "Restrito pelos Termos de Serviço — revise os termos",
+ "caution": "Cuidado — cláusulas de uso pessoal / proxy",
"ok": "Geralmente permissivo"
}
},
"providerHealthAutopilot": {
"title": "Piloto Automático de Saúde do Provedor",
- "description": "Encontra provedores instáveis, tempos de espera de conta, erros obsoletos e correções manuais seguras.",
+ "description": "Encontra provedores instáveis, cooldowns de conta, erros desatualizados e correções manuais seguras.",
"loadFailed": "Falha ao carregar o relatório do piloto automático",
- "actionApplied": "{action} aplicado.",
- "actionFailed": "Ação do piloto automático falhou",
+ "actionApplied": "{action} aplicado(a).",
+ "actionFailed": "Falha na ação do piloto automático",
"refresh": "Atualizar",
"status": "Status",
"issues": "Problemas",
@@ -12829,57 +12831,57 @@
"loading": "carregando"
},
"loadingRecommendations": "Carregando recomendações do provedor...",
- "noRecommendations": "Nenhuma recomendação de integridade do provedor no momento.",
+ "noRecommendations": "Nenhuma recomendação de saúde do provedor no momento.",
"providerMetrics": "pontuação {score}% · ativos {active}/{total} · cooldown {cooldown} · bloqueios de modelo {lockouts}",
"providerState": {
"healthy": "saudável",
"degraded": "degradado",
- "down": "inoperante"
+ "down": "inativo"
},
"severity": {
- "info": "info",
+ "info": "informação",
"warning": "aviso",
"critical": "crítico"
},
- "remainingSeconds": "{seconds}s restantes",
+ "remainingSeconds": "restam {seconds}s",
"errorCode": "código {code}",
"applying": "Aplicando...",
"issue": {
- "circuitOpenTitle": "O disjuntor do provedor está aberto",
- "circuitOpenRecommendation": "Verifique a recuperação do upstream e, em seguida, redefina o disjuntor do provedor ou aguarde a janela de nova tentativa.",
+ "circuitOpenTitle": "O circuit breaker do provedor está aberto",
+ "circuitOpenRecommendation": "Verifique a recuperação do upstream e, em seguida, redefina o circuit breaker do provedor ou aguarde a janela de nova tentativa.",
"circuitRecoveryTitle": "O provedor está testando a recuperação",
- "circuitRecoveryRecommendation": "Aguarde a conclusão da próxima sondagem ou redefina o disjuntor após a verificação manual.",
- "terminalTitle": "{label} tem um estado de conta terminal",
- "terminalRecommendation": "Verifique o faturamento, autentique-se novamente ou substitua a credencial antes de reativá-la.",
+ "circuitRecoveryRecommendation": "Deixe a próxima sondagem terminar ou redefina o breaker após verificação manual.",
+ "terminalTitle": "{label} está em um estado terminal de conta",
+ "terminalRecommendation": "Verifique o faturamento, reautentique ou substitua a credencial antes de reativá-la.",
"cooldownTitle": "{label} está em cooldown temporário",
"cooldownRecommendation": "Aguarde a janela de nova tentativa do upstream ou limpe o cooldown após validar a recuperação.",
- "staleErrorTitle": "{label} tem um estado de erro desatualizado",
- "staleErrorRecommendation": "Limpe os campos de erro desatualizados para que a conexão fique elegível para o roteamento normal novamente.",
+ "staleErrorTitle": "{label} tem estado de erro desatualizado",
+ "staleErrorRecommendation": "Limpe os campos de erro desatualizados para que a conexão volte a ser elegível para o roteamento normal.",
"inactiveTitle": "{label} está desativado",
"inactiveRecommendation": "Reative apenas se isso não tiver sido desativado intencionalmente.",
"modelLockoutTitle": "{model} está bloqueado para uma conexão",
- "modelLockoutRecommendation": "Resolva o estado da conexão ou confirme se a cota/disponibilidade do modelo foi recuperada antes de limpar o bloqueio.",
- "quotaTitle": "O monitor de cota relata {status}",
- "quotaRecommendation": "Revise o uso da cota e alterne o tráfego para outra conexão saudável, se necessário."
+ "modelLockoutRecommendation": "Resolva o estado da conexão ou confirme que a cota/disponibilidade do modelo se recuperou antes de limpar o bloqueio.",
+ "quotaTitle": "O monitor de cota reporta {status}",
+ "quotaRecommendation": "Revise o uso da cota e redirecione o tráfego para outra conexão saudável, se necessário."
},
"action": {
- "resetProviderBreaker": "Redefinir disjuntor do provedor",
+ "resetProviderBreaker": "Redefinir breaker do provedor",
"clearConnectionCooldown": "Limpar cooldown da conexão",
"disableConnection": "Desativar esta conexão",
"clearStaleError": "Limpar estado de erro desatualizado",
"reactivateConnection": "Reativar conexão",
- "clearModelLockout": "Limpar bloqueio do modelo"
+ "clearModelLockout": "Limpar bloqueio de modelo"
}
},
"changelogPage": {
"newsTab": "Novidades",
- "changelogTab": "Registro de alterações",
- "loading": "Carregando registro de alterações...",
- "announcementsLoadFailed": "Não foi possível carregar os comunicados. Tente novamente mais tarde.",
- "noAnnouncements": "Nenhum comunicado novo no momento.",
+ "changelogTab": "Changelog",
+ "loading": "Carregando changelog...",
+ "announcementsLoadFailed": "Não foi possível carregar os anúncios. Tente novamente mais tarde.",
+ "noAnnouncements": "Nenhum anúncio novo no momento.",
"learnMore": "Saiba mais",
- "changelogLoadFailed": "Não foi possível carregar o registro de alterações. Tente novamente mais tarde.",
- "retry": "Tentar novamente",
+ "changelogLoadFailed": "Não foi possível carregar o changelog. Tente novamente mais tarde.",
+ "retry": "Retry",
"viewFullHistory": "Ver histórico completo no GitHub"
},
"reasoningRouting": {
@@ -12988,31 +12990,31 @@
"testButton": "Testar Chaos Mode",
"testTask": "Escreva um poema curto sobre inteligência artificial",
"loadingProviderModels": "Carregando provedores...",
- "systemPromptPlaceholder": "Opcional: substituir o prompt do sistema padrão do modo caos...",
+ "systemPromptPlaceholder": "Opcional: substituir o prompt de sistema padrão do modo caos...",
"enabled": "Ativado",
"disabled": "Desativado",
- "maxTokens": "Máximo de tokens",
- "maxTokensDesc": "Máximo de tokens por resposta do modelo. Valores mais altos custam mais e demoram mais.",
+ "maxTokens": "Tokens Máximos",
+ "maxTokensDesc": "Número máximo de tokens por resposta do modelo. Valores mais altos custam mais e demoram mais.",
"providerIdPlaceholder": "ID do provedor (digite ou selecione)",
"modelIdPlaceholder": "ID do modelo (opcional)",
"on": "LIGADO",
"off": "DESLIGADO",
"availableProviders": "Provedores disponíveis ({count})",
- "noProviderOverrides": "Sem substituições — todos os provedores ativos participarão com seus modelos padrão",
+ "noProviderOverrides": "Nenhuma substituição — todos os provedores ativos participarão com seus modelos padrão",
"resetFailed": "__MISSING__:Reset failed",
"resetSuccess": "__MISSING__:Config reset to defaults",
"running": "__MISSING__:Running...",
"testFailed": "__MISSING__:Test failed"
},
"kimiSponsorBanner": {
- "title": "A Kimi (Moonshot AI) é a amiga fundadora de código aberto do OmniRoute",
- "description": "O Kimi K3 traz uma janela de contexto de 1M de tokens e desempenho de codificação de ponta para o OmniRoute por uma fração do custo.",
+ "title": "A Kimi (Moonshot AI) agora é patrocinadora oficial do OmniRoute",
+ "description": "A Kimi K3 traz uma janela de contexto de 1M de tokens e desempenho de ponta em programação ao OmniRoute por uma fração do custo.",
"cta": "Obter Kimi Code",
- "partnerLinkNote": "Link de parceiro",
- "dismissAriaLabel": "Descartar"
+ "partnerLinkNote": "Link de parceria",
+ "dismissAriaLabel": "Dispensar"
},
-"featureFlagExposeFunctionalGatewayMirrorsDescription": "Anuncie os IDs de espelho / em /v1/models para modelos cujo proprietário canônico não possui credenciais ativas, mas um gateway de passagem com credenciais ativas os roteia. Aviso: adiciona entradas de catálogo para todos os clientes quando ativado globalmente.",
-"radarPage": {
+ "featureFlagExposeFunctionalGatewayMirrorsDescription": "Anuncie os IDs de espelho / em /v1/models para modelos cujo proprietário canônico não possui credenciais ativas, mas um gateway de passagem com credenciais ativas os roteia. Aviso: adiciona entradas de catálogo para todos os clientes quando ativado globalmente.",
+ "radarPage": {
"title": "Catálogo Radar",
"subtitle": "Catálogo de modelos gratuitos enriquecido com inteligência comunitária",
"loading": "Carregando catálogo...",
@@ -13068,7 +13070,7 @@
"campaignsUpsellCommunity": "Limited-time campaigns are a supporter extra. Everything on this page's fixed links stays free for everyone.",
"campaignsValidUntil": "Valid until {date}"
},
-"radarSetupPage": {
+ "radarSetupPage": {
"title": "Configuração do Provedor",
"setupTitle": "Configuração: {provider}",
"setupSubtitle": "Siga os passos abaixo para configurar este provedor",
@@ -13093,7 +13095,7 @@
"addConnectionDescription": "Ainda não tem uma conexão? Adicione uma no painel de provedores.",
"addConnectionLink": "Ir para provedores →"
},
-"resilienceConnections": {
+ "resilienceConnections": {
"title": "Resiliência de Conexão",
"table": {
"status": "Status",
@@ -13187,12 +13189,12 @@
"degraded.source.modelLockouts": "Bloqueios de Modelo",
"degraded.source.count": "Contagem de Conexões"
},
-"featureFlagCapabilityFilterEnabledDescription": "Rejeitar requisições antes do despacho quando o modelo alvo nao possui as capacidades necessarias (visao, ferramentas, saída estruturada, janela de contexto). Protege requisições diretas que ignoram o filtro de compatibilidade do combo.",
-"capabilityFilter.visionMismatch": "O provedor nao suporta visao para esta requisicao de imagem",
-"capabilityFilter.toolsMismatch": "O provedor nao suporta chamada de ferramentas",
-"capabilityFilter.structuredOutputMismatch": "O provedor nao suporta saida estruturada",
-"capabilityFilter.contextWindowMismatch": "A requisicao excede a janela de contexto do provedor",
-"publicSystem": {
+ "featureFlagCapabilityFilterEnabledDescription": "Rejeitar requisições antes do despacho quando o modelo alvo nao possui as capacidades necessarias (visao, ferramentas, saída estruturada, janela de contexto). Protege requisições diretas que ignoram o filtro de compatibilidade do combo.",
+ "capabilityFilter.visionMismatch": "O provedor nao suporta visao para esta requisicao de imagem",
+ "capabilityFilter.toolsMismatch": "O provedor nao suporta chamada de ferramentas",
+ "capabilityFilter.structuredOutputMismatch": "O provedor nao suporta saida estruturada",
+ "capabilityFilter.contextWindowMismatch": "A requisicao excede a janela de contexto do provedor",
+ "publicSystem": {
"notFound": {
"title": "__MISSING__:Page not found",
"description": "__MISSING__:The page you're looking for doesn't exist or has been moved.",
@@ -13329,7 +13331,7 @@
}
}
},
-"kiroAuthModal": {
+ "kiroAuthModal": {
"title": "__MISSING__:Connect {providerLabel}",
"chooseMethod": "__MISSING__:Choose your authentication method:",
"builderId": "__MISSING__:AWS Builder ID",
@@ -13371,7 +13373,7 @@
"errorApiKeyImportFailed": "__MISSING__:API key import failed",
"errorIdcStartUrlRequired": "__MISSING__:Please enter your IDC start URL"
},
-"kiroSocialOAuthModal": {
+ "kiroSocialOAuthModal": {
"title": "__MISSING__:Connect {providerLabel} via {providerName}",
"errorStartAuthorization": "__MISSING__:Failed to start authorization",
"errorAuthorizationExpired": "__MISSING__:Authorization expired. Start the login flow again.",
@@ -13390,7 +13392,7 @@
"errorTitle": "__MISSING__:Connection Failed",
"close": "__MISSING__:Close"
},
-"traeAuthModal": {
+ "traeAuthModal": {
"errorAuthorizationFailed": "__MISSING__:Authorization failed",
"errorPopupBlocked": "__MISSING__:Popup blocked — allow popups for this site, or paste the token manually below.",
"errorPopupClosed": "__MISSING__:Authorization window was closed before completing.",
@@ -13416,14 +13418,14 @@
"importToken": "__MISSING__:Import Token",
"cancel": "__MISSING__:Cancel"
},
-"sharedComponents": {
+ "sharedComponents": {
"distributeProxies": {
"distributing": "__MISSING__:Distributing...",
"complete": "__MISSING__:Complete",
"defaultLabel": "__MISSING__:Distribute Proxies"
}
},
-"providerTest": {
+ "providerTest": {
"dialogLabel": "__MISSING__:Test {provider}",
"deprecated": "__MISSING__:deprecated",
"risk": "__MISSING__:risk",
@@ -13458,7 +13460,7 @@
"tokens": "__MISSING__:Tokens"
}
},
-"proxyLog": {
+ "proxyLog": {
"detailAriaLabel": "__MISSING__:Proxy log detail",
"event": "__MISSING__:Proxy Event",
"close": "__MISSING__:Close proxy detail modal",
@@ -13476,7 +13478,7 @@
"error": "__MISSING__:Error",
"configuration": "__MISSING__:Proxy Configuration"
},
-"requestTimeline": {
+ "requestTimeline": {
"title": "__MISSING__:Request Timeline",
"modes": {
"follow": "__MISSING__:Follow",
@@ -13501,7 +13503,7 @@
"unknownModel": "__MISSING__:unknown",
"pending": "__MISSING__:pending"
},
-"metadata": {
+ "metadata": {
"compressionTitle": "__MISSING__:Compression",
"compressionDescription": "__MISSING__:Configure context compression settings to reduce token usage and costs.",
"relayTitle": "__MISSING__:OmniRoute — Relay Proxies",
@@ -13538,7 +13540,25 @@
"cancelConfirmMessage": "O hub aborta a execução no runner. Não dá para desfazer.",
"cancelFailed": "O hub recusou o cancelamento",
"close": "Fechar",
- "error": "Erro"
+ "error": "Erro",
+ "faroTitle": "Faro — porta-voz da frota",
+ "faroSubtitle": "Chat e voz, ancorados nos eventos reais da frota. Comandos destrutivos sempre pedem confirmação.",
+ "faroEmpty": "Pergunte sobre a frota — ex.: \"como está a frota?\"",
+ "faroPending": "O Faro está pedindo confirmação",
+ "faroPlaceholder": "fale com o Faro…",
+ "faroSend": "enviar",
+ "faroOffline": "Faro (porta-voz) fora do ar",
+ "yes": "Sim",
+ "no": "Não",
+ "pushToTalk": "Segure para falar",
+ "speakAnswers": "falar as respostas",
+ "voiceModels": "Modelos de voz (provider/model deste OmniRoute)",
+ "voiceIdle": "falar",
+ "voiceListening": "ouvindo…",
+ "voiceThinking": "pensando…",
+ "voiceSpeaking": "falando…",
+ "sttFailed": "Transcrição falhou (confira modelo/provider de STT)",
+ "ttsFailed": "Síntese de voz falhou (confira modelo/provider de TTS)",
+ "micDenied": "Microfone indisponível ou permissão negada"
}
-}
-
+}
\ No newline at end of file
diff --git a/src/lib/conductor/faroProxy.ts b/src/lib/conductor/faroProxy.ts
new file mode 100644
index 0000000000..be10df1416
--- /dev/null
+++ b/src/lib/conductor/faroProxy.ts
@@ -0,0 +1,46 @@
+/**
+ * Server-side proxy to Faro, the OmniConductor spokesperson (Conductor PRD RF4).
+ *
+ * Faro's `/ask` requires a valid hub credential (Bearer) — that token lives only
+ * in server env, so the browser talks to our /api/conductor/ask route, never to
+ * Faro directly. The response is whitelisted to {text, pending}: `pending` set
+ * means Faro is asking for confirmation (the UI offers Sim/Não); the safety gate
+ * itself lives in Faro's engine and is never bypassed here.
+ */
+
+import { z } from "zod";
+
+const faroResponseSchema = z.object({
+ text: z.string(),
+ pending: z.unknown().nullish(),
+});
+
+export interface FaroAnswer {
+ ok: boolean;
+ text: string;
+ pending: unknown;
+}
+
+export interface FaroProxyOptions {
+ fetchImpl?: typeof fetch;
+}
+
+const DEFAULT_FARO_URL = "http://127.0.0.1:7920";
+
+export async function askFaro(message: string, opts: FaroProxyOptions = {}): Promise {
+ const base = process.env.CONDUCTOR_SPOKESPERSON_URL?.trim() || DEFAULT_FARO_URL;
+ const token = process.env.CONDUCTOR_HUB_TOKEN?.trim() ?? "";
+ try {
+ const doFetch = opts.fetchImpl ?? fetch;
+ const res = await doFetch(`${base}/ask`, {
+ method: "POST",
+ headers: { authorization: `Bearer ${token}`, "content-type": "application/json" },
+ body: JSON.stringify({ message }),
+ });
+ if (!res.ok) return { ok: false, text: "", pending: null };
+ const parsed = faroResponseSchema.parse(await res.json());
+ return { ok: true, text: parsed.text, pending: parsed.pending ?? null };
+ } catch {
+ return { ok: false, text: "", pending: null };
+ }
+}
diff --git a/src/lib/env/runtimeEnv.ts b/src/lib/env/runtimeEnv.ts
index 577f228b62..bdf5cccb2a 100644
--- a/src/lib/env/runtimeEnv.ts
+++ b/src/lib/env/runtimeEnv.ts
@@ -70,6 +70,9 @@ export const webRuntimeEnvSchema = z.object({
BASE_URL: optionalHttpUrl,
NEXT_PUBLIC_BASE_URL: optionalHttpUrl,
CONDUCTOR_HUB_URL: optionalHttpUrl,
+
+ CONDUCTOR_SPOKESPERSON_URL: optionalHttpUrl,
+.8.50
CONDUCTOR_HUB_TOKEN: optionalTrimmedString,
OMNIROUTE_PORT: optionalPortEnv,
API_PORT: optionalPortEnv,
diff --git a/tests/unit/conductor-ask-route.test.ts b/tests/unit/conductor-ask-route.test.ts
new file mode 100644
index 0000000000..9edfffbc8d
--- /dev/null
+++ b/tests/unit/conductor-ask-route.test.ts
@@ -0,0 +1,85 @@
+import test from "node:test";
+import assert from "node:assert/strict";
+import fs from "node:fs";
+import os from "node:os";
+import path from "node:path";
+import { createServer, type Server } from "node:http";
+
+const TEST_DATA_DIR = fs.mkdtempSync(path.join(os.tmpdir(), "omniroute-conductor-ask-"));
+process.env.DATA_DIR = TEST_DATA_DIR;
+
+const core = await import("../../src/lib/db/core.ts");
+const askRoute = await import("../../src/app/api/conductor/ask/route.ts");
+
+const servers: Server[] = [];
+
+test.beforeEach(() => {
+ core.resetDbInstance();
+ fs.rmSync(TEST_DATA_DIR, { recursive: true, force: true });
+ fs.mkdirSync(TEST_DATA_DIR, { recursive: true });
+ delete process.env.CONDUCTOR_SPOKESPERSON_URL;
+});
+
+test.after(async () => {
+ core.resetDbInstance();
+ fs.rmSync(TEST_DATA_DIR, { recursive: true, force: true });
+ delete process.env.CONDUCTOR_SPOKESPERSON_URL;
+ while (servers.length > 0) {
+ const s = servers.pop();
+ await new Promise((resolve) => s?.close(resolve));
+ }
+});
+
+test("fonte: auth antes do proxy; token nunca manuseado na rota", () => {
+ const src = fs.readFileSync(path.join(process.cwd(), "src/app/api/conductor/ask/route.ts"), "utf8");
+ const authAt = src.indexOf("requireManagementAuth(");
+ assert.ok(authAt > 0);
+ assert.match(src, /if \(authError\) return authError;/);
+ assert.ok(src.indexOf("askFaro(") > authAt, "askFaro só depois do gate");
+ assert.ok(!src.includes("CONDUCTOR_HUB_TOKEN"), "token vive no faroProxy, não na rota");
+});
+
+test("POST valida o body (Zod) e repassa text+pending do Faro", async () => {
+ await new Promise((resolve) => {
+ const server = createServer((req, res) => {
+ res.writeHead(200, { "content-type": "application/json" });
+ res.end(JSON.stringify({ text: "frota vazia", pending: null }));
+ });
+ servers.push(server);
+ server.listen(0, "127.0.0.1", () => {
+ const addr = server.address();
+ process.env.CONDUCTOR_SPOKESPERSON_URL = `http://127.0.0.1:${typeof addr === "object" && addr ? addr.port : 0}`;
+ resolve();
+ });
+ });
+ const ok = await askRoute.POST(
+ new Request("http://localhost/api/conductor/ask", {
+ method: "POST",
+ headers: { "content-type": "application/json" },
+ body: JSON.stringify({ message: "como está a frota?" }),
+ })
+ );
+ assert.equal(ok.status, 200);
+ assert.deepEqual(await ok.json(), { text: "frota vazia", pending: null });
+
+ const bad = await askRoute.POST(
+ new Request("http://localhost/api/conductor/ask", {
+ method: "POST",
+ headers: { "content-type": "application/json" },
+ body: JSON.stringify({ message: "" }),
+ })
+ );
+ assert.equal(bad.status, 400, "mensagem vazia é rejeitada pelo Zod");
+});
+
+test("Faro fora do ar → 503 sanitizado", async () => {
+ process.env.CONDUCTOR_SPOKESPERSON_URL = "http://127.0.0.1:1";
+ const res = await askRoute.POST(
+ new Request("http://localhost/api/conductor/ask", {
+ method: "POST",
+ headers: { "content-type": "application/json" },
+ body: JSON.stringify({ message: "oi" }),
+ })
+ );
+ assert.equal(res.status, 503);
+});
diff --git a/tests/unit/conductor-faro-chat.test.ts b/tests/unit/conductor-faro-chat.test.ts
new file mode 100644
index 0000000000..91fe7bd4d5
--- /dev/null
+++ b/tests/unit/conductor-faro-chat.test.ts
@@ -0,0 +1,39 @@
+import test from "node:test";
+import assert from "node:assert/strict";
+import fs from "node:fs";
+import path from "node:path";
+
+// Invariantes de segurança/UX do chat com voz (componentes React: vitest-ui advisory + dashboard-typecheck).
+const CHAT = "src/app/(dashboard)/dashboard/conductor/FaroChat.tsx";
+
+function src(): string {
+ return fs.readFileSync(path.join(process.cwd(), CHAT), "utf8");
+}
+
+test("client fala SÓ com o OmniRoute: /api/conductor/ask + /api/v1/audio/* (nunca Faro/hub direto)", () => {
+ const s = src();
+ assert.match(s, /"use client"/);
+ assert.match(s, /\/api\/conductor\/ask/);
+ assert.match(s, /\/api\/v1\/audio\/transcriptions/);
+ assert.match(s, /\/api\/v1\/audio\/speech/);
+ assert.ok(!s.includes(":7920"), "endereço do Faro nunca no client");
+ assert.ok(!s.includes("CONDUCTOR_"), "nenhuma env do Conductor no client");
+});
+
+test("pending do Faro → botões Sim/Não que enviam 'sim'/'não' (trava de confirmação é do motor do Faro)", () => {
+ const s = src();
+ assert.match(s, /pending/);
+ assert.match(s, /"sim"/);
+ assert.match(s, /"não"/);
+});
+
+test("voz: push-to-talk com MediaRecorder/getUserMedia; STT multipart sem Content-Type manual; TTS via Blob com revoke", () => {
+ const s = src();
+ assert.match(s, /navigator\.mediaDevices\.getUserMedia/);
+ assert.match(s, /MediaRecorder/);
+ assert.match(s, /FormData\(\)/);
+ assert.ok(!/audio\/transcriptions[\s\S]{0,300}content-type/i.test(s), "multipart deixa o browser definir o boundary");
+ assert.match(s, /URL\.createObjectURL/);
+ assert.match(s, /URL\.revokeObjectURL/);
+ assert.match(s, /useTranslations\("conductor"\)/);
+});
diff --git a/tests/unit/conductor-faro-proxy.test.ts b/tests/unit/conductor-faro-proxy.test.ts
new file mode 100644
index 0000000000..1309316a44
--- /dev/null
+++ b/tests/unit/conductor-faro-proxy.test.ts
@@ -0,0 +1,61 @@
+import test from "node:test";
+import assert from "node:assert/strict";
+
+import { askFaro } from "../../src/lib/conductor/faroProxy.ts";
+
+function fakeFaro(body: unknown, status = 200) {
+ const calls: { url: string; auth: string | null; body: unknown }[] = [];
+ const impl = (async (url: string | URL | Request, init?: RequestInit) => {
+ calls.push({
+ url: String(url),
+ auth: (init?.headers as Record | undefined)?.authorization ?? null,
+ body: JSON.parse(String(init?.body ?? "{}")),
+ });
+ return new Response(JSON.stringify(body), { status });
+ }) as typeof fetch;
+ return { impl, calls };
+}
+
+test.beforeEach(() => {
+ process.env.CONDUCTOR_SPOKESPERSON_URL = "http://faro.test:7920";
+ process.env.CONDUCTOR_HUB_TOKEN = "tok-hub";
+});
+
+test.after(() => {
+ delete process.env.CONDUCTOR_SPOKESPERSON_URL;
+ delete process.env.CONDUCTOR_HUB_TOKEN;
+});
+
+test("repassa a mensagem ao /ask com o token server-side e devolve text+pending", async () => {
+ const { impl, calls } = fakeFaro({ text: "frota ok", pending: { kind: "cancel_task" }, extra: "NÃO passa" });
+ const r = await askFaro("como está a frota?", { fetchImpl: impl });
+ assert.deepEqual(r, { ok: true, text: "frota ok", pending: { kind: "cancel_task" } });
+ assert.equal(calls[0].url, "http://faro.test:7920/ask");
+ assert.equal(calls[0].auth, "Bearer tok-hub");
+ assert.deepEqual(calls[0].body, { message: "como está a frota?" });
+});
+
+test("pending null passa como null (sem confirmação pendente)", async () => {
+ const { impl } = fakeFaro({ text: "oi", pending: null });
+ const r = await askFaro("oi", { fetchImpl: impl });
+ assert.deepEqual(r, { ok: true, text: "oi", pending: null });
+});
+
+test("Faro fora do ar / erro HTTP → degradado {ok:false} sem lançar nem vazar corpo", async () => {
+ const failing = (async () => {
+ throw new Error("ECONNREFUSED");
+ }) as unknown as typeof fetch;
+ const down = await askFaro("oi", { fetchImpl: failing });
+ assert.equal(down.ok, false);
+ const { impl } = fakeFaro({ error: "segredo interno" }, 401);
+ const denied = await askFaro("oi", { fetchImpl: impl });
+ assert.equal(denied.ok, false);
+ assert.ok(!JSON.stringify(denied).includes("segredo interno"));
+});
+
+test("URL default do Faro é loopback :7920 quando a env não está setada", async () => {
+ delete process.env.CONDUCTOR_SPOKESPERSON_URL;
+ const { impl, calls } = fakeFaro({ text: "x", pending: null });
+ await askFaro("oi", { fetchImpl: impl });
+ assert.equal(calls[0].url, "http://127.0.0.1:7920/ask");
+});