Merge pull request #1321 from diegosouzapw/release/v3.6.7
Some checks failed
CI / Lint (push) Has been cancelled
CI / Build language matrix (push) Has been cancelled
CI / PR Test Policy (push) Has been cancelled
CI / Advanced Security Scans (push) Has been cancelled
CI / Build (push) Has been cancelled
Publish to Docker Hub / Build and Push Docker (multi-arch) (push) Has been cancelled
CI / i18n Validation (push) Has been cancelled
CI / Package Artifact (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Coverage (push) Has been cancelled
CI / E2E Tests (4/4) (push) Has been cancelled
CI / SonarQube (push) Has been cancelled
CI / PR Coverage Comment (push) Has been cancelled
CI / E2E Tests (1/4) (push) Has been cancelled
CI / E2E Tests (2/4) (push) Has been cancelled
CI / E2E Tests (3/4) (push) Has been cancelled
CI / Integration Tests (push) Has been cancelled
CI / Security Tests (push) Has been cancelled
CI / CI Dashboard (push) Has been cancelled

Release v3.6.7
This commit is contained in:
Diego Rodrigues de Sa e Souza 2026-04-16 08:46:47 -03:00 committed by GitHub
commit fb2141382f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
52 changed files with 6361 additions and 652 deletions

View file

@ -0,0 +1,27 @@
# Workflow: Fix CLI Node 22 TS Entrypoint Issue
## Issue Description
In OmniRoute >= 3.6.6, the `package.json` declares the main CLI binary as `bin/omniroute.ts`. While Node 22 introduced experimental support for executing TypeScript files natively via the `--experimental-strip-types` flag (and `--experimental-transform-types`), Node.js explicitly disables this feature for any files loaded from inside a `node_modules` directory.
When users install `omniroute` globally (or locally) via npm, the CLI shim points to `bin/omniroute.ts` inside `node_modules`. Running `omniroute` on Node 22 results in:
`Error [ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING]: Stripping types is currently unsupported for files under node_modules`
This makes the CLI completely unusable out-of-the-box on Node 22, despite the `engines` field claiming support for `>=22.22.2`.
## Proposed Solution
The CLI entrypoint distributed in the NPM package must be a JavaScript file, not a TypeScript file.
1. Restore `bin/omniroute.mjs` as the actual CLI entrypoint, or implement a build step during `npm run build:cli` that compiles `bin/omniroute.ts` to `bin/omniroute.mjs` before publishing.
2. Update `package.json` to point the `bin` field back to the compiled `.js`/`.mjs` file:
```json
"bin": {
"omniroute": "bin/omniroute.mjs"
}
```
3. Ensure `scripts/prepublish.ts` handles the compilation or validation of the binary entrypoint correctly so this regression doesn't happen again.
## Task
Please implement this fix, ensure the tests pass, and create a Pull Request against the main branch.

View file

@ -4,6 +4,19 @@
---
## [3.6.7] — 2026-04-16
### ✨ New Features
- **feat(i18n):** Add internationalization support for combo features and dashboard components; sync translations across 31 keys (#1318)
### 🐛 Bug Fixes
- **fix(cli):** Resolve Node 22 TS entrypoint incompatibility by using esbuild compilation (#1315)
- **fix(chat):** Preserve max_output_tokens for Responses API targets in chatCore sanitization (#1313)
- **fix(api):** API Manager usage stats showing 0 for all registered keys (#1310)
- **fix(dashboard):** Auto-scroll ActivityHeatmap to show current date (#1309)
## [3.6.6] — 2026-04-15
### ✨ New Features

View file

@ -1,7 +1,7 @@
openapi: 3.1.0
info:
title: OmniRoute API
version: 3.6.6
version: 3.6.7
description: |
OmniRoute is a local-first AI API proxy router. It provides an OpenAI-compatible
endpoint that routes requests to multiple AI providers with load balancing,

View file

@ -1,6 +1,6 @@
{
"name": "omniroute-desktop",
"version": "3.6.6",
"version": "3.6.7",
"description": "OmniRoute Desktop Application",
"main": "main.js",
"author": {

View file

@ -910,8 +910,21 @@ export async function handleChatCore({
}
// ── Common input sanitization (runs for ALL paths including passthrough) ──
// #994: Normalize max_output_tokens to max_tokens for universal compatibility
if (body.max_output_tokens !== undefined) {
// #994: Normalize between max_output_tokens and max_tokens for universal compatibility.
// For Responses API targets, max_output_tokens is the canonical field. For others,
// max_tokens is preferred. We handle normalization here to support passthrough
// paths where the translator is skipped.
if (targetFormat === FORMATS.OPENAI_RESPONSES) {
if (body.max_output_tokens === undefined) {
if (body.max_completion_tokens !== undefined) {
body.max_output_tokens = body.max_completion_tokens;
delete body.max_completion_tokens;
} else if (body.max_tokens !== undefined) {
body.max_output_tokens = body.max_tokens;
delete body.max_tokens;
}
}
} else if (body.max_output_tokens !== undefined) {
if (body.max_tokens === undefined) {
body.max_tokens = body.max_output_tokens;
}

View file

@ -1,6 +1,6 @@
{
"name": "@omniroute/open-sse",
"version": "3.6.6",
"version": "3.6.7",
"description": "Express SSE sidecar for OmniRoute — handles streaming, protocol translation, and provider orchestration",
"type": "module",
"main": "index.js",

6
package-lock.json generated
View file

@ -1,12 +1,12 @@
{
"name": "omniroute",
"version": "3.6.6",
"version": "3.6.7",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "omniroute",
"version": "3.6.6",
"version": "3.6.7",
"hasInstallScript": true,
"license": "MIT",
"workspaces": [
@ -20962,7 +20962,7 @@
},
"open-sse": {
"name": "@omniroute/open-sse",
"version": "3.6.6"
"version": "3.6.7"
}
}
}

View file

@ -1,6 +1,6 @@
{
"name": "omniroute",
"version": "3.6.6",
"version": "3.6.7",
"description": "Smart AI Router with auto fallback — route to FREE & cheap models, zero downtime. Works with Cursor, Cline, Claude Desktop, Codex, and any OpenAI-compatible tool.",
"type": "module",
"bin": {

View file

@ -166,24 +166,36 @@ export default function ApiManagerPageClient() {
const fetchUsageStats = async (apiKeys: ApiKey[]) => {
if (apiKeys.length === 0) return;
try {
const res = await fetch("/api/usage/call-logs?limit=1000");
if (!res.ok) return;
const logs = await res.json();
// Fetch analytics (accurate aggregated counts) and recent call-logs
// (for lastUsed timestamps) in parallel.
// The previous approach matched call-logs by key.id === log.apiKeyId,
// but these use different ID schemes and never matched, yielding 0.
const [analyticsRes, logsRes] = await Promise.all([
fetch("/api/usage/analytics?range=all"),
fetch("/api/usage/call-logs?limit=1000"),
]);
const analytics = analyticsRes.ok ? await analyticsRes.json() : null;
const byApiKey: any[] = analytics?.byApiKey || [];
const logs = logsRes.ok ? await logsRes.json() : [];
const stats: Record<string, KeyUsageStats> = {};
for (const key of apiKeys) {
const keyLogs = (logs || []).filter(
(log: any) => log.apiKeyId === key.id || log.apiKeyName === key.name
// Match analytics entry by key name (reliable across both systems)
const analyticsMatch = byApiKey.find(
(entry: any) => entry.apiKeyName === key.name
);
// The call-logs endpoint returns entries sorted by timestamp DESC,
// so the first match is the most recent one.
const lastUsed = (logs || []).find(
(log: any) => log.apiKeyName === key.name
)?.timestamp || null;
stats[key.id] = {
totalRequests: keyLogs.length,
lastUsed:
keyLogs.length > 0
? keyLogs.sort(
(a: any, b: any) =>
new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()
)[0]?.timestamp
: null,
totalRequests: analyticsMatch?.requests ?? 0,
lastUsed,
};
}
setUsageStats(stats);

View file

@ -164,7 +164,11 @@ export default function BuilderIntelligentStep({
>
{MODE_PACK_OPTIONS.map((modePack) => (
<option key={modePack.id} value={modePack.id}>
{modePack.label}
{getI18nOrFallback(
t,
`modePack${modePack.id[0].toUpperCase()}${modePack.id.slice(1)}`,
modePack.label
)}
</option>
))}
</select>

View file

@ -120,6 +120,21 @@ const STRATEGY_GUIDANCE_FALLBACK = {
avoid: "Avoid when models have different quality or latency and order matters.",
example: "Example: Multiple accounts of the same model to distribute usage evenly.",
},
auto: {
when: "Use when you have one preferred model and only want fallback on failure.",
avoid: "Avoid when you need balanced load between models.",
example: "Example: Primary coding model with cheaper backup for outages.",
},
lkgp: {
when: "Use when you have one preferred model and only want fallback on failure.",
avoid: "Avoid when you need balanced load between models.",
example: "Example: Primary coding model with cheaper backup for outages.",
},
"context-optimized": {
when: "Use when you have one preferred model and only want fallback on failure.",
avoid: "Avoid when you need balanced load between models.",
example: "Example: Primary coding model with cheaper backup for outages.",
},
};
const ADVANCED_FIELD_HELP_FALLBACK = {
@ -224,6 +239,33 @@ const STRATEGY_RECOMMENDATIONS_FALLBACK = {
"Guarantees no model is skipped or repeated within a cycle.",
],
},
auto: {
title: "Fail-safe baseline",
description: "Use one primary model and keep fallback chain short and reliable.",
tips: [
"Put your most reliable model first.",
"Keep 1-2 backup models with similar quality.",
"Use safe retries to absorb transient provider failures.",
],
},
lkgp: {
title: "Fail-safe baseline",
description: "Use one primary model and keep fallback chain short and reliable.",
tips: [
"Put your most reliable model first.",
"Keep 1-2 backup models with similar quality.",
"Use safe retries to absorb transient provider failures.",
],
},
"context-optimized": {
title: "Fail-safe baseline",
description: "Use one primary model and keep fallback chain short and reliable.",
tips: [
"Put your most reliable model first.",
"Keep 1-2 backup models with similar quality.",
"Use safe retries to absorb transient provider failures.",
],
},
};
const COMBO_USAGE_GUIDE_STORAGE_KEY = "omniroute:combos:hide-usage-guide";
@ -2467,7 +2509,7 @@ function ComboFormModal({ isOpen, combo, onClose, onSave, activeProviders }) {
<p className="text-[10px] text-text-muted mt-0.5">
{getI18nOrFallback(
t,
"builderFlowDescription",
"builderStagesDescription",
"Move through the stages in order to define the combo, build the steps, choose the routing strategy and review the result."
)}
</p>
@ -2719,7 +2761,7 @@ function ComboFormModal({ isOpen, combo, onClose, onSave, activeProviders }) {
<p className="text-[10px] text-text-muted mt-0.5">
{getI18nOrFallback(
t,
"builderDescription",
"builderStepsDescription",
"Build each combo step in sequence: provider, model, then account. This allows repeating the same provider and model with different accounts."
)}
</p>
@ -2797,7 +2839,7 @@ function ComboFormModal({ isOpen, combo, onClose, onSave, activeProviders }) {
<option value={COMBO_BUILDER_AUTO_CONNECTION}>
{getI18nOrFallback(
t,
"builderDynamicAccount",
"autoSelectAccount",
"Auto-select account at runtime"
)}
</option>
@ -2820,7 +2862,7 @@ function ComboFormModal({ isOpen, combo, onClose, onSave, activeProviders }) {
? formatModelDisplay(builderCandidateStep)
: getI18nOrFallback(
t,
"builderPreviewEmpty",
"previewNextStep",
"Choose provider and model to preview the next step."
)}
</p>
@ -2858,7 +2900,7 @@ function ComboFormModal({ isOpen, combo, onClose, onSave, activeProviders }) {
<option value="">
{getI18nOrFallback(
t,
"builderSelectComboRef",
"selectComboToReference",
"Select an existing combo to reference"
)}
</option>
@ -3113,7 +3155,7 @@ function ComboFormModal({ isOpen, combo, onClose, onSave, activeProviders }) {
className="w-full mt-2 py-2 border border-dashed border-black/10 dark:border-white/10 rounded-lg text-xs text-text-muted hover:text-primary hover:border-primary/30 transition-colors flex items-center justify-center gap-1"
>
<span className="material-symbols-outlined text-[16px]">travel_explore</span>
{getI18nOrFallback(t, "builderOpenLegacyCatalog", "Browse legacy model catalog")}
{getI18nOrFallback(t, "browseLegacyCatalog", "Browse legacy model catalog")}
</button>
</div>
)}
@ -3388,34 +3430,31 @@ function ComboFormModal({ isOpen, combo, onClose, onSave, activeProviders }) {
<span className="material-symbols-outlined text-[14px] text-primary">
smart_toy
</span>
<p className="text-xs font-medium">Agent Features</p>
<span className="text-[10px] text-text-muted">
optional, for agent/tool workflows
</span>
<p className="text-xs font-medium">{t("agentFeaturesTitle")}</p>
<span className="text-[10px] text-text-muted">{t("agentFeaturesDescription")}</span>
</div>
{/* System Message Override */}
<div>
<label className="text-[11px] font-medium text-text-muted block mb-0.5">
System Message Override
{t("agentFeaturesSystemMessageOverride")}
</label>
<textarea
rows={2}
value={agentSystemMessage}
onChange={(e) => setAgentSystemMessage(e.target.value)}
placeholder="Override the system prompt for all requests routed through this combo…"
placeholder={t("agentFeaturesSystemMessagePlaceholder")}
className="w-full text-xs py-1.5 px-2 rounded border border-black/10 dark:border-white/10 bg-transparent focus:border-primary focus:outline-none resize-none"
/>
<p className="text-[10px] text-text-muted mt-0.5">
Replaces any system message sent by the client. Leave empty to pass through client
system messages.
{t("agentFeaturesSystemMessageHint")}
</p>
</div>
{/* Tool Filter Regex */}
<div>
<label className="text-[11px] font-medium text-text-muted block mb-0.5">
Tool Filter Regex
{t("agentFeaturesToolFilterRegex")}
</label>
<input
type="text"
@ -3425,8 +3464,7 @@ function ComboFormModal({ isOpen, combo, onClose, onSave, activeProviders }) {
className="w-full text-xs py-1.5 px-2 rounded border border-black/10 dark:border-white/10 bg-transparent focus:border-primary focus:outline-none font-mono"
/>
<p className="text-[10px] text-text-muted mt-0.5">
Only tools whose name matches this regex are forwarded to the provider. Leave
empty to forward all tools.
{t("agentFeaturesToolFilterHint")}
</p>
</div>
@ -3434,11 +3472,10 @@ function ComboFormModal({ isOpen, combo, onClose, onSave, activeProviders }) {
<div className="flex items-center justify-between gap-2">
<div>
<label className="text-[11px] font-medium text-text-muted block">
Context Cache Protection
{t("agentFeaturesContextCacheProtection")}
</label>
<p className="text-[10px] text-text-muted">
Pins the provider/model across turns to preserve cache sessions. Internal tags
are stripped before forwarding to the provider.
{t("agentFeaturesContextCacheHint")}
</p>
</div>
<input
@ -3673,7 +3710,7 @@ function ComboFormModal({ isOpen, combo, onClose, onSave, activeProviders }) {
)
: getI18nOrFallback(
t,
"builderNeedSteps",
"addStepBeforeContinue",
"Add at least one step before continuing to the next stage."
)}
</div>

View file

@ -1,6 +1,7 @@
"use client";
import { useState, useEffect, useCallback, useRef } from "react";
import { useTranslations } from "next-intl";
import { Card, Button, Select, Badge } from "@/shared/components";
import { ALIAS_TO_ID } from "@/shared/constants/providers";
import { pickMaskedDisplayValue, pickDisplayValue } from "@/shared/utils/maskEmail";
@ -31,18 +32,7 @@ interface ConnectionOption {
authType: string;
}
const ENDPOINT_OPTIONS = [
{ value: "chat", label: "Chat Completions" },
{ value: "responses", label: "Responses" },
{ value: "images", label: "Image Generation" },
{ value: "embeddings", label: "Embeddings" },
{ value: "speech", label: "Text to Speech" },
{ value: "transcription", label: "Audio Transcription" },
{ value: "video", label: "Video Generation" },
{ value: "music", label: "Music Generation" },
{ value: "rerank", label: "Rerank" },
{ value: "search", label: "Web Search" },
];
// Endpoint options will be generated dynamically with translations
const DEFAULT_BODIES: Record<string, object> = {
chat: {
@ -154,13 +144,14 @@ async function fileToBase64(file: File): Promise<string> {
/** Render image results from OpenAI-compatible format */
function ImageResultsInline({ data }: { data: any }) {
const t = useTranslations("playground");
const images: Array<{ url?: string; b64_json?: string; revised_prompt?: string }> =
data?.data || [];
if (images.length === 0) return null;
return (
<div className="p-4 space-y-3">
<p className="text-xs text-text-muted font-medium uppercase tracking-wider">
{images.length} image{images.length > 1 ? "s" : ""} generated
{t("imagesGenerated", { count: images.length })}
</p>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
{images.map((img, i) => {
@ -171,7 +162,7 @@ function ImageResultsInline({ data }: { data: any }) {
{/* eslint-disable-next-line @next/next/no-img-element */}
<img
src={src}
alt={img.revised_prompt || `Generated image ${i + 1}`}
alt={img.revised_prompt || t("generatedImage", { index: i + 1 })}
className="w-full"
/>
<a
@ -180,7 +171,7 @@ function ImageResultsInline({ data }: { data: any }) {
className="absolute bottom-2 right-2 bg-black/60 text-white text-xs px-2 py-1 rounded opacity-0 group-hover:opacity-100 transition-opacity flex items-center gap-1"
>
<span className="material-symbols-outlined text-[13px]">download</span>
Save
{t("save")}
</a>
</div>
);
@ -191,6 +182,22 @@ function ImageResultsInline({ data }: { data: any }) {
}
export default function PlaygroundPage() {
const t = useTranslations("playground");
// Get translated endpoint options
const getEndpointOptions = () => [
{ value: "chat", label: t("endpointOptions.chat") },
{ value: "responses", label: t("endpointOptions.responses") },
{ value: "images", label: t("endpointOptions.images") },
{ value: "embeddings", label: t("endpointOptions.embeddings") },
{ value: "speech", label: t("endpointOptions.speech") },
{ value: "transcription", label: t("endpointOptions.transcription") },
{ value: "video", label: t("endpointOptions.video") },
{ value: "music", label: t("endpointOptions.music") },
{ value: "rerank", label: t("endpointOptions.rerank") },
{ value: "search", label: t("endpointOptions.search") },
];
const [models, setModels] = useState<ModelInfo[]>([]);
const [providers, setProviders] = useState<ProviderOption[]>([]);
const [allConnections, setAllConnections] = useState<ConnectionOption[]>([]);
@ -472,11 +479,8 @@ export default function PlaygroundPage() {
science
</span>
<div>
<p className="font-medium text-text-main mb-0.5">Model Playground</p>
<p>
Test any model directly from the dashboard. Pick a provider, model, and endpoint type,
then send a request to see the raw response.
</p>
<p className="font-medium text-text-main mb-0.5">{t("title")}</p>
<p>{t("description")}</p>
</div>
</div>
@ -486,12 +490,12 @@ export default function PlaygroundPage() {
{/* Endpoint — always first */}
<div className="flex-1 w-full">
<label className="block text-xs font-medium text-text-muted mb-1.5 uppercase tracking-wider">
Endpoint
{t("endpoint")}
</label>
<Select
value={selectedEndpoint}
onChange={(e: any) => handleEndpointChange(e.target.value)}
options={ENDPOINT_OPTIONS}
options={getEndpointOptions()}
className="w-full"
/>
</div>
@ -500,7 +504,7 @@ export default function PlaygroundPage() {
{!isSearchEndpoint && (
<div className="flex-1 w-full">
<label className="block text-xs font-medium text-text-muted mb-1.5 uppercase tracking-wider">
Provider
{t("provider")}
</label>
<Select
value={selectedProvider}
@ -515,7 +519,7 @@ export default function PlaygroundPage() {
{!isSearchEndpoint && (
<div className="flex-1 w-full">
<label className="block text-xs font-medium text-text-muted mb-1.5 uppercase tracking-wider">
Model
{t("model")}
</label>
<Select
value={selectedModel}
@ -530,7 +534,7 @@ export default function PlaygroundPage() {
{!isSearchEndpoint && (
<div className="flex-1 w-full">
<label className="block text-xs font-medium text-text-muted mb-1.5 uppercase tracking-wider">
Account / Key
{t("accountKey")}
</label>
<Select
value={selectedConnection}
@ -540,8 +544,8 @@ export default function PlaygroundPage() {
value: "",
label:
providerConnections.length > 0
? `Auto (${providerConnections.length} accounts)`
: "No accounts",
? t("autoAccounts", { count: providerConnections.length })
: t("noAccounts"),
},
...providerConnections.map((c) => ({
value: c.id,
@ -558,7 +562,7 @@ export default function PlaygroundPage() {
<div className="shrink-0">
{loading ? (
<Button icon="stop" variant="secondary" onClick={handleCancel}>
Cancel
{t("cancel")}
</Button>
) : (
<Button
@ -569,7 +573,7 @@ export default function PlaygroundPage() {
(!selectedModel && !isTranscriptionEndpoint)
}
>
Send
{t("send")}
</Button>
)}
</div>
@ -591,16 +595,16 @@ export default function PlaygroundPage() {
attach_file
</span>
<h3 className="text-sm font-semibold text-text-main">
{isTranscriptionEndpoint ? "Audio File" : "Attach Images (Vision)"}
{isTranscriptionEndpoint ? t("audioFile") : t("attachImages")}
</h3>
{isTranscriptionEndpoint && (
<Badge variant="info" size="sm">
multipart/form-data
{t("multipartFormData")}
</Badge>
)}
{supportsVision && (
<Badge variant="info" size="sm">
up to 4 images
{t("upToImages")}
</Badge>
)}
</div>
@ -623,7 +627,7 @@ export default function PlaygroundPage() {
{!uploadedFile && (
<p className="text-xs text-amber-500 mt-1 flex items-center gap-1">
<span className="material-symbols-outlined text-[12px]">info</span>
Select an audio file to transcribe (mp3, wav, m4a, ogg, flac)
{t("selectAudioFile")}
</p>
)}
</div>
@ -664,7 +668,7 @@ export default function PlaygroundPage() {
onClick={() => setUploadedImages([])}
className="text-xs text-text-muted hover:text-red-500 self-center ml-1"
>
Clear all
{t("clearAll")}
</button>
</div>
)}
@ -684,7 +688,7 @@ export default function PlaygroundPage() {
<span className="material-symbols-outlined text-[18px] text-text-muted">
upload
</span>
<h3 className="text-sm font-semibold text-text-main">Request</h3>
<h3 className="text-sm font-semibold text-text-main">{t("request")}</h3>
<Badge variant="info" size="sm">
POST {ENDPOINT_PATHS[selectedEndpoint]}
</Badge>
@ -693,7 +697,7 @@ export default function PlaygroundPage() {
<button
onClick={() => handleCopy(requestBody)}
className="p-1.5 rounded hover:bg-black/5 dark:hover:bg-white/5 text-text-muted hover:text-text-main transition-colors"
title="Copy"
title={t("copy")}
>
<span className="material-symbols-outlined text-[16px]">content_copy</span>
</button>
@ -704,7 +708,7 @@ export default function PlaygroundPage() {
setRequestBody(JSON.stringify(template, null, 2));
}}
className="p-1.5 rounded hover:bg-black/5 dark:hover:bg-white/5 text-text-muted hover:text-text-main transition-colors"
title="Reset to default"
title={t("resetToDefault")}
>
<span className="material-symbols-outlined text-[16px]">restart_alt</span>
</button>
@ -715,8 +719,7 @@ export default function PlaygroundPage() {
<span className="material-symbols-outlined text-[12px] text-amber-500 mt-0.5">
info
</span>
Transcription uses multipart/form-data. Upload the audio file above JSON below
controls extra params (model, language).
{t("transcriptionHint")}
</p>
)}
<div className="border border-border rounded-lg overflow-hidden">
@ -748,7 +751,7 @@ export default function PlaygroundPage() {
<span className="material-symbols-outlined text-[18px] text-text-muted">
download
</span>
<h3 className="text-sm font-semibold text-text-main">Response</h3>
<h3 className="text-sm font-semibold text-text-main">{t("response")}</h3>
{responseStatus !== null && (
<Badge
variant={
@ -772,7 +775,7 @@ export default function PlaygroundPage() {
<button
onClick={() => handleCopy(responseBody)}
className="p-1.5 rounded hover:bg-black/5 dark:hover:bg-white/5 text-text-muted hover:text-text-main transition-colors"
title="Copy"
title={t("copy")}
>
<span className="material-symbols-outlined text-[16px]">content_copy</span>
</button>
@ -788,7 +791,7 @@ export default function PlaygroundPage() {
className="inline-flex items-center gap-2 text-sm text-primary hover:underline"
>
<span className="material-symbols-outlined text-[16px]">download</span>
Download audio
{t("downloadAudio")}
</a>
</div>
) : imageData ? (
@ -796,7 +799,7 @@ export default function PlaygroundPage() {
) : transcriptionText !== null ? (
<div className="p-4 space-y-2">
<p className="text-xs text-text-muted font-medium uppercase tracking-wider">
Transcription
{t("transcription")}
</p>
<div className="bg-surface/50 rounded p-3 text-sm text-text-main leading-relaxed whitespace-pre-wrap">
{transcriptionText}
@ -806,7 +809,7 @@ export default function PlaygroundPage() {
className="text-xs text-primary hover:underline flex items-center gap-1"
>
<span className="material-symbols-outlined text-[12px]">content_copy</span>
Copy text
{t("copyText")}
</button>
</div>
) : (

View file

@ -1,6 +1,7 @@
"use client";
import { useCallback, useEffect, useMemo, useState } from "react";
import { useTranslations } from "next-intl";
import { Button, Card, Modal } from "@/shared/components";
type ProxyItem = {
@ -51,6 +52,7 @@ const EMPTY_FORM = {
};
export default function ProxyRegistryManager() {
const t = useTranslations("proxyRegistry");
const [items, setItems] = useState<ProxyItem[]>([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
@ -124,7 +126,7 @@ export default function ProxyRegistryManager() {
const res = await fetch("/api/settings/proxies");
const data = await res.json().catch(() => ({}));
if (!res.ok) {
setError(data?.error?.message || "Failed to load proxy registry");
setError(data?.error?.message || t("errorLoadFailed"));
setItems([]);
return;
}
@ -134,7 +136,7 @@ export default function ProxyRegistryManager() {
void loadHealth();
void loadAllUsage(ids);
} catch (e: any) {
setError(e?.message || "Failed to load proxy registry");
setError(e?.message || t("errorLoadFailed"));
setItems([]);
} finally {
setLoading(false);
@ -221,7 +223,7 @@ export default function ProxyRegistryManager() {
if (!res.ok) {
setTestById((prev) => ({
...prev,
[item.id]: { success: false, error: data?.error?.message || "Test failed" },
[item.id]: { success: false, error: data?.error?.message || t("failed") },
}));
return;
}
@ -235,7 +237,7 @@ export default function ProxyRegistryManager() {
const handleSave = async () => {
if (!form.name.trim() || !form.host.trim()) {
setError("Name and host are required");
setError(t("errorNameHostRequired"));
return;
}
@ -270,7 +272,7 @@ export default function ProxyRegistryManager() {
});
const data = await res.json().catch(() => ({}));
if (!res.ok) {
setError(data?.error?.message || "Failed to save proxy");
setError(data?.error?.message || t("errorSaveFailed"));
return;
}
@ -278,7 +280,7 @@ export default function ProxyRegistryManager() {
setForm(EMPTY_FORM);
await load();
} catch (e: any) {
setError(e?.message || "Failed to save proxy");
setError(e?.message || t("errorSaveFailed"));
} finally {
setSaving(false);
}
@ -298,9 +300,7 @@ export default function ProxyRegistryManager() {
const payload = await res.json().catch(() => ({}));
const inUse = res.status === 409;
if (inUse) {
const ok = window.confirm(
"This proxy is still assigned. Force delete and remove all assignments?"
);
const ok = window.confirm(t("errorForceDeleteConfirm"));
if (!ok) return;
const forceRes = await fetch(`/api/settings/proxies?id=${encodeURIComponent(id)}&force=1`, {
@ -309,7 +309,7 @@ export default function ProxyRegistryManager() {
if (!forceRes.ok) {
const forcePayload = await forceRes.json().catch(() => ({}));
setError(forcePayload?.error?.message || "Failed to force delete proxy");
setError(forcePayload?.error?.message || t("errorDeleteFailed"));
return;
}
@ -317,9 +317,9 @@ export default function ProxyRegistryManager() {
return;
}
setError(payload?.error?.message || "Failed to delete proxy");
setError(payload?.error?.message || t("errorDeleteFailed"));
} catch (e: any) {
setError(e?.message || "Failed to delete proxy");
setError(e?.message || t("errorDeleteFailed"));
}
};
@ -334,12 +334,12 @@ export default function ProxyRegistryManager() {
});
const data = await res.json().catch(() => ({}));
if (!res.ok) {
setError(data?.error?.message || "Failed to migrate legacy proxy config");
setError(data?.error?.message || t("errorMigrateFailed"));
return;
}
await load();
} catch (e: any) {
setError(e?.message || "Failed to migrate legacy proxy config");
setError(e?.message || t("errorMigrateFailed"));
} finally {
setMigrating(false);
}
@ -368,7 +368,7 @@ export default function ProxyRegistryManager() {
});
const payload = await res.json().catch(() => ({}));
if (!res.ok) {
setError(payload?.error?.message || "Failed to run bulk assignment");
setError(payload?.error?.message || t("errorBulkFailed"));
return;
}
@ -376,7 +376,7 @@ export default function ProxyRegistryManager() {
setBulkScopeIds("");
await load();
} catch (e: any) {
setError(e?.message || "Failed to run bulk assignment");
setError(e?.message || t("errorBulkFailed"));
} finally {
setBulkSaving(false);
}
@ -387,8 +387,8 @@ export default function ProxyRegistryManager() {
<Card className="p-6">
<div className="flex items-center justify-between gap-3 mb-4">
<div>
<h3 className="text-lg font-semibold">Proxy Registry</h3>
<p className="text-sm text-text-muted">Store reusable proxies and track assignments.</p>
<h3 className="text-lg font-semibold">{t("title")}</h3>
<p className="text-sm text-text-muted">{t("description")}</p>
</div>
<div className="flex items-center gap-2">
<Button
@ -399,7 +399,7 @@ export default function ProxyRegistryManager() {
loading={migrating}
data-testid="proxy-registry-import-legacy"
>
Import Legacy
{t("importLegacy")}
</Button>
<Button
size="sm"
@ -408,7 +408,7 @@ export default function ProxyRegistryManager() {
onClick={() => setBulkOpen(true)}
data-testid="proxy-registry-open-bulk"
>
Bulk Assign
{t("bulkAssign")}
</Button>
<Button
size="sm"
@ -416,7 +416,7 @@ export default function ProxyRegistryManager() {
onClick={openCreate}
data-testid="proxy-registry-open-create"
>
Add Proxy
{t("addProxy")}
</Button>
</div>
</div>
@ -428,20 +428,20 @@ export default function ProxyRegistryManager() {
)}
{loading ? (
<div className="text-sm text-text-muted">Loading proxies...</div>
<div className="text-sm text-text-muted">{t("loading")}</div>
) : items.length === 0 ? (
<div className="text-sm text-text-muted">No saved proxies yet.</div>
<div className="text-sm text-text-muted">{t("noProxies")}</div>
) : (
<div className="overflow-x-auto">
<table className="w-full text-sm">
<thead>
<tr className="text-left text-text-muted border-b border-border">
<th className="py-2 pr-3">Name</th>
<th className="py-2 pr-3">Endpoint</th>
<th className="py-2 pr-3">Status</th>
<th className="py-2 pr-3">Health (24h)</th>
<th className="py-2 pr-3">Usage</th>
<th className="py-2">Actions</th>
<th className="py-2 pr-3">{t("tableName")}</th>
<th className="py-2 pr-3">{t("tableEndpoint")}</th>
<th className="py-2 pr-3">{t("tableStatus")}</th>
<th className="py-2 pr-3">{t("tableHealth")}</th>
<th className="py-2 pr-3">{t("tableUsage")}</th>
<th className="py-2">{t("tableActions")}</th>
</tr>
</thead>
<tbody>
@ -483,8 +483,10 @@ export default function ProxyRegistryManager() {
)
) : health ? (
<>
<span>{health.successRate ?? 0}% success</span>
<span>{health.avgLatencyMs ?? "-"} ms avg</span>
<span>{t("successRate", { rate: health.successRate ?? 0 })}</span>
<span>
{t("avgLatency", { latency: health.avgLatencyMs ?? "-" })}
</span>
</>
) : (
<span></span>
@ -493,8 +495,8 @@ export default function ProxyRegistryManager() {
</td>
<td className="py-2 pr-3 text-xs text-text-muted">
{usageById[item.id] != null
? `${usageById[item.id].count} assignment(s)`
: "—"}
? t("assignmentsCount", { count: usageById[item.id].count })
: t("noData")}
</td>
<td className="py-2">
<div className="flex items-center gap-1">
@ -505,7 +507,7 @@ export default function ProxyRegistryManager() {
onClick={() => void handleTestProxy(item)}
loading={testingId === item.id}
>
Test
{t("test")}
</Button>
<Button
size="sm"
@ -513,7 +515,7 @@ export default function ProxyRegistryManager() {
icon="edit"
onClick={() => openEdit(item)}
>
Edit
{t("edit")}
</Button>
<Button
size="sm"
@ -522,7 +524,7 @@ export default function ProxyRegistryManager() {
onClick={() => void handleDelete(item.id)}
className="!text-red-400"
>
Delete
{t("delete")}
</Button>
</div>
</td>
@ -540,13 +542,13 @@ export default function ProxyRegistryManager() {
onClose={() => {
if (!saving) setModalOpen(false);
}}
title={editingId ? "Edit Proxy" : "Create Proxy"}
title={editingId ? t("modalEditTitle") : t("modalCreateTitle")}
maxWidth="lg"
>
<div className="flex flex-col gap-3">
<div className="grid grid-cols-2 gap-3">
<div>
<label className="text-xs text-text-muted mb-1 block">Name</label>
<label className="text-xs text-text-muted mb-1 block">{t("labelName")}</label>
<input
data-testid="proxy-registry-name-input"
className="w-full px-3 py-2 rounded bg-bg-subtle border border-border"

View file

@ -136,7 +136,10 @@
"Failed to save pricing": "فشل حفظ الأسعار",
"Failed to reset pricing": "فشل في إعادة تعيين التسعير",
"apikey": "مفتاح واجهة برمجة التطبيقات",
"http": "HTTP"
"http": "HTTP",
"checkSystemStatus": "Check System Status",
"goToDashboard": "Go to Dashboard",
"nothingHere": "Nothing here yet"
},
"sidebar": {
"home": "الصفحة الرئيسية",
@ -640,7 +643,8 @@
"opencode": "استخدمه عندما تفضل تشغيل الوكيل الأصلي للمحطة والأتمتة النصية عبر OpenCode.",
"kiro": "يُستخدم عند دمج Kiro والتحكم في توجيه النموذج مركزيًا من OmniRoute.",
"antigravity": "يُستخدم عندما يجب اعتراض حركة مرور Antigravity/Kiro عبر MITM وتوجيهها إلى OmniRoute.",
"copilot": "استخدمه عندما تريد UX بأسلوب دردشة Copilot أثناء فرض مفاتيح OmniRoute وقواعد التوجيه."
"copilot": "استخدمه عندما تريد UX بأسلوب دردشة Copilot أثناء فرض مفاتيح OmniRoute وقواعد التوجيه.",
"windsurf": "Use when you want an AI-first IDE with Codeium/Windsurf models routed through OmniRoute."
},
"toolDescriptions": {
"antigravity": "جوجل مكافحة الجاذبية IDE مع MITM",
@ -655,7 +659,8 @@
"opencode": "OpenCode AI coding agent (Terminal)",
"kiro": "Amazon Kiro — AI-powered IDE",
"windsurf": "Windsurf AI Code Editor",
"copilot": "GitHub Copilot AI Assistant"
"copilot": "GitHub Copilot AI Assistant",
"qwen": "Alibaba Qwen Code CLI"
},
"guides": {
"cursor": {
@ -890,6 +895,16 @@
"when": "Use when you want perfectly even spread — each model used once before repeating.",
"avoid": "Avoid when models have different quality or latency and order matters.",
"example": "Example: Multiple accounts of the same model to distribute usage evenly."
},
"p2c": {
"example": "Example: High-throughput inference across 4+ equivalent model endpoints.",
"avoid": "Avoid for small combos with 2 or fewer models — no benefit over round-robin.",
"when": "Use when you want low-latency selection using Power-of-Two-Choices algorithm."
},
"context-relay": {
"example": "Example: Codex sessions that rotate across multiple accounts near quota exhaustion.",
"avoid": "Avoid when account switching is rare or when you do not want extra summarization requests.",
"when": "Use when long sessions must survive account rotation without losing the working context."
}
},
"advancedHelp": {
@ -1009,7 +1024,117 @@
"wizardStep3Title": "Choose Strategy",
"wizardStep3Desc": "Pick how requests are distributed across your models - 13 strategies available",
"wizardStep4Title": "Review & Save",
"wizardStep4Desc": "Review your configuration and activate the combo"
"wizardStep4Desc": "Review your configuration and activate the combo",
"advancedWeightsTitle": "Advanced: Scoring Weights",
"contextRelaySummaryModelHelp": "Optional override model used only for generating the handoff summary. Leave empty to reuse the active combo model.",
"candidatePoolLabel": "Candidate Pool",
"emailVisibilityStateOff": "Off",
"builderStage": {
"intelligent": {
"description": "Auto-routing candidate pool, presets, and scoring",
"label": "Smart Routing"
},
"strategy": {
"description": "Routing behavior and advanced settings",
"label": "Strategy"
},
"basics": {
"label": "Basics",
"description": "Name and starting template"
},
"steps": {
"description": "Provider, model, and account selection",
"label": "Steps"
},
"review": {
"label": "Review",
"description": "Final validation before saving"
}
},
"weightLatencyInv": "Latency",
"filterAll": "All",
"weightTierPriority": "Tier",
"builderPreview": "Preview",
"allProvidersEvaluated": "No candidate pool configured. All active providers are evaluated at runtime.",
"filterEmptyTitle": "No combos match this strategy filter.",
"reviewAdvanced": "Advanced Settings",
"routerStrategyLabel": "Router Strategy",
"builderFlowTitle": "Combo Builder Flow",
"builderIntelligentDesc": "Configure the multi-factor scoring engine for this auto-routing combo.",
"contextRelaySummaryModel": "Summary Model",
"builderModel": "Model",
"excludedProviders": "Excluded Providers",
"emailVisibilityStateOn": "On",
"noExcludedProviders": "No providers are currently excluded.",
"contextRelayHandoffThresholdHelp": "When quota usage reaches this threshold, OmniRoute generates a structured handoff summary before the active account is exhausted.",
"highCircuitBreakerRate": "High circuit breaker trip rate detected.",
"intelligentPanelTitle": "Intelligent Routing Dashboard",
"builderTitle": "Build a Combo",
"budgetCapLabel": "Budget Cap (USD / request)",
"filterEmptyIntelligentDescription": "Create an auto or LKGP combo to populate the intelligent routing dashboard.",
"candidatePoolHint": "Select which providers this engine should evaluate. Leave empty to use all active providers.",
"builderStageLocked": "Locked — complete previous stage first",
"reviewComboRefs": "Combo References",
"builderAddStep": "Add step",
"builderComboRef": "Combo Ref",
"candidatePoolAllProviders": "All providers",
"weightStability": "Stability",
"reviewProviders": "Providers",
"builderAccount": "Account",
"weightTaskFit": "Task Fit",
"strategyRules": "Rules (6-Factor Scoring)",
"reorderHandle": "Drag to reorder",
"allProvidersHealthy": "Providers are reporting healthy routing conditions.",
"contextRelayMaxMessagesHelp": "Limits how much recent history is condensed into the relay summary.",
"builderSelectModel": "Select model",
"cooldownMinutes": "Cooldown: {minutes}m",
"builderBrowseCatalog": "Browse catalog",
"weightQuota": "Quota",
"reviewIntelligentTitle": "Intelligent Routing Config",
"modePackHint": "Switch presets to bias the routing engine without rebuilding the combo.",
"statusOverview": "Status Overview",
"weightHealth": "Health",
"builderProviderFirst": "Pick provider first",
"reviewAgentFlags": "Agent Flags",
"explorationRateLabel": "Exploration Rate",
"builderIntelligentTitle": "Intelligent Routing Configuration",
"filterIntelligent": "Intelligent",
"builderLoadingProviders": "Loading providers...",
"builderProvider": "Provider",
"reviewSequence": "Model Sequence",
"builderPinnedAccount": "Pinned Account",
"intelligentPanelDesc": "Real-time scoring and health status for this auto-routing combo.",
"budgetCapPlaceholder": "No limit",
"candidatePoolEmpty": "No active providers available yet.",
"modePackLabel": "Mode Pack",
"activeModePack": "Active Mode Pack",
"builderComboRefStep": "Add combo reference",
"failedReorder": "Failed to reorder models",
"incidentMode": "Incident Mode",
"reviewStrategy": "Strategy",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex account rotation. Pair it with multiple accounts of the same provider for the best continuity.",
"reviewName": "Name",
"builderAddComboRef": "Add combo reference",
"normalOperation": "Normal Operation",
"builderSelectProvider": "Select provider",
"filterDeterministic": "Deterministic",
"builderStageCurrent": "Current stage",
"reviewNoSteps": "No steps configured",
"excludedProvidersHint": "Providers with an OPEN circuit breaker are temporarily excluded from routing.",
"contextRelayHandoffThreshold": "Handoff Threshold",
"weightCostInv": "Cost",
"providerScores": "Provider Scores",
"explorationRateHint": "{percent}% of requests can explore non-optimal providers.",
"reviewSteps": "Steps",
"builderLegacyEntry": "Legacy entry",
"contextRelayMaxMessages": "Max Messages For Summary",
"contextRelay": "Context Relay",
"contextRelayDesc": "Preserves session continuity with handoff summaries when accounts rotate",
"builderStagePending": "Pending",
"filterEmptyDeterministicDescription": "Only auto and LKGP combos exist right now. Switch back to All or create a deterministic combo.",
"modePackUpdated": "Mode pack updated to {pack}.",
"reviewAccounts": "Accounts",
"builderStageVisited": "Stage completed"
},
"costs": {
"title": "التكاليف",
@ -1147,7 +1272,9 @@
"a2aQuickStartStep2": "إرسال طلبات JSON - RPC إلى@@ PH0 @@ باستخدام @@PH1 @@ أو `message/stream`.",
"a2aQuickStartStep3": "تتبع المهام والتحكم فيها باستخدام `tasks/get` و `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format",
"musicDesc": "Generate music and audio tracks via ComfyUI (Stable Audio, MusicGen)",
"musicGeneration": "Music Generation"
},
"endpoints": {
"tabProxy": "Endpoint Proxy",
@ -1749,7 +1876,22 @@
"close": "Close",
"statusDeactivated": "Deactivated (Manual)",
"statusBanned": "Banned / Sandbox Violation",
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted"
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted",
"imagesGenerations": "Images Generations",
"repairEnvSuccess": "OAuth defaults restored",
"hideEmails": "Hide all emails",
"showEmails": "Show all emails",
"repairEnvWorking": "Repairing...",
"audioTranscriptions": "Audio Transcriptions",
"embeddings": "Embeddings",
"repairEnv": "Repair env",
"selectAllModels": "Select all",
"deselectAllModels": "Deselect all",
"noModelsMatch": "No models match \"{filter}\"",
"audioSpeech": "Audio Speech",
"repairEnvHint": "Restore missing OAuth defaults into .env without overwriting existing values.",
"modelsActiveCount": "{active}/{total} active",
"repairEnvFailed": "Failed to repair .env"
},
"settings": {
"title": "الإعدادات",
@ -2266,7 +2408,11 @@
"wildcardPatternModeDesc": "Use wildcard aliases with * and ? when a family of models should map to one target.",
"noExactAliasesConfigured": "No exact-match aliases configured.",
"wildcardRulesTitle": "Wildcard Rules",
"noWildcardAliasesConfigured": "No wildcard aliases configured."
"noWildcardAliasesConfigured": "No wildcard aliases configured.",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex accounts and uses these values as global defaults for new or unconfigured combos.",
"contextRelayHandoffThreshold": "Handoff Threshold",
"contextRelayMaxMessages": "Max Messages For Summary",
"contextRelaySummaryModel": "Summary Model"
},
"translator": {
"title": "مترجم",
@ -2692,7 +2838,11 @@
"waitingForOpenAIAuthorization": "في انتظار ترخيص OpenAI...",
"waitingForAntigravityAuthorization": "في انتظار تصريح مكافحة الجاذبية...",
"waitingForQoderAuthorization": "في انتظار ترخيص Qoder...",
"exchangingCodeForTokens": "استبدال الكود بالرموز..."
"exchangingCodeForTokens": "استبدال الكود بالرموز...",
"nodeIncompatibleDesc": "You are running Node.js {version}, which is outside OmniRoute's supported secure runtime policy. Use a patched Node.js 20.x or 22.x LTS release.",
"nodeIncompatibleHint": "OmniRoute requires Node.js 20.20.2+ (20.x LTS) or 22.22.2+ (22.x LTS). Node 22 LTS is recommended.",
"nodeIncompatibleTitle": "Incompatible Node.js Version",
"nodeIncompatibleFixLabel": "Fix: install a patched Node.js 22 LTS release"
},
"landing": {
"brandName": "OmniRoute",
@ -3108,7 +3258,26 @@
"peakCached": "Peak cached",
"deduplicatedRequests": "Deduplicated Requests",
"savedCalls": "Saved API Calls",
"totalProcessed": "Total Requests Processed"
"totalProcessed": "Total Requests Processed",
"cacheRateDesc": "of total requests",
"noTrendData": "No prompt cache activity has been recorded over the last 24 hours.",
"lastUpdated": "Last updated",
"cachedRequests24h": "Cached Requests (24h)",
"semanticCache": "Semantic Cache",
"semanticCacheSectionDesc": "OmniRoute's own deterministic response cache. When enabled, repeated non-streaming temperature=0 requests can be served locally without hitting the upstream provider.",
"providerCacheRateDesc": "Each provider exposes total input tokens, cache read tokens, and cache write tokens so you can verify the reuse ratio against raw totals.",
"busiestHour": "Busiest Hour",
"semanticEntriesDesc": "Persisted semantic cache records currently stored in SQLite. Provider-side prompt cache activity is not listed here.",
"noPromptCacheData": "No provider-side prompt cache activity has been recorded yet.",
"hoursTracked": "hours tracked",
"promptCacheSectionDesc": "Shows provider-side prompt caching activity from usage history so you can see where cache control is active and how much input reuse you are getting.",
"cacheRate": "Cache Rate",
"activityVolume": "Activity",
"peakCacheRate": "Peak Cache Rate",
"entriesLoadError": "Failed to load semantic cache entries.",
"semanticCacheDisabledDesc": "Semantic cache is disabled. OmniRoute will skip local response reuse until you turn it back on in Settings.",
"trendHour": "Hour",
"promptTrendDesc": "Hourly request volume, cache coverage, and cache read volume across the last 24 hours."
},
"memory": {
"title": "Memory Management",
@ -3132,7 +3301,8 @@
"factual": "Factual",
"episodic": "Episodic",
"procedural": "Procedural",
"semantic": "Semantic"
"semantic": "Semantic",
"delete": "Delete"
},
"skills": {
"title": "Skills",

View file

@ -136,7 +136,10 @@
"Failed to save pricing": "Неуспешно запазване на цената",
"Failed to reset pricing": "Неуспешно нулиране на цените",
"apikey": "API ключ",
"http": "HTTP"
"http": "HTTP",
"checkSystemStatus": "Check System Status",
"goToDashboard": "Go to Dashboard",
"nothingHere": "Nothing here yet"
},
"sidebar": {
"home": "Начало",
@ -640,7 +643,8 @@
"opencode": "Използвайте, когато предпочитате нативни за терминални агенти и скриптова автоматизация чрез OpenCode.",
"kiro": "Използвайте, когато интегрирате Kiro и контролирате маршрутизирането на модела централно от OmniRoute.",
"antigravity": "Използвайте, когато трафикът на Antigravity/Kiro трябва да бъде прихванат чрез MITM и насочен към OmniRoute.",
"copilot": "Използвайте, когато искате UX в стил на чат Copilot, като същевременно налагате OmniRoute ключове и правила за маршрутизиране."
"copilot": "Използвайте, когато искате UX в стил на чат Copilot, като същевременно налагате OmniRoute ключове и правила за маршрутизиране.",
"windsurf": "Use when you want an AI-first IDE with Codeium/Windsurf models routed through OmniRoute."
},
"toolDescriptions": {
"antigravity": "Google Antigravity IDE с MITM",
@ -655,7 +659,8 @@
"opencode": "OpenCode AI coding agent (Terminal)",
"kiro": "Amazon Kiro — AI-powered IDE",
"windsurf": "Windsurf AI Code Editor",
"copilot": "GitHub Copilot AI Assistant"
"copilot": "GitHub Copilot AI Assistant",
"qwen": "Alibaba Qwen Code CLI"
},
"guides": {
"cursor": {
@ -890,6 +895,16 @@
"when": "Use when you want perfectly even spread — each model used once before repeating.",
"avoid": "Avoid when models have different quality or latency and order matters.",
"example": "Example: Multiple accounts of the same model to distribute usage evenly."
},
"p2c": {
"when": "Use when you want low-latency selection using Power-of-Two-Choices algorithm.",
"example": "Example: High-throughput inference across 4+ equivalent model endpoints.",
"avoid": "Avoid for small combos with 2 or fewer models — no benefit over round-robin."
},
"context-relay": {
"example": "Example: Codex sessions that rotate across multiple accounts near quota exhaustion.",
"when": "Use when long sessions must survive account rotation without losing the working context.",
"avoid": "Avoid when account switching is rare or when you do not want extra summarization requests."
}
},
"advancedHelp": {
@ -1009,7 +1024,117 @@
"wizardStep3Title": "Choose Strategy",
"wizardStep3Desc": "Pick how requests are distributed across your models - 13 strategies available",
"wizardStep4Title": "Review & Save",
"wizardStep4Desc": "Review your configuration and activate the combo"
"wizardStep4Desc": "Review your configuration and activate the combo",
"emailVisibilityStateOff": "Off",
"builderStage": {
"steps": {
"description": "Provider, model, and account selection",
"label": "Steps"
},
"basics": {
"description": "Name and starting template",
"label": "Basics"
},
"review": {
"label": "Review",
"description": "Final validation before saving"
},
"intelligent": {
"description": "Auto-routing candidate pool, presets, and scoring",
"label": "Smart Routing"
},
"strategy": {
"description": "Routing behavior and advanced settings",
"label": "Strategy"
}
},
"builderPinnedAccount": "Pinned Account",
"weightTierPriority": "Tier",
"builderStageCurrent": "Current stage",
"budgetCapLabel": "Budget Cap (USD / request)",
"builderAccount": "Account",
"builderAddStep": "Add step",
"modePackUpdated": "Mode pack updated to {pack}.",
"builderModel": "Model",
"builderProvider": "Provider",
"builderStagePending": "Pending",
"filterAll": "All",
"explorationRateHint": "{percent}% of requests can explore non-optimal providers.",
"candidatePoolAllProviders": "All providers",
"routerStrategyLabel": "Router Strategy",
"reviewProviders": "Providers",
"reviewAccounts": "Accounts",
"intelligentPanelDesc": "Real-time scoring and health status for this auto-routing combo.",
"candidatePoolEmpty": "No active providers available yet.",
"builderSelectProvider": "Select provider",
"reviewStrategy": "Strategy",
"strategyRules": "Rules (6-Factor Scoring)",
"normalOperation": "Normal Operation",
"builderTitle": "Build a Combo",
"contextRelayDesc": "Preserves session continuity with handoff summaries when accounts rotate",
"reviewNoSteps": "No steps configured",
"reviewComboRefs": "Combo References",
"allProvidersHealthy": "Providers are reporting healthy routing conditions.",
"filterEmptyIntelligentDescription": "Create an auto or LKGP combo to populate the intelligent routing dashboard.",
"builderPreview": "Preview",
"reviewIntelligentTitle": "Intelligent Routing Config",
"reviewSteps": "Steps",
"weightTaskFit": "Task Fit",
"filterEmptyDeterministicDescription": "Only auto and LKGP combos exist right now. Switch back to All or create a deterministic combo.",
"builderIntelligentDesc": "Configure the multi-factor scoring engine for this auto-routing combo.",
"builderAddComboRef": "Add combo reference",
"activeModePack": "Active Mode Pack",
"highCircuitBreakerRate": "High circuit breaker trip rate detected.",
"statusOverview": "Status Overview",
"contextRelayHandoffThresholdHelp": "When quota usage reaches this threshold, OmniRoute generates a structured handoff summary before the active account is exhausted.",
"reorderHandle": "Drag to reorder",
"modePackLabel": "Mode Pack",
"excludedProviders": "Excluded Providers",
"noExcludedProviders": "No providers are currently excluded.",
"budgetCapPlaceholder": "No limit",
"builderBrowseCatalog": "Browse catalog",
"contextRelayMaxMessagesHelp": "Limits how much recent history is condensed into the relay summary.",
"failedReorder": "Failed to reorder models",
"providerScores": "Provider Scores",
"reviewAgentFlags": "Agent Flags",
"builderLoadingProviders": "Loading providers...",
"builderLegacyEntry": "Legacy entry",
"builderProviderFirst": "Pick provider first",
"reviewName": "Name",
"filterIntelligent": "Intelligent",
"weightLatencyInv": "Latency",
"contextRelaySummaryModel": "Summary Model",
"incidentMode": "Incident Mode",
"builderComboRef": "Combo Ref",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex account rotation. Pair it with multiple accounts of the same provider for the best continuity.",
"weightHealth": "Health",
"emailVisibilityStateOn": "On",
"weightStability": "Stability",
"filterDeterministic": "Deterministic",
"explorationRateLabel": "Exploration Rate",
"reviewAdvanced": "Advanced Settings",
"contextRelayMaxMessages": "Max Messages For Summary",
"cooldownMinutes": "Cooldown: {minutes}m",
"reviewSequence": "Model Sequence",
"builderStageVisited": "Stage completed",
"builderIntelligentTitle": "Intelligent Routing Configuration",
"excludedProvidersHint": "Providers with an OPEN circuit breaker are temporarily excluded from routing.",
"contextRelay": "Context Relay",
"builderFlowTitle": "Combo Builder Flow",
"weightCostInv": "Cost",
"modePackHint": "Switch presets to bias the routing engine without rebuilding the combo.",
"advancedWeightsTitle": "Advanced: Scoring Weights",
"candidatePoolHint": "Select which providers this engine should evaluate. Leave empty to use all active providers.",
"candidatePoolLabel": "Candidate Pool",
"contextRelayHandoffThreshold": "Handoff Threshold",
"contextRelaySummaryModelHelp": "Optional override model used only for generating the handoff summary. Leave empty to reuse the active combo model.",
"builderStageLocked": "Locked — complete previous stage first",
"allProvidersEvaluated": "No candidate pool configured. All active providers are evaluated at runtime.",
"builderSelectModel": "Select model",
"filterEmptyTitle": "No combos match this strategy filter.",
"weightQuota": "Quota",
"builderComboRefStep": "Add combo reference",
"intelligentPanelTitle": "Intelligent Routing Dashboard"
},
"costs": {
"title": "Разходи",
@ -1147,7 +1272,9 @@
"a2aQuickStartStep2": "Изпратете JSON - RPC заявки до@@ PH0 @@, като използвате @@ PH1 @@ или @@ PH2 @@.",
"a2aQuickStartStep3": "Проследяване и контрол на задачите с помощта на @@ PH0 @@ и @@ PH1 @@.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format",
"musicDesc": "Generate music and audio tracks via ComfyUI (Stable Audio, MusicGen)",
"musicGeneration": "Music Generation"
},
"endpoints": {
"tabProxy": "Endpoint Proxy",
@ -1749,7 +1876,22 @@
"close": "Close",
"statusDeactivated": "Deactivated (Manual)",
"statusBanned": "Banned / Sandbox Violation",
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted"
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted",
"noModelsMatch": "No models match \"{filter}\"",
"audioTranscriptions": "Audio Transcriptions",
"deselectAllModels": "Deselect all",
"audioSpeech": "Audio Speech",
"repairEnvHint": "Restore missing OAuth defaults into .env without overwriting existing values.",
"embeddings": "Embeddings",
"hideEmails": "Hide all emails",
"imagesGenerations": "Images Generations",
"repairEnvFailed": "Failed to repair .env",
"repairEnv": "Repair env",
"selectAllModels": "Select all",
"modelsActiveCount": "{active}/{total} active",
"repairEnvWorking": "Repairing...",
"showEmails": "Show all emails",
"repairEnvSuccess": "OAuth defaults restored"
},
"settings": {
"title": "Настройки",
@ -2266,7 +2408,11 @@
"wildcardPatternModeDesc": "Use wildcard aliases with * and ? when a family of models should map to one target.",
"noExactAliasesConfigured": "No exact-match aliases configured.",
"wildcardRulesTitle": "Wildcard Rules",
"noWildcardAliasesConfigured": "No wildcard aliases configured."
"noWildcardAliasesConfigured": "No wildcard aliases configured.",
"contextRelayMaxMessages": "Max Messages For Summary",
"contextRelayHandoffThreshold": "Handoff Threshold",
"contextRelaySummaryModel": "Summary Model",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex accounts and uses these values as global defaults for new or unconfigured combos."
},
"translator": {
"title": "Преводач",
@ -2692,7 +2838,11 @@
"waitingForOpenAIAuthorization": "Изчаква се разрешение за OpenAI...",
"waitingForAntigravityAuthorization": "Изчаква се разрешение за антигравитация...",
"waitingForQoderAuthorization": "Изчаква се разрешение за Qoder...",
"exchangingCodeForTokens": "Размяна на код за токени..."
"exchangingCodeForTokens": "Размяна на код за токени...",
"nodeIncompatibleHint": "OmniRoute requires Node.js 20.20.2+ (20.x LTS) or 22.22.2+ (22.x LTS). Node 22 LTS is recommended.",
"nodeIncompatibleTitle": "Incompatible Node.js Version",
"nodeIncompatibleDesc": "You are running Node.js {version}, which is outside OmniRoute's supported secure runtime policy. Use a patched Node.js 20.x or 22.x LTS release.",
"nodeIncompatibleFixLabel": "Fix: install a patched Node.js 22 LTS release"
},
"landing": {
"brandName": "OmniRoute",
@ -3108,7 +3258,26 @@
"peakCached": "Peak cached",
"deduplicatedRequests": "Deduplicated Requests",
"savedCalls": "Saved API Calls",
"totalProcessed": "Total Requests Processed"
"totalProcessed": "Total Requests Processed",
"trendHour": "Hour",
"busiestHour": "Busiest Hour",
"activityVolume": "Activity",
"promptTrendDesc": "Hourly request volume, cache coverage, and cache read volume across the last 24 hours.",
"noTrendData": "No prompt cache activity has been recorded over the last 24 hours.",
"noPromptCacheData": "No provider-side prompt cache activity has been recorded yet.",
"providerCacheRateDesc": "Each provider exposes total input tokens, cache read tokens, and cache write tokens so you can verify the reuse ratio against raw totals.",
"hoursTracked": "hours tracked",
"cacheRate": "Cache Rate",
"promptCacheSectionDesc": "Shows provider-side prompt caching activity from usage history so you can see where cache control is active and how much input reuse you are getting.",
"semanticCacheSectionDesc": "OmniRoute's own deterministic response cache. When enabled, repeated non-streaming temperature=0 requests can be served locally without hitting the upstream provider.",
"semanticEntriesDesc": "Persisted semantic cache records currently stored in SQLite. Provider-side prompt cache activity is not listed here.",
"entriesLoadError": "Failed to load semantic cache entries.",
"semanticCacheDisabledDesc": "Semantic cache is disabled. OmniRoute will skip local response reuse until you turn it back on in Settings.",
"cachedRequests24h": "Cached Requests (24h)",
"semanticCache": "Semantic Cache",
"cacheRateDesc": "of total requests",
"lastUpdated": "Last updated",
"peakCacheRate": "Peak Cache Rate"
},
"memory": {
"title": "Memory Management",
@ -3132,7 +3301,8 @@
"factual": "Factual",
"episodic": "Episodic",
"procedural": "Procedural",
"semantic": "Semantic"
"semantic": "Semantic",
"delete": "Delete"
},
"skills": {
"title": "Skills",

View file

@ -136,7 +136,10 @@
"Failed to save pricing": "Nepodařilo se uložit ceny",
"Failed to reset pricing": "Nepodařilo se resetovat ceny",
"apikey": "API klíč",
"http": "HTTP"
"http": "HTTP",
"goToDashboard": "Go to Dashboard",
"nothingHere": "Nothing here yet",
"checkSystemStatus": "Check System Status"
},
"sidebar": {
"home": "Domov",
@ -640,7 +643,8 @@
"opencode": "Použijte, pokud dáváte přednost spouštění agentů nativně v terminálu a skriptované automatizaci přes OpenCode.",
"kiro": "Použijte při integraci Kiro a centrálním řízení směrování modelů z OmniRoute.",
"antigravity": "Použijte, pokud musí být provoz Antigravity/Kiro zachycen prostřednictvím MITM a směrován do OmniRoute.",
"copilot": "Použijte, pokud chcete uživatelské rozhraní ve stylu Copilot chat a zároveň vynutit klíče a pravidla směrování OmniRoute."
"copilot": "Použijte, pokud chcete uživatelské rozhraní ve stylu Copilot chat a zároveň vynutit klíče a pravidla směrování OmniRoute.",
"windsurf": "Use when you want an AI-first IDE with Codeium/Windsurf models routed through OmniRoute."
},
"toolDescriptions": {
"antigravity": "Google Antigravity IDE s MITM",
@ -655,7 +659,8 @@
"opencode": "OpenCode AI coding agent (Terminál)",
"kiro": "Amazon Kiro AI poháněné IDE",
"windsurf": "Windsurf AI Code Editor",
"copilot": "GitHub Copilot AI Assistant"
"copilot": "GitHub Copilot AI Assistant",
"qwen": "Alibaba Qwen Code CLI"
},
"guides": {
"cursor": {
@ -890,6 +895,16 @@
"when": "Použijte, když chcete rovnoměrné rozložení — každý model se použije jednou před opakováním.",
"avoid": "Nepoužívejte, když mají modely různou kvalitu nebo latenci a záleží na pořadí.",
"example": "Příklad: Více účtů stejného modelu pro rovnoměrné rozložení využití."
},
"context-relay": {
"avoid": "Avoid when account switching is rare or when you do not want extra summarization requests.",
"example": "Example: Codex sessions that rotate across multiple accounts near quota exhaustion.",
"when": "Use when long sessions must survive account rotation without losing the working context."
},
"p2c": {
"example": "Example: High-throughput inference across 4+ equivalent model endpoints.",
"avoid": "Avoid for small combos with 2 or fewer models — no benefit over round-robin.",
"when": "Use when you want low-latency selection using Power-of-Two-Choices algorithm."
}
},
"advancedHelp": {
@ -1009,7 +1024,117 @@
"wizardStep3Title": "Choose Strategy",
"wizardStep3Desc": "Pick how requests are distributed across your models - 13 strategies available",
"wizardStep4Title": "Review & Save",
"wizardStep4Desc": "Review your configuration and activate the combo"
"wizardStep4Desc": "Review your configuration and activate the combo",
"weightHealth": "Health",
"candidatePoolEmpty": "No active providers available yet.",
"builderStageLocked": "Locked — complete previous stage first",
"reorderHandle": "Drag to reorder",
"excludedProviders": "Excluded Providers",
"reviewProviders": "Providers",
"contextRelayMaxMessagesHelp": "Limits how much recent history is condensed into the relay summary.",
"reviewSequence": "Model Sequence",
"advancedWeightsTitle": "Advanced: Scoring Weights",
"candidatePoolAllProviders": "All providers",
"weightQuota": "Quota",
"reviewNoSteps": "No steps configured",
"modePackLabel": "Mode Pack",
"builderIntelligentDesc": "Configure the multi-factor scoring engine for this auto-routing combo.",
"reviewAdvanced": "Advanced Settings",
"contextRelayHandoffThreshold": "Handoff Threshold",
"emailVisibilityStateOn": "On",
"reviewName": "Name",
"routerStrategyLabel": "Router Strategy",
"weightStability": "Stability",
"normalOperation": "Normal Operation",
"builderFlowTitle": "Combo Builder Flow",
"intelligentPanelDesc": "Real-time scoring and health status for this auto-routing combo.",
"builderStage": {
"strategy": {
"description": "Routing behavior and advanced settings",
"label": "Strategy"
},
"steps": {
"label": "Steps",
"description": "Provider, model, and account selection"
},
"intelligent": {
"label": "Smart Routing",
"description": "Auto-routing candidate pool, presets, and scoring"
},
"review": {
"label": "Review",
"description": "Final validation before saving"
},
"basics": {
"description": "Name and starting template",
"label": "Basics"
}
},
"builderStageCurrent": "Current stage",
"reviewComboRefs": "Combo References",
"failedReorder": "Failed to reorder models",
"builderComboRef": "Combo Ref",
"builderPinnedAccount": "Pinned Account",
"reviewAgentFlags": "Agent Flags",
"highCircuitBreakerRate": "High circuit breaker trip rate detected.",
"builderSelectModel": "Select model",
"modePackHint": "Switch presets to bias the routing engine without rebuilding the combo.",
"builderAddStep": "Add step",
"builderAccount": "Account",
"builderAddComboRef": "Add combo reference",
"builderLoadingProviders": "Loading providers...",
"cooldownMinutes": "Cooldown: {minutes}m",
"contextRelayHandoffThresholdHelp": "When quota usage reaches this threshold, OmniRoute generates a structured handoff summary before the active account is exhausted.",
"modePackUpdated": "Mode pack updated to {pack}.",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex account rotation. Pair it with multiple accounts of the same provider for the best continuity.",
"reviewSteps": "Steps",
"filterEmptyIntelligentDescription": "Create an auto or LKGP combo to populate the intelligent routing dashboard.",
"builderIntelligentTitle": "Intelligent Routing Configuration",
"weightLatencyInv": "Latency",
"filterDeterministic": "Deterministic",
"builderSelectProvider": "Select provider",
"builderStageVisited": "Stage completed",
"builderTitle": "Build a Combo",
"emailVisibilityStateOff": "Off",
"contextRelaySummaryModel": "Summary Model",
"incidentMode": "Incident Mode",
"candidatePoolLabel": "Candidate Pool",
"contextRelaySummaryModelHelp": "Optional override model used only for generating the handoff summary. Leave empty to reuse the active combo model.",
"builderPreview": "Preview",
"contextRelayMaxMessages": "Max Messages For Summary",
"allProvidersHealthy": "Providers are reporting healthy routing conditions.",
"providerScores": "Provider Scores",
"statusOverview": "Status Overview",
"budgetCapPlaceholder": "No limit",
"reviewIntelligentTitle": "Intelligent Routing Config",
"strategyRules": "Rules (6-Factor Scoring)",
"weightTierPriority": "Tier",
"builderBrowseCatalog": "Browse catalog",
"builderStagePending": "Pending",
"weightCostInv": "Cost",
"builderModel": "Model",
"builderComboRefStep": "Add combo reference",
"builderProvider": "Provider",
"filterEmptyDeterministicDescription": "Only auto and LKGP combos exist right now. Switch back to All or create a deterministic combo.",
"excludedProvidersHint": "Providers with an OPEN circuit breaker are temporarily excluded from routing.",
"filterIntelligent": "Intelligent",
"explorationRateLabel": "Exploration Rate",
"contextRelayDesc": "Preserves session continuity with handoff summaries when accounts rotate",
"contextRelay": "Context Relay",
"reviewAccounts": "Accounts",
"noExcludedProviders": "No providers are currently excluded.",
"explorationRateHint": "{percent}% of requests can explore non-optimal providers.",
"filterEmptyTitle": "No combos match this strategy filter.",
"builderProviderFirst": "Pick provider first",
"builderLegacyEntry": "Legacy entry",
"weightTaskFit": "Task Fit",
"allProvidersEvaluated": "No candidate pool configured. All active providers are evaluated at runtime.",
"filterAll": "All",
"candidatePoolHint": "Select which providers this engine should evaluate. Leave empty to use all active providers.",
"activeModePack": "Active Mode Pack",
"intelligentPanelTitle": "Intelligent Routing Dashboard",
"budgetCapLabel": "Budget Cap (USD / request)",
"reviewStrategy": "Strategy"
},
"costs": {
"title": "Náklady",
@ -1147,7 +1272,9 @@
"a2aQuickStartStep2": "Odešlete požadavky JSON-RPC na `POST /a2a` pomocí `message/send` nebo `message/stream`.",
"a2aQuickStartStep3": "Sledujte a ovládejte úkoly pomocí příkazů `tasks/get` a `tasks/cancel`.",
"completionsLegacy": "Completions (Zastaralé)",
"completionsLegacyDesc": "Zastaralé OpenAI text completion akceptuje oba formáty, prompt string i messages array."
"completionsLegacyDesc": "Zastaralé OpenAI text completion akceptuje oba formáty, prompt string i messages array.",
"musicGeneration": "Music Generation",
"musicDesc": "Generate music and audio tracks via ComfyUI (Stable Audio, MusicGen)"
},
"endpoints": {
"tabProxy": "Koncová Proxy",
@ -1749,7 +1876,22 @@
"close": "Zavřít",
"statusDeactivated": "Deaktivováno (Manuální)",
"statusBanned": "Zablokováno / Porušení sandboxu",
"statusCreditsExhausted": "Nedostatečný zůstatek / Kvóta vyčerpána"
"statusCreditsExhausted": "Nedostatečný zůstatek / Kvóta vyčerpána",
"hideEmails": "Hide all emails",
"repairEnv": "Repair env",
"showEmails": "Show all emails",
"modelsActiveCount": "{active}/{total} active",
"audioSpeech": "Audio Speech",
"embeddings": "Embeddings",
"selectAllModels": "Select all",
"deselectAllModels": "Deselect all",
"repairEnvSuccess": "OAuth defaults restored",
"imagesGenerations": "Images Generations",
"audioTranscriptions": "Audio Transcriptions",
"noModelsMatch": "No models match \"{filter}\"",
"repairEnvFailed": "Failed to repair .env",
"repairEnvWorking": "Repairing...",
"repairEnvHint": "Restore missing OAuth defaults into .env without overwriting existing values."
},
"settings": {
"title": "Nastavení",
@ -2266,7 +2408,11 @@
"wildcardPatternModeDesc": "Use wildcard aliases with * and ? when a family of models should map to one target.",
"noExactAliasesConfigured": "No exact-match aliases configured.",
"wildcardRulesTitle": "Wildcard Rules",
"noWildcardAliasesConfigured": "No wildcard aliases configured."
"noWildcardAliasesConfigured": "No wildcard aliases configured.",
"contextRelaySummaryModel": "Summary Model",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex accounts and uses these values as global defaults for new or unconfigured combos.",
"contextRelayMaxMessages": "Max Messages For Summary",
"contextRelayHandoffThreshold": "Handoff Threshold"
},
"translator": {
"title": "Překladatel",
@ -2692,7 +2838,11 @@
"waitingForOpenAIAuthorization": "Čekám na OpenAI autorizaci...",
"waitingForAntigravityAuthorization": "Čekám na Antigravity autorizaci...",
"waitingForQoderAuthorization": "Čekám na Qoder autorizaci...",
"exchangingCodeForTokens": "Vyměňuji kód za tokeny..."
"exchangingCodeForTokens": "Vyměňuji kód za tokeny...",
"nodeIncompatibleHint": "OmniRoute requires Node.js 20.20.2+ (20.x LTS) or 22.22.2+ (22.x LTS). Node 22 LTS is recommended.",
"nodeIncompatibleFixLabel": "Fix: install a patched Node.js 22 LTS release",
"nodeIncompatibleDesc": "You are running Node.js {version}, which is outside OmniRoute's supported secure runtime policy. Use a patched Node.js 20.x or 22.x LTS release.",
"nodeIncompatibleTitle": "Incompatible Node.js Version"
},
"landing": {
"brandName": "OmniRoute",
@ -3108,7 +3258,26 @@
"peakCached": "Vrchol mezipaměti",
"deduplicatedRequests": "Deduplikované požadavky",
"savedCalls": "Uložená API volání",
"totalProcessed": "Celkem zpracováno"
"totalProcessed": "Celkem zpracováno",
"cachedRequests24h": "Cached Requests (24h)",
"noPromptCacheData": "No provider-side prompt cache activity has been recorded yet.",
"providerCacheRateDesc": "Each provider exposes total input tokens, cache read tokens, and cache write tokens so you can verify the reuse ratio against raw totals.",
"semanticCacheSectionDesc": "OmniRoute's own deterministic response cache. When enabled, repeated non-streaming temperature=0 requests can be served locally without hitting the upstream provider.",
"lastUpdated": "Last updated",
"semanticEntriesDesc": "Persisted semantic cache records currently stored in SQLite. Provider-side prompt cache activity is not listed here.",
"cacheRateDesc": "of total requests",
"noTrendData": "No prompt cache activity has been recorded over the last 24 hours.",
"cacheRate": "Cache Rate",
"semanticCacheDisabledDesc": "Semantic cache is disabled. OmniRoute will skip local response reuse until you turn it back on in Settings.",
"busiestHour": "Busiest Hour",
"trendHour": "Hour",
"peakCacheRate": "Peak Cache Rate",
"hoursTracked": "hours tracked",
"semanticCache": "Semantic Cache",
"entriesLoadError": "Failed to load semantic cache entries.",
"promptCacheSectionDesc": "Shows provider-side prompt caching activity from usage history so you can see where cache control is active and how much input reuse you are getting.",
"activityVolume": "Activity",
"promptTrendDesc": "Hourly request volume, cache coverage, and cache read volume across the last 24 hours."
},
"memory": {
"title": "Správa paměti",
@ -3132,7 +3301,8 @@
"factual": "Faktická",
"episodic": "Epizodická",
"procedural": "Procedurální",
"semantic": "Sémantická"
"semantic": "Sémantická",
"delete": "Delete"
},
"skills": {
"title": "Dovednosti",

View file

@ -136,7 +136,10 @@
"Failed to save pricing": "Kunne ikke gemme prisen",
"Failed to reset pricing": "Failed to reset pricing",
"apikey": "API nøgle",
"http": "HTTP"
"http": "HTTP",
"goToDashboard": "Go to Dashboard",
"checkSystemStatus": "Check System Status",
"nothingHere": "Nothing here yet"
},
"sidebar": {
"home": "Hjem",
@ -640,7 +643,8 @@
"opencode": "Brug, når du foretrækker terminal-native agentkørsler og scriptet automatisering via OpenCode.",
"kiro": "Bruges ved integration af Kiro og styring af modelrouting centralt fra OmniRoute.",
"antigravity": "Bruges, når Antigravity/Kiro-trafik skal opsnappes gennem MITM og dirigeres til OmniRoute.",
"copilot": "Brug, når du ønsker Copilot-chatstil UX, mens du håndhæver OmniRoute-nøgler og routingregler."
"copilot": "Brug, når du ønsker Copilot-chatstil UX, mens du håndhæver OmniRoute-nøgler og routingregler.",
"windsurf": "Use when you want an AI-first IDE with Codeium/Windsurf models routed through OmniRoute."
},
"toolDescriptions": {
"antigravity": "Google Antigravity IDE med MITM",
@ -655,7 +659,8 @@
"opencode": "OpenCode AI coding agent (Terminal)",
"kiro": "Amazon Kiro — AI-powered IDE",
"windsurf": "Windsurf AI Code Editor",
"copilot": "GitHub Copilot AI Assistant"
"copilot": "GitHub Copilot AI Assistant",
"qwen": "Alibaba Qwen Code CLI"
},
"guides": {
"cursor": {
@ -890,6 +895,16 @@
"when": "Use when you want perfectly even spread — each model used once before repeating.",
"avoid": "Avoid when models have different quality or latency and order matters.",
"example": "Example: Multiple accounts of the same model to distribute usage evenly."
},
"p2c": {
"example": "Example: High-throughput inference across 4+ equivalent model endpoints.",
"when": "Use when you want low-latency selection using Power-of-Two-Choices algorithm.",
"avoid": "Avoid for small combos with 2 or fewer models — no benefit over round-robin."
},
"context-relay": {
"example": "Example: Codex sessions that rotate across multiple accounts near quota exhaustion.",
"when": "Use when long sessions must survive account rotation without losing the working context.",
"avoid": "Avoid when account switching is rare or when you do not want extra summarization requests."
}
},
"advancedHelp": {
@ -1009,7 +1024,117 @@
"wizardStep3Title": "Choose Strategy",
"wizardStep3Desc": "Pick how requests are distributed across your models - 13 strategies available",
"wizardStep4Title": "Review & Save",
"wizardStep4Desc": "Review your configuration and activate the combo"
"wizardStep4Desc": "Review your configuration and activate the combo",
"builderProviderFirst": "Pick provider first",
"intelligentPanelTitle": "Intelligent Routing Dashboard",
"modePackUpdated": "Mode pack updated to {pack}.",
"builderStage": {
"steps": {
"description": "Provider, model, and account selection",
"label": "Steps"
},
"strategy": {
"label": "Strategy",
"description": "Routing behavior and advanced settings"
},
"review": {
"description": "Final validation before saving",
"label": "Review"
},
"intelligent": {
"label": "Smart Routing",
"description": "Auto-routing candidate pool, presets, and scoring"
},
"basics": {
"label": "Basics",
"description": "Name and starting template"
}
},
"explorationRateLabel": "Exploration Rate",
"budgetCapLabel": "Budget Cap (USD / request)",
"reorderHandle": "Drag to reorder",
"builderPreview": "Preview",
"reviewName": "Name",
"weightStability": "Stability",
"builderStageVisited": "Stage completed",
"filterEmptyDeterministicDescription": "Only auto and LKGP combos exist right now. Switch back to All or create a deterministic combo.",
"routerStrategyLabel": "Router Strategy",
"candidatePoolHint": "Select which providers this engine should evaluate. Leave empty to use all active providers.",
"filterIntelligent": "Intelligent",
"contextRelayDesc": "Preserves session continuity with handoff summaries when accounts rotate",
"providerScores": "Provider Scores",
"modePackLabel": "Mode Pack",
"builderAddStep": "Add step",
"builderProvider": "Provider",
"reviewNoSteps": "No steps configured",
"builderLoadingProviders": "Loading providers...",
"builderSelectProvider": "Select provider",
"excludedProvidersHint": "Providers with an OPEN circuit breaker are temporarily excluded from routing.",
"reviewAccounts": "Accounts",
"failedReorder": "Failed to reorder models",
"contextRelayMaxMessagesHelp": "Limits how much recent history is condensed into the relay summary.",
"builderStagePending": "Pending",
"builderPinnedAccount": "Pinned Account",
"allProvidersHealthy": "Providers are reporting healthy routing conditions.",
"normalOperation": "Normal Operation",
"filterEmptyTitle": "No combos match this strategy filter.",
"excludedProviders": "Excluded Providers",
"contextRelaySummaryModel": "Summary Model",
"reviewComboRefs": "Combo References",
"reviewAdvanced": "Advanced Settings",
"builderModel": "Model",
"candidatePoolEmpty": "No active providers available yet.",
"modePackHint": "Switch presets to bias the routing engine without rebuilding the combo.",
"advancedWeightsTitle": "Advanced: Scoring Weights",
"builderLegacyEntry": "Legacy entry",
"intelligentPanelDesc": "Real-time scoring and health status for this auto-routing combo.",
"incidentMode": "Incident Mode",
"reviewProviders": "Providers",
"budgetCapPlaceholder": "No limit",
"contextRelaySummaryModelHelp": "Optional override model used only for generating the handoff summary. Leave empty to reuse the active combo model.",
"highCircuitBreakerRate": "High circuit breaker trip rate detected.",
"filterDeterministic": "Deterministic",
"weightTierPriority": "Tier",
"explorationRateHint": "{percent}% of requests can explore non-optimal providers.",
"emailVisibilityStateOn": "On",
"reviewSequence": "Model Sequence",
"strategyRules": "Rules (6-Factor Scoring)",
"builderComboRefStep": "Add combo reference",
"builderBrowseCatalog": "Browse catalog",
"builderComboRef": "Combo Ref",
"builderAccount": "Account",
"builderStageLocked": "Locked — complete previous stage first",
"contextRelayHandoffThreshold": "Handoff Threshold",
"candidatePoolAllProviders": "All providers",
"reviewSteps": "Steps",
"candidatePoolLabel": "Candidate Pool",
"contextRelay": "Context Relay",
"filterAll": "All",
"builderAddComboRef": "Add combo reference",
"weightLatencyInv": "Latency",
"emailVisibilityStateOff": "Off",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex account rotation. Pair it with multiple accounts of the same provider for the best continuity.",
"weightCostInv": "Cost",
"weightTaskFit": "Task Fit",
"reviewStrategy": "Strategy",
"filterEmptyIntelligentDescription": "Create an auto or LKGP combo to populate the intelligent routing dashboard.",
"allProvidersEvaluated": "No candidate pool configured. All active providers are evaluated at runtime.",
"cooldownMinutes": "Cooldown: {minutes}m",
"statusOverview": "Status Overview",
"builderTitle": "Build a Combo",
"builderIntelligentDesc": "Configure the multi-factor scoring engine for this auto-routing combo.",
"builderIntelligentTitle": "Intelligent Routing Configuration",
"reviewIntelligentTitle": "Intelligent Routing Config",
"activeModePack": "Active Mode Pack",
"builderSelectModel": "Select model",
"weightHealth": "Health",
"weightQuota": "Quota",
"reviewAgentFlags": "Agent Flags",
"contextRelayHandoffThresholdHelp": "When quota usage reaches this threshold, OmniRoute generates a structured handoff summary before the active account is exhausted.",
"noExcludedProviders": "No providers are currently excluded.",
"builderStageCurrent": "Current stage",
"builderFlowTitle": "Combo Builder Flow",
"contextRelayMaxMessages": "Max Messages For Summary"
},
"costs": {
"title": "Omkostninger",
@ -1147,7 +1272,9 @@
"a2aQuickStartStep2": "Send JSON-RPC-anmodninger til`POST /a2a`vedhjælp af `message/send` eller `message/stream`.",
"a2aQuickStartStep3": "Spor og kontroller opgaver ved hjælp af `tasks/get` og `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format",
"musicDesc": "Generate music and audio tracks via ComfyUI (Stable Audio, MusicGen)",
"musicGeneration": "Music Generation"
},
"endpoints": {
"tabProxy": "Endpoint Proxy",
@ -1749,7 +1876,22 @@
"close": "Close",
"statusDeactivated": "Deactivated (Manual)",
"statusBanned": "Banned / Sandbox Violation",
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted"
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted",
"repairEnvWorking": "Repairing...",
"repairEnvSuccess": "OAuth defaults restored",
"repairEnvHint": "Restore missing OAuth defaults into .env without overwriting existing values.",
"showEmails": "Show all emails",
"audioSpeech": "Audio Speech",
"modelsActiveCount": "{active}/{total} active",
"repairEnvFailed": "Failed to repair .env",
"audioTranscriptions": "Audio Transcriptions",
"deselectAllModels": "Deselect all",
"imagesGenerations": "Images Generations",
"embeddings": "Embeddings",
"hideEmails": "Hide all emails",
"noModelsMatch": "No models match \"{filter}\"",
"repairEnv": "Repair env",
"selectAllModels": "Select all"
},
"settings": {
"title": "Indstillinger",
@ -2266,7 +2408,11 @@
"wildcardPatternModeDesc": "Use wildcard aliases with * and ? when a family of models should map to one target.",
"noExactAliasesConfigured": "No exact-match aliases configured.",
"wildcardRulesTitle": "Wildcard Rules",
"noWildcardAliasesConfigured": "No wildcard aliases configured."
"noWildcardAliasesConfigured": "No wildcard aliases configured.",
"contextRelaySummaryModel": "Summary Model",
"contextRelayHandoffThreshold": "Handoff Threshold",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex accounts and uses these values as global defaults for new or unconfigured combos.",
"contextRelayMaxMessages": "Max Messages For Summary"
},
"translator": {
"title": "Oversætter",
@ -2692,7 +2838,11 @@
"waitingForOpenAIAuthorization": "Venter på OpenAI-godkendelse...",
"waitingForAntigravityAuthorization": "Venter på antigravity-autorisation...",
"waitingForQoderAuthorization": "Venter på Qoder-godkendelse...",
"exchangingCodeForTokens": "Udveksler kode til tokens..."
"exchangingCodeForTokens": "Udveksler kode til tokens...",
"nodeIncompatibleTitle": "Incompatible Node.js Version",
"nodeIncompatibleDesc": "You are running Node.js {version}, which is outside OmniRoute's supported secure runtime policy. Use a patched Node.js 20.x or 22.x LTS release.",
"nodeIncompatibleFixLabel": "Fix: install a patched Node.js 22 LTS release",
"nodeIncompatibleHint": "OmniRoute requires Node.js 20.20.2+ (20.x LTS) or 22.22.2+ (22.x LTS). Node 22 LTS is recommended."
},
"landing": {
"brandName": "OmniRoute",
@ -3108,7 +3258,26 @@
"peakCached": "Peak cached",
"deduplicatedRequests": "Deduplicated Requests",
"savedCalls": "Saved API Calls",
"totalProcessed": "Total Requests Processed"
"totalProcessed": "Total Requests Processed",
"lastUpdated": "Last updated",
"peakCacheRate": "Peak Cache Rate",
"cachedRequests24h": "Cached Requests (24h)",
"promptTrendDesc": "Hourly request volume, cache coverage, and cache read volume across the last 24 hours.",
"semanticCacheSectionDesc": "OmniRoute's own deterministic response cache. When enabled, repeated non-streaming temperature=0 requests can be served locally without hitting the upstream provider.",
"providerCacheRateDesc": "Each provider exposes total input tokens, cache read tokens, and cache write tokens so you can verify the reuse ratio against raw totals.",
"noTrendData": "No prompt cache activity has been recorded over the last 24 hours.",
"entriesLoadError": "Failed to load semantic cache entries.",
"trendHour": "Hour",
"semanticCacheDisabledDesc": "Semantic cache is disabled. OmniRoute will skip local response reuse until you turn it back on in Settings.",
"noPromptCacheData": "No provider-side prompt cache activity has been recorded yet.",
"promptCacheSectionDesc": "Shows provider-side prompt caching activity from usage history so you can see where cache control is active and how much input reuse you are getting.",
"hoursTracked": "hours tracked",
"busiestHour": "Busiest Hour",
"cacheRateDesc": "of total requests",
"semanticEntriesDesc": "Persisted semantic cache records currently stored in SQLite. Provider-side prompt cache activity is not listed here.",
"activityVolume": "Activity",
"semanticCache": "Semantic Cache",
"cacheRate": "Cache Rate"
},
"memory": {
"title": "Memory Management",
@ -3132,7 +3301,8 @@
"factual": "Factual",
"episodic": "Episodic",
"procedural": "Procedural",
"semantic": "Semantic"
"semantic": "Semantic",
"delete": "Delete"
},
"skills": {
"title": "Skills",

View file

@ -136,7 +136,10 @@
"Failed to save pricing": "Preise speichern fehlgeschlagen",
"Failed to reset pricing": "Preise zurücksetzen fehlgeschlagen",
"apikey": "API-Schlüssel",
"http": "HTTP"
"http": "HTTP",
"nothingHere": "Nothing here yet",
"checkSystemStatus": "Check System Status",
"goToDashboard": "Go to Dashboard"
},
"sidebar": {
"home": "Zuhause",
@ -640,7 +643,8 @@
"opencode": "Verwenden Sie diese Option, wenn Sie terminalnative Agentenausführungen und Skriptautomatisierung über OpenCode bevorzugen.",
"kiro": "Zur Verwendung bei der Integration von Kiro und der zentralen Steuerung des Modellroutings über OmniRoute.",
"antigravity": "Wird verwendet, wenn Antigravity/Kiro-Verkehr über MITM abgefangen und an OmniRoute weitergeleitet werden muss.",
"copilot": "Verwenden Sie diese Option, wenn Sie eine UX im Copilot-Chat-Stil wünschen und gleichzeitig OmniRoute-Schlüssel und Routing-Regeln durchsetzen möchten."
"copilot": "Verwenden Sie diese Option, wenn Sie eine UX im Copilot-Chat-Stil wünschen und gleichzeitig OmniRoute-Schlüssel und Routing-Regeln durchsetzen möchten.",
"windsurf": "Use when you want an AI-first IDE with Codeium/Windsurf models routed through OmniRoute."
},
"toolDescriptions": {
"antigravity": "Google Antigravity IDE mit MITM",
@ -655,7 +659,8 @@
"opencode": "OpenCode AI coding agent (Terminal)",
"kiro": "Amazon Kiro — AI-powered IDE",
"windsurf": "Windsurf AI Code Editor",
"copilot": "GitHub Copilot AI Assistant"
"copilot": "GitHub Copilot AI Assistant",
"qwen": "Alibaba Qwen Code CLI"
},
"guides": {
"cursor": {
@ -890,6 +895,16 @@
"when": "Use when you want perfectly even spread — each model used once before repeating.",
"avoid": "Avoid when models have different quality or latency and order matters.",
"example": "Example: Multiple accounts of the same model to distribute usage evenly."
},
"context-relay": {
"avoid": "Avoid when account switching is rare or when you do not want extra summarization requests.",
"when": "Use when long sessions must survive account rotation without losing the working context.",
"example": "Example: Codex sessions that rotate across multiple accounts near quota exhaustion."
},
"p2c": {
"avoid": "Avoid for small combos with 2 or fewer models — no benefit over round-robin.",
"when": "Use when you want low-latency selection using Power-of-Two-Choices algorithm.",
"example": "Example: High-throughput inference across 4+ equivalent model endpoints."
}
},
"advancedHelp": {
@ -1009,7 +1024,117 @@
"wizardStep3Title": "Choose Strategy",
"wizardStep3Desc": "Pick how requests are distributed across your models - 13 strategies available",
"wizardStep4Title": "Review & Save",
"wizardStep4Desc": "Review your configuration and activate the combo"
"wizardStep4Desc": "Review your configuration and activate the combo",
"filterEmptyDeterministicDescription": "Only auto and LKGP combos exist right now. Switch back to All or create a deterministic combo.",
"weightCostInv": "Cost",
"builderStage": {
"steps": {
"description": "Provider, model, and account selection",
"label": "Steps"
},
"review": {
"label": "Review",
"description": "Final validation before saving"
},
"strategy": {
"description": "Routing behavior and advanced settings",
"label": "Strategy"
},
"intelligent": {
"label": "Smart Routing",
"description": "Auto-routing candidate pool, presets, and scoring"
},
"basics": {
"label": "Basics",
"description": "Name and starting template"
}
},
"builderFlowTitle": "Combo Builder Flow",
"weightHealth": "Health",
"contextRelayDesc": "Preserves session continuity with handoff summaries when accounts rotate",
"incidentMode": "Incident Mode",
"budgetCapLabel": "Budget Cap (USD / request)",
"intelligentPanelDesc": "Real-time scoring and health status for this auto-routing combo.",
"filterAll": "All",
"filterEmptyTitle": "No combos match this strategy filter.",
"statusOverview": "Status Overview",
"contextRelay": "Context Relay",
"failedReorder": "Failed to reorder models",
"contextRelayHandoffThreshold": "Handoff Threshold",
"builderPinnedAccount": "Pinned Account",
"highCircuitBreakerRate": "High circuit breaker trip rate detected.",
"excludedProviders": "Excluded Providers",
"builderAddComboRef": "Add combo reference",
"reorderHandle": "Drag to reorder",
"builderComboRef": "Combo Ref",
"contextRelaySummaryModelHelp": "Optional override model used only for generating the handoff summary. Leave empty to reuse the active combo model.",
"builderSelectModel": "Select model",
"allProvidersHealthy": "Providers are reporting healthy routing conditions.",
"providerScores": "Provider Scores",
"activeModePack": "Active Mode Pack",
"builderTitle": "Build a Combo",
"weightQuota": "Quota",
"reviewProviders": "Providers",
"allProvidersEvaluated": "No candidate pool configured. All active providers are evaluated at runtime.",
"builderSelectProvider": "Select provider",
"reviewSteps": "Steps",
"routerStrategyLabel": "Router Strategy",
"builderPreview": "Preview",
"reviewIntelligentTitle": "Intelligent Routing Config",
"emailVisibilityStateOff": "Off",
"builderStageCurrent": "Current stage",
"builderStageLocked": "Locked — complete previous stage first",
"builderAddStep": "Add step",
"reviewAdvanced": "Advanced Settings",
"noExcludedProviders": "No providers are currently excluded.",
"emailVisibilityStateOn": "On",
"modePackUpdated": "Mode pack updated to {pack}.",
"builderLegacyEntry": "Legacy entry",
"reviewName": "Name",
"builderIntelligentDesc": "Configure the multi-factor scoring engine for this auto-routing combo.",
"weightStability": "Stability",
"budgetCapPlaceholder": "No limit",
"candidatePoolLabel": "Candidate Pool",
"contextRelayMaxMessages": "Max Messages For Summary",
"strategyRules": "Rules (6-Factor Scoring)",
"builderProviderFirst": "Pick provider first",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex account rotation. Pair it with multiple accounts of the same provider for the best continuity.",
"builderProvider": "Provider",
"weightTierPriority": "Tier",
"reviewAgentFlags": "Agent Flags",
"intelligentPanelTitle": "Intelligent Routing Dashboard",
"filterEmptyIntelligentDescription": "Create an auto or LKGP combo to populate the intelligent routing dashboard.",
"contextRelayMaxMessagesHelp": "Limits how much recent history is condensed into the relay summary.",
"filterIntelligent": "Intelligent",
"builderStagePending": "Pending",
"reviewNoSteps": "No steps configured",
"builderComboRefStep": "Add combo reference",
"cooldownMinutes": "Cooldown: {minutes}m",
"reviewAccounts": "Accounts",
"explorationRateLabel": "Exploration Rate",
"explorationRateHint": "{percent}% of requests can explore non-optimal providers.",
"candidatePoolEmpty": "No active providers available yet.",
"reviewComboRefs": "Combo References",
"contextRelayHandoffThresholdHelp": "When quota usage reaches this threshold, OmniRoute generates a structured handoff summary before the active account is exhausted.",
"builderStageVisited": "Stage completed",
"modePackLabel": "Mode Pack",
"weightLatencyInv": "Latency",
"builderAccount": "Account",
"weightTaskFit": "Task Fit",
"reviewStrategy": "Strategy",
"reviewSequence": "Model Sequence",
"builderModel": "Model",
"candidatePoolHint": "Select which providers this engine should evaluate. Leave empty to use all active providers.",
"normalOperation": "Normal Operation",
"excludedProvidersHint": "Providers with an OPEN circuit breaker are temporarily excluded from routing.",
"filterDeterministic": "Deterministic",
"candidatePoolAllProviders": "All providers",
"contextRelaySummaryModel": "Summary Model",
"builderBrowseCatalog": "Browse catalog",
"builderIntelligentTitle": "Intelligent Routing Configuration",
"modePackHint": "Switch presets to bias the routing engine without rebuilding the combo.",
"advancedWeightsTitle": "Advanced: Scoring Weights",
"builderLoadingProviders": "Loading providers..."
},
"costs": {
"title": "Kosten",
@ -1147,7 +1272,9 @@
"a2aQuickStartStep2": "Senden Sie JSON-RPC-Anfragen an `POST /a2a` mit `message/send` oder `message/stream`.",
"a2aQuickStartStep3": "Verfolgen und steuern Sie Aufgaben mit `tasks/get` und `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format",
"musicDesc": "Generate music and audio tracks via ComfyUI (Stable Audio, MusicGen)",
"musicGeneration": "Music Generation"
},
"endpoints": {
"tabProxy": "Endpoint Proxy",
@ -1749,7 +1876,22 @@
"close": "Close",
"statusDeactivated": "Deactivated (Manual)",
"statusBanned": "Banned / Sandbox Violation",
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted"
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted",
"modelsActiveCount": "{active}/{total} active",
"hideEmails": "Hide all emails",
"embeddings": "Embeddings",
"deselectAllModels": "Deselect all",
"audioSpeech": "Audio Speech",
"repairEnvFailed": "Failed to repair .env",
"repairEnvHint": "Restore missing OAuth defaults into .env without overwriting existing values.",
"repairEnvSuccess": "OAuth defaults restored",
"showEmails": "Show all emails",
"imagesGenerations": "Images Generations",
"repairEnv": "Repair env",
"selectAllModels": "Select all",
"repairEnvWorking": "Repairing...",
"noModelsMatch": "No models match \"{filter}\"",
"audioTranscriptions": "Audio Transcriptions"
},
"settings": {
"title": "Einstellungen",
@ -2266,7 +2408,11 @@
"wildcardPatternModeDesc": "Use wildcard aliases with * and ? when a family of models should map to one target.",
"noExactAliasesConfigured": "No exact-match aliases configured.",
"wildcardRulesTitle": "Wildcard Rules",
"noWildcardAliasesConfigured": "No wildcard aliases configured."
"noWildcardAliasesConfigured": "No wildcard aliases configured.",
"contextRelayHandoffThreshold": "Handoff Threshold",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex accounts and uses these values as global defaults for new or unconfigured combos.",
"contextRelaySummaryModel": "Summary Model",
"contextRelayMaxMessages": "Max Messages For Summary"
},
"translator": {
"title": "Übersetzer",
@ -2692,7 +2838,11 @@
"waitingForOpenAIAuthorization": "Warte auf OpenAI-Autorisierung...",
"waitingForAntigravityAuthorization": "Warte auf Antigravity-Autorisierung...",
"waitingForQoderAuthorization": "Warte auf Qoder-Autorisierung...",
"exchangingCodeForTokens": "Tausche Code gegen Token aus..."
"exchangingCodeForTokens": "Tausche Code gegen Token aus...",
"nodeIncompatibleFixLabel": "Fix: install a patched Node.js 22 LTS release",
"nodeIncompatibleHint": "OmniRoute requires Node.js 20.20.2+ (20.x LTS) or 22.22.2+ (22.x LTS). Node 22 LTS is recommended.",
"nodeIncompatibleTitle": "Incompatible Node.js Version",
"nodeIncompatibleDesc": "You are running Node.js {version}, which is outside OmniRoute's supported secure runtime policy. Use a patched Node.js 20.x or 22.x LTS release."
},
"landing": {
"brandName": "OmniRoute",
@ -3108,7 +3258,26 @@
"peakCached": "Peak cached",
"deduplicatedRequests": "Deduplicated Requests",
"savedCalls": "Saved API Calls",
"totalProcessed": "Total Requests Processed"
"totalProcessed": "Total Requests Processed",
"providerCacheRateDesc": "Each provider exposes total input tokens, cache read tokens, and cache write tokens so you can verify the reuse ratio against raw totals.",
"lastUpdated": "Last updated",
"hoursTracked": "hours tracked",
"cacheRate": "Cache Rate",
"cacheRateDesc": "of total requests",
"cachedRequests24h": "Cached Requests (24h)",
"busiestHour": "Busiest Hour",
"semanticCacheDisabledDesc": "Semantic cache is disabled. OmniRoute will skip local response reuse until you turn it back on in Settings.",
"noTrendData": "No prompt cache activity has been recorded over the last 24 hours.",
"semanticCacheSectionDesc": "OmniRoute's own deterministic response cache. When enabled, repeated non-streaming temperature=0 requests can be served locally without hitting the upstream provider.",
"promptCacheSectionDesc": "Shows provider-side prompt caching activity from usage history so you can see where cache control is active and how much input reuse you are getting.",
"semanticEntriesDesc": "Persisted semantic cache records currently stored in SQLite. Provider-side prompt cache activity is not listed here.",
"semanticCache": "Semantic Cache",
"activityVolume": "Activity",
"trendHour": "Hour",
"peakCacheRate": "Peak Cache Rate",
"noPromptCacheData": "No provider-side prompt cache activity has been recorded yet.",
"promptTrendDesc": "Hourly request volume, cache coverage, and cache read volume across the last 24 hours.",
"entriesLoadError": "Failed to load semantic cache entries."
},
"memory": {
"title": "Memory Management",
@ -3132,7 +3301,8 @@
"factual": "Factual",
"episodic": "Episodic",
"procedural": "Procedural",
"semantic": "Semantic"
"semantic": "Semantic",
"delete": "Delete"
},
"skills": {
"title": "Skills",

View file

@ -904,6 +904,16 @@
"when": "Use when you want perfectly even spread — each model used once before repeating.",
"avoid": "Avoid when models have different quality or latency and order matters.",
"example": "Example: Multiple accounts of the same model to distribute usage evenly."
},
"p2c": {
"when": "Use when you want low-latency selection using Power-of-Two-Choices algorithm.",
"avoid": "Avoid for small combos with 2 or fewer models — no benefit over round-robin.",
"example": "Example: High-throughput inference across 4+ equivalent model endpoints."
},
"context-relay": {
"when": "Use when long sessions must survive account rotation without losing the working context.",
"avoid": "Avoid when account switching is rare or when you do not want extra summarization requests.",
"example": "Example: Codex sessions that rotate across multiple accounts near quota exhaustion."
}
},
"advancedHelp": {
@ -1073,6 +1083,16 @@
"reorderHandle": "Drag to reorder",
"failedReorder": "Failed to reorder models",
"builderFlowTitle": "Combo Builder Flow",
"builderStage": {
"basics": { "label": "Basics", "description": "Name and starting template" },
"steps": { "label": "Steps", "description": "Provider, model, and account selection" },
"strategy": { "label": "Strategy", "description": "Routing behavior and advanced settings" },
"intelligent": {
"label": "Smart Routing",
"description": "Auto-routing candidate pool, presets, and scoring"
},
"review": { "label": "Review", "description": "Final validation before saving" }
},
"builderStageVisited": "Stage completed",
"builderStageCurrent": "Current stage",
"builderStagePending": "Pending",

View file

@ -136,7 +136,10 @@
"Failed to save pricing": "No se pudo guardar el precio",
"Failed to reset pricing": "No se pudo restablecer el precio",
"apikey": "Clave API",
"http": "HTTP"
"http": "HTTP",
"checkSystemStatus": "Check System Status",
"nothingHere": "Nothing here yet",
"goToDashboard": "Go to Dashboard"
},
"sidebar": {
"home": "Inicio",
@ -640,7 +643,8 @@
"opencode": "Úselo cuando prefiera ejecuciones de agentes nativos de terminal y automatización con scripts a través de OpenCode.",
"kiro": "Utilícelo al integrar Kiro y controlar el enrutamiento de modelos de forma centralizada desde OmniRoute.",
"antigravity": "Úselo cuando el tráfico de Antigravity/Kiro debe interceptarse a través de MITM y enrutarse a OmniRoute.",
"copilot": "Úselo cuando desee una experiencia de usuario estilo chat Copilot mientras aplica las claves de OmniRoute y las reglas de enrutamiento."
"copilot": "Úselo cuando desee una experiencia de usuario estilo chat Copilot mientras aplica las claves de OmniRoute y las reglas de enrutamiento.",
"windsurf": "Use when you want an AI-first IDE with Codeium/Windsurf models routed through OmniRoute."
},
"toolDescriptions": {
"antigravity": "IDE antigravedad de Google con MITM",
@ -655,7 +659,8 @@
"opencode": "OpenCode AI coding agent (Terminal)",
"kiro": "Amazon Kiro — AI-powered IDE",
"windsurf": "Windsurf AI Code Editor",
"copilot": "GitHub Copilot AI Assistant"
"copilot": "GitHub Copilot AI Assistant",
"qwen": "Alibaba Qwen Code CLI"
},
"guides": {
"cursor": {
@ -890,6 +895,16 @@
"when": "Use when you want perfectly even spread — each model used once before repeating.",
"avoid": "Avoid when models have different quality or latency and order matters.",
"example": "Example: Multiple accounts of the same model to distribute usage evenly."
},
"p2c": {
"when": "Use when you want low-latency selection using Power-of-Two-Choices algorithm.",
"avoid": "Avoid for small combos with 2 or fewer models — no benefit over round-robin.",
"example": "Example: High-throughput inference across 4+ equivalent model endpoints."
},
"context-relay": {
"example": "Example: Codex sessions that rotate across multiple accounts near quota exhaustion.",
"avoid": "Avoid when account switching is rare or when you do not want extra summarization requests.",
"when": "Use when long sessions must survive account rotation without losing the working context."
}
},
"advancedHelp": {
@ -1009,7 +1024,117 @@
"wizardStep3Title": "Choose Strategy",
"wizardStep3Desc": "Pick how requests are distributed across your models - 13 strategies available",
"wizardStep4Title": "Review & Save",
"wizardStep4Desc": "Review your configuration and activate the combo"
"wizardStep4Desc": "Review your configuration and activate the combo",
"weightTierPriority": "Tier",
"explorationRateLabel": "Exploration Rate",
"normalOperation": "Normal Operation",
"builderStage": {
"steps": {
"description": "Provider, model, and account selection",
"label": "Steps"
},
"review": {
"label": "Review",
"description": "Final validation before saving"
},
"basics": {
"label": "Basics",
"description": "Name and starting template"
},
"strategy": {
"description": "Routing behavior and advanced settings",
"label": "Strategy"
},
"intelligent": {
"label": "Smart Routing",
"description": "Auto-routing candidate pool, presets, and scoring"
}
},
"contextRelayMaxMessages": "Max Messages For Summary",
"contextRelaySummaryModelHelp": "Optional override model used only for generating the handoff summary. Leave empty to reuse the active combo model.",
"filterEmptyTitle": "No combos match this strategy filter.",
"reviewAdvanced": "Advanced Settings",
"providerScores": "Provider Scores",
"filterDeterministic": "Deterministic",
"allProvidersHealthy": "Providers are reporting healthy routing conditions.",
"filterIntelligent": "Intelligent",
"builderIntelligentDesc": "Configure the multi-factor scoring engine for this auto-routing combo.",
"excludedProviders": "Excluded Providers",
"builderAddStep": "Add step",
"reorderHandle": "Drag to reorder",
"builderProviderFirst": "Pick provider first",
"builderLegacyEntry": "Legacy entry",
"reviewName": "Name",
"weightQuota": "Quota",
"filterAll": "All",
"builderPreview": "Preview",
"reviewStrategy": "Strategy",
"reviewSteps": "Steps",
"statusOverview": "Status Overview",
"builderIntelligentTitle": "Intelligent Routing Configuration",
"excludedProvidersHint": "Providers with an OPEN circuit breaker are temporarily excluded from routing.",
"contextRelayDesc": "Preserves session continuity with handoff summaries when accounts rotate",
"weightHealth": "Health",
"builderAccount": "Account",
"intelligentPanelDesc": "Real-time scoring and health status for this auto-routing combo.",
"weightLatencyInv": "Latency",
"modePackHint": "Switch presets to bias the routing engine without rebuilding the combo.",
"builderLoadingProviders": "Loading providers...",
"weightStability": "Stability",
"weightTaskFit": "Task Fit",
"budgetCapPlaceholder": "No limit",
"builderProvider": "Provider",
"emailVisibilityStateOn": "On",
"builderStageVisited": "Stage completed",
"noExcludedProviders": "No providers are currently excluded.",
"highCircuitBreakerRate": "High circuit breaker trip rate detected.",
"candidatePoolEmpty": "No active providers available yet.",
"allProvidersEvaluated": "No candidate pool configured. All active providers are evaluated at runtime.",
"reviewAgentFlags": "Agent Flags",
"builderStageLocked": "Locked — complete previous stage first",
"reviewNoSteps": "No steps configured",
"candidatePoolLabel": "Candidate Pool",
"builderStageCurrent": "Current stage",
"builderComboRef": "Combo Ref",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex account rotation. Pair it with multiple accounts of the same provider for the best continuity.",
"emailVisibilityStateOff": "Off",
"builderAddComboRef": "Add combo reference",
"intelligentPanelTitle": "Intelligent Routing Dashboard",
"modePackUpdated": "Mode pack updated to {pack}.",
"contextRelaySummaryModel": "Summary Model",
"builderModel": "Model",
"reviewProviders": "Providers",
"candidatePoolAllProviders": "All providers",
"builderFlowTitle": "Combo Builder Flow",
"routerStrategyLabel": "Router Strategy",
"builderStagePending": "Pending",
"contextRelayHandoffThreshold": "Handoff Threshold",
"cooldownMinutes": "Cooldown: {minutes}m",
"contextRelayMaxMessagesHelp": "Limits how much recent history is condensed into the relay summary.",
"builderSelectModel": "Select model",
"builderSelectProvider": "Select provider",
"failedReorder": "Failed to reorder models",
"reviewIntelligentTitle": "Intelligent Routing Config",
"explorationRateHint": "{percent}% of requests can explore non-optimal providers.",
"incidentMode": "Incident Mode",
"candidatePoolHint": "Select which providers this engine should evaluate. Leave empty to use all active providers.",
"builderTitle": "Build a Combo",
"builderPinnedAccount": "Pinned Account",
"contextRelayHandoffThresholdHelp": "When quota usage reaches this threshold, OmniRoute generates a structured handoff summary before the active account is exhausted.",
"activeModePack": "Active Mode Pack",
"builderComboRefStep": "Add combo reference",
"strategyRules": "Rules (6-Factor Scoring)",
"contextRelay": "Context Relay",
"reviewSequence": "Model Sequence",
"reviewAccounts": "Accounts",
"reviewComboRefs": "Combo References",
"filterEmptyIntelligentDescription": "Create an auto or LKGP combo to populate the intelligent routing dashboard.",
"filterEmptyDeterministicDescription": "Only auto and LKGP combos exist right now. Switch back to All or create a deterministic combo.",
"budgetCapLabel": "Budget Cap (USD / request)",
"modePackLabel": "Mode Pack",
"weightCostInv": "Cost",
"builderBrowseCatalog": "Browse catalog",
"advancedWeightsTitle": "Advanced: Scoring Weights"
},
"costs": {
"title": "Costos",
@ -1147,7 +1272,9 @@
"a2aQuickStartStep2": "Envíe solicitudes JSON-RPC a `POST /a2a` usando `message/send` o `message/stream`.",
"a2aQuickStartStep3": "Realice un seguimiento y controle las tareas utilizando `tasks/get` y `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format",
"musicDesc": "Generate music and audio tracks via ComfyUI (Stable Audio, MusicGen)",
"musicGeneration": "Music Generation"
},
"endpoints": {
"tabProxy": "Endpoint Proxy",
@ -1754,7 +1881,17 @@
"close": "Close",
"statusDeactivated": "Deactivated (Manual)",
"statusBanned": "Banned / Sandbox Violation",
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted"
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted",
"modelsActiveCount": "{active}/{total} active",
"audioTranscriptions": "Audio Transcriptions",
"imagesGenerations": "Images Generations",
"deselectAllModels": "Deselect all",
"selectAllModels": "Select all",
"embeddings": "Embeddings",
"showEmails": "Show all emails",
"audioSpeech": "Audio Speech",
"noModelsMatch": "No models match \"{filter}\"",
"hideEmails": "Hide all emails"
},
"settings": {
"title": "Configuración",
@ -2271,7 +2408,11 @@
"wildcardPatternModeDesc": "Use wildcard aliases with * and ? when a family of models should map to one target.",
"noExactAliasesConfigured": "No exact-match aliases configured.",
"wildcardRulesTitle": "Wildcard Rules",
"noWildcardAliasesConfigured": "No wildcard aliases configured."
"noWildcardAliasesConfigured": "No wildcard aliases configured.",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex accounts and uses these values as global defaults for new or unconfigured combos.",
"contextRelayHandoffThreshold": "Handoff Threshold",
"contextRelayMaxMessages": "Max Messages For Summary",
"contextRelaySummaryModel": "Summary Model"
},
"translator": {
"title": "Traductor",
@ -2697,7 +2838,11 @@
"waitingForOpenAIAuthorization": "Waiting for OpenAI authorization...",
"waitingForAntigravityAuthorization": "Waiting for Antigravity authorization...",
"waitingForQoderAuthorization": "Waiting for Qoder authorization...",
"exchangingCodeForTokens": "Exchanging code for tokens..."
"exchangingCodeForTokens": "Exchanging code for tokens...",
"nodeIncompatibleDesc": "You are running Node.js {version}, which is outside OmniRoute's supported secure runtime policy. Use a patched Node.js 20.x or 22.x LTS release.",
"nodeIncompatibleHint": "OmniRoute requires Node.js 20.20.2+ (20.x LTS) or 22.22.2+ (22.x LTS). Node 22 LTS is recommended.",
"nodeIncompatibleFixLabel": "Fix: install a patched Node.js 22 LTS release",
"nodeIncompatibleTitle": "Incompatible Node.js Version"
},
"landing": {
"brandName": "OmniRuta",
@ -3113,7 +3258,26 @@
"peakCached": "Peak cached",
"deduplicatedRequests": "Deduplicated Requests",
"savedCalls": "Saved API Calls",
"totalProcessed": "Total Requests Processed"
"totalProcessed": "Total Requests Processed",
"busiestHour": "Busiest Hour",
"promptCacheSectionDesc": "Shows provider-side prompt caching activity from usage history so you can see where cache control is active and how much input reuse you are getting.",
"promptTrendDesc": "Hourly request volume, cache coverage, and cache read volume across the last 24 hours.",
"activityVolume": "Activity",
"cacheRate": "Cache Rate",
"noTrendData": "No prompt cache activity has been recorded over the last 24 hours.",
"trendHour": "Hour",
"semanticCache": "Semantic Cache",
"providerCacheRateDesc": "Each provider exposes total input tokens, cache read tokens, and cache write tokens so you can verify the reuse ratio against raw totals.",
"cacheRateDesc": "of total requests",
"peakCacheRate": "Peak Cache Rate",
"semanticCacheSectionDesc": "OmniRoute's own deterministic response cache. When enabled, repeated non-streaming temperature=0 requests can be served locally without hitting the upstream provider.",
"entriesLoadError": "Failed to load semantic cache entries.",
"semanticCacheDisabledDesc": "Semantic cache is disabled. OmniRoute will skip local response reuse until you turn it back on in Settings.",
"noPromptCacheData": "No provider-side prompt cache activity has been recorded yet.",
"hoursTracked": "hours tracked",
"lastUpdated": "Last updated",
"semanticEntriesDesc": "Persisted semantic cache records currently stored in SQLite. Provider-side prompt cache activity is not listed here.",
"cachedRequests24h": "Cached Requests (24h)"
},
"memory": {
"title": "Memory Management",
@ -3137,7 +3301,8 @@
"factual": "Factual",
"episodic": "Episodic",
"procedural": "Procedural",
"semantic": "Semantic"
"semantic": "Semantic",
"delete": "Delete"
},
"skills": {
"title": "Skills",

View file

@ -136,7 +136,10 @@
"Failed to save pricing": "Hinnoittelun tallentaminen epäonnistui",
"Failed to reset pricing": "Hinnoittelun nollaaminen epäonnistui",
"apikey": "API-avain",
"http": "HTTP"
"http": "HTTP",
"checkSystemStatus": "Check System Status",
"nothingHere": "Nothing here yet",
"goToDashboard": "Go to Dashboard"
},
"sidebar": {
"home": "Kotiin",
@ -640,7 +643,8 @@
"opencode": "Käytä, kun haluat käyttää päätealustaisia agentteja ja komentosarjottua automaatiota OpenCoden kautta.",
"kiro": "Käytä integroitaessa Kiroa ja ohjattaessa mallin reititystä keskitetysti OmniRoutesta.",
"antigravity": "Käytä, kun Antigravity/Kiro-liikenne on siepattava MITM:n kautta ja ohjattava OmniRouteen.",
"copilot": "Käytä, kun haluat Copilot-chat-tyylisen UX:n ja pakota OmniRoute-avaimia ja reitityssääntöjä."
"copilot": "Käytä, kun haluat Copilot-chat-tyylisen UX:n ja pakota OmniRoute-avaimia ja reitityssääntöjä.",
"windsurf": "Use when you want an AI-first IDE with Codeium/Windsurf models routed through OmniRoute."
},
"toolDescriptions": {
"antigravity": "Google Antigravity IDE ja MITM",
@ -655,7 +659,8 @@
"opencode": "OpenCode AI coding agent (Terminal)",
"kiro": "Amazon Kiro — AI-powered IDE",
"windsurf": "Windsurf AI Code Editor",
"copilot": "GitHub Copilot AI Assistant"
"copilot": "GitHub Copilot AI Assistant",
"qwen": "Alibaba Qwen Code CLI"
},
"guides": {
"cursor": {
@ -890,6 +895,16 @@
"when": "Use when you want perfectly even spread — each model used once before repeating.",
"avoid": "Avoid when models have different quality or latency and order matters.",
"example": "Example: Multiple accounts of the same model to distribute usage evenly."
},
"p2c": {
"example": "Example: High-throughput inference across 4+ equivalent model endpoints.",
"when": "Use when you want low-latency selection using Power-of-Two-Choices algorithm.",
"avoid": "Avoid for small combos with 2 or fewer models — no benefit over round-robin."
},
"context-relay": {
"when": "Use when long sessions must survive account rotation without losing the working context.",
"example": "Example: Codex sessions that rotate across multiple accounts near quota exhaustion.",
"avoid": "Avoid when account switching is rare or when you do not want extra summarization requests."
}
},
"advancedHelp": {
@ -1009,7 +1024,117 @@
"wizardStep3Title": "Choose Strategy",
"wizardStep3Desc": "Pick how requests are distributed across your models - 13 strategies available",
"wizardStep4Title": "Review & Save",
"wizardStep4Desc": "Review your configuration and activate the combo"
"wizardStep4Desc": "Review your configuration and activate the combo",
"modePackUpdated": "Mode pack updated to {pack}.",
"allProvidersHealthy": "Providers are reporting healthy routing conditions.",
"reviewStrategy": "Strategy",
"incidentMode": "Incident Mode",
"builderTitle": "Build a Combo",
"contextRelayHandoffThresholdHelp": "When quota usage reaches this threshold, OmniRoute generates a structured handoff summary before the active account is exhausted.",
"candidatePoolLabel": "Candidate Pool",
"weightHealth": "Health",
"builderStage": {
"basics": {
"description": "Name and starting template",
"label": "Basics"
},
"steps": {
"description": "Provider, model, and account selection",
"label": "Steps"
},
"strategy": {
"description": "Routing behavior and advanced settings",
"label": "Strategy"
},
"review": {
"label": "Review",
"description": "Final validation before saving"
},
"intelligent": {
"label": "Smart Routing",
"description": "Auto-routing candidate pool, presets, and scoring"
}
},
"statusOverview": "Status Overview",
"weightQuota": "Quota",
"weightTierPriority": "Tier",
"reviewAccounts": "Accounts",
"intelligentPanelDesc": "Real-time scoring and health status for this auto-routing combo.",
"excludedProvidersHint": "Providers with an OPEN circuit breaker are temporarily excluded from routing.",
"strategyRules": "Rules (6-Factor Scoring)",
"cooldownMinutes": "Cooldown: {minutes}m",
"builderIntelligentTitle": "Intelligent Routing Configuration",
"advancedWeightsTitle": "Advanced: Scoring Weights",
"budgetCapPlaceholder": "No limit",
"modePackLabel": "Mode Pack",
"builderSelectModel": "Select model",
"contextRelaySummaryModel": "Summary Model",
"builderAccount": "Account",
"emailVisibilityStateOn": "On",
"contextRelaySummaryModelHelp": "Optional override model used only for generating the handoff summary. Leave empty to reuse the active combo model.",
"emailVisibilityStateOff": "Off",
"filterEmptyDeterministicDescription": "Only auto and LKGP combos exist right now. Switch back to All or create a deterministic combo.",
"reviewName": "Name",
"filterEmptyTitle": "No combos match this strategy filter.",
"builderLoadingProviders": "Loading providers...",
"builderIntelligentDesc": "Configure the multi-factor scoring engine for this auto-routing combo.",
"candidatePoolHint": "Select which providers this engine should evaluate. Leave empty to use all active providers.",
"reorderHandle": "Drag to reorder",
"contextRelayDesc": "Preserves session continuity with handoff summaries when accounts rotate",
"reviewSteps": "Steps",
"builderAddStep": "Add step",
"builderComboRef": "Combo Ref",
"weightTaskFit": "Task Fit",
"builderProviderFirst": "Pick provider first",
"filterEmptyIntelligentDescription": "Create an auto or LKGP combo to populate the intelligent routing dashboard.",
"weightCostInv": "Cost",
"builderPreview": "Preview",
"reviewComboRefs": "Combo References",
"builderStageCurrent": "Current stage",
"builderLegacyEntry": "Legacy entry",
"weightLatencyInv": "Latency",
"routerStrategyLabel": "Router Strategy",
"failedReorder": "Failed to reorder models",
"builderBrowseCatalog": "Browse catalog",
"candidatePoolAllProviders": "All providers",
"highCircuitBreakerRate": "High circuit breaker trip rate detected.",
"budgetCapLabel": "Budget Cap (USD / request)",
"allProvidersEvaluated": "No candidate pool configured. All active providers are evaluated at runtime.",
"providerScores": "Provider Scores",
"contextRelay": "Context Relay",
"candidatePoolEmpty": "No active providers available yet.",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex account rotation. Pair it with multiple accounts of the same provider for the best continuity.",
"filterIntelligent": "Intelligent",
"reviewSequence": "Model Sequence",
"explorationRateLabel": "Exploration Rate",
"builderSelectProvider": "Select provider",
"builderFlowTitle": "Combo Builder Flow",
"activeModePack": "Active Mode Pack",
"reviewNoSteps": "No steps configured",
"reviewAdvanced": "Advanced Settings",
"reviewProviders": "Providers",
"filterAll": "All",
"reviewIntelligentTitle": "Intelligent Routing Config",
"builderComboRefStep": "Add combo reference",
"excludedProviders": "Excluded Providers",
"noExcludedProviders": "No providers are currently excluded.",
"builderStageVisited": "Stage completed",
"normalOperation": "Normal Operation",
"intelligentPanelTitle": "Intelligent Routing Dashboard",
"builderStagePending": "Pending",
"contextRelayHandoffThreshold": "Handoff Threshold",
"contextRelayMaxMessages": "Max Messages For Summary",
"filterDeterministic": "Deterministic",
"builderPinnedAccount": "Pinned Account",
"explorationRateHint": "{percent}% of requests can explore non-optimal providers.",
"modePackHint": "Switch presets to bias the routing engine without rebuilding the combo.",
"weightStability": "Stability",
"builderProvider": "Provider",
"reviewAgentFlags": "Agent Flags",
"builderModel": "Model",
"builderStageLocked": "Locked — complete previous stage first",
"contextRelayMaxMessagesHelp": "Limits how much recent history is condensed into the relay summary.",
"builderAddComboRef": "Add combo reference"
},
"costs": {
"title": "Kustannukset",
@ -1147,7 +1272,9 @@
"a2aQuickStartStep2": "Lähetä JSON-RPC-pyynnöt osoitteeseen `POST /a2a` käyttämällä `message/send` tai `message/stream`.",
"a2aQuickStartStep3": "Seuraa ja ohjaa tehtäviä käyttämällä `tasks/get` ja `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format",
"musicGeneration": "Music Generation",
"musicDesc": "Generate music and audio tracks via ComfyUI (Stable Audio, MusicGen)"
},
"endpoints": {
"tabProxy": "Endpoint Proxy",
@ -1749,7 +1876,22 @@
"close": "Close",
"statusDeactivated": "Deactivated (Manual)",
"statusBanned": "Banned / Sandbox Violation",
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted"
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted",
"repairEnv": "Repair env",
"audioSpeech": "Audio Speech",
"selectAllModels": "Select all",
"audioTranscriptions": "Audio Transcriptions",
"repairEnvWorking": "Repairing...",
"repairEnvSuccess": "OAuth defaults restored",
"embeddings": "Embeddings",
"deselectAllModels": "Deselect all",
"imagesGenerations": "Images Generations",
"repairEnvHint": "Restore missing OAuth defaults into .env without overwriting existing values.",
"modelsActiveCount": "{active}/{total} active",
"repairEnvFailed": "Failed to repair .env",
"hideEmails": "Hide all emails",
"showEmails": "Show all emails",
"noModelsMatch": "No models match \"{filter}\""
},
"settings": {
"title": "Asetukset",
@ -2266,7 +2408,11 @@
"wildcardPatternModeDesc": "Use wildcard aliases with * and ? when a family of models should map to one target.",
"noExactAliasesConfigured": "No exact-match aliases configured.",
"wildcardRulesTitle": "Wildcard Rules",
"noWildcardAliasesConfigured": "No wildcard aliases configured."
"noWildcardAliasesConfigured": "No wildcard aliases configured.",
"contextRelayHandoffThreshold": "Handoff Threshold",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex accounts and uses these values as global defaults for new or unconfigured combos.",
"contextRelayMaxMessages": "Max Messages For Summary",
"contextRelaySummaryModel": "Summary Model"
},
"translator": {
"title": "Kääntäjä",
@ -2692,7 +2838,11 @@
"waitingForOpenAIAuthorization": "Odotetaan OpenAI-valtuutusta...",
"waitingForAntigravityAuthorization": "Odotetaan antigravitaatiovaltuutusta...",
"waitingForQoderAuthorization": "Odotetaan Qoder-valtuutusta...",
"exchangingCodeForTokens": "Vaihdetaan koodia tokeneihin..."
"exchangingCodeForTokens": "Vaihdetaan koodia tokeneihin...",
"nodeIncompatibleFixLabel": "Fix: install a patched Node.js 22 LTS release",
"nodeIncompatibleTitle": "Incompatible Node.js Version",
"nodeIncompatibleDesc": "You are running Node.js {version}, which is outside OmniRoute's supported secure runtime policy. Use a patched Node.js 20.x or 22.x LTS release.",
"nodeIncompatibleHint": "OmniRoute requires Node.js 20.20.2+ (20.x LTS) or 22.22.2+ (22.x LTS). Node 22 LTS is recommended."
},
"landing": {
"brandName": "OmniRoute",
@ -3108,7 +3258,26 @@
"peakCached": "Peak cached",
"deduplicatedRequests": "Deduplicated Requests",
"savedCalls": "Saved API Calls",
"totalProcessed": "Total Requests Processed"
"totalProcessed": "Total Requests Processed",
"cacheRateDesc": "of total requests",
"semanticCacheSectionDesc": "OmniRoute's own deterministic response cache. When enabled, repeated non-streaming temperature=0 requests can be served locally without hitting the upstream provider.",
"semanticCache": "Semantic Cache",
"cachedRequests24h": "Cached Requests (24h)",
"semanticCacheDisabledDesc": "Semantic cache is disabled. OmniRoute will skip local response reuse until you turn it back on in Settings.",
"cacheRate": "Cache Rate",
"providerCacheRateDesc": "Each provider exposes total input tokens, cache read tokens, and cache write tokens so you can verify the reuse ratio against raw totals.",
"promptTrendDesc": "Hourly request volume, cache coverage, and cache read volume across the last 24 hours.",
"entriesLoadError": "Failed to load semantic cache entries.",
"noPromptCacheData": "No provider-side prompt cache activity has been recorded yet.",
"hoursTracked": "hours tracked",
"semanticEntriesDesc": "Persisted semantic cache records currently stored in SQLite. Provider-side prompt cache activity is not listed here.",
"busiestHour": "Busiest Hour",
"noTrendData": "No prompt cache activity has been recorded over the last 24 hours.",
"peakCacheRate": "Peak Cache Rate",
"promptCacheSectionDesc": "Shows provider-side prompt caching activity from usage history so you can see where cache control is active and how much input reuse you are getting.",
"trendHour": "Hour",
"lastUpdated": "Last updated",
"activityVolume": "Activity"
},
"memory": {
"title": "Memory Management",
@ -3132,7 +3301,8 @@
"factual": "Factual",
"episodic": "Episodic",
"procedural": "Procedural",
"semantic": "Semantic"
"semantic": "Semantic",
"delete": "Delete"
},
"skills": {
"title": "Skills",

View file

@ -136,7 +136,10 @@
"Failed to save pricing": "Échec de l'enregistrement des prix",
"Failed to reset pricing": "Échec de la réinitialisation des prix",
"apikey": "Clé API",
"http": "HTTP"
"http": "HTTP",
"nothingHere": "Nothing here yet",
"goToDashboard": "Go to Dashboard",
"checkSystemStatus": "Check System Status"
},
"sidebar": {
"home": "Accueil",
@ -640,7 +643,8 @@
"opencode": "À utiliser lorsque vous préférez les exécutions d'agents natifs du terminal et l'automatisation par script via OpenCode.",
"kiro": "À utiliser lors de l'intégration de Kiro et du contrôle centralisé du routage de modèles à partir d'OmniRoute.",
"antigravity": "À utiliser lorsque le trafic Antigravity/Kiro doit être intercepté via MITM et acheminé vers OmniRoute.",
"copilot": "À utiliser lorsque vous souhaitez une UX de style chat Copilot tout en appliquant les clés OmniRoute et les règles de routage."
"copilot": "À utiliser lorsque vous souhaitez une UX de style chat Copilot tout en appliquant les clés OmniRoute et les règles de routage.",
"windsurf": "Use when you want an AI-first IDE with Codeium/Windsurf models routed through OmniRoute."
},
"toolDescriptions": {
"antigravity": "IDE Google Antigravity avec MITM",
@ -655,7 +659,8 @@
"opencode": "OpenCode AI coding agent (Terminal)",
"kiro": "Amazon Kiro — AI-powered IDE",
"windsurf": "Windsurf AI Code Editor",
"copilot": "GitHub Copilot AI Assistant"
"copilot": "GitHub Copilot AI Assistant",
"qwen": "Alibaba Qwen Code CLI"
},
"guides": {
"cursor": {
@ -890,6 +895,16 @@
"when": "Use when you want perfectly even spread — each model used once before repeating.",
"avoid": "Avoid when models have different quality or latency and order matters.",
"example": "Example: Multiple accounts of the same model to distribute usage evenly."
},
"context-relay": {
"when": "Use when long sessions must survive account rotation without losing the working context.",
"avoid": "Avoid when account switching is rare or when you do not want extra summarization requests.",
"example": "Example: Codex sessions that rotate across multiple accounts near quota exhaustion."
},
"p2c": {
"when": "Use when you want low-latency selection using Power-of-Two-Choices algorithm.",
"avoid": "Avoid for small combos with 2 or fewer models — no benefit over round-robin.",
"example": "Example: High-throughput inference across 4+ equivalent model endpoints."
}
},
"advancedHelp": {
@ -1009,7 +1024,117 @@
"wizardStep3Title": "Choose Strategy",
"wizardStep3Desc": "Pick how requests are distributed across your models - 13 strategies available",
"wizardStep4Title": "Review & Save",
"wizardStep4Desc": "Review your configuration and activate the combo"
"wizardStep4Desc": "Review your configuration and activate the combo",
"builderIntelligentTitle": "Intelligent Routing Configuration",
"intelligentPanelDesc": "Real-time scoring and health status for this auto-routing combo.",
"allProvidersEvaluated": "No candidate pool configured. All active providers are evaluated at runtime.",
"excludedProvidersHint": "Providers with an OPEN circuit breaker are temporarily excluded from routing.",
"reviewAdvanced": "Advanced Settings",
"builderStage": {
"review": {
"label": "Review",
"description": "Final validation before saving"
},
"strategy": {
"label": "Strategy",
"description": "Routing behavior and advanced settings"
},
"steps": {
"label": "Steps",
"description": "Provider, model, and account selection"
},
"intelligent": {
"label": "Smart Routing",
"description": "Auto-routing candidate pool, presets, and scoring"
},
"basics": {
"label": "Basics",
"description": "Name and starting template"
}
},
"builderProviderFirst": "Pick provider first",
"contextRelayMaxMessages": "Max Messages For Summary",
"builderAddStep": "Add step",
"filterIntelligent": "Intelligent",
"failedReorder": "Failed to reorder models",
"providerScores": "Provider Scores",
"reviewIntelligentTitle": "Intelligent Routing Config",
"filterDeterministic": "Deterministic",
"contextRelayDesc": "Preserves session continuity with handoff summaries when accounts rotate",
"noExcludedProviders": "No providers are currently excluded.",
"filterEmptyIntelligentDescription": "Create an auto or LKGP combo to populate the intelligent routing dashboard.",
"reviewNoSteps": "No steps configured",
"builderComboRef": "Combo Ref",
"builderStageVisited": "Stage completed",
"builderComboRefStep": "Add combo reference",
"builderSelectProvider": "Select provider",
"builderStagePending": "Pending",
"candidatePoolEmpty": "No active providers available yet.",
"reviewSteps": "Steps",
"cooldownMinutes": "Cooldown: {minutes}m",
"builderLegacyEntry": "Legacy entry",
"intelligentPanelTitle": "Intelligent Routing Dashboard",
"builderAccount": "Account",
"candidatePoolHint": "Select which providers this engine should evaluate. Leave empty to use all active providers.",
"filterEmptyDeterministicDescription": "Only auto and LKGP combos exist right now. Switch back to All or create a deterministic combo.",
"emailVisibilityStateOff": "Off",
"weightTierPriority": "Tier",
"weightCostInv": "Cost",
"contextRelayHandoffThresholdHelp": "When quota usage reaches this threshold, OmniRoute generates a structured handoff summary before the active account is exhausted.",
"reviewName": "Name",
"builderLoadingProviders": "Loading providers...",
"routerStrategyLabel": "Router Strategy",
"builderFlowTitle": "Combo Builder Flow",
"weightStability": "Stability",
"explorationRateLabel": "Exploration Rate",
"activeModePack": "Active Mode Pack",
"highCircuitBreakerRate": "High circuit breaker trip rate detected.",
"allProvidersHealthy": "Providers are reporting healthy routing conditions.",
"excludedProviders": "Excluded Providers",
"builderSelectModel": "Select model",
"weightQuota": "Quota",
"reviewSequence": "Model Sequence",
"builderAddComboRef": "Add combo reference",
"contextRelayHandoffThreshold": "Handoff Threshold",
"filterAll": "All",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex account rotation. Pair it with multiple accounts of the same provider for the best continuity.",
"builderStageLocked": "Locked — complete previous stage first",
"weightHealth": "Health",
"budgetCapLabel": "Budget Cap (USD / request)",
"reviewComboRefs": "Combo References",
"budgetCapPlaceholder": "No limit",
"builderProvider": "Provider",
"builderBrowseCatalog": "Browse catalog",
"builderStageCurrent": "Current stage",
"incidentMode": "Incident Mode",
"contextRelaySummaryModel": "Summary Model",
"modePackHint": "Switch presets to bias the routing engine without rebuilding the combo.",
"weightLatencyInv": "Latency",
"builderPreview": "Preview",
"candidatePoolAllProviders": "All providers",
"filterEmptyTitle": "No combos match this strategy filter.",
"reviewAgentFlags": "Agent Flags",
"contextRelayMaxMessagesHelp": "Limits how much recent history is condensed into the relay summary.",
"weightTaskFit": "Task Fit",
"builderIntelligentDesc": "Configure the multi-factor scoring engine for this auto-routing combo.",
"contextRelay": "Context Relay",
"statusOverview": "Status Overview",
"modePackUpdated": "Mode pack updated to {pack}.",
"reorderHandle": "Drag to reorder",
"explorationRateHint": "{percent}% of requests can explore non-optimal providers.",
"builderTitle": "Build a Combo",
"candidatePoolLabel": "Candidate Pool",
"advancedWeightsTitle": "Advanced: Scoring Weights",
"modePackLabel": "Mode Pack",
"reviewStrategy": "Strategy",
"strategyRules": "Rules (6-Factor Scoring)",
"contextRelaySummaryModelHelp": "Optional override model used only for generating the handoff summary. Leave empty to reuse the active combo model.",
"reviewProviders": "Providers",
"reviewAccounts": "Accounts",
"builderModel": "Model",
"normalOperation": "Normal Operation",
"emailVisibilityStateOn": "On",
"builderPinnedAccount": "Pinned Account"
},
"costs": {
"title": "Coûts",
@ -1147,7 +1272,9 @@
"a2aQuickStartStep2": "Envoyez des requêtes JSON-RPC à `POST /a2a` en utilisant `message/send` ou `message/stream`.",
"a2aQuickStartStep3": "Suivez et contrôlez les tâches à laide de `tasks/get` et `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format",
"musicGeneration": "Music Generation",
"musicDesc": "Generate music and audio tracks via ComfyUI (Stable Audio, MusicGen)"
},
"endpoints": {
"tabProxy": "Endpoint Proxy",
@ -1749,7 +1876,22 @@
"close": "Close",
"statusDeactivated": "Deactivated (Manual)",
"statusBanned": "Banned / Sandbox Violation",
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted"
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted",
"audioTranscriptions": "Audio Transcriptions",
"noModelsMatch": "No models match \"{filter}\"",
"showEmails": "Show all emails",
"selectAllModels": "Select all",
"repairEnvHint": "Restore missing OAuth defaults into .env without overwriting existing values.",
"audioSpeech": "Audio Speech",
"modelsActiveCount": "{active}/{total} active",
"repairEnvSuccess": "OAuth defaults restored",
"repairEnvWorking": "Repairing...",
"hideEmails": "Hide all emails",
"repairEnv": "Repair env",
"deselectAllModels": "Deselect all",
"embeddings": "Embeddings",
"repairEnvFailed": "Failed to repair .env",
"imagesGenerations": "Images Generations"
},
"settings": {
"title": "Paramètres",
@ -2266,7 +2408,11 @@
"wildcardPatternModeDesc": "Use wildcard aliases with * and ? when a family of models should map to one target.",
"noExactAliasesConfigured": "No exact-match aliases configured.",
"wildcardRulesTitle": "Wildcard Rules",
"noWildcardAliasesConfigured": "No wildcard aliases configured."
"noWildcardAliasesConfigured": "No wildcard aliases configured.",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex accounts and uses these values as global defaults for new or unconfigured combos.",
"contextRelayMaxMessages": "Max Messages For Summary",
"contextRelaySummaryModel": "Summary Model",
"contextRelayHandoffThreshold": "Handoff Threshold"
},
"translator": {
"title": "Traducteur",
@ -2692,7 +2838,11 @@
"waitingForOpenAIAuthorization": "Waiting for OpenAI authorization...",
"waitingForAntigravityAuthorization": "Waiting for Antigravity authorization...",
"waitingForQoderAuthorization": "Waiting for Qoder authorization...",
"exchangingCodeForTokens": "Exchanging code for tokens..."
"exchangingCodeForTokens": "Exchanging code for tokens...",
"nodeIncompatibleFixLabel": "Fix: install a patched Node.js 22 LTS release",
"nodeIncompatibleTitle": "Incompatible Node.js Version",
"nodeIncompatibleDesc": "You are running Node.js {version}, which is outside OmniRoute's supported secure runtime policy. Use a patched Node.js 20.x or 22.x LTS release.",
"nodeIncompatibleHint": "OmniRoute requires Node.js 20.20.2+ (20.x LTS) or 22.22.2+ (22.x LTS). Node 22 LTS is recommended."
},
"landing": {
"brandName": "OmniRoute",
@ -3108,7 +3258,26 @@
"peakCached": "Peak cached",
"deduplicatedRequests": "Deduplicated Requests",
"savedCalls": "Saved API Calls",
"totalProcessed": "Total Requests Processed"
"totalProcessed": "Total Requests Processed",
"trendHour": "Hour",
"cacheRateDesc": "of total requests",
"peakCacheRate": "Peak Cache Rate",
"activityVolume": "Activity",
"semanticEntriesDesc": "Persisted semantic cache records currently stored in SQLite. Provider-side prompt cache activity is not listed here.",
"entriesLoadError": "Failed to load semantic cache entries.",
"promptTrendDesc": "Hourly request volume, cache coverage, and cache read volume across the last 24 hours.",
"noTrendData": "No prompt cache activity has been recorded over the last 24 hours.",
"cachedRequests24h": "Cached Requests (24h)",
"cacheRate": "Cache Rate",
"semanticCacheSectionDesc": "OmniRoute's own deterministic response cache. When enabled, repeated non-streaming temperature=0 requests can be served locally without hitting the upstream provider.",
"semanticCache": "Semantic Cache",
"lastUpdated": "Last updated",
"hoursTracked": "hours tracked",
"promptCacheSectionDesc": "Shows provider-side prompt caching activity from usage history so you can see where cache control is active and how much input reuse you are getting.",
"semanticCacheDisabledDesc": "Semantic cache is disabled. OmniRoute will skip local response reuse until you turn it back on in Settings.",
"noPromptCacheData": "No provider-side prompt cache activity has been recorded yet.",
"busiestHour": "Busiest Hour",
"providerCacheRateDesc": "Each provider exposes total input tokens, cache read tokens, and cache write tokens so you can verify the reuse ratio against raw totals."
},
"memory": {
"title": "Memory Management",
@ -3132,7 +3301,8 @@
"factual": "Factual",
"episodic": "Episodic",
"procedural": "Procedural",
"semantic": "Semantic"
"semantic": "Semantic",
"delete": "Delete"
},
"skills": {
"title": "Skills",

View file

@ -136,7 +136,10 @@
"Failed to save pricing": "חיסכון במחיר נכשל",
"Failed to reset pricing": "איפוס התמחור נכשל",
"apikey": "מפתח API",
"http": "HTTP"
"http": "HTTP",
"checkSystemStatus": "Check System Status",
"goToDashboard": "Go to Dashboard",
"nothingHere": "Nothing here yet"
},
"sidebar": {
"home": "בית",
@ -640,7 +643,8 @@
"opencode": "השתמש כאשר אתה מעדיף ריצות סוכנים מקוריים ומאוטומציה של סקריפטים באמצעות OpenCode.",
"kiro": "השתמש בעת שילוב Kiro ושליטה בניתוב מודלים באופן מרכזי מ- OmniRoute.",
"antigravity": "השתמש כאשר יש ליירט תעבורת Antigravity/Kiro דרך MITM ולנתב אל OmniRoute.",
"copilot": "השתמש כאשר אתה רוצה UX בסגנון צ'אט Copilot תוך אכיפת מפתחות וכללי ניתוב OmniRoute."
"copilot": "השתמש כאשר אתה רוצה UX בסגנון צ'אט Copilot תוך אכיפת מפתחות וכללי ניתוב OmniRoute.",
"windsurf": "Use when you want an AI-first IDE with Codeium/Windsurf models routed through OmniRoute."
},
"toolDescriptions": {
"antigravity": "Google Antigravity IDE עם MITM",
@ -655,7 +659,8 @@
"opencode": "OpenCode AI coding agent (Terminal)",
"kiro": "Amazon Kiro — AI-powered IDE",
"windsurf": "Windsurf AI Code Editor",
"copilot": "GitHub Copilot AI Assistant"
"copilot": "GitHub Copilot AI Assistant",
"qwen": "Alibaba Qwen Code CLI"
},
"guides": {
"cursor": {
@ -890,6 +895,16 @@
"when": "Use when you want perfectly even spread — each model used once before repeating.",
"avoid": "Avoid when models have different quality or latency and order matters.",
"example": "Example: Multiple accounts of the same model to distribute usage evenly."
},
"p2c": {
"avoid": "Avoid for small combos with 2 or fewer models — no benefit over round-robin.",
"example": "Example: High-throughput inference across 4+ equivalent model endpoints.",
"when": "Use when you want low-latency selection using Power-of-Two-Choices algorithm."
},
"context-relay": {
"when": "Use when long sessions must survive account rotation without losing the working context.",
"avoid": "Avoid when account switching is rare or when you do not want extra summarization requests.",
"example": "Example: Codex sessions that rotate across multiple accounts near quota exhaustion."
}
},
"advancedHelp": {
@ -1009,7 +1024,117 @@
"wizardStep3Title": "Choose Strategy",
"wizardStep3Desc": "Pick how requests are distributed across your models - 13 strategies available",
"wizardStep4Title": "Review & Save",
"wizardStep4Desc": "Review your configuration and activate the combo"
"wizardStep4Desc": "Review your configuration and activate the combo",
"explorationRateLabel": "Exploration Rate",
"weightTaskFit": "Task Fit",
"builderBrowseCatalog": "Browse catalog",
"explorationRateHint": "{percent}% of requests can explore non-optimal providers.",
"highCircuitBreakerRate": "High circuit breaker trip rate detected.",
"builderFlowTitle": "Combo Builder Flow",
"weightHealth": "Health",
"contextRelayMaxMessagesHelp": "Limits how much recent history is condensed into the relay summary.",
"modePackUpdated": "Mode pack updated to {pack}.",
"builderIntelligentTitle": "Intelligent Routing Configuration",
"budgetCapPlaceholder": "No limit",
"contextRelayMaxMessages": "Max Messages For Summary",
"builderIntelligentDesc": "Configure the multi-factor scoring engine for this auto-routing combo.",
"providerScores": "Provider Scores",
"builderPreview": "Preview",
"advancedWeightsTitle": "Advanced: Scoring Weights",
"builderStageVisited": "Stage completed",
"weightLatencyInv": "Latency",
"allProvidersHealthy": "Providers are reporting healthy routing conditions.",
"cooldownMinutes": "Cooldown: {minutes}m",
"contextRelayHandoffThresholdHelp": "When quota usage reaches this threshold, OmniRoute generates a structured handoff summary before the active account is exhausted.",
"builderProvider": "Provider",
"failedReorder": "Failed to reorder models",
"modePackHint": "Switch presets to bias the routing engine without rebuilding the combo.",
"builderStage": {
"basics": {
"description": "Name and starting template",
"label": "Basics"
},
"intelligent": {
"label": "Smart Routing",
"description": "Auto-routing candidate pool, presets, and scoring"
},
"steps": {
"label": "Steps",
"description": "Provider, model, and account selection"
},
"review": {
"description": "Final validation before saving",
"label": "Review"
},
"strategy": {
"label": "Strategy",
"description": "Routing behavior and advanced settings"
}
},
"reviewSteps": "Steps",
"builderLoadingProviders": "Loading providers...",
"weightCostInv": "Cost",
"builderAccount": "Account",
"activeModePack": "Active Mode Pack",
"contextRelayDesc": "Preserves session continuity with handoff summaries when accounts rotate",
"routerStrategyLabel": "Router Strategy",
"reviewAccounts": "Accounts",
"builderStageLocked": "Locked — complete previous stage first",
"reviewStrategy": "Strategy",
"builderProviderFirst": "Pick provider first",
"contextRelaySummaryModelHelp": "Optional override model used only for generating the handoff summary. Leave empty to reuse the active combo model.",
"intelligentPanelTitle": "Intelligent Routing Dashboard",
"filterEmptyDeterministicDescription": "Only auto and LKGP combos exist right now. Switch back to All or create a deterministic combo.",
"contextRelayHandoffThreshold": "Handoff Threshold",
"candidatePoolHint": "Select which providers this engine should evaluate. Leave empty to use all active providers.",
"builderAddComboRef": "Add combo reference",
"contextRelay": "Context Relay",
"incidentMode": "Incident Mode",
"builderSelectModel": "Select model",
"builderComboRef": "Combo Ref",
"strategyRules": "Rules (6-Factor Scoring)",
"builderStagePending": "Pending",
"reviewAgentFlags": "Agent Flags",
"budgetCapLabel": "Budget Cap (USD / request)",
"normalOperation": "Normal Operation",
"filterEmptyIntelligentDescription": "Create an auto or LKGP combo to populate the intelligent routing dashboard.",
"builderTitle": "Build a Combo",
"reviewIntelligentTitle": "Intelligent Routing Config",
"emailVisibilityStateOff": "Off",
"filterAll": "All",
"builderStageCurrent": "Current stage",
"builderModel": "Model",
"weightStability": "Stability",
"excludedProviders": "Excluded Providers",
"builderLegacyEntry": "Legacy entry",
"builderPinnedAccount": "Pinned Account",
"contextRelaySummaryModel": "Summary Model",
"candidatePoolEmpty": "No active providers available yet.",
"candidatePoolAllProviders": "All providers",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex account rotation. Pair it with multiple accounts of the same provider for the best continuity.",
"reorderHandle": "Drag to reorder",
"noExcludedProviders": "No providers are currently excluded.",
"emailVisibilityStateOn": "On",
"allProvidersEvaluated": "No candidate pool configured. All active providers are evaluated at runtime.",
"modePackLabel": "Mode Pack",
"weightQuota": "Quota",
"builderSelectProvider": "Select provider",
"candidatePoolLabel": "Candidate Pool",
"filterDeterministic": "Deterministic",
"reviewName": "Name",
"intelligentPanelDesc": "Real-time scoring and health status for this auto-routing combo.",
"builderAddStep": "Add step",
"reviewAdvanced": "Advanced Settings",
"reviewSequence": "Model Sequence",
"excludedProvidersHint": "Providers with an OPEN circuit breaker are temporarily excluded from routing.",
"statusOverview": "Status Overview",
"builderComboRefStep": "Add combo reference",
"filterIntelligent": "Intelligent",
"reviewNoSteps": "No steps configured",
"reviewComboRefs": "Combo References",
"reviewProviders": "Providers",
"weightTierPriority": "Tier",
"filterEmptyTitle": "No combos match this strategy filter."
},
"costs": {
"title": "עלויות",
@ -1147,7 +1272,9 @@
"a2aQuickStartStep2": "Send JSON-RPC requests to `POST /a2a` using `message/send` or `message/stream`.",
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format",
"musicDesc": "Generate music and audio tracks via ComfyUI (Stable Audio, MusicGen)",
"musicGeneration": "Music Generation"
},
"endpoints": {
"tabProxy": "Endpoint Proxy",
@ -1749,7 +1876,22 @@
"close": "Close",
"statusDeactivated": "Deactivated (Manual)",
"statusBanned": "Banned / Sandbox Violation",
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted"
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted",
"repairEnvFailed": "Failed to repair .env",
"showEmails": "Show all emails",
"noModelsMatch": "No models match \"{filter}\"",
"deselectAllModels": "Deselect all",
"modelsActiveCount": "{active}/{total} active",
"repairEnvSuccess": "OAuth defaults restored",
"imagesGenerations": "Images Generations",
"embeddings": "Embeddings",
"audioSpeech": "Audio Speech",
"hideEmails": "Hide all emails",
"audioTranscriptions": "Audio Transcriptions",
"selectAllModels": "Select all",
"repairEnv": "Repair env",
"repairEnvWorking": "Repairing...",
"repairEnvHint": "Restore missing OAuth defaults into .env without overwriting existing values."
},
"settings": {
"title": "הגדרות",
@ -2266,7 +2408,11 @@
"wildcardPatternModeDesc": "Use wildcard aliases with * and ? when a family of models should map to one target.",
"noExactAliasesConfigured": "No exact-match aliases configured.",
"wildcardRulesTitle": "Wildcard Rules",
"noWildcardAliasesConfigured": "No wildcard aliases configured."
"noWildcardAliasesConfigured": "No wildcard aliases configured.",
"contextRelayHandoffThreshold": "Handoff Threshold",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex accounts and uses these values as global defaults for new or unconfigured combos.",
"contextRelaySummaryModel": "Summary Model",
"contextRelayMaxMessages": "Max Messages For Summary"
},
"translator": {
"title": "מתרגם",
@ -2692,7 +2838,11 @@
"waitingForOpenAIAuthorization": "ממתין להרשאת OpenAI...",
"waitingForAntigravityAuthorization": "ממתין לאישור נגד כבידה...",
"waitingForQoderAuthorization": "ממתין להרשאת Qoder...",
"exchangingCodeForTokens": "מחליף קוד לאסימונים..."
"exchangingCodeForTokens": "מחליף קוד לאסימונים...",
"nodeIncompatibleDesc": "You are running Node.js {version}, which is outside OmniRoute's supported secure runtime policy. Use a patched Node.js 20.x or 22.x LTS release.",
"nodeIncompatibleHint": "OmniRoute requires Node.js 20.20.2+ (20.x LTS) or 22.22.2+ (22.x LTS). Node 22 LTS is recommended.",
"nodeIncompatibleFixLabel": "Fix: install a patched Node.js 22 LTS release",
"nodeIncompatibleTitle": "Incompatible Node.js Version"
},
"landing": {
"brandName": "OmniRoute",
@ -3108,7 +3258,26 @@
"peakCached": "Peak cached",
"deduplicatedRequests": "Deduplicated Requests",
"savedCalls": "Saved API Calls",
"totalProcessed": "Total Requests Processed"
"totalProcessed": "Total Requests Processed",
"trendHour": "Hour",
"semanticEntriesDesc": "Persisted semantic cache records currently stored in SQLite. Provider-side prompt cache activity is not listed here.",
"semanticCache": "Semantic Cache",
"cacheRateDesc": "of total requests",
"activityVolume": "Activity",
"promptCacheSectionDesc": "Shows provider-side prompt caching activity from usage history so you can see where cache control is active and how much input reuse you are getting.",
"lastUpdated": "Last updated",
"cacheRate": "Cache Rate",
"promptTrendDesc": "Hourly request volume, cache coverage, and cache read volume across the last 24 hours.",
"busiestHour": "Busiest Hour",
"entriesLoadError": "Failed to load semantic cache entries.",
"cachedRequests24h": "Cached Requests (24h)",
"semanticCacheSectionDesc": "OmniRoute's own deterministic response cache. When enabled, repeated non-streaming temperature=0 requests can be served locally without hitting the upstream provider.",
"noPromptCacheData": "No provider-side prompt cache activity has been recorded yet.",
"peakCacheRate": "Peak Cache Rate",
"providerCacheRateDesc": "Each provider exposes total input tokens, cache read tokens, and cache write tokens so you can verify the reuse ratio against raw totals.",
"semanticCacheDisabledDesc": "Semantic cache is disabled. OmniRoute will skip local response reuse until you turn it back on in Settings.",
"hoursTracked": "hours tracked",
"noTrendData": "No prompt cache activity has been recorded over the last 24 hours."
},
"memory": {
"title": "Memory Management",
@ -3132,7 +3301,8 @@
"factual": "Factual",
"episodic": "Episodic",
"procedural": "Procedural",
"semantic": "Semantic"
"semantic": "Semantic",
"delete": "Delete"
},
"skills": {
"title": "Skills",

View file

@ -136,7 +136,10 @@
"Failed to save pricing": "Failed to save pricing",
"Failed to reset pricing": "Failed to reset pricing",
"apikey": "API Key",
"http": "HTTP"
"http": "HTTP",
"nothingHere": "Nothing here yet",
"checkSystemStatus": "Check System Status",
"goToDashboard": "Go to Dashboard"
},
"sidebar": {
"home": "घर",
@ -640,7 +643,8 @@
"opencode": "जब आप ओपनकोड के माध्यम से टर्मिनल-नेटिव एजेंट रन और स्क्रिप्टेड ऑटोमेशन पसंद करते हैं तो इसका उपयोग करें।",
"kiro": "किरो को एकीकृत करते समय और ओमनीरूट से केंद्रीय रूप से मॉडल रूटिंग को नियंत्रित करते समय उपयोग करें।",
"antigravity": "इसका उपयोग तब करें जब एंटीग्रेविटी/किरो ट्रैफिक को एमआईटीएम के माध्यम से रोका जाना चाहिए और ओमनीरूट पर भेजा जाना चाहिए।",
"copilot": "जब आप ओम्निरूट कुंजी और रूटिंग नियमों को लागू करते समय कोपायलट चैट शैली यूएक्स चाहते हैं तो इसका उपयोग करें।"
"copilot": "जब आप ओम्निरूट कुंजी और रूटिंग नियमों को लागू करते समय कोपायलट चैट शैली यूएक्स चाहते हैं तो इसका उपयोग करें।",
"windsurf": "Use when you want an AI-first IDE with Codeium/Windsurf models routed through OmniRoute."
},
"toolDescriptions": {
"antigravity": "एमआईटीएम के साथ गूगल एंटीग्रेविटी आईडीई",
@ -655,7 +659,8 @@
"opencode": "OpenCode AI coding agent (Terminal)",
"kiro": "Amazon Kiro — AI-powered IDE",
"windsurf": "Windsurf AI Code Editor",
"copilot": "GitHub Copilot AI Assistant"
"copilot": "GitHub Copilot AI Assistant",
"qwen": "Alibaba Qwen Code CLI"
},
"guides": {
"cursor": {
@ -890,6 +895,16 @@
"when": "Use when you want perfectly even spread — each model used once before repeating.",
"avoid": "Avoid when models have different quality or latency and order matters.",
"example": "Example: Multiple accounts of the same model to distribute usage evenly."
},
"p2c": {
"when": "Use when you want low-latency selection using Power-of-Two-Choices algorithm.",
"avoid": "Avoid for small combos with 2 or fewer models — no benefit over round-robin.",
"example": "Example: High-throughput inference across 4+ equivalent model endpoints."
},
"context-relay": {
"when": "Use when long sessions must survive account rotation without losing the working context.",
"avoid": "Avoid when account switching is rare or when you do not want extra summarization requests.",
"example": "Example: Codex sessions that rotate across multiple accounts near quota exhaustion."
}
},
"advancedHelp": {
@ -1009,7 +1024,117 @@
"wizardStep3Title": "Choose Strategy",
"wizardStep3Desc": "Pick how requests are distributed across your models - 13 strategies available",
"wizardStep4Title": "Review & Save",
"wizardStep4Desc": "Review your configuration and activate the combo"
"wizardStep4Desc": "Review your configuration and activate the combo",
"builderIntelligentTitle": "Intelligent Routing Configuration",
"activeModePack": "Active Mode Pack",
"modePackHint": "Switch presets to bias the routing engine without rebuilding the combo.",
"highCircuitBreakerRate": "High circuit breaker trip rate detected.",
"reviewAccounts": "Accounts",
"contextRelaySummaryModel": "Summary Model",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex account rotation. Pair it with multiple accounts of the same provider for the best continuity.",
"cooldownMinutes": "Cooldown: {minutes}m",
"builderTitle": "Build a Combo",
"intelligentPanelTitle": "Intelligent Routing Dashboard",
"filterEmptyDeterministicDescription": "Only auto and LKGP combos exist right now. Switch back to All or create a deterministic combo.",
"contextRelayDesc": "Preserves session continuity with handoff summaries when accounts rotate",
"contextRelayHandoffThresholdHelp": "When quota usage reaches this threshold, OmniRoute generates a structured handoff summary before the active account is exhausted.",
"reviewProviders": "Providers",
"builderModel": "Model",
"weightHealth": "Health",
"weightStability": "Stability",
"allProvidersHealthy": "Providers are reporting healthy routing conditions.",
"emailVisibilityStateOff": "Off",
"filterEmptyIntelligentDescription": "Create an auto or LKGP combo to populate the intelligent routing dashboard.",
"candidatePoolAllProviders": "All providers",
"routerStrategyLabel": "Router Strategy",
"builderBrowseCatalog": "Browse catalog",
"builderStage": {
"steps": {
"label": "Steps",
"description": "Provider, model, and account selection"
},
"strategy": {
"description": "Routing behavior and advanced settings",
"label": "Strategy"
},
"basics": {
"label": "Basics",
"description": "Name and starting template"
},
"intelligent": {
"label": "Smart Routing",
"description": "Auto-routing candidate pool, presets, and scoring"
},
"review": {
"label": "Review",
"description": "Final validation before saving"
}
},
"builderProviderFirst": "Pick provider first",
"reviewNoSteps": "No steps configured",
"contextRelayHandoffThreshold": "Handoff Threshold",
"builderFlowTitle": "Combo Builder Flow",
"builderPinnedAccount": "Pinned Account",
"builderStageLocked": "Locked — complete previous stage first",
"filterDeterministic": "Deterministic",
"candidatePoolLabel": "Candidate Pool",
"contextRelay": "Context Relay",
"reorderHandle": "Drag to reorder",
"contextRelayMaxMessagesHelp": "Limits how much recent history is condensed into the relay summary.",
"candidatePoolHint": "Select which providers this engine should evaluate. Leave empty to use all active providers.",
"builderAccount": "Account",
"builderAddComboRef": "Add combo reference",
"reviewAdvanced": "Advanced Settings",
"modePackUpdated": "Mode pack updated to {pack}.",
"builderPreview": "Preview",
"noExcludedProviders": "No providers are currently excluded.",
"statusOverview": "Status Overview",
"reviewName": "Name",
"advancedWeightsTitle": "Advanced: Scoring Weights",
"reviewSequence": "Model Sequence",
"intelligentPanelDesc": "Real-time scoring and health status for this auto-routing combo.",
"builderComboRefStep": "Add combo reference",
"weightLatencyInv": "Latency",
"contextRelayMaxMessages": "Max Messages For Summary",
"builderIntelligentDesc": "Configure the multi-factor scoring engine for this auto-routing combo.",
"weightTierPriority": "Tier",
"modePackLabel": "Mode Pack",
"builderAddStep": "Add step",
"budgetCapLabel": "Budget Cap (USD / request)",
"builderLegacyEntry": "Legacy entry",
"explorationRateLabel": "Exploration Rate",
"filterAll": "All",
"builderStageCurrent": "Current stage",
"filterIntelligent": "Intelligent",
"contextRelaySummaryModelHelp": "Optional override model used only for generating the handoff summary. Leave empty to reuse the active combo model.",
"weightTaskFit": "Task Fit",
"explorationRateHint": "{percent}% of requests can explore non-optimal providers.",
"excludedProvidersHint": "Providers with an OPEN circuit breaker are temporarily excluded from routing.",
"builderStagePending": "Pending",
"budgetCapPlaceholder": "No limit",
"weightQuota": "Quota",
"reviewAgentFlags": "Agent Flags",
"builderStageVisited": "Stage completed",
"providerScores": "Provider Scores",
"allProvidersEvaluated": "No candidate pool configured. All active providers are evaluated at runtime.",
"strategyRules": "Rules (6-Factor Scoring)",
"normalOperation": "Normal Operation",
"builderSelectModel": "Select model",
"builderLoadingProviders": "Loading providers...",
"builderComboRef": "Combo Ref",
"failedReorder": "Failed to reorder models",
"builderSelectProvider": "Select provider",
"weightCostInv": "Cost",
"emailVisibilityStateOn": "On",
"reviewIntelligentTitle": "Intelligent Routing Config",
"candidatePoolEmpty": "No active providers available yet.",
"reviewStrategy": "Strategy",
"reviewComboRefs": "Combo References",
"filterEmptyTitle": "No combos match this strategy filter.",
"builderProvider": "Provider",
"incidentMode": "Incident Mode",
"reviewSteps": "Steps",
"excludedProviders": "Excluded Providers"
},
"costs": {
"title": "लागत",
@ -1147,7 +1272,9 @@
"a2aQuickStartStep2": "Send JSON-RPC requests to `POST /a2a` using `message/send` or `message/stream`.",
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format",
"musicDesc": "Generate music and audio tracks via ComfyUI (Stable Audio, MusicGen)",
"musicGeneration": "Music Generation"
},
"endpoints": {
"tabProxy": "Endpoint Proxy",
@ -1749,7 +1876,22 @@
"close": "Close",
"statusDeactivated": "Deactivated (Manual)",
"statusBanned": "Banned / Sandbox Violation",
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted"
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted",
"noModelsMatch": "No models match \"{filter}\"",
"hideEmails": "Hide all emails",
"imagesGenerations": "Images Generations",
"repairEnvFailed": "Failed to repair .env",
"repairEnvWorking": "Repairing...",
"repairEnvHint": "Restore missing OAuth defaults into .env without overwriting existing values.",
"selectAllModels": "Select all",
"embeddings": "Embeddings",
"deselectAllModels": "Deselect all",
"repairEnv": "Repair env",
"repairEnvSuccess": "OAuth defaults restored",
"audioSpeech": "Audio Speech",
"showEmails": "Show all emails",
"modelsActiveCount": "{active}/{total} active",
"audioTranscriptions": "Audio Transcriptions"
},
"settings": {
"title": "सेटिंग्स",
@ -2266,7 +2408,11 @@
"wildcardPatternModeDesc": "Use wildcard aliases with * and ? when a family of models should map to one target.",
"noExactAliasesConfigured": "No exact-match aliases configured.",
"wildcardRulesTitle": "Wildcard Rules",
"noWildcardAliasesConfigured": "No wildcard aliases configured."
"noWildcardAliasesConfigured": "No wildcard aliases configured.",
"contextRelaySummaryModel": "Summary Model",
"contextRelayMaxMessages": "Max Messages For Summary",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex accounts and uses these values as global defaults for new or unconfigured combos.",
"contextRelayHandoffThreshold": "Handoff Threshold"
},
"translator": {
"title": "अनुवादक",
@ -2692,7 +2838,11 @@
"waitingForOpenAIAuthorization": "Waiting for OpenAI authorization...",
"waitingForAntigravityAuthorization": "Waiting for Antigravity authorization...",
"waitingForQoderAuthorization": "Waiting for Qoder authorization...",
"exchangingCodeForTokens": "Exchanging code for tokens..."
"exchangingCodeForTokens": "Exchanging code for tokens...",
"nodeIncompatibleTitle": "Incompatible Node.js Version",
"nodeIncompatibleFixLabel": "Fix: install a patched Node.js 22 LTS release",
"nodeIncompatibleDesc": "You are running Node.js {version}, which is outside OmniRoute's supported secure runtime policy. Use a patched Node.js 20.x or 22.x LTS release.",
"nodeIncompatibleHint": "OmniRoute requires Node.js 20.20.2+ (20.x LTS) or 22.22.2+ (22.x LTS). Node 22 LTS is recommended."
},
"landing": {
"brandName": "ओम्निरूट",
@ -3108,7 +3258,26 @@
"peakCached": "Peak cached",
"deduplicatedRequests": "Deduplicated Requests",
"savedCalls": "Saved API Calls",
"totalProcessed": "Total Requests Processed"
"totalProcessed": "Total Requests Processed",
"semanticCache": "Semantic Cache",
"cachedRequests24h": "Cached Requests (24h)",
"semanticCacheDisabledDesc": "Semantic cache is disabled. OmniRoute will skip local response reuse until you turn it back on in Settings.",
"entriesLoadError": "Failed to load semantic cache entries.",
"peakCacheRate": "Peak Cache Rate",
"noPromptCacheData": "No provider-side prompt cache activity has been recorded yet.",
"activityVolume": "Activity",
"lastUpdated": "Last updated",
"semanticEntriesDesc": "Persisted semantic cache records currently stored in SQLite. Provider-side prompt cache activity is not listed here.",
"semanticCacheSectionDesc": "OmniRoute's own deterministic response cache. When enabled, repeated non-streaming temperature=0 requests can be served locally without hitting the upstream provider.",
"promptTrendDesc": "Hourly request volume, cache coverage, and cache read volume across the last 24 hours.",
"cacheRate": "Cache Rate",
"trendHour": "Hour",
"providerCacheRateDesc": "Each provider exposes total input tokens, cache read tokens, and cache write tokens so you can verify the reuse ratio against raw totals.",
"noTrendData": "No prompt cache activity has been recorded over the last 24 hours.",
"promptCacheSectionDesc": "Shows provider-side prompt caching activity from usage history so you can see where cache control is active and how much input reuse you are getting.",
"hoursTracked": "hours tracked",
"cacheRateDesc": "of total requests",
"busiestHour": "Busiest Hour"
},
"memory": {
"title": "Memory Management",
@ -3132,7 +3301,8 @@
"factual": "Factual",
"episodic": "Episodic",
"procedural": "Procedural",
"semantic": "Semantic"
"semantic": "Semantic",
"delete": "Delete"
},
"skills": {
"title": "Skills",

View file

@ -136,7 +136,10 @@
"Failed to save pricing": "Nem sikerült menteni az árakat",
"Failed to reset pricing": "Nem sikerült visszaállítani az árakat",
"apikey": "API kulcs",
"http": "HTTP"
"http": "HTTP",
"nothingHere": "Nothing here yet",
"goToDashboard": "Go to Dashboard",
"checkSystemStatus": "Check System Status"
},
"sidebar": {
"home": "Otthon",
@ -640,7 +643,8 @@
"opencode": "Akkor használja, ha a terminál-natív ügynökfuttatásokat és az OpenCode-on keresztüli parancsfájl-automatizálást részesíti előnyben.",
"kiro": "Használja a Kiro integrálásához és a modell-útválasztás központi vezérléséhez az OmniRoute-ból.",
"antigravity": "Akkor használja, ha az Antigravity/Kiro forgalmat MITM-en keresztül kell elfogni, és az OmniRoute-hoz kell irányítani.",
"copilot": "Használja, ha másodpilóta csevegési stílusú UX-et szeretne, miközben betartja az OmniRoute kulcsokat és útválasztási szabályokat."
"copilot": "Használja, ha másodpilóta csevegési stílusú UX-et szeretne, miközben betartja az OmniRoute kulcsokat és útválasztási szabályokat.",
"windsurf": "Use when you want an AI-first IDE with Codeium/Windsurf models routed through OmniRoute."
},
"toolDescriptions": {
"antigravity": "Google Antigravity IDE MITM-mel",
@ -655,7 +659,8 @@
"opencode": "OpenCode AI coding agent (Terminal)",
"kiro": "Amazon Kiro — AI-powered IDE",
"windsurf": "Windsurf AI Code Editor",
"copilot": "GitHub Copilot AI Assistant"
"copilot": "GitHub Copilot AI Assistant",
"qwen": "Alibaba Qwen Code CLI"
},
"guides": {
"cursor": {
@ -890,6 +895,16 @@
"when": "Use when you want perfectly even spread — each model used once before repeating.",
"avoid": "Avoid when models have different quality or latency and order matters.",
"example": "Example: Multiple accounts of the same model to distribute usage evenly."
},
"context-relay": {
"avoid": "Avoid when account switching is rare or when you do not want extra summarization requests.",
"example": "Example: Codex sessions that rotate across multiple accounts near quota exhaustion.",
"when": "Use when long sessions must survive account rotation without losing the working context."
},
"p2c": {
"when": "Use when you want low-latency selection using Power-of-Two-Choices algorithm.",
"example": "Example: High-throughput inference across 4+ equivalent model endpoints.",
"avoid": "Avoid for small combos with 2 or fewer models — no benefit over round-robin."
}
},
"advancedHelp": {
@ -1009,7 +1024,117 @@
"wizardStep3Title": "Choose Strategy",
"wizardStep3Desc": "Pick how requests are distributed across your models - 13 strategies available",
"wizardStep4Title": "Review & Save",
"wizardStep4Desc": "Review your configuration and activate the combo"
"wizardStep4Desc": "Review your configuration and activate the combo",
"reviewIntelligentTitle": "Intelligent Routing Config",
"intelligentPanelDesc": "Real-time scoring and health status for this auto-routing combo.",
"builderProvider": "Provider",
"weightTierPriority": "Tier",
"builderComboRefStep": "Add combo reference",
"builderStage": {
"intelligent": {
"label": "Smart Routing",
"description": "Auto-routing candidate pool, presets, and scoring"
},
"review": {
"description": "Final validation before saving",
"label": "Review"
},
"steps": {
"description": "Provider, model, and account selection",
"label": "Steps"
},
"strategy": {
"label": "Strategy",
"description": "Routing behavior and advanced settings"
},
"basics": {
"label": "Basics",
"description": "Name and starting template"
}
},
"normalOperation": "Normal Operation",
"builderIntelligentDesc": "Configure the multi-factor scoring engine for this auto-routing combo.",
"builderProviderFirst": "Pick provider first",
"reorderHandle": "Drag to reorder",
"allProvidersEvaluated": "No candidate pool configured. All active providers are evaluated at runtime.",
"weightHealth": "Health",
"reviewStrategy": "Strategy",
"reviewSteps": "Steps",
"builderSelectProvider": "Select provider",
"routerStrategyLabel": "Router Strategy",
"candidatePoolAllProviders": "All providers",
"modePackLabel": "Mode Pack",
"builderStagePending": "Pending",
"candidatePoolHint": "Select which providers this engine should evaluate. Leave empty to use all active providers.",
"filterIntelligent": "Intelligent",
"contextRelayDesc": "Preserves session continuity with handoff summaries when accounts rotate",
"contextRelaySummaryModel": "Summary Model",
"builderTitle": "Build a Combo",
"contextRelaySummaryModelHelp": "Optional override model used only for generating the handoff summary. Leave empty to reuse the active combo model.",
"reviewAdvanced": "Advanced Settings",
"emailVisibilityStateOn": "On",
"builderStageCurrent": "Current stage",
"candidatePoolLabel": "Candidate Pool",
"weightTaskFit": "Task Fit",
"builderLegacyEntry": "Legacy entry",
"explorationRateLabel": "Exploration Rate",
"builderBrowseCatalog": "Browse catalog",
"incidentMode": "Incident Mode",
"builderAddStep": "Add step",
"builderFlowTitle": "Combo Builder Flow",
"reviewSequence": "Model Sequence",
"builderStageVisited": "Stage completed",
"noExcludedProviders": "No providers are currently excluded.",
"builderModel": "Model",
"highCircuitBreakerRate": "High circuit breaker trip rate detected.",
"filterEmptyDeterministicDescription": "Only auto and LKGP combos exist right now. Switch back to All or create a deterministic combo.",
"reviewNoSteps": "No steps configured",
"modePackUpdated": "Mode pack updated to {pack}.",
"weightStability": "Stability",
"strategyRules": "Rules (6-Factor Scoring)",
"candidatePoolEmpty": "No active providers available yet.",
"providerScores": "Provider Scores",
"reviewAccounts": "Accounts",
"weightQuota": "Quota",
"builderIntelligentTitle": "Intelligent Routing Configuration",
"failedReorder": "Failed to reorder models",
"weightCostInv": "Cost",
"builderPinnedAccount": "Pinned Account",
"weightLatencyInv": "Latency",
"filterEmptyIntelligentDescription": "Create an auto or LKGP combo to populate the intelligent routing dashboard.",
"excludedProviders": "Excluded Providers",
"allProvidersHealthy": "Providers are reporting healthy routing conditions.",
"cooldownMinutes": "Cooldown: {minutes}m",
"activeModePack": "Active Mode Pack",
"reviewProviders": "Providers",
"builderComboRef": "Combo Ref",
"budgetCapPlaceholder": "No limit",
"builderAccount": "Account",
"statusOverview": "Status Overview",
"modePackHint": "Switch presets to bias the routing engine without rebuilding the combo.",
"builderAddComboRef": "Add combo reference",
"builderStageLocked": "Locked — complete previous stage first",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex account rotation. Pair it with multiple accounts of the same provider for the best continuity.",
"excludedProvidersHint": "Providers with an OPEN circuit breaker are temporarily excluded from routing.",
"contextRelayMaxMessages": "Max Messages For Summary",
"explorationRateHint": "{percent}% of requests can explore non-optimal providers.",
"contextRelayHandoffThresholdHelp": "When quota usage reaches this threshold, OmniRoute generates a structured handoff summary before the active account is exhausted.",
"builderSelectModel": "Select model",
"emailVisibilityStateOff": "Off",
"filterEmptyTitle": "No combos match this strategy filter.",
"filterAll": "All",
"reviewAgentFlags": "Agent Flags",
"reviewComboRefs": "Combo References",
"builderPreview": "Preview",
"contextRelayHandoffThreshold": "Handoff Threshold",
"advancedWeightsTitle": "Advanced: Scoring Weights",
"budgetCapLabel": "Budget Cap (USD / request)",
"builderLoadingProviders": "Loading providers...",
"reviewName": "Name",
"contextRelay": "Context Relay",
"filterDeterministic": "Deterministic",
"contextRelayMaxMessagesHelp": "Limits how much recent history is condensed into the relay summary.",
"intelligentPanelTitle": "Intelligent Routing Dashboard"
},
"costs": {
"title": "Költségek",
@ -1147,7 +1272,9 @@
"a2aQuickStartStep2": "Send JSON-RPC requests to `POST /a2a` using `message/send` or `message/stream`.",
"a2aQuickStartStep3": "Kövesse nyomon és vezérelje a feladatokat a `tasks/get` és `tasks/cancel` használatával.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format",
"musicGeneration": "Music Generation",
"musicDesc": "Generate music and audio tracks via ComfyUI (Stable Audio, MusicGen)"
},
"endpoints": {
"tabProxy": "Endpoint Proxy",
@ -1749,7 +1876,22 @@
"close": "Close",
"statusDeactivated": "Deactivated (Manual)",
"statusBanned": "Banned / Sandbox Violation",
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted"
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted",
"audioSpeech": "Audio Speech",
"deselectAllModels": "Deselect all",
"repairEnvFailed": "Failed to repair .env",
"repairEnvWorking": "Repairing...",
"hideEmails": "Hide all emails",
"noModelsMatch": "No models match \"{filter}\"",
"showEmails": "Show all emails",
"repairEnvSuccess": "OAuth defaults restored",
"modelsActiveCount": "{active}/{total} active",
"repairEnvHint": "Restore missing OAuth defaults into .env without overwriting existing values.",
"repairEnv": "Repair env",
"embeddings": "Embeddings",
"imagesGenerations": "Images Generations",
"audioTranscriptions": "Audio Transcriptions",
"selectAllModels": "Select all"
},
"settings": {
"title": "Beállítások elemre",
@ -2266,7 +2408,11 @@
"wildcardPatternModeDesc": "Use wildcard aliases with * and ? when a family of models should map to one target.",
"noExactAliasesConfigured": "No exact-match aliases configured.",
"wildcardRulesTitle": "Wildcard Rules",
"noWildcardAliasesConfigured": "No wildcard aliases configured."
"noWildcardAliasesConfigured": "No wildcard aliases configured.",
"contextRelaySummaryModel": "Summary Model",
"contextRelayHandoffThreshold": "Handoff Threshold",
"contextRelayMaxMessages": "Max Messages For Summary",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex accounts and uses these values as global defaults for new or unconfigured combos."
},
"translator": {
"title": "Fordító",
@ -2692,7 +2838,11 @@
"waitingForOpenAIAuthorization": "Várakozás az OpenAI engedélyezésére...",
"waitingForAntigravityAuthorization": "Várakozás az Antigravitációs engedélyezésre...",
"waitingForQoderAuthorization": "Várakozás az Qoder engedélyezésére...",
"exchangingCodeForTokens": "Kód cseréje tokenre..."
"exchangingCodeForTokens": "Kód cseréje tokenre...",
"nodeIncompatibleTitle": "Incompatible Node.js Version",
"nodeIncompatibleFixLabel": "Fix: install a patched Node.js 22 LTS release",
"nodeIncompatibleHint": "OmniRoute requires Node.js 20.20.2+ (20.x LTS) or 22.22.2+ (22.x LTS). Node 22 LTS is recommended.",
"nodeIncompatibleDesc": "You are running Node.js {version}, which is outside OmniRoute's supported secure runtime policy. Use a patched Node.js 20.x or 22.x LTS release."
},
"landing": {
"brandName": "OmniRoute",
@ -3108,7 +3258,26 @@
"peakCached": "Peak cached",
"deduplicatedRequests": "Deduplicated Requests",
"savedCalls": "Saved API Calls",
"totalProcessed": "Total Requests Processed"
"totalProcessed": "Total Requests Processed",
"hoursTracked": "hours tracked",
"semanticEntriesDesc": "Persisted semantic cache records currently stored in SQLite. Provider-side prompt cache activity is not listed here.",
"semanticCache": "Semantic Cache",
"cacheRate": "Cache Rate",
"lastUpdated": "Last updated",
"semanticCacheSectionDesc": "OmniRoute's own deterministic response cache. When enabled, repeated non-streaming temperature=0 requests can be served locally without hitting the upstream provider.",
"noTrendData": "No prompt cache activity has been recorded over the last 24 hours.",
"cacheRateDesc": "of total requests",
"trendHour": "Hour",
"cachedRequests24h": "Cached Requests (24h)",
"activityVolume": "Activity",
"promptCacheSectionDesc": "Shows provider-side prompt caching activity from usage history so you can see where cache control is active and how much input reuse you are getting.",
"noPromptCacheData": "No provider-side prompt cache activity has been recorded yet.",
"peakCacheRate": "Peak Cache Rate",
"busiestHour": "Busiest Hour",
"entriesLoadError": "Failed to load semantic cache entries.",
"promptTrendDesc": "Hourly request volume, cache coverage, and cache read volume across the last 24 hours.",
"semanticCacheDisabledDesc": "Semantic cache is disabled. OmniRoute will skip local response reuse until you turn it back on in Settings.",
"providerCacheRateDesc": "Each provider exposes total input tokens, cache read tokens, and cache write tokens so you can verify the reuse ratio against raw totals."
},
"memory": {
"title": "Memory Management",
@ -3132,7 +3301,8 @@
"factual": "Factual",
"episodic": "Episodic",
"procedural": "Procedural",
"semantic": "Semantic"
"semantic": "Semantic",
"delete": "Delete"
},
"skills": {
"title": "Skills",

View file

@ -136,7 +136,10 @@
"Failed to save pricing": "Gagal menyimpan harga",
"Failed to reset pricing": "Gagal menyetel ulang harga",
"apikey": "Kunci API",
"http": "HTTP"
"http": "HTTP",
"nothingHere": "Nothing here yet",
"goToDashboard": "Go to Dashboard",
"checkSystemStatus": "Check System Status"
},
"sidebar": {
"home": "Rumah",
@ -640,7 +643,8 @@
"opencode": "Gunakan saat Anda lebih suka menjalankan agen terminal-asli dan otomatisasi skrip melalui OpenCode.",
"kiro": "Gunakan saat mengintegrasikan Kiro dan mengontrol perutean model secara terpusat dari OmniRoute.",
"antigravity": "Gunakan ketika lalu lintas Antigravitasi/Kiro harus dicegat melalui MITM dan dialihkan ke OmniRoute.",
"copilot": "Gunakan saat Anda menginginkan UX gaya obrolan kopilot sambil menerapkan kunci OmniRoute dan aturan perutean."
"copilot": "Gunakan saat Anda menginginkan UX gaya obrolan kopilot sambil menerapkan kunci OmniRoute dan aturan perutean.",
"windsurf": "Use when you want an AI-first IDE with Codeium/Windsurf models routed through OmniRoute."
},
"toolDescriptions": {
"antigravity": "IDE Antigravitasi Google dengan MITM",
@ -655,7 +659,8 @@
"opencode": "OpenCode AI coding agent (Terminal)",
"kiro": "Amazon Kiro — AI-powered IDE",
"windsurf": "Windsurf AI Code Editor",
"copilot": "GitHub Copilot AI Assistant"
"copilot": "GitHub Copilot AI Assistant",
"qwen": "Alibaba Qwen Code CLI"
},
"guides": {
"cursor": {
@ -890,6 +895,16 @@
"when": "Use when you want perfectly even spread — each model used once before repeating.",
"avoid": "Avoid when models have different quality or latency and order matters.",
"example": "Example: Multiple accounts of the same model to distribute usage evenly."
},
"p2c": {
"avoid": "Avoid for small combos with 2 or fewer models — no benefit over round-robin.",
"example": "Example: High-throughput inference across 4+ equivalent model endpoints.",
"when": "Use when you want low-latency selection using Power-of-Two-Choices algorithm."
},
"context-relay": {
"when": "Use when long sessions must survive account rotation without losing the working context.",
"avoid": "Avoid when account switching is rare or when you do not want extra summarization requests.",
"example": "Example: Codex sessions that rotate across multiple accounts near quota exhaustion."
}
},
"advancedHelp": {
@ -1009,7 +1024,117 @@
"wizardStep3Title": "Choose Strategy",
"wizardStep3Desc": "Pick how requests are distributed across your models - 13 strategies available",
"wizardStep4Title": "Review & Save",
"wizardStep4Desc": "Review your configuration and activate the combo"
"wizardStep4Desc": "Review your configuration and activate the combo",
"filterEmptyDeterministicDescription": "Only auto and LKGP combos exist right now. Switch back to All or create a deterministic combo.",
"incidentMode": "Incident Mode",
"builderLoadingProviders": "Loading providers...",
"builderTitle": "Build a Combo",
"contextRelaySummaryModelHelp": "Optional override model used only for generating the handoff summary. Leave empty to reuse the active combo model.",
"builderIntelligentDesc": "Configure the multi-factor scoring engine for this auto-routing combo.",
"reviewSteps": "Steps",
"builderStage": {
"steps": {
"description": "Provider, model, and account selection",
"label": "Steps"
},
"intelligent": {
"label": "Smart Routing",
"description": "Auto-routing candidate pool, presets, and scoring"
},
"strategy": {
"label": "Strategy",
"description": "Routing behavior and advanced settings"
},
"basics": {
"label": "Basics",
"description": "Name and starting template"
},
"review": {
"description": "Final validation before saving",
"label": "Review"
}
},
"reviewAdvanced": "Advanced Settings",
"builderComboRefStep": "Add combo reference",
"builderProvider": "Provider",
"modePackHint": "Switch presets to bias the routing engine without rebuilding the combo.",
"filterEmptyIntelligentDescription": "Create an auto or LKGP combo to populate the intelligent routing dashboard.",
"weightStability": "Stability",
"builderStageCurrent": "Current stage",
"explorationRateHint": "{percent}% of requests can explore non-optimal providers.",
"contextRelayHandoffThresholdHelp": "When quota usage reaches this threshold, OmniRoute generates a structured handoff summary before the active account is exhausted.",
"advancedWeightsTitle": "Advanced: Scoring Weights",
"activeModePack": "Active Mode Pack",
"contextRelayMaxMessagesHelp": "Limits how much recent history is condensed into the relay summary.",
"builderSelectModel": "Select model",
"reviewSequence": "Model Sequence",
"noExcludedProviders": "No providers are currently excluded.",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex account rotation. Pair it with multiple accounts of the same provider for the best continuity.",
"builderSelectProvider": "Select provider",
"budgetCapLabel": "Budget Cap (USD / request)",
"excludedProviders": "Excluded Providers",
"builderStagePending": "Pending",
"reviewNoSteps": "No steps configured",
"reviewStrategy": "Strategy",
"candidatePoolEmpty": "No active providers available yet.",
"weightQuota": "Quota",
"budgetCapPlaceholder": "No limit",
"builderStageLocked": "Locked — complete previous stage first",
"failedReorder": "Failed to reorder models",
"candidatePoolHint": "Select which providers this engine should evaluate. Leave empty to use all active providers.",
"weightCostInv": "Cost",
"builderLegacyEntry": "Legacy entry",
"intelligentPanelTitle": "Intelligent Routing Dashboard",
"contextRelayDesc": "Preserves session continuity with handoff summaries when accounts rotate",
"weightHealth": "Health",
"allProvidersEvaluated": "No candidate pool configured. All active providers are evaluated at runtime.",
"reviewComboRefs": "Combo References",
"weightTierPriority": "Tier",
"statusOverview": "Status Overview",
"explorationRateLabel": "Exploration Rate",
"emailVisibilityStateOn": "On",
"candidatePoolLabel": "Candidate Pool",
"reorderHandle": "Drag to reorder",
"builderModel": "Model",
"excludedProvidersHint": "Providers with an OPEN circuit breaker are temporarily excluded from routing.",
"reviewIntelligentTitle": "Intelligent Routing Config",
"reviewProviders": "Providers",
"contextRelaySummaryModel": "Summary Model",
"normalOperation": "Normal Operation",
"strategyRules": "Rules (6-Factor Scoring)",
"filterDeterministic": "Deterministic",
"cooldownMinutes": "Cooldown: {minutes}m",
"builderBrowseCatalog": "Browse catalog",
"contextRelayMaxMessages": "Max Messages For Summary",
"weightTaskFit": "Task Fit",
"builderAddStep": "Add step",
"reviewName": "Name",
"providerScores": "Provider Scores",
"allProvidersHealthy": "Providers are reporting healthy routing conditions.",
"builderPinnedAccount": "Pinned Account",
"builderAddComboRef": "Add combo reference",
"builderAccount": "Account",
"filterIntelligent": "Intelligent",
"contextRelay": "Context Relay",
"builderFlowTitle": "Combo Builder Flow",
"builderStageVisited": "Stage completed",
"modePackLabel": "Mode Pack",
"routerStrategyLabel": "Router Strategy",
"builderIntelligentTitle": "Intelligent Routing Configuration",
"highCircuitBreakerRate": "High circuit breaker trip rate detected.",
"builderPreview": "Preview",
"emailVisibilityStateOff": "Off",
"filterAll": "All",
"builderComboRef": "Combo Ref",
"intelligentPanelDesc": "Real-time scoring and health status for this auto-routing combo.",
"builderProviderFirst": "Pick provider first",
"candidatePoolAllProviders": "All providers",
"reviewAgentFlags": "Agent Flags",
"weightLatencyInv": "Latency",
"reviewAccounts": "Accounts",
"filterEmptyTitle": "No combos match this strategy filter.",
"modePackUpdated": "Mode pack updated to {pack}.",
"contextRelayHandoffThreshold": "Handoff Threshold"
},
"costs": {
"title": "Biaya",
@ -1147,7 +1272,9 @@
"a2aQuickStartStep2": "Send JSON-RPC requests to `POST /a2a` using `message/send` or `message/stream`.",
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format",
"musicGeneration": "Music Generation",
"musicDesc": "Generate music and audio tracks via ComfyUI (Stable Audio, MusicGen)"
},
"endpoints": {
"tabProxy": "Endpoint Proxy",
@ -1749,7 +1876,22 @@
"close": "Close",
"statusDeactivated": "Deactivated (Manual)",
"statusBanned": "Banned / Sandbox Violation",
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted"
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted",
"repairEnvHint": "Restore missing OAuth defaults into .env without overwriting existing values.",
"deselectAllModels": "Deselect all",
"repairEnvFailed": "Failed to repair .env",
"modelsActiveCount": "{active}/{total} active",
"audioSpeech": "Audio Speech",
"selectAllModels": "Select all",
"repairEnvWorking": "Repairing...",
"hideEmails": "Hide all emails",
"repairEnv": "Repair env",
"repairEnvSuccess": "OAuth defaults restored",
"embeddings": "Embeddings",
"showEmails": "Show all emails",
"imagesGenerations": "Images Generations",
"noModelsMatch": "No models match \"{filter}\"",
"audioTranscriptions": "Audio Transcriptions"
},
"settings": {
"title": "Pengaturan",
@ -2266,7 +2408,11 @@
"wildcardPatternModeDesc": "Use wildcard aliases with * and ? when a family of models should map to one target.",
"noExactAliasesConfigured": "No exact-match aliases configured.",
"wildcardRulesTitle": "Wildcard Rules",
"noWildcardAliasesConfigured": "No wildcard aliases configured."
"noWildcardAliasesConfigured": "No wildcard aliases configured.",
"contextRelayMaxMessages": "Max Messages For Summary",
"contextRelaySummaryModel": "Summary Model",
"contextRelayHandoffThreshold": "Handoff Threshold",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex accounts and uses these values as global defaults for new or unconfigured combos."
},
"translator": {
"title": "Penerjemah",
@ -2692,7 +2838,11 @@
"waitingForOpenAIAuthorization": "Waiting for OpenAI authorization...",
"waitingForAntigravityAuthorization": "Waiting for Antigravity authorization...",
"waitingForQoderAuthorization": "Waiting for Qoder authorization...",
"exchangingCodeForTokens": "Exchanging code for tokens..."
"exchangingCodeForTokens": "Exchanging code for tokens...",
"nodeIncompatibleTitle": "Incompatible Node.js Version",
"nodeIncompatibleFixLabel": "Fix: install a patched Node.js 22 LTS release",
"nodeIncompatibleDesc": "You are running Node.js {version}, which is outside OmniRoute's supported secure runtime policy. Use a patched Node.js 20.x or 22.x LTS release.",
"nodeIncompatibleHint": "OmniRoute requires Node.js 20.20.2+ (20.x LTS) or 22.22.2+ (22.x LTS). Node 22 LTS is recommended."
},
"landing": {
"brandName": "OmniRoute",
@ -3108,7 +3258,26 @@
"peakCached": "Peak cached",
"deduplicatedRequests": "Deduplicated Requests",
"savedCalls": "Saved API Calls",
"totalProcessed": "Total Requests Processed"
"totalProcessed": "Total Requests Processed",
"activityVolume": "Activity",
"cacheRateDesc": "of total requests",
"semanticCacheDisabledDesc": "Semantic cache is disabled. OmniRoute will skip local response reuse until you turn it back on in Settings.",
"peakCacheRate": "Peak Cache Rate",
"promptTrendDesc": "Hourly request volume, cache coverage, and cache read volume across the last 24 hours.",
"trendHour": "Hour",
"semanticCacheSectionDesc": "OmniRoute's own deterministic response cache. When enabled, repeated non-streaming temperature=0 requests can be served locally without hitting the upstream provider.",
"providerCacheRateDesc": "Each provider exposes total input tokens, cache read tokens, and cache write tokens so you can verify the reuse ratio against raw totals.",
"cacheRate": "Cache Rate",
"entriesLoadError": "Failed to load semantic cache entries.",
"cachedRequests24h": "Cached Requests (24h)",
"noTrendData": "No prompt cache activity has been recorded over the last 24 hours.",
"semanticCache": "Semantic Cache",
"noPromptCacheData": "No provider-side prompt cache activity has been recorded yet.",
"hoursTracked": "hours tracked",
"lastUpdated": "Last updated",
"busiestHour": "Busiest Hour",
"promptCacheSectionDesc": "Shows provider-side prompt caching activity from usage history so you can see where cache control is active and how much input reuse you are getting.",
"semanticEntriesDesc": "Persisted semantic cache records currently stored in SQLite. Provider-side prompt cache activity is not listed here."
},
"memory": {
"title": "Memory Management",
@ -3132,7 +3301,8 @@
"factual": "Factual",
"episodic": "Episodic",
"procedural": "Procedural",
"semantic": "Semantic"
"semantic": "Semantic",
"delete": "Delete"
},
"skills": {
"title": "Skills",

View file

@ -136,7 +136,10 @@
"Failed to save pricing": "Impossibile salvare i prezzi",
"Failed to reset pricing": "Impossibile reimpostare i prezzi",
"apikey": "Chiave API",
"http": "HTTP"
"http": "HTTP",
"checkSystemStatus": "Check System Status",
"goToDashboard": "Go to Dashboard",
"nothingHere": "Nothing here yet"
},
"sidebar": {
"home": "Casa",
@ -640,7 +643,8 @@
"opencode": "Utilizzalo quando preferisci l'esecuzione dell'agente nativo del terminale e l'automazione basata su script tramite OpenCode.",
"kiro": "Da utilizzare quando si integra Kiro e si controlla l'instradamento del modello centralmente da OmniRoute.",
"antigravity": "Da utilizzare quando il traffico Antigravity/Kiro deve essere intercettato tramite MITM e instradato a OmniRoute.",
"copilot": "Utilizzalo quando desideri un'esperienza utente in stile chat Copilot applicando al tempo stesso le chiavi OmniRoute e le regole di routing."
"copilot": "Utilizzalo quando desideri un'esperienza utente in stile chat Copilot applicando al tempo stesso le chiavi OmniRoute e le regole di routing.",
"windsurf": "Use when you want an AI-first IDE with Codeium/Windsurf models routed through OmniRoute."
},
"toolDescriptions": {
"antigravity": "IDE Antigravità di Google con MITM",
@ -655,7 +659,8 @@
"opencode": "OpenCode AI coding agent (Terminal)",
"kiro": "Amazon Kiro — AI-powered IDE",
"windsurf": "Windsurf AI Code Editor",
"copilot": "GitHub Copilot AI Assistant"
"copilot": "GitHub Copilot AI Assistant",
"qwen": "Alibaba Qwen Code CLI"
},
"guides": {
"cursor": {
@ -890,6 +895,16 @@
"when": "Use when you want perfectly even spread — each model used once before repeating.",
"avoid": "Avoid when models have different quality or latency and order matters.",
"example": "Example: Multiple accounts of the same model to distribute usage evenly."
},
"context-relay": {
"example": "Example: Codex sessions that rotate across multiple accounts near quota exhaustion.",
"when": "Use when long sessions must survive account rotation without losing the working context.",
"avoid": "Avoid when account switching is rare or when you do not want extra summarization requests."
},
"p2c": {
"when": "Use when you want low-latency selection using Power-of-Two-Choices algorithm.",
"example": "Example: High-throughput inference across 4+ equivalent model endpoints.",
"avoid": "Avoid for small combos with 2 or fewer models — no benefit over round-robin."
}
},
"advancedHelp": {
@ -1009,7 +1024,117 @@
"wizardStep3Title": "Choose Strategy",
"wizardStep3Desc": "Pick how requests are distributed across your models - 13 strategies available",
"wizardStep4Title": "Review & Save",
"wizardStep4Desc": "Review your configuration and activate the combo"
"wizardStep4Desc": "Review your configuration and activate the combo",
"reorderHandle": "Drag to reorder",
"builderComboRef": "Combo Ref",
"builderStage": {
"steps": {
"label": "Steps",
"description": "Provider, model, and account selection"
},
"basics": {
"description": "Name and starting template",
"label": "Basics"
},
"strategy": {
"label": "Strategy",
"description": "Routing behavior and advanced settings"
},
"review": {
"label": "Review",
"description": "Final validation before saving"
},
"intelligent": {
"description": "Auto-routing candidate pool, presets, and scoring",
"label": "Smart Routing"
}
},
"budgetCapLabel": "Budget Cap (USD / request)",
"reviewIntelligentTitle": "Intelligent Routing Config",
"candidatePoolHint": "Select which providers this engine should evaluate. Leave empty to use all active providers.",
"builderProviderFirst": "Pick provider first",
"advancedWeightsTitle": "Advanced: Scoring Weights",
"emailVisibilityStateOff": "Off",
"reviewProviders": "Providers",
"builderAddStep": "Add step",
"candidatePoolAllProviders": "All providers",
"builderBrowseCatalog": "Browse catalog",
"contextRelayMaxMessagesHelp": "Limits how much recent history is condensed into the relay summary.",
"strategyRules": "Rules (6-Factor Scoring)",
"builderTitle": "Build a Combo",
"statusOverview": "Status Overview",
"modePackUpdated": "Mode pack updated to {pack}.",
"reviewNoSteps": "No steps configured",
"intelligentPanelTitle": "Intelligent Routing Dashboard",
"builderStageCurrent": "Current stage",
"reviewSequence": "Model Sequence",
"filterDeterministic": "Deterministic",
"reviewStrategy": "Strategy",
"builderPreview": "Preview",
"budgetCapPlaceholder": "No limit",
"candidatePoolEmpty": "No active providers available yet.",
"filterEmptyIntelligentDescription": "Create an auto or LKGP combo to populate the intelligent routing dashboard.",
"builderFlowTitle": "Combo Builder Flow",
"weightTierPriority": "Tier",
"contextRelayMaxMessages": "Max Messages For Summary",
"builderComboRefStep": "Add combo reference",
"filterEmptyTitle": "No combos match this strategy filter.",
"excludedProvidersHint": "Providers with an OPEN circuit breaker are temporarily excluded from routing.",
"builderSelectModel": "Select model",
"reviewSteps": "Steps",
"cooldownMinutes": "Cooldown: {minutes}m",
"weightQuota": "Quota",
"activeModePack": "Active Mode Pack",
"explorationRateLabel": "Exploration Rate",
"builderIntelligentTitle": "Intelligent Routing Configuration",
"builderIntelligentDesc": "Configure the multi-factor scoring engine for this auto-routing combo.",
"builderAddComboRef": "Add combo reference",
"builderPinnedAccount": "Pinned Account",
"normalOperation": "Normal Operation",
"failedReorder": "Failed to reorder models",
"reviewAgentFlags": "Agent Flags",
"weightTaskFit": "Task Fit",
"builderModel": "Model",
"reviewComboRefs": "Combo References",
"modePackLabel": "Mode Pack",
"filterEmptyDeterministicDescription": "Only auto and LKGP combos exist right now. Switch back to All or create a deterministic combo.",
"contextRelayHandoffThreshold": "Handoff Threshold",
"allProvidersHealthy": "Providers are reporting healthy routing conditions.",
"contextRelayHandoffThresholdHelp": "When quota usage reaches this threshold, OmniRoute generates a structured handoff summary before the active account is exhausted.",
"builderAccount": "Account",
"reviewAdvanced": "Advanced Settings",
"filterAll": "All",
"weightHealth": "Health",
"excludedProviders": "Excluded Providers",
"weightStability": "Stability",
"builderProvider": "Provider",
"candidatePoolLabel": "Candidate Pool",
"weightLatencyInv": "Latency",
"explorationRateHint": "{percent}% of requests can explore non-optimal providers.",
"filterIntelligent": "Intelligent",
"builderLegacyEntry": "Legacy entry",
"builderSelectProvider": "Select provider",
"incidentMode": "Incident Mode",
"contextRelaySummaryModel": "Summary Model",
"modePackHint": "Switch presets to bias the routing engine without rebuilding the combo.",
"builderStageLocked": "Locked — complete previous stage first",
"providerScores": "Provider Scores",
"allProvidersEvaluated": "No candidate pool configured. All active providers are evaluated at runtime.",
"builderLoadingProviders": "Loading providers...",
"builderStageVisited": "Stage completed",
"intelligentPanelDesc": "Real-time scoring and health status for this auto-routing combo.",
"builderStagePending": "Pending",
"reviewName": "Name",
"noExcludedProviders": "No providers are currently excluded.",
"emailVisibilityStateOn": "On",
"contextRelayDesc": "Preserves session continuity with handoff summaries when accounts rotate",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex account rotation. Pair it with multiple accounts of the same provider for the best continuity.",
"contextRelay": "Context Relay",
"reviewAccounts": "Accounts",
"weightCostInv": "Cost",
"routerStrategyLabel": "Router Strategy",
"highCircuitBreakerRate": "High circuit breaker trip rate detected.",
"contextRelaySummaryModelHelp": "Optional override model used only for generating the handoff summary. Leave empty to reuse the active combo model."
},
"costs": {
"title": "Costi",
@ -1147,7 +1272,9 @@
"a2aQuickStartStep2": "Send JSON-RPC requests to `POST /a2a` using `message/send` or `message/stream`.",
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format",
"musicGeneration": "Music Generation",
"musicDesc": "Generate music and audio tracks via ComfyUI (Stable Audio, MusicGen)"
},
"endpoints": {
"tabProxy": "Endpoint Proxy",
@ -1749,7 +1876,22 @@
"close": "Close",
"statusDeactivated": "Deactivated (Manual)",
"statusBanned": "Banned / Sandbox Violation",
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted"
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted",
"imagesGenerations": "Images Generations",
"repairEnvHint": "Restore missing OAuth defaults into .env without overwriting existing values.",
"noModelsMatch": "No models match \"{filter}\"",
"audioTranscriptions": "Audio Transcriptions",
"deselectAllModels": "Deselect all",
"repairEnvSuccess": "OAuth defaults restored",
"modelsActiveCount": "{active}/{total} active",
"selectAllModels": "Select all",
"audioSpeech": "Audio Speech",
"repairEnv": "Repair env",
"repairEnvFailed": "Failed to repair .env",
"hideEmails": "Hide all emails",
"repairEnvWorking": "Repairing...",
"embeddings": "Embeddings",
"showEmails": "Show all emails"
},
"settings": {
"title": "Impostazioni",
@ -2266,7 +2408,11 @@
"wildcardPatternModeDesc": "Use wildcard aliases with * and ? when a family of models should map to one target.",
"noExactAliasesConfigured": "No exact-match aliases configured.",
"wildcardRulesTitle": "Wildcard Rules",
"noWildcardAliasesConfigured": "No wildcard aliases configured."
"noWildcardAliasesConfigured": "No wildcard aliases configured.",
"contextRelaySummaryModel": "Summary Model",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex accounts and uses these values as global defaults for new or unconfigured combos.",
"contextRelayHandoffThreshold": "Handoff Threshold",
"contextRelayMaxMessages": "Max Messages For Summary"
},
"translator": {
"title": "Traduttore",
@ -2692,7 +2838,11 @@
"waitingForOpenAIAuthorization": "Waiting for OpenAI authorization...",
"waitingForAntigravityAuthorization": "Waiting for Antigravity authorization...",
"waitingForQoderAuthorization": "Waiting for Qoder authorization...",
"exchangingCodeForTokens": "Exchanging code for tokens..."
"exchangingCodeForTokens": "Exchanging code for tokens...",
"nodeIncompatibleDesc": "You are running Node.js {version}, which is outside OmniRoute's supported secure runtime policy. Use a patched Node.js 20.x or 22.x LTS release.",
"nodeIncompatibleTitle": "Incompatible Node.js Version",
"nodeIncompatibleHint": "OmniRoute requires Node.js 20.20.2+ (20.x LTS) or 22.22.2+ (22.x LTS). Node 22 LTS is recommended.",
"nodeIncompatibleFixLabel": "Fix: install a patched Node.js 22 LTS release"
},
"landing": {
"brandName": "OmniRoute",
@ -3108,7 +3258,26 @@
"peakCached": "Peak cached",
"deduplicatedRequests": "Deduplicated Requests",
"savedCalls": "Saved API Calls",
"totalProcessed": "Total Requests Processed"
"totalProcessed": "Total Requests Processed",
"hoursTracked": "hours tracked",
"noTrendData": "No prompt cache activity has been recorded over the last 24 hours.",
"activityVolume": "Activity",
"peakCacheRate": "Peak Cache Rate",
"trendHour": "Hour",
"cacheRateDesc": "of total requests",
"promptCacheSectionDesc": "Shows provider-side prompt caching activity from usage history so you can see where cache control is active and how much input reuse you are getting.",
"semanticCacheSectionDesc": "OmniRoute's own deterministic response cache. When enabled, repeated non-streaming temperature=0 requests can be served locally without hitting the upstream provider.",
"cacheRate": "Cache Rate",
"promptTrendDesc": "Hourly request volume, cache coverage, and cache read volume across the last 24 hours.",
"busiestHour": "Busiest Hour",
"semanticCacheDisabledDesc": "Semantic cache is disabled. OmniRoute will skip local response reuse until you turn it back on in Settings.",
"providerCacheRateDesc": "Each provider exposes total input tokens, cache read tokens, and cache write tokens so you can verify the reuse ratio against raw totals.",
"cachedRequests24h": "Cached Requests (24h)",
"lastUpdated": "Last updated",
"semanticEntriesDesc": "Persisted semantic cache records currently stored in SQLite. Provider-side prompt cache activity is not listed here.",
"entriesLoadError": "Failed to load semantic cache entries.",
"semanticCache": "Semantic Cache",
"noPromptCacheData": "No provider-side prompt cache activity has been recorded yet."
},
"memory": {
"title": "Memory Management",
@ -3132,7 +3301,8 @@
"factual": "Factual",
"episodic": "Episodic",
"procedural": "Procedural",
"semantic": "Semantic"
"semantic": "Semantic",
"delete": "Delete"
},
"skills": {
"title": "Skills",

View file

@ -136,7 +136,10 @@
"Failed to save pricing": "価格設定を保存できませんでした",
"Failed to reset pricing": "価格設定のリセットに失敗しました",
"apikey": "APIキー",
"http": "HTTP"
"http": "HTTP",
"checkSystemStatus": "Check System Status",
"nothingHere": "Nothing here yet",
"goToDashboard": "Go to Dashboard"
},
"sidebar": {
"home": "ホーム",
@ -640,7 +643,8 @@
"opencode": "ターミナルネイティブのエージェントの実行と OpenCode によるスクリプトによる自動化を希望する場合に使用します。",
"kiro": "Kiro を統合し、OmniRoute からモデルのルーティングを一元的に制御する場合に使用します。",
"antigravity": "Antigravity/Kiro トラフィックを MITM 経由でインターセプトし、OmniRoute にルーティングする必要がある場合に使用します。",
"copilot": "OmniRoute キーとルーティング ルールを適用しながら、Copilot チャット スタイルの UX が必要な場合に使用します。"
"copilot": "OmniRoute キーとルーティング ルールを適用しながら、Copilot チャット スタイルの UX が必要な場合に使用します。",
"windsurf": "Use when you want an AI-first IDE with Codeium/Windsurf models routed through OmniRoute."
},
"toolDescriptions": {
"antigravity": "MITM を備えた Google Antigravity IDE",
@ -655,7 +659,8 @@
"opencode": "OpenCode AI coding agent (Terminal)",
"kiro": "Amazon Kiro — AI-powered IDE",
"windsurf": "Windsurf AI Code Editor",
"copilot": "GitHub Copilot AI Assistant"
"copilot": "GitHub Copilot AI Assistant",
"qwen": "Alibaba Qwen Code CLI"
},
"guides": {
"cursor": {
@ -890,6 +895,16 @@
"when": "Use when you want perfectly even spread — each model used once before repeating.",
"avoid": "Avoid when models have different quality or latency and order matters.",
"example": "Example: Multiple accounts of the same model to distribute usage evenly."
},
"context-relay": {
"example": "Example: Codex sessions that rotate across multiple accounts near quota exhaustion.",
"avoid": "Avoid when account switching is rare or when you do not want extra summarization requests.",
"when": "Use when long sessions must survive account rotation without losing the working context."
},
"p2c": {
"when": "Use when you want low-latency selection using Power-of-Two-Choices algorithm.",
"example": "Example: High-throughput inference across 4+ equivalent model endpoints.",
"avoid": "Avoid for small combos with 2 or fewer models — no benefit over round-robin."
}
},
"advancedHelp": {
@ -1009,7 +1024,117 @@
"wizardStep3Title": "Choose Strategy",
"wizardStep3Desc": "Pick how requests are distributed across your models - 13 strategies available",
"wizardStep4Title": "Review & Save",
"wizardStep4Desc": "Review your configuration and activate the combo"
"wizardStep4Desc": "Review your configuration and activate the combo",
"explorationRateLabel": "Exploration Rate",
"builderFlowTitle": "Combo Builder Flow",
"builderStage": {
"basics": {
"description": "Name and starting template",
"label": "Basics"
},
"strategy": {
"label": "Strategy",
"description": "Routing behavior and advanced settings"
},
"intelligent": {
"label": "Smart Routing",
"description": "Auto-routing candidate pool, presets, and scoring"
},
"steps": {
"label": "Steps",
"description": "Provider, model, and account selection"
},
"review": {
"label": "Review",
"description": "Final validation before saving"
}
},
"budgetCapLabel": "Budget Cap (USD / request)",
"excludedProvidersHint": "Providers with an OPEN circuit breaker are temporarily excluded from routing.",
"allProvidersEvaluated": "No candidate pool configured. All active providers are evaluated at runtime.",
"builderBrowseCatalog": "Browse catalog",
"builderSelectModel": "Select model",
"emailVisibilityStateOff": "Off",
"noExcludedProviders": "No providers are currently excluded.",
"excludedProviders": "Excluded Providers",
"modePackUpdated": "Mode pack updated to {pack}.",
"statusOverview": "Status Overview",
"builderStageLocked": "Locked — complete previous stage first",
"builderPinnedAccount": "Pinned Account",
"reviewIntelligentTitle": "Intelligent Routing Config",
"advancedWeightsTitle": "Advanced: Scoring Weights",
"reviewStrategy": "Strategy",
"normalOperation": "Normal Operation",
"weightStability": "Stability",
"contextRelaySummaryModel": "Summary Model",
"builderIntelligentDesc": "Configure the multi-factor scoring engine for this auto-routing combo.",
"incidentMode": "Incident Mode",
"candidatePoolEmpty": "No active providers available yet.",
"reviewProviders": "Providers",
"strategyRules": "Rules (6-Factor Scoring)",
"builderAddComboRef": "Add combo reference",
"candidatePoolAllProviders": "All providers",
"contextRelay": "Context Relay",
"filterAll": "All",
"weightTaskFit": "Task Fit",
"weightTierPriority": "Tier",
"builderIntelligentTitle": "Intelligent Routing Configuration",
"allProvidersHealthy": "Providers are reporting healthy routing conditions.",
"contextRelayHandoffThreshold": "Handoff Threshold",
"intelligentPanelTitle": "Intelligent Routing Dashboard",
"filterEmptyDeterministicDescription": "Only auto and LKGP combos exist right now. Switch back to All or create a deterministic combo.",
"weightQuota": "Quota",
"builderComboRef": "Combo Ref",
"weightCostInv": "Cost",
"filterEmptyIntelligentDescription": "Create an auto or LKGP combo to populate the intelligent routing dashboard.",
"candidatePoolLabel": "Candidate Pool",
"modePackHint": "Switch presets to bias the routing engine without rebuilding the combo.",
"filterIntelligent": "Intelligent",
"cooldownMinutes": "Cooldown: {minutes}m",
"builderStageCurrent": "Current stage",
"weightHealth": "Health",
"builderComboRefStep": "Add combo reference",
"reviewComboRefs": "Combo References",
"builderPreview": "Preview",
"intelligentPanelDesc": "Real-time scoring and health status for this auto-routing combo.",
"contextRelayMaxMessagesHelp": "Limits how much recent history is condensed into the relay summary.",
"builderProvider": "Provider",
"reviewSequence": "Model Sequence",
"filterDeterministic": "Deterministic",
"builderProviderFirst": "Pick provider first",
"modePackLabel": "Mode Pack",
"reviewAccounts": "Accounts",
"builderLoadingProviders": "Loading providers...",
"providerScores": "Provider Scores",
"builderModel": "Model",
"highCircuitBreakerRate": "High circuit breaker trip rate detected.",
"failedReorder": "Failed to reorder models",
"builderLegacyEntry": "Legacy entry",
"routerStrategyLabel": "Router Strategy",
"activeModePack": "Active Mode Pack",
"builderStagePending": "Pending",
"reorderHandle": "Drag to reorder",
"contextRelayHandoffThresholdHelp": "When quota usage reaches this threshold, OmniRoute generates a structured handoff summary before the active account is exhausted.",
"reviewAdvanced": "Advanced Settings",
"weightLatencyInv": "Latency",
"contextRelayDesc": "Preserves session continuity with handoff summaries when accounts rotate",
"explorationRateHint": "{percent}% of requests can explore non-optimal providers.",
"reviewSteps": "Steps",
"budgetCapPlaceholder": "No limit",
"candidatePoolHint": "Select which providers this engine should evaluate. Leave empty to use all active providers.",
"builderAddStep": "Add step",
"builderStageVisited": "Stage completed",
"builderAccount": "Account",
"reviewName": "Name",
"builderSelectProvider": "Select provider",
"contextRelaySummaryModelHelp": "Optional override model used only for generating the handoff summary. Leave empty to reuse the active combo model.",
"filterEmptyTitle": "No combos match this strategy filter.",
"builderTitle": "Build a Combo",
"reviewAgentFlags": "Agent Flags",
"emailVisibilityStateOn": "On",
"contextRelayMaxMessages": "Max Messages For Summary",
"reviewNoSteps": "No steps configured",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex account rotation. Pair it with multiple accounts of the same provider for the best continuity."
},
"costs": {
"title": "コスト",
@ -1147,7 +1272,9 @@
"a2aQuickStartStep2": "Send JSON-RPC requests to `POST /a2a` using `message/send` or `message/stream`.",
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format",
"musicGeneration": "Music Generation",
"musicDesc": "Generate music and audio tracks via ComfyUI (Stable Audio, MusicGen)"
},
"endpoints": {
"tabProxy": "エンドポイント プロキシ",
@ -1749,7 +1876,22 @@
"close": "Close",
"statusDeactivated": "Deactivated (Manual)",
"statusBanned": "Banned / Sandbox Violation",
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted"
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted",
"embeddings": "Embeddings",
"repairEnvSuccess": "OAuth defaults restored",
"audioSpeech": "Audio Speech",
"repairEnvWorking": "Repairing...",
"audioTranscriptions": "Audio Transcriptions",
"noModelsMatch": "No models match \"{filter}\"",
"repairEnvFailed": "Failed to repair .env",
"imagesGenerations": "Images Generations",
"showEmails": "Show all emails",
"repairEnv": "Repair env",
"deselectAllModels": "Deselect all",
"selectAllModels": "Select all",
"repairEnvHint": "Restore missing OAuth defaults into .env without overwriting existing values.",
"modelsActiveCount": "{active}/{total} active",
"hideEmails": "Hide all emails"
},
"settings": {
"title": "設定",
@ -2266,7 +2408,11 @@
"wildcardPatternModeDesc": "Use wildcard aliases with * and ? when a family of models should map to one target.",
"noExactAliasesConfigured": "No exact-match aliases configured.",
"wildcardRulesTitle": "Wildcard Rules",
"noWildcardAliasesConfigured": "No wildcard aliases configured."
"noWildcardAliasesConfigured": "No wildcard aliases configured.",
"contextRelaySummaryModel": "Summary Model",
"contextRelayMaxMessages": "Max Messages For Summary",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex accounts and uses these values as global defaults for new or unconfigured combos.",
"contextRelayHandoffThreshold": "Handoff Threshold"
},
"translator": {
"title": "翻訳者",
@ -2692,7 +2838,11 @@
"waitingForOpenAIAuthorization": "Waiting for OpenAI authorization...",
"waitingForAntigravityAuthorization": "Waiting for Antigravity authorization...",
"waitingForQoderAuthorization": "Waiting for Qoder authorization...",
"exchangingCodeForTokens": "Exchanging code for tokens..."
"exchangingCodeForTokens": "Exchanging code for tokens...",
"nodeIncompatibleFixLabel": "Fix: install a patched Node.js 22 LTS release",
"nodeIncompatibleTitle": "Incompatible Node.js Version",
"nodeIncompatibleHint": "OmniRoute requires Node.js 20.20.2+ (20.x LTS) or 22.22.2+ (22.x LTS). Node 22 LTS is recommended.",
"nodeIncompatibleDesc": "You are running Node.js {version}, which is outside OmniRoute's supported secure runtime policy. Use a patched Node.js 20.x or 22.x LTS release."
},
"landing": {
"brandName": "オムニルート",
@ -3108,7 +3258,26 @@
"peakCached": "Peak cached",
"deduplicatedRequests": "Deduplicated Requests",
"savedCalls": "Saved API Calls",
"totalProcessed": "Total Requests Processed"
"totalProcessed": "Total Requests Processed",
"cachedRequests24h": "Cached Requests (24h)",
"semanticEntriesDesc": "Persisted semantic cache records currently stored in SQLite. Provider-side prompt cache activity is not listed here.",
"providerCacheRateDesc": "Each provider exposes total input tokens, cache read tokens, and cache write tokens so you can verify the reuse ratio against raw totals.",
"trendHour": "Hour",
"cacheRate": "Cache Rate",
"hoursTracked": "hours tracked",
"entriesLoadError": "Failed to load semantic cache entries.",
"semanticCacheSectionDesc": "OmniRoute's own deterministic response cache. When enabled, repeated non-streaming temperature=0 requests can be served locally without hitting the upstream provider.",
"noPromptCacheData": "No provider-side prompt cache activity has been recorded yet.",
"activityVolume": "Activity",
"promptCacheSectionDesc": "Shows provider-side prompt caching activity from usage history so you can see where cache control is active and how much input reuse you are getting.",
"noTrendData": "No prompt cache activity has been recorded over the last 24 hours.",
"peakCacheRate": "Peak Cache Rate",
"lastUpdated": "Last updated",
"promptTrendDesc": "Hourly request volume, cache coverage, and cache read volume across the last 24 hours.",
"busiestHour": "Busiest Hour",
"semanticCache": "Semantic Cache",
"cacheRateDesc": "of total requests",
"semanticCacheDisabledDesc": "Semantic cache is disabled. OmniRoute will skip local response reuse until you turn it back on in Settings."
},
"memory": {
"title": "Memory Management",
@ -3132,7 +3301,8 @@
"factual": "Factual",
"episodic": "Episodic",
"procedural": "Procedural",
"semantic": "Semantic"
"semantic": "Semantic",
"delete": "Delete"
},
"skills": {
"title": "Skills",

View file

@ -136,7 +136,10 @@
"Failed to save pricing": "가격을 저장하지 못했습니다.",
"Failed to reset pricing": "가격을 재설정하지 못했습니다.",
"apikey": "API 키",
"http": "HTTP"
"http": "HTTP",
"goToDashboard": "Go to Dashboard",
"nothingHere": "Nothing here yet",
"checkSystemStatus": "Check System Status"
},
"sidebar": {
"home": "홈",
@ -640,7 +643,8 @@
"opencode": "OpenCode를 통해 터미널 기반 에이전트 실행 및 스크립트 자동화를 선호할 때 사용하세요.",
"kiro": "Kiro를 통합하고 OmniRoute에서 중앙에서 모델 라우팅을 제어할 때 사용합니다.",
"antigravity": "Antigravity/Kiro 트래픽이 MITM을 통해 가로채어 OmniRoute로 라우팅되어야 하는 경우에 사용합니다.",
"copilot": "OmniRoute 키와 라우팅 규칙을 적용하면서 Copilot 채팅 스타일 UX를 원할 때 사용하세요."
"copilot": "OmniRoute 키와 라우팅 규칙을 적용하면서 Copilot 채팅 스타일 UX를 원할 때 사용하세요.",
"windsurf": "Use when you want an AI-first IDE with Codeium/Windsurf models routed through OmniRoute."
},
"toolDescriptions": {
"antigravity": "MITM이 포함된 Google 반중력 IDE",
@ -655,7 +659,8 @@
"opencode": "OpenCode AI coding agent (Terminal)",
"kiro": "Amazon Kiro — AI-powered IDE",
"windsurf": "Windsurf AI Code Editor",
"copilot": "GitHub Copilot AI Assistant"
"copilot": "GitHub Copilot AI Assistant",
"qwen": "Alibaba Qwen Code CLI"
},
"guides": {
"cursor": {
@ -890,6 +895,16 @@
"when": "Use when you want perfectly even spread — each model used once before repeating.",
"avoid": "Avoid when models have different quality or latency and order matters.",
"example": "Example: Multiple accounts of the same model to distribute usage evenly."
},
"p2c": {
"avoid": "Avoid for small combos with 2 or fewer models — no benefit over round-robin.",
"when": "Use when you want low-latency selection using Power-of-Two-Choices algorithm.",
"example": "Example: High-throughput inference across 4+ equivalent model endpoints."
},
"context-relay": {
"avoid": "Avoid when account switching is rare or when you do not want extra summarization requests.",
"example": "Example: Codex sessions that rotate across multiple accounts near quota exhaustion.",
"when": "Use when long sessions must survive account rotation without losing the working context."
}
},
"advancedHelp": {
@ -1009,7 +1024,117 @@
"wizardStep3Title": "Choose Strategy",
"wizardStep3Desc": "Pick how requests are distributed across your models - 13 strategies available",
"wizardStep4Title": "Review & Save",
"wizardStep4Desc": "Review your configuration and activate the combo"
"wizardStep4Desc": "Review your configuration and activate the combo",
"contextRelayDesc": "Preserves session continuity with handoff summaries when accounts rotate",
"filterAll": "All",
"builderAddComboRef": "Add combo reference",
"cooldownMinutes": "Cooldown: {minutes}m",
"excludedProviders": "Excluded Providers",
"emailVisibilityStateOn": "On",
"builderStage": {
"intelligent": {
"description": "Auto-routing candidate pool, presets, and scoring",
"label": "Smart Routing"
},
"steps": {
"description": "Provider, model, and account selection",
"label": "Steps"
},
"review": {
"label": "Review",
"description": "Final validation before saving"
},
"basics": {
"label": "Basics",
"description": "Name and starting template"
},
"strategy": {
"description": "Routing behavior and advanced settings",
"label": "Strategy"
}
},
"builderLoadingProviders": "Loading providers...",
"providerScores": "Provider Scores",
"filterDeterministic": "Deterministic",
"weightCostInv": "Cost",
"builderAddStep": "Add step",
"intelligentPanelTitle": "Intelligent Routing Dashboard",
"incidentMode": "Incident Mode",
"builderPinnedAccount": "Pinned Account",
"builderProvider": "Provider",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex account rotation. Pair it with multiple accounts of the same provider for the best continuity.",
"contextRelayHandoffThreshold": "Handoff Threshold",
"weightTierPriority": "Tier",
"allProvidersHealthy": "Providers are reporting healthy routing conditions.",
"builderStagePending": "Pending",
"reviewAgentFlags": "Agent Flags",
"builderSelectModel": "Select model",
"normalOperation": "Normal Operation",
"builderBrowseCatalog": "Browse catalog",
"modePackUpdated": "Mode pack updated to {pack}.",
"activeModePack": "Active Mode Pack",
"contextRelayMaxMessagesHelp": "Limits how much recent history is condensed into the relay summary.",
"noExcludedProviders": "No providers are currently excluded.",
"excludedProvidersHint": "Providers with an OPEN circuit breaker are temporarily excluded from routing.",
"weightLatencyInv": "Latency",
"weightStability": "Stability",
"builderComboRefStep": "Add combo reference",
"explorationRateHint": "{percent}% of requests can explore non-optimal providers.",
"statusOverview": "Status Overview",
"reviewSteps": "Steps",
"failedReorder": "Failed to reorder models",
"modePackHint": "Switch presets to bias the routing engine without rebuilding the combo.",
"builderSelectProvider": "Select provider",
"builderModel": "Model",
"highCircuitBreakerRate": "High circuit breaker trip rate detected.",
"builderStageVisited": "Stage completed",
"weightQuota": "Quota",
"builderStageLocked": "Locked — complete previous stage first",
"reviewNoSteps": "No steps configured",
"candidatePoolLabel": "Candidate Pool",
"builderIntelligentTitle": "Intelligent Routing Configuration",
"builderIntelligentDesc": "Configure the multi-factor scoring engine for this auto-routing combo.",
"advancedWeightsTitle": "Advanced: Scoring Weights",
"reviewName": "Name",
"builderProviderFirst": "Pick provider first",
"reviewIntelligentTitle": "Intelligent Routing Config",
"routerStrategyLabel": "Router Strategy",
"allProvidersEvaluated": "No candidate pool configured. All active providers are evaluated at runtime.",
"filterEmptyIntelligentDescription": "Create an auto or LKGP combo to populate the intelligent routing dashboard.",
"weightTaskFit": "Task Fit",
"builderStageCurrent": "Current stage",
"candidatePoolHint": "Select which providers this engine should evaluate. Leave empty to use all active providers.",
"contextRelayMaxMessages": "Max Messages For Summary",
"reviewAccounts": "Accounts",
"reviewProviders": "Providers",
"builderLegacyEntry": "Legacy entry",
"strategyRules": "Rules (6-Factor Scoring)",
"builderPreview": "Preview",
"candidatePoolAllProviders": "All providers",
"builderComboRef": "Combo Ref",
"builderFlowTitle": "Combo Builder Flow",
"builderTitle": "Build a Combo",
"reviewSequence": "Model Sequence",
"filterIntelligent": "Intelligent",
"filterEmptyTitle": "No combos match this strategy filter.",
"budgetCapPlaceholder": "No limit",
"contextRelaySummaryModelHelp": "Optional override model used only for generating the handoff summary. Leave empty to reuse the active combo model.",
"reviewAdvanced": "Advanced Settings",
"weightHealth": "Health",
"contextRelayHandoffThresholdHelp": "When quota usage reaches this threshold, OmniRoute generates a structured handoff summary before the active account is exhausted.",
"intelligentPanelDesc": "Real-time scoring and health status for this auto-routing combo.",
"candidatePoolEmpty": "No active providers available yet.",
"explorationRateLabel": "Exploration Rate",
"reorderHandle": "Drag to reorder",
"filterEmptyDeterministicDescription": "Only auto and LKGP combos exist right now. Switch back to All or create a deterministic combo.",
"emailVisibilityStateOff": "Off",
"contextRelaySummaryModel": "Summary Model",
"reviewStrategy": "Strategy",
"reviewComboRefs": "Combo References",
"modePackLabel": "Mode Pack",
"contextRelay": "Context Relay",
"budgetCapLabel": "Budget Cap (USD / request)",
"builderAccount": "Account"
},
"costs": {
"title": "비용",
@ -1147,7 +1272,9 @@
"a2aQuickStartStep2": "Send JSON-RPC requests to `POST /a2a` using `message/send` or `message/stream`.",
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format",
"musicGeneration": "Music Generation",
"musicDesc": "Generate music and audio tracks via ComfyUI (Stable Audio, MusicGen)"
},
"endpoints": {
"tabProxy": "엔드포인트 프록시",
@ -1749,7 +1876,22 @@
"close": "Close",
"statusDeactivated": "Deactivated (Manual)",
"statusBanned": "Banned / Sandbox Violation",
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted"
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted",
"noModelsMatch": "No models match \"{filter}\"",
"embeddings": "Embeddings",
"deselectAllModels": "Deselect all",
"modelsActiveCount": "{active}/{total} active",
"repairEnvHint": "Restore missing OAuth defaults into .env without overwriting existing values.",
"repairEnvWorking": "Repairing...",
"imagesGenerations": "Images Generations",
"audioSpeech": "Audio Speech",
"showEmails": "Show all emails",
"audioTranscriptions": "Audio Transcriptions",
"selectAllModels": "Select all",
"repairEnvFailed": "Failed to repair .env",
"hideEmails": "Hide all emails",
"repairEnv": "Repair env",
"repairEnvSuccess": "OAuth defaults restored"
},
"settings": {
"title": "설정",
@ -2266,7 +2408,11 @@
"wildcardPatternModeDesc": "Use wildcard aliases with * and ? when a family of models should map to one target.",
"noExactAliasesConfigured": "No exact-match aliases configured.",
"wildcardRulesTitle": "Wildcard Rules",
"noWildcardAliasesConfigured": "No wildcard aliases configured."
"noWildcardAliasesConfigured": "No wildcard aliases configured.",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex accounts and uses these values as global defaults for new or unconfigured combos.",
"contextRelaySummaryModel": "Summary Model",
"contextRelayMaxMessages": "Max Messages For Summary",
"contextRelayHandoffThreshold": "Handoff Threshold"
},
"translator": {
"title": "번역기",
@ -2692,7 +2838,11 @@
"waitingForOpenAIAuthorization": "Waiting for OpenAI authorization...",
"waitingForAntigravityAuthorization": "Waiting for Antigravity authorization...",
"waitingForQoderAuthorization": "Waiting for Qoder authorization...",
"exchangingCodeForTokens": "Exchanging code for tokens..."
"exchangingCodeForTokens": "Exchanging code for tokens...",
"nodeIncompatibleDesc": "You are running Node.js {version}, which is outside OmniRoute's supported secure runtime policy. Use a patched Node.js 20.x or 22.x LTS release.",
"nodeIncompatibleHint": "OmniRoute requires Node.js 20.20.2+ (20.x LTS) or 22.22.2+ (22.x LTS). Node 22 LTS is recommended.",
"nodeIncompatibleFixLabel": "Fix: install a patched Node.js 22 LTS release",
"nodeIncompatibleTitle": "Incompatible Node.js Version"
},
"landing": {
"brandName": "옴니루트",
@ -3108,7 +3258,26 @@
"peakCached": "Peak cached",
"deduplicatedRequests": "Deduplicated Requests",
"savedCalls": "Saved API Calls",
"totalProcessed": "Total Requests Processed"
"totalProcessed": "Total Requests Processed",
"hoursTracked": "hours tracked",
"semanticEntriesDesc": "Persisted semantic cache records currently stored in SQLite. Provider-side prompt cache activity is not listed here.",
"semanticCacheDisabledDesc": "Semantic cache is disabled. OmniRoute will skip local response reuse until you turn it back on in Settings.",
"cacheRateDesc": "of total requests",
"activityVolume": "Activity",
"noPromptCacheData": "No provider-side prompt cache activity has been recorded yet.",
"cacheRate": "Cache Rate",
"entriesLoadError": "Failed to load semantic cache entries.",
"providerCacheRateDesc": "Each provider exposes total input tokens, cache read tokens, and cache write tokens so you can verify the reuse ratio against raw totals.",
"promptCacheSectionDesc": "Shows provider-side prompt caching activity from usage history so you can see where cache control is active and how much input reuse you are getting.",
"semanticCache": "Semantic Cache",
"noTrendData": "No prompt cache activity has been recorded over the last 24 hours.",
"peakCacheRate": "Peak Cache Rate",
"busiestHour": "Busiest Hour",
"trendHour": "Hour",
"promptTrendDesc": "Hourly request volume, cache coverage, and cache read volume across the last 24 hours.",
"semanticCacheSectionDesc": "OmniRoute's own deterministic response cache. When enabled, repeated non-streaming temperature=0 requests can be served locally without hitting the upstream provider.",
"lastUpdated": "Last updated",
"cachedRequests24h": "Cached Requests (24h)"
},
"memory": {
"title": "Memory Management",
@ -3132,7 +3301,8 @@
"factual": "Factual",
"episodic": "Episodic",
"procedural": "Procedural",
"semantic": "Semantic"
"semantic": "Semantic",
"delete": "Delete"
},
"skills": {
"title": "Skills",

View file

@ -136,7 +136,10 @@
"Failed to save pricing": "Gagal menyimpan harga",
"Failed to reset pricing": "Gagal menetapkan semula harga",
"apikey": "Kunci API",
"http": "HTTP"
"http": "HTTP",
"checkSystemStatus": "Check System Status",
"nothingHere": "Nothing here yet",
"goToDashboard": "Go to Dashboard"
},
"sidebar": {
"home": "Rumah",
@ -640,7 +643,8 @@
"opencode": "Gunakan apabila anda lebih suka ejen terminal-native run dan automasi skrip melalui OpenCode.",
"kiro": "Gunakan apabila menyepadukan Kiro dan mengawal penghalaan model secara berpusat daripada OmniRoute.",
"antigravity": "Gunakan apabila trafik Antigraviti/Kiro mesti dipintas melalui MITM dan dihalakan ke OmniRoute.",
"copilot": "Gunakan apabila anda mahu Copilot gaya sembang UX sambil menguatkuasakan kekunci OmniRoute dan peraturan penghalaan."
"copilot": "Gunakan apabila anda mahu Copilot gaya sembang UX sambil menguatkuasakan kekunci OmniRoute dan peraturan penghalaan.",
"windsurf": "Use when you want an AI-first IDE with Codeium/Windsurf models routed through OmniRoute."
},
"toolDescriptions": {
"antigravity": "IDE Antigraviti Google dengan MITM",
@ -655,7 +659,8 @@
"opencode": "OpenCode AI coding agent (Terminal)",
"kiro": "Amazon Kiro — AI-powered IDE",
"windsurf": "Windsurf AI Code Editor",
"copilot": "GitHub Copilot AI Assistant"
"copilot": "GitHub Copilot AI Assistant",
"qwen": "Alibaba Qwen Code CLI"
},
"guides": {
"cursor": {
@ -890,6 +895,16 @@
"when": "Use when you want perfectly even spread — each model used once before repeating.",
"avoid": "Avoid when models have different quality or latency and order matters.",
"example": "Example: Multiple accounts of the same model to distribute usage evenly."
},
"p2c": {
"when": "Use when you want low-latency selection using Power-of-Two-Choices algorithm.",
"avoid": "Avoid for small combos with 2 or fewer models — no benefit over round-robin.",
"example": "Example: High-throughput inference across 4+ equivalent model endpoints."
},
"context-relay": {
"avoid": "Avoid when account switching is rare or when you do not want extra summarization requests.",
"when": "Use when long sessions must survive account rotation without losing the working context.",
"example": "Example: Codex sessions that rotate across multiple accounts near quota exhaustion."
}
},
"advancedHelp": {
@ -1009,7 +1024,117 @@
"wizardStep3Title": "Choose Strategy",
"wizardStep3Desc": "Pick how requests are distributed across your models - 13 strategies available",
"wizardStep4Title": "Review & Save",
"wizardStep4Desc": "Review your configuration and activate the combo"
"wizardStep4Desc": "Review your configuration and activate the combo",
"explorationRateLabel": "Exploration Rate",
"contextRelayMaxMessages": "Max Messages For Summary",
"builderStage": {
"intelligent": {
"label": "Smart Routing",
"description": "Auto-routing candidate pool, presets, and scoring"
},
"steps": {
"label": "Steps",
"description": "Provider, model, and account selection"
},
"review": {
"label": "Review",
"description": "Final validation before saving"
},
"basics": {
"description": "Name and starting template",
"label": "Basics"
},
"strategy": {
"description": "Routing behavior and advanced settings",
"label": "Strategy"
}
},
"builderIntelligentDesc": "Configure the multi-factor scoring engine for this auto-routing combo.",
"builderComboRefStep": "Add combo reference",
"highCircuitBreakerRate": "High circuit breaker trip rate detected.",
"builderFlowTitle": "Combo Builder Flow",
"contextRelayHandoffThresholdHelp": "When quota usage reaches this threshold, OmniRoute generates a structured handoff summary before the active account is exhausted.",
"reviewAccounts": "Accounts",
"builderAddStep": "Add step",
"strategyRules": "Rules (6-Factor Scoring)",
"statusOverview": "Status Overview",
"reviewNoSteps": "No steps configured",
"intelligentPanelDesc": "Real-time scoring and health status for this auto-routing combo.",
"reviewAgentFlags": "Agent Flags",
"reviewComboRefs": "Combo References",
"budgetCapPlaceholder": "No limit",
"builderStagePending": "Pending",
"modePackUpdated": "Mode pack updated to {pack}.",
"weightLatencyInv": "Latency",
"emailVisibilityStateOff": "Off",
"contextRelayDesc": "Preserves session continuity with handoff summaries when accounts rotate",
"reviewIntelligentTitle": "Intelligent Routing Config",
"advancedWeightsTitle": "Advanced: Scoring Weights",
"candidatePoolHint": "Select which providers this engine should evaluate. Leave empty to use all active providers.",
"incidentMode": "Incident Mode",
"builderPinnedAccount": "Pinned Account",
"allProvidersHealthy": "Providers are reporting healthy routing conditions.",
"builderAddComboRef": "Add combo reference",
"budgetCapLabel": "Budget Cap (USD / request)",
"explorationRateHint": "{percent}% of requests can explore non-optimal providers.",
"cooldownMinutes": "Cooldown: {minutes}m",
"filterAll": "All",
"builderIntelligentTitle": "Intelligent Routing Configuration",
"filterEmptyIntelligentDescription": "Create an auto or LKGP combo to populate the intelligent routing dashboard.",
"reviewProviders": "Providers",
"providerScores": "Provider Scores",
"reviewSequence": "Model Sequence",
"contextRelaySummaryModelHelp": "Optional override model used only for generating the handoff summary. Leave empty to reuse the active combo model.",
"intelligentPanelTitle": "Intelligent Routing Dashboard",
"modePackLabel": "Mode Pack",
"normalOperation": "Normal Operation",
"builderStageVisited": "Stage completed",
"builderProviderFirst": "Pick provider first",
"builderLegacyEntry": "Legacy entry",
"reorderHandle": "Drag to reorder",
"filterIntelligent": "Intelligent",
"activeModePack": "Active Mode Pack",
"contextRelay": "Context Relay",
"filterEmptyTitle": "No combos match this strategy filter.",
"modePackHint": "Switch presets to bias the routing engine without rebuilding the combo.",
"candidatePoolLabel": "Candidate Pool",
"reviewSteps": "Steps",
"weightHealth": "Health",
"builderTitle": "Build a Combo",
"candidatePoolAllProviders": "All providers",
"builderSelectProvider": "Select provider",
"filterEmptyDeterministicDescription": "Only auto and LKGP combos exist right now. Switch back to All or create a deterministic combo.",
"builderComboRef": "Combo Ref",
"weightTaskFit": "Task Fit",
"builderStageCurrent": "Current stage",
"builderBrowseCatalog": "Browse catalog",
"filterDeterministic": "Deterministic",
"builderModel": "Model",
"builderStageLocked": "Locked — complete previous stage first",
"contextRelayMaxMessagesHelp": "Limits how much recent history is condensed into the relay summary.",
"emailVisibilityStateOn": "On",
"allProvidersEvaluated": "No candidate pool configured. All active providers are evaluated at runtime.",
"weightTierPriority": "Tier",
"builderAccount": "Account",
"builderSelectModel": "Select model",
"builderProvider": "Provider",
"reviewStrategy": "Strategy",
"contextRelaySummaryModel": "Summary Model",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex account rotation. Pair it with multiple accounts of the same provider for the best continuity.",
"weightCostInv": "Cost",
"excludedProviders": "Excluded Providers",
"reviewName": "Name",
"weightQuota": "Quota",
"contextRelayHandoffThreshold": "Handoff Threshold",
"candidatePoolEmpty": "No active providers available yet.",
"excludedProvidersHint": "Providers with an OPEN circuit breaker are temporarily excluded from routing.",
"builderLoadingProviders": "Loading providers...",
"reviewAdvanced": "Advanced Settings",
"weightStability": "Stability",
"noExcludedProviders": "No providers are currently excluded.",
"routerStrategyLabel": "Router Strategy",
"failedReorder": "Failed to reorder models",
"builderPreview": "Preview"
},
"costs": {
"title": "Kos",
@ -1147,7 +1272,9 @@
"a2aQuickStartStep2": "Hantar permintaan JSON-RPC ke `POST /a2a` menggunakan `message/send` atau `message/stream`.",
"a2aQuickStartStep3": "Jejak dan kawal tugas menggunakan `tasks/get` dan `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format",
"musicDesc": "Generate music and audio tracks via ComfyUI (Stable Audio, MusicGen)",
"musicGeneration": "Music Generation"
},
"endpoints": {
"tabProxy": "Endpoint Proxy",
@ -1749,7 +1876,22 @@
"close": "Close",
"statusDeactivated": "Deactivated (Manual)",
"statusBanned": "Banned / Sandbox Violation",
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted"
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted",
"noModelsMatch": "No models match \"{filter}\"",
"deselectAllModels": "Deselect all",
"selectAllModels": "Select all",
"repairEnvFailed": "Failed to repair .env",
"audioSpeech": "Audio Speech",
"repairEnvHint": "Restore missing OAuth defaults into .env without overwriting existing values.",
"audioTranscriptions": "Audio Transcriptions",
"embeddings": "Embeddings",
"modelsActiveCount": "{active}/{total} active",
"repairEnvWorking": "Repairing...",
"imagesGenerations": "Images Generations",
"hideEmails": "Hide all emails",
"repairEnvSuccess": "OAuth defaults restored",
"showEmails": "Show all emails",
"repairEnv": "Repair env"
},
"settings": {
"title": "tetapan",
@ -2266,7 +2408,11 @@
"wildcardPatternModeDesc": "Use wildcard aliases with * and ? when a family of models should map to one target.",
"noExactAliasesConfigured": "No exact-match aliases configured.",
"wildcardRulesTitle": "Wildcard Rules",
"noWildcardAliasesConfigured": "No wildcard aliases configured."
"noWildcardAliasesConfigured": "No wildcard aliases configured.",
"contextRelayMaxMessages": "Max Messages For Summary",
"contextRelayHandoffThreshold": "Handoff Threshold",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex accounts and uses these values as global defaults for new or unconfigured combos.",
"contextRelaySummaryModel": "Summary Model"
},
"translator": {
"title": "Penterjemah",
@ -2692,7 +2838,11 @@
"waitingForOpenAIAuthorization": "Menunggu kebenaran OpenAI...",
"waitingForAntigravityAuthorization": "Menunggu kebenaran Antigraviti...",
"waitingForQoderAuthorization": "Menunggu kebenaran Qoder...",
"exchangingCodeForTokens": "Bertukar kod untuk token..."
"exchangingCodeForTokens": "Bertukar kod untuk token...",
"nodeIncompatibleHint": "OmniRoute requires Node.js 20.20.2+ (20.x LTS) or 22.22.2+ (22.x LTS). Node 22 LTS is recommended.",
"nodeIncompatibleTitle": "Incompatible Node.js Version",
"nodeIncompatibleFixLabel": "Fix: install a patched Node.js 22 LTS release",
"nodeIncompatibleDesc": "You are running Node.js {version}, which is outside OmniRoute's supported secure runtime policy. Use a patched Node.js 20.x or 22.x LTS release."
},
"landing": {
"brandName": "OmniRoute",
@ -3108,7 +3258,26 @@
"peakCached": "Peak cached",
"deduplicatedRequests": "Deduplicated Requests",
"savedCalls": "Saved API Calls",
"totalProcessed": "Total Requests Processed"
"totalProcessed": "Total Requests Processed",
"noPromptCacheData": "No provider-side prompt cache activity has been recorded yet.",
"entriesLoadError": "Failed to load semantic cache entries.",
"semanticCache": "Semantic Cache",
"trendHour": "Hour",
"cachedRequests24h": "Cached Requests (24h)",
"semanticCacheDisabledDesc": "Semantic cache is disabled. OmniRoute will skip local response reuse until you turn it back on in Settings.",
"busiestHour": "Busiest Hour",
"noTrendData": "No prompt cache activity has been recorded over the last 24 hours.",
"semanticEntriesDesc": "Persisted semantic cache records currently stored in SQLite. Provider-side prompt cache activity is not listed here.",
"hoursTracked": "hours tracked",
"promptTrendDesc": "Hourly request volume, cache coverage, and cache read volume across the last 24 hours.",
"cacheRate": "Cache Rate",
"activityVolume": "Activity",
"cacheRateDesc": "of total requests",
"peakCacheRate": "Peak Cache Rate",
"promptCacheSectionDesc": "Shows provider-side prompt caching activity from usage history so you can see where cache control is active and how much input reuse you are getting.",
"semanticCacheSectionDesc": "OmniRoute's own deterministic response cache. When enabled, repeated non-streaming temperature=0 requests can be served locally without hitting the upstream provider.",
"providerCacheRateDesc": "Each provider exposes total input tokens, cache read tokens, and cache write tokens so you can verify the reuse ratio against raw totals.",
"lastUpdated": "Last updated"
},
"memory": {
"title": "Memory Management",
@ -3132,7 +3301,8 @@
"factual": "Factual",
"episodic": "Episodic",
"procedural": "Procedural",
"semantic": "Semantic"
"semantic": "Semantic",
"delete": "Delete"
},
"skills": {
"title": "Skills",

View file

@ -136,7 +136,10 @@
"Failed to save pricing": "Kan de prijzen niet opslaan",
"Failed to reset pricing": "Kan de prijzen niet opnieuw instellen",
"apikey": "API-sleutel",
"http": "HTTP"
"http": "HTTP",
"goToDashboard": "Go to Dashboard",
"checkSystemStatus": "Check System Status",
"nothingHere": "Nothing here yet"
},
"sidebar": {
"home": "Thuis",
@ -640,7 +643,8 @@
"opencode": "Gebruik dit wanneer u de voorkeur geeft aan terminal-native agentruns en scriptautomatisering via OpenCode.",
"kiro": "Te gebruiken bij het integreren van Kiro en het centraal beheren van modelrouting vanuit OmniRoute.",
"antigravity": "Gebruik wanneer Antigravity/Kiro-verkeer moet worden onderschept via MITM en naar OmniRoute moet worden gerouteerd.",
"copilot": "Gebruik wanneer u UX in Copilot-chatstijl wilt terwijl u OmniRoute-sleutels en routeringsregels afdwingt."
"copilot": "Gebruik wanneer u UX in Copilot-chatstijl wilt terwijl u OmniRoute-sleutels en routeringsregels afdwingt.",
"windsurf": "Use when you want an AI-first IDE with Codeium/Windsurf models routed through OmniRoute."
},
"toolDescriptions": {
"antigravity": "Google Antigravity IDE met MITM",
@ -655,7 +659,8 @@
"opencode": "OpenCode AI coding agent (Terminal)",
"kiro": "Amazon Kiro — AI-powered IDE",
"windsurf": "Windsurf AI Code Editor",
"copilot": "GitHub Copilot AI Assistant"
"copilot": "GitHub Copilot AI Assistant",
"qwen": "Alibaba Qwen Code CLI"
},
"guides": {
"cursor": {
@ -890,6 +895,16 @@
"when": "Use when you want perfectly even spread — each model used once before repeating.",
"avoid": "Avoid when models have different quality or latency and order matters.",
"example": "Example: Multiple accounts of the same model to distribute usage evenly."
},
"p2c": {
"example": "Example: High-throughput inference across 4+ equivalent model endpoints.",
"avoid": "Avoid for small combos with 2 or fewer models — no benefit over round-robin.",
"when": "Use when you want low-latency selection using Power-of-Two-Choices algorithm."
},
"context-relay": {
"avoid": "Avoid when account switching is rare or when you do not want extra summarization requests.",
"when": "Use when long sessions must survive account rotation without losing the working context.",
"example": "Example: Codex sessions that rotate across multiple accounts near quota exhaustion."
}
},
"advancedHelp": {
@ -1009,7 +1024,117 @@
"wizardStep3Title": "Choose Strategy",
"wizardStep3Desc": "Pick how requests are distributed across your models - 13 strategies available",
"wizardStep4Title": "Review & Save",
"wizardStep4Desc": "Review your configuration and activate the combo"
"wizardStep4Desc": "Review your configuration and activate the combo",
"builderTitle": "Build a Combo",
"explorationRateHint": "{percent}% of requests can explore non-optimal providers.",
"weightTierPriority": "Tier",
"reviewAccounts": "Accounts",
"builderIntelligentDesc": "Configure the multi-factor scoring engine for this auto-routing combo.",
"weightLatencyInv": "Latency",
"advancedWeightsTitle": "Advanced: Scoring Weights",
"filterEmptyIntelligentDescription": "Create an auto or LKGP combo to populate the intelligent routing dashboard.",
"reviewAdvanced": "Advanced Settings",
"reviewName": "Name",
"weightQuota": "Quota",
"modePackLabel": "Mode Pack",
"noExcludedProviders": "No providers are currently excluded.",
"candidatePoolHint": "Select which providers this engine should evaluate. Leave empty to use all active providers.",
"reorderHandle": "Drag to reorder",
"contextRelayDesc": "Preserves session continuity with handoff summaries when accounts rotate",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex account rotation. Pair it with multiple accounts of the same provider for the best continuity.",
"intelligentPanelDesc": "Real-time scoring and health status for this auto-routing combo.",
"builderStage": {
"review": {
"description": "Final validation before saving",
"label": "Review"
},
"intelligent": {
"label": "Smart Routing",
"description": "Auto-routing candidate pool, presets, and scoring"
},
"steps": {
"label": "Steps",
"description": "Provider, model, and account selection"
},
"basics": {
"label": "Basics",
"description": "Name and starting template"
},
"strategy": {
"description": "Routing behavior and advanced settings",
"label": "Strategy"
}
},
"builderProvider": "Provider",
"reviewNoSteps": "No steps configured",
"allProvidersEvaluated": "No candidate pool configured. All active providers are evaluated at runtime.",
"reviewIntelligentTitle": "Intelligent Routing Config",
"activeModePack": "Active Mode Pack",
"builderComboRef": "Combo Ref",
"builderComboRefStep": "Add combo reference",
"builderPreview": "Preview",
"reviewStrategy": "Strategy",
"builderStageLocked": "Locked — complete previous stage first",
"budgetCapPlaceholder": "No limit",
"builderProviderFirst": "Pick provider first",
"reviewProviders": "Providers",
"incidentMode": "Incident Mode",
"reviewSteps": "Steps",
"weightStability": "Stability",
"filterDeterministic": "Deterministic",
"budgetCapLabel": "Budget Cap (USD / request)",
"candidatePoolAllProviders": "All providers",
"builderSelectModel": "Select model",
"routerStrategyLabel": "Router Strategy",
"filterIntelligent": "Intelligent",
"builderLegacyEntry": "Legacy entry",
"contextRelaySummaryModelHelp": "Optional override model used only for generating the handoff summary. Leave empty to reuse the active combo model.",
"filterEmptyTitle": "No combos match this strategy filter.",
"providerScores": "Provider Scores",
"contextRelayMaxMessages": "Max Messages For Summary",
"contextRelayHandoffThresholdHelp": "When quota usage reaches this threshold, OmniRoute generates a structured handoff summary before the active account is exhausted.",
"candidatePoolEmpty": "No active providers available yet.",
"normalOperation": "Normal Operation",
"contextRelaySummaryModel": "Summary Model",
"builderAccount": "Account",
"failedReorder": "Failed to reorder models",
"reviewSequence": "Model Sequence",
"builderStageVisited": "Stage completed",
"excludedProvidersHint": "Providers with an OPEN circuit breaker are temporarily excluded from routing.",
"excludedProviders": "Excluded Providers",
"builderModel": "Model",
"builderAddComboRef": "Add combo reference",
"builderStagePending": "Pending",
"builderPinnedAccount": "Pinned Account",
"builderIntelligentTitle": "Intelligent Routing Configuration",
"weightCostInv": "Cost",
"weightTaskFit": "Task Fit",
"contextRelay": "Context Relay",
"statusOverview": "Status Overview",
"allProvidersHealthy": "Providers are reporting healthy routing conditions.",
"contextRelayMaxMessagesHelp": "Limits how much recent history is condensed into the relay summary.",
"builderAddStep": "Add step",
"modePackUpdated": "Mode pack updated to {pack}.",
"builderLoadingProviders": "Loading providers...",
"modePackHint": "Switch presets to bias the routing engine without rebuilding the combo.",
"builderSelectProvider": "Select provider",
"filterAll": "All",
"builderBrowseCatalog": "Browse catalog",
"builderStageCurrent": "Current stage",
"intelligentPanelTitle": "Intelligent Routing Dashboard",
"explorationRateLabel": "Exploration Rate",
"builderFlowTitle": "Combo Builder Flow",
"reviewAgentFlags": "Agent Flags",
"emailVisibilityStateOff": "Off",
"strategyRules": "Rules (6-Factor Scoring)",
"reviewComboRefs": "Combo References",
"candidatePoolLabel": "Candidate Pool",
"emailVisibilityStateOn": "On",
"contextRelayHandoffThreshold": "Handoff Threshold",
"highCircuitBreakerRate": "High circuit breaker trip rate detected.",
"cooldownMinutes": "Cooldown: {minutes}m",
"filterEmptyDeterministicDescription": "Only auto and LKGP combos exist right now. Switch back to All or create a deterministic combo.",
"weightHealth": "Health"
},
"costs": {
"title": "Kosten",
@ -1147,7 +1272,9 @@
"a2aQuickStartStep2": "Send JSON-RPC requests to `POST /a2a` using `message/send` or `message/stream`.",
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format",
"musicGeneration": "Music Generation",
"musicDesc": "Generate music and audio tracks via ComfyUI (Stable Audio, MusicGen)"
},
"endpoints": {
"tabProxy": "Endpoint Proxy",
@ -1749,7 +1876,22 @@
"close": "Close",
"statusDeactivated": "Deactivated (Manual)",
"statusBanned": "Banned / Sandbox Violation",
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted"
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted",
"audioTranscriptions": "Audio Transcriptions",
"repairEnvFailed": "Failed to repair .env",
"hideEmails": "Hide all emails",
"repairEnvWorking": "Repairing...",
"embeddings": "Embeddings",
"repairEnv": "Repair env",
"repairEnvHint": "Restore missing OAuth defaults into .env without overwriting existing values.",
"noModelsMatch": "No models match \"{filter}\"",
"selectAllModels": "Select all",
"modelsActiveCount": "{active}/{total} active",
"repairEnvSuccess": "OAuth defaults restored",
"deselectAllModels": "Deselect all",
"imagesGenerations": "Images Generations",
"audioSpeech": "Audio Speech",
"showEmails": "Show all emails"
},
"settings": {
"title": "Instellingen",
@ -2266,7 +2408,11 @@
"wildcardPatternModeDesc": "Use wildcard aliases with * and ? when a family of models should map to one target.",
"noExactAliasesConfigured": "No exact-match aliases configured.",
"wildcardRulesTitle": "Wildcard Rules",
"noWildcardAliasesConfigured": "No wildcard aliases configured."
"noWildcardAliasesConfigured": "No wildcard aliases configured.",
"contextRelaySummaryModel": "Summary Model",
"contextRelayMaxMessages": "Max Messages For Summary",
"contextRelayHandoffThreshold": "Handoff Threshold",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex accounts and uses these values as global defaults for new or unconfigured combos."
},
"translator": {
"title": "Vertaler",
@ -2692,7 +2838,11 @@
"waitingForOpenAIAuthorization": "Wachten op OpenAI-autorisatie...",
"waitingForAntigravityAuthorization": "Wachten op toestemming voor anti-zwaartekracht...",
"waitingForQoderAuthorization": "Wachten op Qoder-autorisatie...",
"exchangingCodeForTokens": "Code uitwisselen voor tokens..."
"exchangingCodeForTokens": "Code uitwisselen voor tokens...",
"nodeIncompatibleHint": "OmniRoute requires Node.js 20.20.2+ (20.x LTS) or 22.22.2+ (22.x LTS). Node 22 LTS is recommended.",
"nodeIncompatibleTitle": "Incompatible Node.js Version",
"nodeIncompatibleDesc": "You are running Node.js {version}, which is outside OmniRoute's supported secure runtime policy. Use a patched Node.js 20.x or 22.x LTS release.",
"nodeIncompatibleFixLabel": "Fix: install a patched Node.js 22 LTS release"
},
"landing": {
"brandName": "OmniRoute",
@ -3108,7 +3258,26 @@
"peakCached": "Peak cached",
"deduplicatedRequests": "Deduplicated Requests",
"savedCalls": "Saved API Calls",
"totalProcessed": "Total Requests Processed"
"totalProcessed": "Total Requests Processed",
"hoursTracked": "hours tracked",
"busiestHour": "Busiest Hour",
"lastUpdated": "Last updated",
"activityVolume": "Activity",
"trendHour": "Hour",
"semanticCache": "Semantic Cache",
"noPromptCacheData": "No provider-side prompt cache activity has been recorded yet.",
"semanticEntriesDesc": "Persisted semantic cache records currently stored in SQLite. Provider-side prompt cache activity is not listed here.",
"promptTrendDesc": "Hourly request volume, cache coverage, and cache read volume across the last 24 hours.",
"entriesLoadError": "Failed to load semantic cache entries.",
"cacheRateDesc": "of total requests",
"cachedRequests24h": "Cached Requests (24h)",
"providerCacheRateDesc": "Each provider exposes total input tokens, cache read tokens, and cache write tokens so you can verify the reuse ratio against raw totals.",
"semanticCacheSectionDesc": "OmniRoute's own deterministic response cache. When enabled, repeated non-streaming temperature=0 requests can be served locally without hitting the upstream provider.",
"cacheRate": "Cache Rate",
"promptCacheSectionDesc": "Shows provider-side prompt caching activity from usage history so you can see where cache control is active and how much input reuse you are getting.",
"semanticCacheDisabledDesc": "Semantic cache is disabled. OmniRoute will skip local response reuse until you turn it back on in Settings.",
"noTrendData": "No prompt cache activity has been recorded over the last 24 hours.",
"peakCacheRate": "Peak Cache Rate"
},
"memory": {
"title": "Memory Management",
@ -3132,7 +3301,8 @@
"factual": "Factual",
"episodic": "Episodic",
"procedural": "Procedural",
"semantic": "Semantic"
"semantic": "Semantic",
"delete": "Delete"
},
"skills": {
"title": "Skills",

View file

@ -136,7 +136,10 @@
"Failed to save pricing": "Kunne ikke lagre prisen",
"Failed to reset pricing": "Kunne ikke tilbakestille priser",
"apikey": "API-nøkkel",
"http": "HTTP"
"http": "HTTP",
"goToDashboard": "Go to Dashboard",
"checkSystemStatus": "Check System Status",
"nothingHere": "Nothing here yet"
},
"sidebar": {
"home": "Hjem",
@ -640,7 +643,8 @@
"opencode": "Bruk når du foretrekker terminal-native agentkjøringer og skriptautomatisering via OpenCode.",
"kiro": "Brukes når du integrerer Kiro og kontrollerer modellruting sentralt fra OmniRoute.",
"antigravity": "Brukes når Antigravity/Kiro-trafikk må avskjæres gjennom MITM og rutes til OmniRoute.",
"copilot": "Bruk når du vil ha Copilot chat-stil UX mens du håndhever OmniRoute-nøkler og rutingsregler."
"copilot": "Bruk når du vil ha Copilot chat-stil UX mens du håndhever OmniRoute-nøkler og rutingsregler.",
"windsurf": "Use when you want an AI-first IDE with Codeium/Windsurf models routed through OmniRoute."
},
"toolDescriptions": {
"antigravity": "Google Antigravity IDE med MITM",
@ -655,7 +659,8 @@
"opencode": "OpenCode AI coding agent (Terminal)",
"kiro": "Amazon Kiro — AI-powered IDE",
"windsurf": "Windsurf AI Code Editor",
"copilot": "GitHub Copilot AI Assistant"
"copilot": "GitHub Copilot AI Assistant",
"qwen": "Alibaba Qwen Code CLI"
},
"guides": {
"cursor": {
@ -890,6 +895,16 @@
"when": "Use when you want perfectly even spread — each model used once before repeating.",
"avoid": "Avoid when models have different quality or latency and order matters.",
"example": "Example: Multiple accounts of the same model to distribute usage evenly."
},
"context-relay": {
"example": "Example: Codex sessions that rotate across multiple accounts near quota exhaustion.",
"avoid": "Avoid when account switching is rare or when you do not want extra summarization requests.",
"when": "Use when long sessions must survive account rotation without losing the working context."
},
"p2c": {
"when": "Use when you want low-latency selection using Power-of-Two-Choices algorithm.",
"example": "Example: High-throughput inference across 4+ equivalent model endpoints.",
"avoid": "Avoid for small combos with 2 or fewer models — no benefit over round-robin."
}
},
"advancedHelp": {
@ -1009,7 +1024,117 @@
"wizardStep3Title": "Choose Strategy",
"wizardStep3Desc": "Pick how requests are distributed across your models - 13 strategies available",
"wizardStep4Title": "Review & Save",
"wizardStep4Desc": "Review your configuration and activate the combo"
"wizardStep4Desc": "Review your configuration and activate the combo",
"reviewComboRefs": "Combo References",
"builderAddComboRef": "Add combo reference",
"reviewAgentFlags": "Agent Flags",
"filterAll": "All",
"contextRelayHandoffThresholdHelp": "When quota usage reaches this threshold, OmniRoute generates a structured handoff summary before the active account is exhausted.",
"builderStage": {
"strategy": {
"description": "Routing behavior and advanced settings",
"label": "Strategy"
},
"steps": {
"label": "Steps",
"description": "Provider, model, and account selection"
},
"review": {
"label": "Review",
"description": "Final validation before saving"
},
"intelligent": {
"description": "Auto-routing candidate pool, presets, and scoring",
"label": "Smart Routing"
},
"basics": {
"description": "Name and starting template",
"label": "Basics"
}
},
"cooldownMinutes": "Cooldown: {minutes}m",
"builderAccount": "Account",
"candidatePoolLabel": "Candidate Pool",
"builderLegacyEntry": "Legacy entry",
"builderProviderFirst": "Pick provider first",
"contextRelayMaxMessagesHelp": "Limits how much recent history is condensed into the relay summary.",
"incidentMode": "Incident Mode",
"excludedProvidersHint": "Providers with an OPEN circuit breaker are temporarily excluded from routing.",
"explorationRateLabel": "Exploration Rate",
"contextRelaySummaryModel": "Summary Model",
"noExcludedProviders": "No providers are currently excluded.",
"weightHealth": "Health",
"budgetCapLabel": "Budget Cap (USD / request)",
"intelligentPanelTitle": "Intelligent Routing Dashboard",
"builderTitle": "Build a Combo",
"builderFlowTitle": "Combo Builder Flow",
"filterEmptyDeterministicDescription": "Only auto and LKGP combos exist right now. Switch back to All or create a deterministic combo.",
"builderModel": "Model",
"builderStageCurrent": "Current stage",
"contextRelaySummaryModelHelp": "Optional override model used only for generating the handoff summary. Leave empty to reuse the active combo model.",
"weightTaskFit": "Task Fit",
"builderComboRefStep": "Add combo reference",
"emailVisibilityStateOff": "Off",
"normalOperation": "Normal Operation",
"reorderHandle": "Drag to reorder",
"weightCostInv": "Cost",
"activeModePack": "Active Mode Pack",
"candidatePoolAllProviders": "All providers",
"builderStageLocked": "Locked — complete previous stage first",
"emailVisibilityStateOn": "On",
"providerScores": "Provider Scores",
"excludedProviders": "Excluded Providers",
"filterEmptyTitle": "No combos match this strategy filter.",
"reviewSequence": "Model Sequence",
"contextRelayDesc": "Preserves session continuity with handoff summaries when accounts rotate",
"failedReorder": "Failed to reorder models",
"builderStagePending": "Pending",
"advancedWeightsTitle": "Advanced: Scoring Weights",
"filterEmptyIntelligentDescription": "Create an auto or LKGP combo to populate the intelligent routing dashboard.",
"weightStability": "Stability",
"allProvidersEvaluated": "No candidate pool configured. All active providers are evaluated at runtime.",
"filterIntelligent": "Intelligent",
"builderSelectModel": "Select model",
"explorationRateHint": "{percent}% of requests can explore non-optimal providers.",
"strategyRules": "Rules (6-Factor Scoring)",
"builderComboRef": "Combo Ref",
"builderIntelligentTitle": "Intelligent Routing Configuration",
"builderLoadingProviders": "Loading providers...",
"builderPinnedAccount": "Pinned Account",
"reviewNoSteps": "No steps configured",
"reviewAccounts": "Accounts",
"modePackLabel": "Mode Pack",
"highCircuitBreakerRate": "High circuit breaker trip rate detected.",
"statusOverview": "Status Overview",
"builderProvider": "Provider",
"contextRelay": "Context Relay",
"builderAddStep": "Add step",
"weightQuota": "Quota",
"candidatePoolEmpty": "No active providers available yet.",
"builderBrowseCatalog": "Browse catalog",
"reviewIntelligentTitle": "Intelligent Routing Config",
"contextRelayMaxMessages": "Max Messages For Summary",
"reviewName": "Name",
"intelligentPanelDesc": "Real-time scoring and health status for this auto-routing combo.",
"builderIntelligentDesc": "Configure the multi-factor scoring engine for this auto-routing combo.",
"modePackUpdated": "Mode pack updated to {pack}.",
"reviewSteps": "Steps",
"weightLatencyInv": "Latency",
"builderPreview": "Preview",
"filterDeterministic": "Deterministic",
"reviewAdvanced": "Advanced Settings",
"candidatePoolHint": "Select which providers this engine should evaluate. Leave empty to use all active providers.",
"modePackHint": "Switch presets to bias the routing engine without rebuilding the combo.",
"contextRelayHandoffThreshold": "Handoff Threshold",
"budgetCapPlaceholder": "No limit",
"allProvidersHealthy": "Providers are reporting healthy routing conditions.",
"builderSelectProvider": "Select provider",
"reviewStrategy": "Strategy",
"routerStrategyLabel": "Router Strategy",
"weightTierPriority": "Tier",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex account rotation. Pair it with multiple accounts of the same provider for the best continuity.",
"builderStageVisited": "Stage completed",
"reviewProviders": "Providers"
},
"costs": {
"title": "Kostnader",
@ -1147,7 +1272,9 @@
"a2aQuickStartStep2": "Send JSON-RPC-forespørsler til `POST /a2a` ved å bruke `message/send` eller `message/stream`.",
"a2aQuickStartStep3": "Spor og kontroller oppgaver ved å bruke `tasks/get` og `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format",
"musicDesc": "Generate music and audio tracks via ComfyUI (Stable Audio, MusicGen)",
"musicGeneration": "Music Generation"
},
"endpoints": {
"tabProxy": "Endpoint Proxy",
@ -1749,7 +1876,22 @@
"close": "Close",
"statusDeactivated": "Deactivated (Manual)",
"statusBanned": "Banned / Sandbox Violation",
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted"
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted",
"repairEnvHint": "Restore missing OAuth defaults into .env without overwriting existing values.",
"audioSpeech": "Audio Speech",
"repairEnv": "Repair env",
"hideEmails": "Hide all emails",
"repairEnvWorking": "Repairing...",
"repairEnvFailed": "Failed to repair .env",
"repairEnvSuccess": "OAuth defaults restored",
"selectAllModels": "Select all",
"audioTranscriptions": "Audio Transcriptions",
"imagesGenerations": "Images Generations",
"embeddings": "Embeddings",
"noModelsMatch": "No models match \"{filter}\"",
"deselectAllModels": "Deselect all",
"showEmails": "Show all emails",
"modelsActiveCount": "{active}/{total} active"
},
"settings": {
"title": "Innstillinger",
@ -2266,7 +2408,11 @@
"wildcardPatternModeDesc": "Use wildcard aliases with * and ? when a family of models should map to one target.",
"noExactAliasesConfigured": "No exact-match aliases configured.",
"wildcardRulesTitle": "Wildcard Rules",
"noWildcardAliasesConfigured": "No wildcard aliases configured."
"noWildcardAliasesConfigured": "No wildcard aliases configured.",
"contextRelayHandoffThreshold": "Handoff Threshold",
"contextRelaySummaryModel": "Summary Model",
"contextRelayMaxMessages": "Max Messages For Summary",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex accounts and uses these values as global defaults for new or unconfigured combos."
},
"translator": {
"title": "Oversetter",
@ -2692,7 +2838,11 @@
"waitingForOpenAIAuthorization": "Venter på OpenAI-godkjenning...",
"waitingForAntigravityAuthorization": "Venter på antigravity-autorisasjon...",
"waitingForQoderAuthorization": "Venter på Qoder-autorisasjon...",
"exchangingCodeForTokens": "Utveksler kode for tokens..."
"exchangingCodeForTokens": "Utveksler kode for tokens...",
"nodeIncompatibleHint": "OmniRoute requires Node.js 20.20.2+ (20.x LTS) or 22.22.2+ (22.x LTS). Node 22 LTS is recommended.",
"nodeIncompatibleDesc": "You are running Node.js {version}, which is outside OmniRoute's supported secure runtime policy. Use a patched Node.js 20.x or 22.x LTS release.",
"nodeIncompatibleTitle": "Incompatible Node.js Version",
"nodeIncompatibleFixLabel": "Fix: install a patched Node.js 22 LTS release"
},
"landing": {
"brandName": "OmniRoute",
@ -3108,7 +3258,26 @@
"peakCached": "Peak cached",
"deduplicatedRequests": "Deduplicated Requests",
"savedCalls": "Saved API Calls",
"totalProcessed": "Total Requests Processed"
"totalProcessed": "Total Requests Processed",
"busiestHour": "Busiest Hour",
"cachedRequests24h": "Cached Requests (24h)",
"activityVolume": "Activity",
"semanticCacheSectionDesc": "OmniRoute's own deterministic response cache. When enabled, repeated non-streaming temperature=0 requests can be served locally without hitting the upstream provider.",
"promptCacheSectionDesc": "Shows provider-side prompt caching activity from usage history so you can see where cache control is active and how much input reuse you are getting.",
"promptTrendDesc": "Hourly request volume, cache coverage, and cache read volume across the last 24 hours.",
"peakCacheRate": "Peak Cache Rate",
"cacheRate": "Cache Rate",
"semanticCacheDisabledDesc": "Semantic cache is disabled. OmniRoute will skip local response reuse until you turn it back on in Settings.",
"noTrendData": "No prompt cache activity has been recorded over the last 24 hours.",
"providerCacheRateDesc": "Each provider exposes total input tokens, cache read tokens, and cache write tokens so you can verify the reuse ratio against raw totals.",
"semanticCache": "Semantic Cache",
"lastUpdated": "Last updated",
"trendHour": "Hour",
"cacheRateDesc": "of total requests",
"hoursTracked": "hours tracked",
"noPromptCacheData": "No provider-side prompt cache activity has been recorded yet.",
"semanticEntriesDesc": "Persisted semantic cache records currently stored in SQLite. Provider-side prompt cache activity is not listed here.",
"entriesLoadError": "Failed to load semantic cache entries."
},
"memory": {
"title": "Memory Management",
@ -3132,7 +3301,8 @@
"factual": "Factual",
"episodic": "Episodic",
"procedural": "Procedural",
"semantic": "Semantic"
"semantic": "Semantic",
"delete": "Delete"
},
"skills": {
"title": "Skills",

View file

@ -136,7 +136,10 @@
"Failed to save pricing": "Nabigong i-save ang pagpepresyo",
"Failed to reset pricing": "Nabigong i-reset ang pagpepresyo",
"apikey": "API Key",
"http": "HTTP"
"http": "HTTP",
"checkSystemStatus": "Check System Status",
"nothingHere": "Nothing here yet",
"goToDashboard": "Go to Dashboard"
},
"sidebar": {
"home": "Bahay",
@ -640,7 +643,8 @@
"opencode": "Gamitin kapag mas gusto mo ang terminal-native agent run at scripted automation sa pamamagitan ng OpenCode.",
"kiro": "Gamitin kapag isinasama ang Kiro at kinokontrol ang pagruruta ng modelo sa gitna mula sa OmniRoute.",
"antigravity": "Gamitin kapag ang trapiko ng Antigravity/Kiro ay dapat ma-intercept sa MITM at iruta sa OmniRoute.",
"copilot": "Gamitin kapag gusto mong Copilot chat style UX habang ipinapatupad ang mga OmniRoute key at mga panuntunan sa pagruruta."
"copilot": "Gamitin kapag gusto mong Copilot chat style UX habang ipinapatupad ang mga OmniRoute key at mga panuntunan sa pagruruta.",
"windsurf": "Use when you want an AI-first IDE with Codeium/Windsurf models routed through OmniRoute."
},
"toolDescriptions": {
"antigravity": "Google Antigravity IDE na may MITM",
@ -655,7 +659,8 @@
"opencode": "OpenCode AI coding agent (Terminal)",
"kiro": "Amazon Kiro — AI-powered IDE",
"windsurf": "Windsurf AI Code Editor",
"copilot": "GitHub Copilot AI Assistant"
"copilot": "GitHub Copilot AI Assistant",
"qwen": "Alibaba Qwen Code CLI"
},
"guides": {
"cursor": {
@ -890,6 +895,16 @@
"when": "Use when you want perfectly even spread — each model used once before repeating.",
"avoid": "Avoid when models have different quality or latency and order matters.",
"example": "Example: Multiple accounts of the same model to distribute usage evenly."
},
"context-relay": {
"example": "Example: Codex sessions that rotate across multiple accounts near quota exhaustion.",
"when": "Use when long sessions must survive account rotation without losing the working context.",
"avoid": "Avoid when account switching is rare or when you do not want extra summarization requests."
},
"p2c": {
"when": "Use when you want low-latency selection using Power-of-Two-Choices algorithm.",
"example": "Example: High-throughput inference across 4+ equivalent model endpoints.",
"avoid": "Avoid for small combos with 2 or fewer models — no benefit over round-robin."
}
},
"advancedHelp": {
@ -1009,7 +1024,117 @@
"wizardStep3Title": "Choose Strategy",
"wizardStep3Desc": "Pick how requests are distributed across your models - 13 strategies available",
"wizardStep4Title": "Review & Save",
"wizardStep4Desc": "Review your configuration and activate the combo"
"wizardStep4Desc": "Review your configuration and activate the combo",
"filterEmptyIntelligentDescription": "Create an auto or LKGP combo to populate the intelligent routing dashboard.",
"contextRelaySummaryModel": "Summary Model",
"filterIntelligent": "Intelligent",
"normalOperation": "Normal Operation",
"strategyRules": "Rules (6-Factor Scoring)",
"providerScores": "Provider Scores",
"modePackHint": "Switch presets to bias the routing engine without rebuilding the combo.",
"builderStageLocked": "Locked — complete previous stage first",
"weightLatencyInv": "Latency",
"intelligentPanelTitle": "Intelligent Routing Dashboard",
"candidatePoolHint": "Select which providers this engine should evaluate. Leave empty to use all active providers.",
"emailVisibilityStateOff": "Off",
"statusOverview": "Status Overview",
"incidentMode": "Incident Mode",
"reviewName": "Name",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex account rotation. Pair it with multiple accounts of the same provider for the best continuity.",
"builderProvider": "Provider",
"builderStageCurrent": "Current stage",
"contextRelayHandoffThresholdHelp": "When quota usage reaches this threshold, OmniRoute generates a structured handoff summary before the active account is exhausted.",
"builderStage": {
"steps": {
"label": "Steps",
"description": "Provider, model, and account selection"
},
"strategy": {
"description": "Routing behavior and advanced settings",
"label": "Strategy"
},
"intelligent": {
"label": "Smart Routing",
"description": "Auto-routing candidate pool, presets, and scoring"
},
"review": {
"label": "Review",
"description": "Final validation before saving"
},
"basics": {
"label": "Basics",
"description": "Name and starting template"
}
},
"failedReorder": "Failed to reorder models",
"reorderHandle": "Drag to reorder",
"builderAddStep": "Add step",
"reviewComboRefs": "Combo References",
"builderPreview": "Preview",
"builderLegacyEntry": "Legacy entry",
"allProvidersHealthy": "Providers are reporting healthy routing conditions.",
"excludedProvidersHint": "Providers with an OPEN circuit breaker are temporarily excluded from routing.",
"filterAll": "All",
"contextRelay": "Context Relay",
"modePackLabel": "Mode Pack",
"contextRelaySummaryModelHelp": "Optional override model used only for generating the handoff summary. Leave empty to reuse the active combo model.",
"allProvidersEvaluated": "No candidate pool configured. All active providers are evaluated at runtime.",
"excludedProviders": "Excluded Providers",
"builderFlowTitle": "Combo Builder Flow",
"filterEmptyDeterministicDescription": "Only auto and LKGP combos exist right now. Switch back to All or create a deterministic combo.",
"contextRelayMaxMessages": "Max Messages For Summary",
"contextRelayHandoffThreshold": "Handoff Threshold",
"cooldownMinutes": "Cooldown: {minutes}m",
"reviewAgentFlags": "Agent Flags",
"weightHealth": "Health",
"builderModel": "Model",
"filterEmptyTitle": "No combos match this strategy filter.",
"reviewSteps": "Steps",
"budgetCapPlaceholder": "No limit",
"filterDeterministic": "Deterministic",
"modePackUpdated": "Mode pack updated to {pack}.",
"budgetCapLabel": "Budget Cap (USD / request)",
"builderAccount": "Account",
"reviewNoSteps": "No steps configured",
"explorationRateHint": "{percent}% of requests can explore non-optimal providers.",
"builderComboRef": "Combo Ref",
"routerStrategyLabel": "Router Strategy",
"builderPinnedAccount": "Pinned Account",
"reviewSequence": "Model Sequence",
"reviewStrategy": "Strategy",
"builderSelectProvider": "Select provider",
"candidatePoolAllProviders": "All providers",
"reviewIntelligentTitle": "Intelligent Routing Config",
"builderBrowseCatalog": "Browse catalog",
"weightTaskFit": "Task Fit",
"contextRelayMaxMessagesHelp": "Limits how much recent history is condensed into the relay summary.",
"advancedWeightsTitle": "Advanced: Scoring Weights",
"builderStagePending": "Pending",
"intelligentPanelDesc": "Real-time scoring and health status for this auto-routing combo.",
"builderIntelligentDesc": "Configure the multi-factor scoring engine for this auto-routing combo.",
"weightCostInv": "Cost",
"builderLoadingProviders": "Loading providers...",
"builderComboRefStep": "Add combo reference",
"builderIntelligentTitle": "Intelligent Routing Configuration",
"highCircuitBreakerRate": "High circuit breaker trip rate detected.",
"weightStability": "Stability",
"candidatePoolLabel": "Candidate Pool",
"noExcludedProviders": "No providers are currently excluded.",
"weightTierPriority": "Tier",
"contextRelayDesc": "Preserves session continuity with handoff summaries when accounts rotate",
"reviewProviders": "Providers",
"builderSelectModel": "Select model",
"builderAddComboRef": "Add combo reference",
"reviewAccounts": "Accounts",
"builderProviderFirst": "Pick provider first",
"explorationRateLabel": "Exploration Rate",
"activeModePack": "Active Mode Pack",
"builderTitle": "Build a Combo",
"emailVisibilityStateOn": "On",
"builderStageVisited": "Stage completed",
"candidatePoolEmpty": "No active providers available yet.",
"weightQuota": "Quota",
"reviewAdvanced": "Advanced Settings"
},
"costs": {
"title": "Mga gastos",
@ -1147,7 +1272,9 @@
"a2aQuickStartStep2": "Send JSON-RPC requests to `POST /a2a` using `message/send` or `message/stream`.",
"a2aQuickStartStep3": "Subaybayan at kontrolin ang mga gawain gamit ang `tasks/get` at `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format",
"musicDesc": "Generate music and audio tracks via ComfyUI (Stable Audio, MusicGen)",
"musicGeneration": "Music Generation"
},
"endpoints": {
"tabProxy": "Endpoint Proxy",
@ -1749,7 +1876,22 @@
"close": "Close",
"statusDeactivated": "Deactivated (Manual)",
"statusBanned": "Banned / Sandbox Violation",
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted"
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted",
"hideEmails": "Hide all emails",
"imagesGenerations": "Images Generations",
"audioSpeech": "Audio Speech",
"repairEnvSuccess": "OAuth defaults restored",
"audioTranscriptions": "Audio Transcriptions",
"showEmails": "Show all emails",
"modelsActiveCount": "{active}/{total} active",
"repairEnvFailed": "Failed to repair .env",
"repairEnv": "Repair env",
"embeddings": "Embeddings",
"selectAllModels": "Select all",
"deselectAllModels": "Deselect all",
"repairEnvWorking": "Repairing...",
"noModelsMatch": "No models match \"{filter}\"",
"repairEnvHint": "Restore missing OAuth defaults into .env without overwriting existing values."
},
"settings": {
"title": "Mga setting",
@ -2266,7 +2408,11 @@
"wildcardPatternModeDesc": "Use wildcard aliases with * and ? when a family of models should map to one target.",
"noExactAliasesConfigured": "No exact-match aliases configured.",
"wildcardRulesTitle": "Wildcard Rules",
"noWildcardAliasesConfigured": "No wildcard aliases configured."
"noWildcardAliasesConfigured": "No wildcard aliases configured.",
"contextRelayMaxMessages": "Max Messages For Summary",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex accounts and uses these values as global defaults for new or unconfigured combos.",
"contextRelayHandoffThreshold": "Handoff Threshold",
"contextRelaySummaryModel": "Summary Model"
},
"translator": {
"title": "Tagasalin",
@ -2692,7 +2838,11 @@
"waitingForOpenAIAuthorization": "Naghihintay ng awtorisasyon sa OpenAI...",
"waitingForAntigravityAuthorization": "Naghihintay ng awtorisasyon sa Antigravity...",
"waitingForQoderAuthorization": "Naghihintay ng awtorisasyon ng Qoder...",
"exchangingCodeForTokens": "Pagpapalit ng code para sa mga token..."
"exchangingCodeForTokens": "Pagpapalit ng code para sa mga token...",
"nodeIncompatibleTitle": "Incompatible Node.js Version",
"nodeIncompatibleHint": "OmniRoute requires Node.js 20.20.2+ (20.x LTS) or 22.22.2+ (22.x LTS). Node 22 LTS is recommended.",
"nodeIncompatibleFixLabel": "Fix: install a patched Node.js 22 LTS release",
"nodeIncompatibleDesc": "You are running Node.js {version}, which is outside OmniRoute's supported secure runtime policy. Use a patched Node.js 20.x or 22.x LTS release."
},
"landing": {
"brandName": "OmniRoute",
@ -3108,7 +3258,26 @@
"peakCached": "Peak cached",
"deduplicatedRequests": "Deduplicated Requests",
"savedCalls": "Saved API Calls",
"totalProcessed": "Total Requests Processed"
"totalProcessed": "Total Requests Processed",
"lastUpdated": "Last updated",
"semanticCache": "Semantic Cache",
"semanticCacheDisabledDesc": "Semantic cache is disabled. OmniRoute will skip local response reuse until you turn it back on in Settings.",
"semanticEntriesDesc": "Persisted semantic cache records currently stored in SQLite. Provider-side prompt cache activity is not listed here.",
"activityVolume": "Activity",
"peakCacheRate": "Peak Cache Rate",
"busiestHour": "Busiest Hour",
"providerCacheRateDesc": "Each provider exposes total input tokens, cache read tokens, and cache write tokens so you can verify the reuse ratio against raw totals.",
"promptTrendDesc": "Hourly request volume, cache coverage, and cache read volume across the last 24 hours.",
"noTrendData": "No prompt cache activity has been recorded over the last 24 hours.",
"cachedRequests24h": "Cached Requests (24h)",
"cacheRateDesc": "of total requests",
"semanticCacheSectionDesc": "OmniRoute's own deterministic response cache. When enabled, repeated non-streaming temperature=0 requests can be served locally without hitting the upstream provider.",
"hoursTracked": "hours tracked",
"cacheRate": "Cache Rate",
"noPromptCacheData": "No provider-side prompt cache activity has been recorded yet.",
"promptCacheSectionDesc": "Shows provider-side prompt caching activity from usage history so you can see where cache control is active and how much input reuse you are getting.",
"entriesLoadError": "Failed to load semantic cache entries.",
"trendHour": "Hour"
},
"memory": {
"title": "Memory Management",
@ -3132,7 +3301,8 @@
"factual": "Factual",
"episodic": "Episodic",
"procedural": "Procedural",
"semantic": "Semantic"
"semantic": "Semantic",
"delete": "Delete"
},
"skills": {
"title": "Skills",

View file

@ -136,7 +136,10 @@
"Failed to save pricing": "Nie udało się zapisać cen",
"Failed to reset pricing": "Nie udało się zresetować cen",
"apikey": "Klucz API",
"http": "HTTP"
"http": "HTTP",
"goToDashboard": "Go to Dashboard",
"nothingHere": "Nothing here yet",
"checkSystemStatus": "Check System Status"
},
"sidebar": {
"home": "Dom",
@ -640,7 +643,8 @@
"opencode": "Użyj, jeśli wolisz uruchamianie agentów natywnych w terminalu i automatyzację skryptów za pośrednictwem OpenCode.",
"kiro": "Użyj podczas integracji Kiro i centralnego sterowania routingiem modeli z OmniRoute.",
"antigravity": "Użyj, gdy ruch antygrawitacyjny/Kiro musi zostać przechwycony przez MITM i skierowany do OmniRoute.",
"copilot": "Użyj, jeśli chcesz mieć UX w stylu czatu Copilot, jednocześnie wymuszając klucze OmniRoute i reguły routingu."
"copilot": "Użyj, jeśli chcesz mieć UX w stylu czatu Copilot, jednocześnie wymuszając klucze OmniRoute i reguły routingu.",
"windsurf": "Use when you want an AI-first IDE with Codeium/Windsurf models routed through OmniRoute."
},
"toolDescriptions": {
"antigravity": "Google Antigravity IDE z MITM",
@ -655,7 +659,8 @@
"opencode": "OpenCode AI coding agent (Terminal)",
"kiro": "Amazon Kiro — AI-powered IDE",
"windsurf": "Windsurf AI Code Editor",
"copilot": "GitHub Copilot AI Assistant"
"copilot": "GitHub Copilot AI Assistant",
"qwen": "Alibaba Qwen Code CLI"
},
"guides": {
"cursor": {
@ -890,6 +895,16 @@
"when": "Use when you want perfectly even spread — each model used once before repeating.",
"avoid": "Avoid when models have different quality or latency and order matters.",
"example": "Example: Multiple accounts of the same model to distribute usage evenly."
},
"p2c": {
"avoid": "Avoid for small combos with 2 or fewer models — no benefit over round-robin.",
"example": "Example: High-throughput inference across 4+ equivalent model endpoints.",
"when": "Use when you want low-latency selection using Power-of-Two-Choices algorithm."
},
"context-relay": {
"example": "Example: Codex sessions that rotate across multiple accounts near quota exhaustion.",
"avoid": "Avoid when account switching is rare or when you do not want extra summarization requests.",
"when": "Use when long sessions must survive account rotation without losing the working context."
}
},
"advancedHelp": {
@ -1009,7 +1024,117 @@
"wizardStep3Title": "Choose Strategy",
"wizardStep3Desc": "Pick how requests are distributed across your models - 13 strategies available",
"wizardStep4Title": "Review & Save",
"wizardStep4Desc": "Review your configuration and activate the combo"
"wizardStep4Desc": "Review your configuration and activate the combo",
"budgetCapLabel": "Budget Cap (USD / request)",
"contextRelayMaxMessagesHelp": "Limits how much recent history is condensed into the relay summary.",
"modePackUpdated": "Mode pack updated to {pack}.",
"filterEmptyDeterministicDescription": "Only auto and LKGP combos exist right now. Switch back to All or create a deterministic combo.",
"excludedProvidersHint": "Providers with an OPEN circuit breaker are temporarily excluded from routing.",
"reviewSteps": "Steps",
"reviewAccounts": "Accounts",
"reorderHandle": "Drag to reorder",
"contextRelaySummaryModel": "Summary Model",
"filterAll": "All",
"activeModePack": "Active Mode Pack",
"advancedWeightsTitle": "Advanced: Scoring Weights",
"providerScores": "Provider Scores",
"builderStage": {
"strategy": {
"label": "Strategy",
"description": "Routing behavior and advanced settings"
},
"basics": {
"label": "Basics",
"description": "Name and starting template"
},
"steps": {
"description": "Provider, model, and account selection",
"label": "Steps"
},
"intelligent": {
"description": "Auto-routing candidate pool, presets, and scoring",
"label": "Smart Routing"
},
"review": {
"description": "Final validation before saving",
"label": "Review"
}
},
"reviewAgentFlags": "Agent Flags",
"filterIntelligent": "Intelligent",
"builderLoadingProviders": "Loading providers...",
"contextRelayDesc": "Preserves session continuity with handoff summaries when accounts rotate",
"excludedProviders": "Excluded Providers",
"allProvidersHealthy": "Providers are reporting healthy routing conditions.",
"weightLatencyInv": "Latency",
"builderIntelligentTitle": "Intelligent Routing Configuration",
"builderLegacyEntry": "Legacy entry",
"weightTaskFit": "Task Fit",
"weightQuota": "Quota",
"builderSelectModel": "Select model",
"filterEmptyTitle": "No combos match this strategy filter.",
"builderProviderFirst": "Pick provider first",
"reviewName": "Name",
"builderStageLocked": "Locked — complete previous stage first",
"builderProvider": "Provider",
"budgetCapPlaceholder": "No limit",
"builderStageVisited": "Stage completed",
"filterEmptyIntelligentDescription": "Create an auto or LKGP combo to populate the intelligent routing dashboard.",
"builderTitle": "Build a Combo",
"builderAccount": "Account",
"weightHealth": "Health",
"contextRelayMaxMessages": "Max Messages For Summary",
"candidatePoolHint": "Select which providers this engine should evaluate. Leave empty to use all active providers.",
"weightTierPriority": "Tier",
"emailVisibilityStateOn": "On",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex account rotation. Pair it with multiple accounts of the same provider for the best continuity.",
"builderComboRefStep": "Add combo reference",
"reviewStrategy": "Strategy",
"builderSelectProvider": "Select provider",
"filterDeterministic": "Deterministic",
"reviewComboRefs": "Combo References",
"builderAddComboRef": "Add combo reference",
"reviewIntelligentTitle": "Intelligent Routing Config",
"modePackLabel": "Mode Pack",
"builderBrowseCatalog": "Browse catalog",
"explorationRateHint": "{percent}% of requests can explore non-optimal providers.",
"builderAddStep": "Add step",
"modePackHint": "Switch presets to bias the routing engine without rebuilding the combo.",
"intelligentPanelDesc": "Real-time scoring and health status for this auto-routing combo.",
"weightStability": "Stability",
"allProvidersEvaluated": "No candidate pool configured. All active providers are evaluated at runtime.",
"builderStageCurrent": "Current stage",
"failedReorder": "Failed to reorder models",
"intelligentPanelTitle": "Intelligent Routing Dashboard",
"reviewProviders": "Providers",
"contextRelayHandoffThresholdHelp": "When quota usage reaches this threshold, OmniRoute generates a structured handoff summary before the active account is exhausted.",
"noExcludedProviders": "No providers are currently excluded.",
"builderIntelligentDesc": "Configure the multi-factor scoring engine for this auto-routing combo.",
"cooldownMinutes": "Cooldown: {minutes}m",
"statusOverview": "Status Overview",
"contextRelayHandoffThreshold": "Handoff Threshold",
"builderPreview": "Preview",
"builderStagePending": "Pending",
"builderModel": "Model",
"highCircuitBreakerRate": "High circuit breaker trip rate detected.",
"strategyRules": "Rules (6-Factor Scoring)",
"candidatePoolAllProviders": "All providers",
"reviewAdvanced": "Advanced Settings",
"reviewSequence": "Model Sequence",
"reviewNoSteps": "No steps configured",
"contextRelaySummaryModelHelp": "Optional override model used only for generating the handoff summary. Leave empty to reuse the active combo model.",
"weightCostInv": "Cost",
"incidentMode": "Incident Mode",
"candidatePoolLabel": "Candidate Pool",
"candidatePoolEmpty": "No active providers available yet.",
"normalOperation": "Normal Operation",
"builderFlowTitle": "Combo Builder Flow",
"contextRelay": "Context Relay",
"explorationRateLabel": "Exploration Rate",
"emailVisibilityStateOff": "Off",
"builderComboRef": "Combo Ref",
"builderPinnedAccount": "Pinned Account",
"routerStrategyLabel": "Router Strategy"
},
"costs": {
"title": "Koszty",
@ -1147,7 +1272,9 @@
"a2aQuickStartStep2": "Send JSON-RPC requests to `POST /a2a` using `message/send` or `message/stream`.",
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format",
"musicGeneration": "Music Generation",
"musicDesc": "Generate music and audio tracks via ComfyUI (Stable Audio, MusicGen)"
},
"endpoints": {
"tabProxy": "Endpoint Proxy",
@ -1749,7 +1876,22 @@
"close": "Close",
"statusDeactivated": "Deactivated (Manual)",
"statusBanned": "Banned / Sandbox Violation",
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted"
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted",
"audioTranscriptions": "Audio Transcriptions",
"repairEnvWorking": "Repairing...",
"hideEmails": "Hide all emails",
"modelsActiveCount": "{active}/{total} active",
"embeddings": "Embeddings",
"selectAllModels": "Select all",
"showEmails": "Show all emails",
"audioSpeech": "Audio Speech",
"deselectAllModels": "Deselect all",
"repairEnv": "Repair env",
"repairEnvFailed": "Failed to repair .env",
"imagesGenerations": "Images Generations",
"noModelsMatch": "No models match \"{filter}\"",
"repairEnvHint": "Restore missing OAuth defaults into .env without overwriting existing values.",
"repairEnvSuccess": "OAuth defaults restored"
},
"settings": {
"title": "Ustawienia",
@ -2266,7 +2408,11 @@
"wildcardPatternModeDesc": "Use wildcard aliases with * and ? when a family of models should map to one target.",
"noExactAliasesConfigured": "No exact-match aliases configured.",
"wildcardRulesTitle": "Wildcard Rules",
"noWildcardAliasesConfigured": "No wildcard aliases configured."
"noWildcardAliasesConfigured": "No wildcard aliases configured.",
"contextRelayMaxMessages": "Max Messages For Summary",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex accounts and uses these values as global defaults for new or unconfigured combos.",
"contextRelayHandoffThreshold": "Handoff Threshold",
"contextRelaySummaryModel": "Summary Model"
},
"translator": {
"title": "Tłumacz",
@ -2692,7 +2838,11 @@
"waitingForOpenAIAuthorization": "Waiting for OpenAI authorization...",
"waitingForAntigravityAuthorization": "Waiting for Antigravity authorization...",
"waitingForQoderAuthorization": "Waiting for Qoder authorization...",
"exchangingCodeForTokens": "Exchanging code for tokens..."
"exchangingCodeForTokens": "Exchanging code for tokens...",
"nodeIncompatibleDesc": "You are running Node.js {version}, which is outside OmniRoute's supported secure runtime policy. Use a patched Node.js 20.x or 22.x LTS release.",
"nodeIncompatibleFixLabel": "Fix: install a patched Node.js 22 LTS release",
"nodeIncompatibleHint": "OmniRoute requires Node.js 20.20.2+ (20.x LTS) or 22.22.2+ (22.x LTS). Node 22 LTS is recommended.",
"nodeIncompatibleTitle": "Incompatible Node.js Version"
},
"landing": {
"brandName": "OmniRoute",
@ -3108,7 +3258,26 @@
"peakCached": "Peak cached",
"deduplicatedRequests": "Deduplicated Requests",
"savedCalls": "Saved API Calls",
"totalProcessed": "Total Requests Processed"
"totalProcessed": "Total Requests Processed",
"cacheRate": "Cache Rate",
"promptCacheSectionDesc": "Shows provider-side prompt caching activity from usage history so you can see where cache control is active and how much input reuse you are getting.",
"activityVolume": "Activity",
"hoursTracked": "hours tracked",
"semanticCacheSectionDesc": "OmniRoute's own deterministic response cache. When enabled, repeated non-streaming temperature=0 requests can be served locally without hitting the upstream provider.",
"semanticEntriesDesc": "Persisted semantic cache records currently stored in SQLite. Provider-side prompt cache activity is not listed here.",
"entriesLoadError": "Failed to load semantic cache entries.",
"noPromptCacheData": "No provider-side prompt cache activity has been recorded yet.",
"semanticCache": "Semantic Cache",
"cacheRateDesc": "of total requests",
"cachedRequests24h": "Cached Requests (24h)",
"noTrendData": "No prompt cache activity has been recorded over the last 24 hours.",
"lastUpdated": "Last updated",
"providerCacheRateDesc": "Each provider exposes total input tokens, cache read tokens, and cache write tokens so you can verify the reuse ratio against raw totals.",
"trendHour": "Hour",
"busiestHour": "Busiest Hour",
"promptTrendDesc": "Hourly request volume, cache coverage, and cache read volume across the last 24 hours.",
"semanticCacheDisabledDesc": "Semantic cache is disabled. OmniRoute will skip local response reuse until you turn it back on in Settings.",
"peakCacheRate": "Peak Cache Rate"
},
"memory": {
"title": "Memory Management",
@ -3132,7 +3301,8 @@
"factual": "Factual",
"episodic": "Episodic",
"procedural": "Procedural",
"semantic": "Semantic"
"semantic": "Semantic",
"delete": "Delete"
},
"skills": {
"title": "Skills",

View file

@ -136,7 +136,10 @@
"Failed to save pricing": "Falha ao salvar o preço",
"Failed to reset pricing": "Falha ao redefinir o preço",
"apikey": "Chave de API",
"http": "HTTP"
"http": "HTTP",
"nothingHere": "Nothing here yet",
"checkSystemStatus": "Check System Status",
"goToDashboard": "Go to Dashboard"
},
"sidebar": {
"home": "Início",
@ -640,7 +643,8 @@
"opencode": "Use quando preferir execuções de agentes nativos de terminal e automação com script via OpenCode.",
"kiro": "Use ao integrar o Kiro e controlar o roteamento do modelo centralmente no OmniRoute.",
"antigravity": "Use quando o tráfego Antigravity/Kiro deve ser interceptado através do MITM e roteado para OmniRoute.",
"copilot": "Use quando desejar UX no estilo de bate-papo do Copilot enquanto impõe chaves OmniRoute e regras de roteamento."
"copilot": "Use quando desejar UX no estilo de bate-papo do Copilot enquanto impõe chaves OmniRoute e regras de roteamento.",
"windsurf": "Use when you want an AI-first IDE with Codeium/Windsurf models routed through OmniRoute."
},
"toolDescriptions": {
"antigravity": "Google Antigravity IDE com MITM",
@ -655,7 +659,8 @@
"opencode": "OpenCode AI coding agent (Terminal)",
"kiro": "Amazon Kiro — IDE com IA",
"windsurf": "Windsurf — Editor de Código com IA",
"copilot": "GitHub Copilot — Assistente de IA"
"copilot": "GitHub Copilot — Assistente de IA",
"qwen": "Alibaba Qwen Code CLI"
},
"guides": {
"cursor": {
@ -899,6 +904,16 @@
"when": "Você quer distribuição perfeitamente uniforme — cada modelo é usado uma vez antes de repetir.",
"avoid": "Os modelos têm qualidade ou latência muito diferentes e a ordem importa.",
"example": "Múltiplas contas do mesmo modelo para distribuir uso de forma equilibrada."
},
"p2c": {
"avoid": "Avoid for small combos with 2 or fewer models — no benefit over round-robin.",
"example": "Example: High-throughput inference across 4+ equivalent model endpoints.",
"when": "Use when you want low-latency selection using Power-of-Two-Choices algorithm."
},
"context-relay": {
"avoid": "Avoid when account switching is rare or when you do not want extra summarization requests.",
"when": "Use when long sessions must survive account rotation without losing the working context.",
"example": "Example: Codex sessions that rotate across multiple accounts near quota exhaustion."
}
},
"advancedHelp": {
@ -1018,7 +1033,108 @@
"wizardStep3Title": "Choose Strategy",
"wizardStep3Desc": "Pick how requests are distributed across your models - 13 strategies available",
"wizardStep4Title": "Review & Save",
"wizardStep4Desc": "Review your configuration and activate the combo"
"wizardStep4Desc": "Review your configuration and activate the combo",
"builderPreview": "Preview",
"builderStage": {
"strategy": {
"label": "Strategy",
"description": "Routing behavior and advanced settings"
},
"review": {
"description": "Final validation before saving",
"label": "Review"
},
"basics": {
"label": "Basics",
"description": "Name and starting template"
},
"steps": {
"label": "Steps",
"description": "Provider, model, and account selection"
},
"intelligent": {
"label": "Smart Routing",
"description": "Auto-routing candidate pool, presets, and scoring"
}
},
"routerStrategyLabel": "Router Strategy",
"emailVisibilityStateOn": "On",
"reviewAdvanced": "Advanced Settings",
"reviewComboRefs": "Combo References",
"weightStability": "Stability",
"excludedProvidersHint": "Providers with an OPEN circuit breaker are temporarily excluded from routing.",
"builderIntelligentTitle": "Intelligent Routing Configuration",
"builderComboRefStep": "Add combo reference",
"builderStageCurrent": "Current stage",
"builderStageVisited": "Stage completed",
"builderAccount": "Account",
"explorationRateLabel": "Exploration Rate",
"excludedProviders": "Excluded Providers",
"weightLatencyInv": "Latency",
"reorderHandle": "Drag to reorder",
"builderTitle": "Build a Combo",
"builderProviderFirst": "Pick provider first",
"intelligentPanelDesc": "Real-time scoring and health status for this auto-routing combo.",
"statusOverview": "Status Overview",
"filterEmptyTitle": "No combos match this strategy filter.",
"builderStageLocked": "Locked — complete previous stage first",
"builderPinnedAccount": "Pinned Account",
"budgetCapLabel": "Budget Cap (USD / request)",
"modePackUpdated": "Mode pack updated to {pack}.",
"incidentMode": "Incident Mode",
"providerScores": "Provider Scores",
"noExcludedProviders": "No providers are currently excluded.",
"normalOperation": "Normal Operation",
"reviewProviders": "Providers",
"builderSelectModel": "Select model",
"filterEmptyDeterministicDescription": "Only auto and LKGP combos exist right now. Switch back to All or create a deterministic combo.",
"builderFlowTitle": "Combo Builder Flow",
"highCircuitBreakerRate": "High circuit breaker trip rate detected.",
"filterIntelligent": "Intelligent",
"weightTierPriority": "Tier",
"intelligentPanelTitle": "Intelligent Routing Dashboard",
"candidatePoolHint": "Select which providers this engine should evaluate. Leave empty to use all active providers.",
"filterDeterministic": "Deterministic",
"builderSelectProvider": "Select provider",
"modePackHint": "Switch presets to bias the routing engine without rebuilding the combo.",
"budgetCapPlaceholder": "No limit",
"builderAddStep": "Add step",
"builderLegacyEntry": "Legacy entry",
"allProvidersHealthy": "Providers are reporting healthy routing conditions.",
"filterAll": "All",
"candidatePoolEmpty": "No active providers available yet.",
"allProvidersEvaluated": "No candidate pool configured. All active providers are evaluated at runtime.",
"builderComboRef": "Combo Ref",
"builderLoadingProviders": "Loading providers...",
"emailVisibilityStateOff": "Off",
"reviewSequence": "Model Sequence",
"reviewSteps": "Steps",
"candidatePoolLabel": "Candidate Pool",
"reviewAgentFlags": "Agent Flags",
"cooldownMinutes": "Cooldown: {minutes}m",
"modePackLabel": "Mode Pack",
"reviewName": "Name",
"weightHealth": "Health",
"explorationRateHint": "{percent}% of requests can explore non-optimal providers.",
"activeModePack": "Active Mode Pack",
"reviewStrategy": "Strategy",
"candidatePoolAllProviders": "All providers",
"advancedWeightsTitle": "Advanced: Scoring Weights",
"reviewIntelligentTitle": "Intelligent Routing Config",
"filterEmptyIntelligentDescription": "Create an auto or LKGP combo to populate the intelligent routing dashboard.",
"failedReorder": "Failed to reorder models",
"builderBrowseCatalog": "Browse catalog",
"weightTaskFit": "Task Fit",
"builderProvider": "Provider",
"reviewAccounts": "Accounts",
"strategyRules": "Rules (6-Factor Scoring)",
"weightCostInv": "Cost",
"builderAddComboRef": "Add combo reference",
"weightQuota": "Quota",
"reviewNoSteps": "No steps configured",
"builderModel": "Model",
"builderStagePending": "Pending",
"builderIntelligentDesc": "Configure the multi-factor scoring engine for this auto-routing combo."
},
"costs": {
"title": "Custos",
@ -1156,7 +1272,9 @@
"a2aQuickStartStep2": "Envie requisições JSON-RPC para `POST /a2a` usando `message/send` ou `message/stream`.",
"a2aQuickStartStep3": "Acompanhe e controle tarefas com `tasks/get` e `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format",
"musicDesc": "Generate music and audio tracks via ComfyUI (Stable Audio, MusicGen)",
"musicGeneration": "Music Generation"
},
"endpoints": {
"tabProxy": "Endpoint Proxy",
@ -1314,7 +1432,8 @@
"factual": "Factual",
"episodic": "Episódica",
"procedural": "Procedural",
"semantic": "Semântica"
"semantic": "Semântica",
"delete": "Delete"
},
"skills": {
"title": "Skills",
@ -1813,7 +1932,18 @@
"statusBanned": "Banido / Sandbox Violation",
"statusCreditsExhausted": "Saldo Insuficiente",
"modelsImported": "{count} models imported",
"close": "Close"
"close": "Close",
"embeddings": "Embeddings",
"audioSpeech": "Audio Speech",
"imagesGenerations": "Images Generations",
"repairEnv": "Repair env",
"repairEnvFailed": "Failed to repair .env",
"repairEnvHint": "Restore missing OAuth defaults into .env without overwriting existing values.",
"showEmails": "Show all emails",
"repairEnvWorking": "Repairing...",
"repairEnvSuccess": "OAuth defaults restored",
"hideEmails": "Hide all emails",
"audioTranscriptions": "Audio Transcriptions"
},
"settings": {
"title": "Configurações",
@ -2760,7 +2890,11 @@
"waitingForOpenAIAuthorization": "Aguardando autorização do OpenAI...",
"waitingForAntigravityAuthorization": "Aguardando autorização antigravidade...",
"waitingForQoderAuthorization": "Aguardando autorização do Qoder...",
"exchangingCodeForTokens": "Trocando código por tokens..."
"exchangingCodeForTokens": "Trocando código por tokens...",
"nodeIncompatibleTitle": "Incompatible Node.js Version",
"nodeIncompatibleFixLabel": "Fix: install a patched Node.js 22 LTS release",
"nodeIncompatibleDesc": "You are running Node.js {version}, which is outside OmniRoute's supported secure runtime policy. Use a patched Node.js 20.x or 22.x LTS release.",
"nodeIncompatibleHint": "OmniRoute requires Node.js 20.20.2+ (20.x LTS) or 22.22.2+ (22.x LTS). Node 22 LTS is recommended."
},
"landing": {
"brandName": "OmniRoute",
@ -3176,6 +3310,25 @@
"deduplicatedRequests": "Requisições Desduplicadas",
"savedCalls": "Chamadas API Poupadas",
"totalProcessed": "Total Processado",
"peakCached": "Peak cached"
"peakCached": "Peak cached",
"entriesLoadError": "Failed to load semantic cache entries.",
"peakCacheRate": "Peak Cache Rate",
"semanticCache": "Semantic Cache",
"busiestHour": "Busiest Hour",
"promptTrendDesc": "Hourly request volume, cache coverage, and cache read volume across the last 24 hours.",
"semanticCacheDisabledDesc": "Semantic cache is disabled. OmniRoute will skip local response reuse until you turn it back on in Settings.",
"activityVolume": "Activity",
"cachedRequests24h": "Cached Requests (24h)",
"cacheRate": "Cache Rate",
"semanticCacheSectionDesc": "OmniRoute's own deterministic response cache. When enabled, repeated non-streaming temperature=0 requests can be served locally without hitting the upstream provider.",
"providerCacheRateDesc": "Each provider exposes total input tokens, cache read tokens, and cache write tokens so you can verify the reuse ratio against raw totals.",
"semanticEntriesDesc": "Persisted semantic cache records currently stored in SQLite. Provider-side prompt cache activity is not listed here.",
"lastUpdated": "Last updated",
"hoursTracked": "hours tracked",
"noPromptCacheData": "No provider-side prompt cache activity has been recorded yet.",
"promptCacheSectionDesc": "Shows provider-side prompt caching activity from usage history so you can see where cache control is active and how much input reuse you are getting.",
"trendHour": "Hour",
"noTrendData": "No prompt cache activity has been recorded over the last 24 hours.",
"cacheRateDesc": "of total requests"
}
}

View file

@ -136,7 +136,10 @@
"Failed to save pricing": "Falha ao salvar o preço",
"Failed to reset pricing": "Falha ao redefinir o preço",
"apikey": "Chave de API",
"http": "HTTP"
"http": "HTTP",
"checkSystemStatus": "Check System Status",
"goToDashboard": "Go to Dashboard",
"nothingHere": "Nothing here yet"
},
"sidebar": {
"home": "Página inicial",
@ -640,7 +643,8 @@
"opencode": "Use quando preferir execuções de agentes nativos de terminal e automação com script via OpenCode.",
"kiro": "Use ao integrar o Kiro e controlar o roteamento do modelo centralmente no OmniRoute.",
"antigravity": "Use quando o tráfego Antigravity/Kiro deve ser interceptado através do MITM e roteado para OmniRoute.",
"copilot": "Use quando desejar UX no estilo de bate-papo do Copilot enquanto impõe chaves OmniRoute e regras de roteamento."
"copilot": "Use quando desejar UX no estilo de bate-papo do Copilot enquanto impõe chaves OmniRoute e regras de roteamento.",
"windsurf": "Use when you want an AI-first IDE with Codeium/Windsurf models routed through OmniRoute."
},
"toolDescriptions": {
"antigravity": "IDE antigravidade do Google com MITM",
@ -655,7 +659,8 @@
"opencode": "OpenCode AI coding agent (Terminal)",
"kiro": "Amazon Kiro — AI-powered IDE",
"windsurf": "Windsurf AI Code Editor",
"copilot": "GitHub Copilot AI Assistant"
"copilot": "GitHub Copilot AI Assistant",
"qwen": "Alibaba Qwen Code CLI"
},
"guides": {
"cursor": {
@ -890,6 +895,16 @@
"when": "Use when you want perfectly even spread — each model used once before repeating.",
"avoid": "Avoid when models have different quality or latency and order matters.",
"example": "Example: Multiple accounts of the same model to distribute usage evenly."
},
"p2c": {
"example": "Example: High-throughput inference across 4+ equivalent model endpoints.",
"avoid": "Avoid for small combos with 2 or fewer models — no benefit over round-robin.",
"when": "Use when you want low-latency selection using Power-of-Two-Choices algorithm."
},
"context-relay": {
"avoid": "Avoid when account switching is rare or when you do not want extra summarization requests.",
"when": "Use when long sessions must survive account rotation without losing the working context.",
"example": "Example: Codex sessions that rotate across multiple accounts near quota exhaustion."
}
},
"advancedHelp": {
@ -1009,7 +1024,117 @@
"wizardStep3Title": "Choose Strategy",
"wizardStep3Desc": "Pick how requests are distributed across your models - 13 strategies available",
"wizardStep4Title": "Review & Save",
"wizardStep4Desc": "Review your configuration and activate the combo"
"wizardStep4Desc": "Review your configuration and activate the combo",
"builderModel": "Model",
"incidentMode": "Incident Mode",
"excludedProvidersHint": "Providers with an OPEN circuit breaker are temporarily excluded from routing.",
"weightCostInv": "Cost",
"builderStage": {
"review": {
"description": "Final validation before saving",
"label": "Review"
},
"steps": {
"label": "Steps",
"description": "Provider, model, and account selection"
},
"intelligent": {
"label": "Smart Routing",
"description": "Auto-routing candidate pool, presets, and scoring"
},
"strategy": {
"description": "Routing behavior and advanced settings",
"label": "Strategy"
},
"basics": {
"description": "Name and starting template",
"label": "Basics"
}
},
"builderComboRef": "Combo Ref",
"budgetCapLabel": "Budget Cap (USD / request)",
"filterEmptyTitle": "No combos match this strategy filter.",
"builderTitle": "Build a Combo",
"failedReorder": "Failed to reorder models",
"builderAddComboRef": "Add combo reference",
"builderProviderFirst": "Pick provider first",
"filterEmptyDeterministicDescription": "Only auto and LKGP combos exist right now. Switch back to All or create a deterministic combo.",
"contextRelayMaxMessagesHelp": "Limits how much recent history is condensed into the relay summary.",
"filterIntelligent": "Intelligent",
"filterAll": "All",
"weightStability": "Stability",
"builderSelectProvider": "Select provider",
"modePackLabel": "Mode Pack",
"cooldownMinutes": "Cooldown: {minutes}m",
"reorderHandle": "Drag to reorder",
"normalOperation": "Normal Operation",
"candidatePoolEmpty": "No active providers available yet.",
"excludedProviders": "Excluded Providers",
"builderStageCurrent": "Current stage",
"modePackHint": "Switch presets to bias the routing engine without rebuilding the combo.",
"contextRelaySummaryModel": "Summary Model",
"intelligentPanelDesc": "Real-time scoring and health status for this auto-routing combo.",
"reviewNoSteps": "No steps configured",
"allProvidersEvaluated": "No candidate pool configured. All active providers are evaluated at runtime.",
"activeModePack": "Active Mode Pack",
"builderAccount": "Account",
"filterEmptyIntelligentDescription": "Create an auto or LKGP combo to populate the intelligent routing dashboard.",
"builderStageLocked": "Locked — complete previous stage first",
"highCircuitBreakerRate": "High circuit breaker trip rate detected.",
"noExcludedProviders": "No providers are currently excluded.",
"intelligentPanelTitle": "Intelligent Routing Dashboard",
"contextRelayHandoffThresholdHelp": "When quota usage reaches this threshold, OmniRoute generates a structured handoff summary before the active account is exhausted.",
"candidatePoolAllProviders": "All providers",
"strategyRules": "Rules (6-Factor Scoring)",
"filterDeterministic": "Deterministic",
"builderStagePending": "Pending",
"weightHealth": "Health",
"budgetCapPlaceholder": "No limit",
"reviewSteps": "Steps",
"emailVisibilityStateOn": "On",
"weightLatencyInv": "Latency",
"builderProvider": "Provider",
"reviewSequence": "Model Sequence",
"builderFlowTitle": "Combo Builder Flow",
"explorationRateLabel": "Exploration Rate",
"reviewAdvanced": "Advanced Settings",
"contextRelayDesc": "Preserves session continuity with handoff summaries when accounts rotate",
"contextRelayMaxMessages": "Max Messages For Summary",
"builderIntelligentTitle": "Intelligent Routing Configuration",
"modePackUpdated": "Mode pack updated to {pack}.",
"builderIntelligentDesc": "Configure the multi-factor scoring engine for this auto-routing combo.",
"advancedWeightsTitle": "Advanced: Scoring Weights",
"statusOverview": "Status Overview",
"reviewAccounts": "Accounts",
"contextRelaySummaryModelHelp": "Optional override model used only for generating the handoff summary. Leave empty to reuse the active combo model.",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex account rotation. Pair it with multiple accounts of the same provider for the best continuity.",
"builderPreview": "Preview",
"builderAddStep": "Add step",
"emailVisibilityStateOff": "Off",
"reviewComboRefs": "Combo References",
"reviewAgentFlags": "Agent Flags",
"builderComboRefStep": "Add combo reference",
"builderLegacyEntry": "Legacy entry",
"reviewProviders": "Providers",
"providerScores": "Provider Scores",
"builderStageVisited": "Stage completed",
"weightQuota": "Quota",
"candidatePoolLabel": "Candidate Pool",
"contextRelay": "Context Relay",
"builderBrowseCatalog": "Browse catalog",
"reviewIntelligentTitle": "Intelligent Routing Config",
"builderLoadingProviders": "Loading providers...",
"routerStrategyLabel": "Router Strategy",
"weightTierPriority": "Tier",
"explorationRateHint": "{percent}% of requests can explore non-optimal providers.",
"reviewName": "Name",
"contextRelayHandoffThreshold": "Handoff Threshold",
"reviewStrategy": "Strategy",
"weightTaskFit": "Task Fit",
"builderPinnedAccount": "Pinned Account",
"allProvidersHealthy": "Providers are reporting healthy routing conditions.",
"candidatePoolHint": "Select which providers this engine should evaluate. Leave empty to use all active providers.",
"builderSelectModel": "Select model"
},
"costs": {
"title": "Custos",
@ -1147,7 +1272,9 @@
"a2aQuickStartStep2": "Send JSON-RPC requests to `POST /a2a` using `message/send` or `message/stream`.",
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format",
"musicGeneration": "Music Generation",
"musicDesc": "Generate music and audio tracks via ComfyUI (Stable Audio, MusicGen)"
},
"endpoints": {
"tabProxy": "Endpoint Proxy",
@ -1305,7 +1432,8 @@
"factual": "Factual",
"episodic": "Episódica",
"procedural": "Procedural",
"semantic": "Semântica"
"semantic": "Semântica",
"delete": "Delete"
},
"skills": {
"title": "Skills",
@ -1804,7 +1932,18 @@
"statusBanned": "Banido / Sandbox Violation",
"statusCreditsExhausted": "Saldo Insuficiente",
"modelsImported": "{count} models imported",
"close": "Close"
"close": "Close",
"repairEnv": "Repair env",
"repairEnvWorking": "Repairing...",
"audioSpeech": "Audio Speech",
"hideEmails": "Hide all emails",
"repairEnvHint": "Restore missing OAuth defaults into .env without overwriting existing values.",
"audioTranscriptions": "Audio Transcriptions",
"imagesGenerations": "Images Generations",
"showEmails": "Show all emails",
"embeddings": "Embeddings",
"repairEnvFailed": "Failed to repair .env",
"repairEnvSuccess": "OAuth defaults restored"
},
"settings": {
"title": "Configurações",
@ -2321,7 +2460,11 @@
"wildcardPatternModeDesc": "Use wildcard aliases with * and ? when a family of models should map to one target.",
"noExactAliasesConfigured": "No exact-match aliases configured.",
"wildcardRulesTitle": "Wildcard Rules",
"noWildcardAliasesConfigured": "No wildcard aliases configured."
"noWildcardAliasesConfigured": "No wildcard aliases configured.",
"contextRelaySummaryModel": "Summary Model",
"contextRelayMaxMessages": "Max Messages For Summary",
"contextRelayHandoffThreshold": "Handoff Threshold",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex accounts and uses these values as global defaults for new or unconfigured combos."
},
"translator": {
"title": "Tradutor",
@ -2747,7 +2890,11 @@
"waitingForOpenAIAuthorization": "Waiting for OpenAI authorization...",
"waitingForAntigravityAuthorization": "Waiting for Antigravity authorization...",
"waitingForQoderAuthorization": "Waiting for Qoder authorization...",
"exchangingCodeForTokens": "Exchanging code for tokens..."
"exchangingCodeForTokens": "Exchanging code for tokens...",
"nodeIncompatibleHint": "OmniRoute requires Node.js 20.20.2+ (20.x LTS) or 22.22.2+ (22.x LTS). Node 22 LTS is recommended.",
"nodeIncompatibleTitle": "Incompatible Node.js Version",
"nodeIncompatibleFixLabel": "Fix: install a patched Node.js 22 LTS release",
"nodeIncompatibleDesc": "You are running Node.js {version}, which is outside OmniRoute's supported secure runtime policy. Use a patched Node.js 20.x or 22.x LTS release."
},
"landing": {
"brandName": "OmniRoute",
@ -3163,6 +3310,25 @@
"deduplicatedRequests": "Requisições Desduplicadas",
"savedCalls": "Chamadas API Poupadas",
"totalProcessed": "Total Processado",
"peakCached": "Peak cached"
"peakCached": "Peak cached",
"lastUpdated": "Last updated",
"cacheRateDesc": "of total requests",
"noPromptCacheData": "No provider-side prompt cache activity has been recorded yet.",
"cacheRate": "Cache Rate",
"entriesLoadError": "Failed to load semantic cache entries.",
"semanticCacheSectionDesc": "OmniRoute's own deterministic response cache. When enabled, repeated non-streaming temperature=0 requests can be served locally without hitting the upstream provider.",
"activityVolume": "Activity",
"busiestHour": "Busiest Hour",
"noTrendData": "No prompt cache activity has been recorded over the last 24 hours.",
"semanticEntriesDesc": "Persisted semantic cache records currently stored in SQLite. Provider-side prompt cache activity is not listed here.",
"hoursTracked": "hours tracked",
"promptCacheSectionDesc": "Shows provider-side prompt caching activity from usage history so you can see where cache control is active and how much input reuse you are getting.",
"semanticCache": "Semantic Cache",
"cachedRequests24h": "Cached Requests (24h)",
"semanticCacheDisabledDesc": "Semantic cache is disabled. OmniRoute will skip local response reuse until you turn it back on in Settings.",
"peakCacheRate": "Peak Cache Rate",
"trendHour": "Hour",
"promptTrendDesc": "Hourly request volume, cache coverage, and cache read volume across the last 24 hours.",
"providerCacheRateDesc": "Each provider exposes total input tokens, cache read tokens, and cache write tokens so you can verify the reuse ratio against raw totals."
}
}

View file

@ -136,7 +136,10 @@
"Failed to save pricing": "Nu s-a salvat prețul",
"Failed to reset pricing": "Nu s-a resetat prețul",
"apikey": "Cheia API",
"http": "HTTP"
"http": "HTTP",
"checkSystemStatus": "Check System Status",
"goToDashboard": "Go to Dashboard",
"nothingHere": "Nothing here yet"
},
"sidebar": {
"home": "Acasă",
@ -640,7 +643,8 @@
"opencode": "Utilizați atunci când preferați rulările de agent nativ terminal și automatizarea prin script prin OpenCode.",
"kiro": "Utilizați atunci când integrați Kiro și controlați rutarea modelului central din OmniRoute.",
"antigravity": "Utilizați atunci când traficul Antigravity/Kiro trebuie interceptat prin MITM și direcționat către OmniRoute.",
"copilot": "Utilizați atunci când doriți UX în stilul de chat Copilot, în timp ce aplicați cheile și regulile de rutare OmniRoute."
"copilot": "Utilizați atunci când doriți UX în stilul de chat Copilot, în timp ce aplicați cheile și regulile de rutare OmniRoute.",
"windsurf": "Use when you want an AI-first IDE with Codeium/Windsurf models routed through OmniRoute."
},
"toolDescriptions": {
"antigravity": "Google Antigravity IDE cu MITM",
@ -655,7 +659,8 @@
"opencode": "OpenCode AI coding agent (Terminal)",
"kiro": "Amazon Kiro — AI-powered IDE",
"windsurf": "Windsurf AI Code Editor",
"copilot": "GitHub Copilot AI Assistant"
"copilot": "GitHub Copilot AI Assistant",
"qwen": "Alibaba Qwen Code CLI"
},
"guides": {
"cursor": {
@ -890,6 +895,16 @@
"when": "Use when you want perfectly even spread — each model used once before repeating.",
"avoid": "Avoid when models have different quality or latency and order matters.",
"example": "Example: Multiple accounts of the same model to distribute usage evenly."
},
"context-relay": {
"example": "Example: Codex sessions that rotate across multiple accounts near quota exhaustion.",
"avoid": "Avoid when account switching is rare or when you do not want extra summarization requests.",
"when": "Use when long sessions must survive account rotation without losing the working context."
},
"p2c": {
"avoid": "Avoid for small combos with 2 or fewer models — no benefit over round-robin.",
"when": "Use when you want low-latency selection using Power-of-Two-Choices algorithm.",
"example": "Example: High-throughput inference across 4+ equivalent model endpoints."
}
},
"advancedHelp": {
@ -1009,7 +1024,117 @@
"wizardStep3Title": "Choose Strategy",
"wizardStep3Desc": "Pick how requests are distributed across your models - 13 strategies available",
"wizardStep4Title": "Review & Save",
"wizardStep4Desc": "Review your configuration and activate the combo"
"wizardStep4Desc": "Review your configuration and activate the combo",
"budgetCapPlaceholder": "No limit",
"emailVisibilityStateOff": "Off",
"weightHealth": "Health",
"builderSelectProvider": "Select provider",
"intelligentPanelTitle": "Intelligent Routing Dashboard",
"reviewProviders": "Providers",
"reviewNoSteps": "No steps configured",
"normalOperation": "Normal Operation",
"reviewStrategy": "Strategy",
"weightTaskFit": "Task Fit",
"contextRelaySummaryModelHelp": "Optional override model used only for generating the handoff summary. Leave empty to reuse the active combo model.",
"builderModel": "Model",
"builderLoadingProviders": "Loading providers...",
"allProvidersHealthy": "Providers are reporting healthy routing conditions.",
"builderPreview": "Preview",
"filterEmptyTitle": "No combos match this strategy filter.",
"filterDeterministic": "Deterministic",
"builderFlowTitle": "Combo Builder Flow",
"candidatePoolAllProviders": "All providers",
"reorderHandle": "Drag to reorder",
"providerScores": "Provider Scores",
"builderBrowseCatalog": "Browse catalog",
"explorationRateHint": "{percent}% of requests can explore non-optimal providers.",
"builderStage": {
"review": {
"description": "Final validation before saving",
"label": "Review"
},
"strategy": {
"label": "Strategy",
"description": "Routing behavior and advanced settings"
},
"basics": {
"description": "Name and starting template",
"label": "Basics"
},
"steps": {
"label": "Steps",
"description": "Provider, model, and account selection"
},
"intelligent": {
"label": "Smart Routing",
"description": "Auto-routing candidate pool, presets, and scoring"
}
},
"reviewIntelligentTitle": "Intelligent Routing Config",
"weightCostInv": "Cost",
"highCircuitBreakerRate": "High circuit breaker trip rate detected.",
"excludedProvidersHint": "Providers with an OPEN circuit breaker are temporarily excluded from routing.",
"contextRelayHandoffThreshold": "Handoff Threshold",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex account rotation. Pair it with multiple accounts of the same provider for the best continuity.",
"reviewAdvanced": "Advanced Settings",
"modePackHint": "Switch presets to bias the routing engine without rebuilding the combo.",
"reviewName": "Name",
"builderStageCurrent": "Current stage",
"statusOverview": "Status Overview",
"advancedWeightsTitle": "Advanced: Scoring Weights",
"candidatePoolEmpty": "No active providers available yet.",
"weightLatencyInv": "Latency",
"excludedProviders": "Excluded Providers",
"contextRelay": "Context Relay",
"contextRelaySummaryModel": "Summary Model",
"contextRelayMaxMessagesHelp": "Limits how much recent history is condensed into the relay summary.",
"builderProvider": "Provider",
"contextRelayMaxMessages": "Max Messages For Summary",
"builderAccount": "Account",
"filterEmptyIntelligentDescription": "Create an auto or LKGP combo to populate the intelligent routing dashboard.",
"candidatePoolLabel": "Candidate Pool",
"reviewComboRefs": "Combo References",
"activeModePack": "Active Mode Pack",
"builderStageVisited": "Stage completed",
"filterEmptyDeterministicDescription": "Only auto and LKGP combos exist right now. Switch back to All or create a deterministic combo.",
"reviewAccounts": "Accounts",
"budgetCapLabel": "Budget Cap (USD / request)",
"candidatePoolHint": "Select which providers this engine should evaluate. Leave empty to use all active providers.",
"builderAddStep": "Add step",
"routerStrategyLabel": "Router Strategy",
"weightTierPriority": "Tier",
"incidentMode": "Incident Mode",
"builderLegacyEntry": "Legacy entry",
"builderComboRefStep": "Add combo reference",
"filterIntelligent": "Intelligent",
"reviewSteps": "Steps",
"builderSelectModel": "Select model",
"contextRelayDesc": "Preserves session continuity with handoff summaries when accounts rotate",
"builderIntelligentDesc": "Configure the multi-factor scoring engine for this auto-routing combo.",
"builderProviderFirst": "Pick provider first",
"builderTitle": "Build a Combo",
"strategyRules": "Rules (6-Factor Scoring)",
"builderIntelligentTitle": "Intelligent Routing Configuration",
"modePackUpdated": "Mode pack updated to {pack}.",
"builderAddComboRef": "Add combo reference",
"builderStagePending": "Pending",
"explorationRateLabel": "Exploration Rate",
"noExcludedProviders": "No providers are currently excluded.",
"failedReorder": "Failed to reorder models",
"weightQuota": "Quota",
"contextRelayHandoffThresholdHelp": "When quota usage reaches this threshold, OmniRoute generates a structured handoff summary before the active account is exhausted.",
"cooldownMinutes": "Cooldown: {minutes}m",
"emailVisibilityStateOn": "On",
"intelligentPanelDesc": "Real-time scoring and health status for this auto-routing combo.",
"reviewAgentFlags": "Agent Flags",
"modePackLabel": "Mode Pack",
"allProvidersEvaluated": "No candidate pool configured. All active providers are evaluated at runtime.",
"filterAll": "All",
"builderStageLocked": "Locked — complete previous stage first",
"builderComboRef": "Combo Ref",
"weightStability": "Stability",
"reviewSequence": "Model Sequence",
"builderPinnedAccount": "Pinned Account"
},
"costs": {
"title": "Costuri",
@ -1147,7 +1272,9 @@
"a2aQuickStartStep2": "Send JSON-RPC requests to `POST /a2a` using `message/send` or `message/stream`.",
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format",
"musicDesc": "Generate music and audio tracks via ComfyUI (Stable Audio, MusicGen)",
"musicGeneration": "Music Generation"
},
"endpoints": {
"tabProxy": "Endpoint Proxy",
@ -1749,7 +1876,22 @@
"close": "Close",
"statusDeactivated": "Deactivated (Manual)",
"statusBanned": "Banned / Sandbox Violation",
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted"
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted",
"imagesGenerations": "Images Generations",
"embeddings": "Embeddings",
"repairEnv": "Repair env",
"selectAllModels": "Select all",
"audioSpeech": "Audio Speech",
"repairEnvHint": "Restore missing OAuth defaults into .env without overwriting existing values.",
"hideEmails": "Hide all emails",
"deselectAllModels": "Deselect all",
"audioTranscriptions": "Audio Transcriptions",
"showEmails": "Show all emails",
"repairEnvWorking": "Repairing...",
"repairEnvFailed": "Failed to repair .env",
"modelsActiveCount": "{active}/{total} active",
"repairEnvSuccess": "OAuth defaults restored",
"noModelsMatch": "No models match \"{filter}\""
},
"settings": {
"title": "Setări",
@ -2266,7 +2408,11 @@
"wildcardPatternModeDesc": "Use wildcard aliases with * and ? when a family of models should map to one target.",
"noExactAliasesConfigured": "No exact-match aliases configured.",
"wildcardRulesTitle": "Wildcard Rules",
"noWildcardAliasesConfigured": "No wildcard aliases configured."
"noWildcardAliasesConfigured": "No wildcard aliases configured.",
"contextRelayHandoffThreshold": "Handoff Threshold",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex accounts and uses these values as global defaults for new or unconfigured combos.",
"contextRelayMaxMessages": "Max Messages For Summary",
"contextRelaySummaryModel": "Summary Model"
},
"translator": {
"title": "Traducător",
@ -2692,7 +2838,11 @@
"waitingForOpenAIAuthorization": "Se așteaptă autorizarea OpenAI...",
"waitingForAntigravityAuthorization": "Se așteaptă autorizația antigravitație...",
"waitingForQoderAuthorization": "Se așteaptă autorizarea Qoder...",
"exchangingCodeForTokens": "Se schimbă codul pentru jetoane..."
"exchangingCodeForTokens": "Se schimbă codul pentru jetoane...",
"nodeIncompatibleFixLabel": "Fix: install a patched Node.js 22 LTS release",
"nodeIncompatibleTitle": "Incompatible Node.js Version",
"nodeIncompatibleDesc": "You are running Node.js {version}, which is outside OmniRoute's supported secure runtime policy. Use a patched Node.js 20.x or 22.x LTS release.",
"nodeIncompatibleHint": "OmniRoute requires Node.js 20.20.2+ (20.x LTS) or 22.22.2+ (22.x LTS). Node 22 LTS is recommended."
},
"landing": {
"brandName": "OmniRoute",
@ -3108,7 +3258,26 @@
"peakCached": "Peak cached",
"deduplicatedRequests": "Deduplicated Requests",
"savedCalls": "Saved API Calls",
"totalProcessed": "Total Requests Processed"
"totalProcessed": "Total Requests Processed",
"promptTrendDesc": "Hourly request volume, cache coverage, and cache read volume across the last 24 hours.",
"noPromptCacheData": "No provider-side prompt cache activity has been recorded yet.",
"entriesLoadError": "Failed to load semantic cache entries.",
"busiestHour": "Busiest Hour",
"hoursTracked": "hours tracked",
"lastUpdated": "Last updated",
"cacheRate": "Cache Rate",
"activityVolume": "Activity",
"semanticCacheSectionDesc": "OmniRoute's own deterministic response cache. When enabled, repeated non-streaming temperature=0 requests can be served locally without hitting the upstream provider.",
"cacheRateDesc": "of total requests",
"trendHour": "Hour",
"semanticCacheDisabledDesc": "Semantic cache is disabled. OmniRoute will skip local response reuse until you turn it back on in Settings.",
"cachedRequests24h": "Cached Requests (24h)",
"providerCacheRateDesc": "Each provider exposes total input tokens, cache read tokens, and cache write tokens so you can verify the reuse ratio against raw totals.",
"semanticEntriesDesc": "Persisted semantic cache records currently stored in SQLite. Provider-side prompt cache activity is not listed here.",
"promptCacheSectionDesc": "Shows provider-side prompt caching activity from usage history so you can see where cache control is active and how much input reuse you are getting.",
"noTrendData": "No prompt cache activity has been recorded over the last 24 hours.",
"semanticCache": "Semantic Cache",
"peakCacheRate": "Peak Cache Rate"
},
"memory": {
"title": "Memory Management",
@ -3132,7 +3301,8 @@
"factual": "Factual",
"episodic": "Episodic",
"procedural": "Procedural",
"semantic": "Semantic"
"semantic": "Semantic",
"delete": "Delete"
},
"skills": {
"title": "Skills",

View file

@ -136,7 +136,10 @@
"Failed to save pricing": "Не удалось сохранить цену.",
"Failed to reset pricing": "Не удалось сбросить цены.",
"apikey": "API-ключ",
"http": "HTTP"
"http": "HTTP",
"checkSystemStatus": "Check System Status",
"goToDashboard": "Go to Dashboard",
"nothingHere": "Nothing here yet"
},
"sidebar": {
"home": "Главная",
@ -640,7 +643,8 @@
"opencode": "Используйте, если вы предпочитаете запускать собственные агенты терминала и автоматизировать скрипты через OpenCode.",
"kiro": "Используйте при интеграции Kiro и централизованном управлении маршрутизацией модели из OmniRoute.",
"antigravity": "Используйте, когда трафик Антигравитации/Киро необходимо перехватить через MITM и направить в OmniRoute.",
"copilot": "Используйте его, если вам нужен пользовательский интерфейс в стиле чата Copilot, одновременно обеспечивая соблюдение ключей OmniRoute и правил маршрутизации."
"copilot": "Используйте его, если вам нужен пользовательский интерфейс в стиле чата Copilot, одновременно обеспечивая соблюдение ключей OmniRoute и правил маршрутизации.",
"windsurf": "Use when you want an AI-first IDE with Codeium/Windsurf models routed through OmniRoute."
},
"toolDescriptions": {
"antigravity": "Google Antigravity IDE с MITM",
@ -655,7 +659,8 @@
"opencode": "OpenCode - агент кодирования с ИИ в терминале",
"kiro": "Amazon Kiro - IDE с ИИ",
"windsurf": "Редактор кода Windsurf с ИИ",
"copilot": "Ассистент GitHub Copilot с ИИ"
"copilot": "Ассистент GitHub Copilot с ИИ",
"qwen": "Alibaba Qwen Code CLI"
},
"guides": {
"cursor": {
@ -914,6 +919,16 @@
"when": "Используйте, когда нужен идеально ровный spread - каждая модель используется один раз перед повтором.",
"avoid": "Избегайте, когда модели отличаются по качеству или задержке и важен порядок.",
"example": "Пример: несколько аккаунтов одной модели для равномерного распределения использования."
},
"context-relay": {
"when": "Use when long sessions must survive account rotation without losing the working context.",
"example": "Example: Codex sessions that rotate across multiple accounts near quota exhaustion.",
"avoid": "Avoid when account switching is rare or when you do not want extra summarization requests."
},
"p2c": {
"example": "Example: High-throughput inference across 4+ equivalent model endpoints.",
"avoid": "Avoid for small combos with 2 or fewer models — no benefit over round-robin.",
"when": "Use when you want low-latency selection using Power-of-Two-Choices algorithm."
}
},
"advancedHelp": {
@ -1033,7 +1048,117 @@
"wizardStep3Title": "Choose Strategy",
"wizardStep3Desc": "Pick how requests are distributed across your models - 13 strategies available",
"wizardStep4Title": "Review & Save",
"wizardStep4Desc": "Review your configuration and activate the combo"
"wizardStep4Desc": "Review your configuration and activate the combo",
"cooldownMinutes": "Cooldown: {minutes}m",
"contextRelaySummaryModel": "Summary Model",
"filterEmptyDeterministicDescription": "Only auto and LKGP combos exist right now. Switch back to All or create a deterministic combo.",
"weightCostInv": "Cost",
"strategyRules": "Rules (6-Factor Scoring)",
"builderStage": {
"basics": {
"label": "Basics",
"description": "Name and starting template"
},
"strategy": {
"label": "Strategy",
"description": "Routing behavior and advanced settings"
},
"intelligent": {
"description": "Auto-routing candidate pool, presets, and scoring",
"label": "Smart Routing"
},
"steps": {
"description": "Provider, model, and account selection",
"label": "Steps"
},
"review": {
"label": "Review",
"description": "Final validation before saving"
}
},
"excludedProvidersHint": "Providers with an OPEN circuit breaker are temporarily excluded from routing.",
"reviewComboRefs": "Combo References",
"builderSelectModel": "Select model",
"builderAddComboRef": "Add combo reference",
"emailVisibilityStateOn": "On",
"filterEmptyIntelligentDescription": "Create an auto or LKGP combo to populate the intelligent routing dashboard.",
"reviewName": "Name",
"intelligentPanelDesc": "Real-time scoring and health status for this auto-routing combo.",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex account rotation. Pair it with multiple accounts of the same provider for the best continuity.",
"activeModePack": "Active Mode Pack",
"modePackUpdated": "Mode pack updated to {pack}.",
"filterAll": "All",
"allProvidersEvaluated": "No candidate pool configured. All active providers are evaluated at runtime.",
"budgetCapLabel": "Budget Cap (USD / request)",
"filterDeterministic": "Deterministic",
"weightHealth": "Health",
"builderPinnedAccount": "Pinned Account",
"reviewAgentFlags": "Agent Flags",
"reviewAccounts": "Accounts",
"reviewNoSteps": "No steps configured",
"reorderHandle": "Drag to reorder",
"weightTaskFit": "Task Fit",
"incidentMode": "Incident Mode",
"weightQuota": "Quota",
"modePackLabel": "Mode Pack",
"builderPreview": "Preview",
"explorationRateHint": "{percent}% of requests can explore non-optimal providers.",
"candidatePoolLabel": "Candidate Pool",
"builderAddStep": "Add step",
"modePackHint": "Switch presets to bias the routing engine without rebuilding the combo.",
"reviewSteps": "Steps",
"weightLatencyInv": "Latency",
"filterEmptyTitle": "No combos match this strategy filter.",
"explorationRateLabel": "Exploration Rate",
"noExcludedProviders": "No providers are currently excluded.",
"weightStability": "Stability",
"candidatePoolHint": "Select which providers this engine should evaluate. Leave empty to use all active providers.",
"allProvidersHealthy": "Providers are reporting healthy routing conditions.",
"builderIntelligentDesc": "Configure the multi-factor scoring engine for this auto-routing combo.",
"builderStageVisited": "Stage completed",
"candidatePoolEmpty": "No active providers available yet.",
"reviewIntelligentTitle": "Intelligent Routing Config",
"builderTitle": "Build a Combo",
"contextRelayMaxMessagesHelp": "Limits how much recent history is condensed into the relay summary.",
"builderAccount": "Account",
"builderStageLocked": "Locked — complete previous stage first",
"reviewAdvanced": "Advanced Settings",
"intelligentPanelTitle": "Intelligent Routing Dashboard",
"failedReorder": "Failed to reorder models",
"routerStrategyLabel": "Router Strategy",
"candidatePoolAllProviders": "All providers",
"statusOverview": "Status Overview",
"builderModel": "Model",
"builderProvider": "Provider",
"emailVisibilityStateOff": "Off",
"reviewStrategy": "Strategy",
"providerScores": "Provider Scores",
"builderComboRef": "Combo Ref",
"builderStageCurrent": "Current stage",
"budgetCapPlaceholder": "No limit",
"highCircuitBreakerRate": "High circuit breaker trip rate detected.",
"contextRelayHandoffThresholdHelp": "When quota usage reaches this threshold, OmniRoute generates a structured handoff summary before the active account is exhausted.",
"normalOperation": "Normal Operation",
"builderLegacyEntry": "Legacy entry",
"builderIntelligentTitle": "Intelligent Routing Configuration",
"builderProviderFirst": "Pick provider first",
"contextRelay": "Context Relay",
"contextRelayDesc": "Preserves session continuity with handoff summaries when accounts rotate",
"contextRelayMaxMessages": "Max Messages For Summary",
"weightTierPriority": "Tier",
"reviewSequence": "Model Sequence",
"builderBrowseCatalog": "Browse catalog",
"contextRelayHandoffThreshold": "Handoff Threshold",
"reviewProviders": "Providers",
"builderFlowTitle": "Combo Builder Flow",
"builderStagePending": "Pending",
"builderLoadingProviders": "Loading providers...",
"excludedProviders": "Excluded Providers",
"builderComboRefStep": "Add combo reference",
"builderSelectProvider": "Select provider",
"filterIntelligent": "Intelligent",
"contextRelaySummaryModelHelp": "Optional override model used only for generating the handoff summary. Leave empty to reuse the active combo model.",
"advancedWeightsTitle": "Advanced: Scoring Weights"
},
"costs": {
"title": "Затраты",
@ -1171,7 +1296,9 @@
"a2aQuickStartStep2": "Отправляйте JSON-RPC-запросы на `POST /a2a` через `message/send` или `message/stream`.",
"a2aQuickStartStep3": "Отслеживайте и управляйте задачами через `tasks/get` и `tasks/cancel`.",
"completionsLegacy": "Завершения (устар.)",
"completionsLegacyDesc": "Устаревшие текстовые завершения OpenAI — поддерживают и строку prompt, и массив messages"
"completionsLegacyDesc": "Устаревшие текстовые завершения OpenAI — поддерживают и строку prompt, и массив messages",
"musicDesc": "Generate music and audio tracks via ComfyUI (Stable Audio, MusicGen)",
"musicGeneration": "Music Generation"
},
"endpoints": {
"tabProxy": "Прокси конечных точек",
@ -1778,7 +1905,17 @@
"chatPathHint": "Пользовательский путь чата для провайдеров с нестандартными API (например, /v4/chat/completions)",
"modelsPathLabel": "Путь эндпоинта моделей",
"modelsPathPlaceholder": "/models",
"modelsPathHint": "Пользовательский путь моделей для проверки (например, /v4/models)"
"modelsPathHint": "Пользовательский путь моделей для проверки (например, /v4/models)",
"showEmails": "Show all emails",
"deselectAllModels": "Deselect all",
"embeddings": "Embeddings",
"hideEmails": "Hide all emails",
"audioSpeech": "Audio Speech",
"imagesGenerations": "Images Generations",
"noModelsMatch": "No models match \"{filter}\"",
"modelsActiveCount": "{active}/{total} active",
"audioTranscriptions": "Audio Transcriptions",
"selectAllModels": "Select all"
},
"settings": {
"title": "Настройки",
@ -2295,7 +2432,11 @@
"wildcardPatternModeDesc": "Use wildcard aliases with * and ? when a family of models should map to one target.",
"noExactAliasesConfigured": "No exact-match aliases configured.",
"wildcardRulesTitle": "Wildcard Rules",
"noWildcardAliasesConfigured": "No wildcard aliases configured."
"noWildcardAliasesConfigured": "No wildcard aliases configured.",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex accounts and uses these values as global defaults for new or unconfigured combos.",
"contextRelayMaxMessages": "Max Messages For Summary",
"contextRelaySummaryModel": "Summary Model",
"contextRelayHandoffThreshold": "Handoff Threshold"
},
"translator": {
"title": "Переводчик",
@ -2721,7 +2862,11 @@
"waitingForOpenAIAuthorization": "Ожидание авторизации OpenAI...",
"waitingForAntigravityAuthorization": "Ожидание авторизации Antigravity...",
"waitingForQoderAuthorization": "Ожидание авторизации Qoder...",
"exchangingCodeForTokens": "Обмен кода на токены..."
"exchangingCodeForTokens": "Обмен кода на токены...",
"nodeIncompatibleDesc": "You are running Node.js {version}, which is outside OmniRoute's supported secure runtime policy. Use a patched Node.js 20.x or 22.x LTS release.",
"nodeIncompatibleHint": "OmniRoute requires Node.js 20.20.2+ (20.x LTS) or 22.22.2+ (22.x LTS). Node 22 LTS is recommended.",
"nodeIncompatibleTitle": "Incompatible Node.js Version",
"nodeIncompatibleFixLabel": "Fix: install a patched Node.js 22 LTS release"
},
"landing": {
"brandName": "ОмниРоут",
@ -3045,7 +3190,8 @@
"factual": "Фактическая",
"episodic": "Эпизодическая",
"procedural": "Процедурная",
"semantic": "Семантическая"
"semantic": "Семантическая",
"delete": "Delete"
},
"skills": {
"title": "Навыки",
@ -3188,6 +3334,25 @@
"deduplicatedRequests": "Дедуплицированные запросы",
"peakCached": "Пик кэша",
"savedCalls": "Сэкономленные API-запросы",
"totalProcessed": "Всего запросов обработано"
"totalProcessed": "Всего запросов обработано",
"trendHour": "Hour",
"promptCacheSectionDesc": "Shows provider-side prompt caching activity from usage history so you can see where cache control is active and how much input reuse you are getting.",
"promptTrendDesc": "Hourly request volume, cache coverage, and cache read volume across the last 24 hours.",
"busiestHour": "Busiest Hour",
"semanticEntriesDesc": "Persisted semantic cache records currently stored in SQLite. Provider-side prompt cache activity is not listed here.",
"activityVolume": "Activity",
"semanticCache": "Semantic Cache",
"peakCacheRate": "Peak Cache Rate",
"noPromptCacheData": "No provider-side prompt cache activity has been recorded yet.",
"hoursTracked": "hours tracked",
"cacheRate": "Cache Rate",
"lastUpdated": "Last updated",
"cachedRequests24h": "Cached Requests (24h)",
"entriesLoadError": "Failed to load semantic cache entries.",
"semanticCacheSectionDesc": "OmniRoute's own deterministic response cache. When enabled, repeated non-streaming temperature=0 requests can be served locally without hitting the upstream provider.",
"semanticCacheDisabledDesc": "Semantic cache is disabled. OmniRoute will skip local response reuse until you turn it back on in Settings.",
"cacheRateDesc": "of total requests",
"noTrendData": "No prompt cache activity has been recorded over the last 24 hours.",
"providerCacheRateDesc": "Each provider exposes total input tokens, cache read tokens, and cache write tokens so you can verify the reuse ratio against raw totals."
}
}

View file

@ -136,7 +136,10 @@
"Failed to save pricing": "Cenu sa nepodarilo uložiť",
"Failed to reset pricing": "Cenu sa nepodarilo resetovať",
"apikey": "API kľúč",
"http": "HTTP"
"http": "HTTP",
"nothingHere": "Nothing here yet",
"checkSystemStatus": "Check System Status",
"goToDashboard": "Go to Dashboard"
},
"sidebar": {
"home": "Domov",
@ -640,7 +643,8 @@
"opencode": "Použite, ak uprednostňujete spúšťanie natívneho agenta a skriptovanú automatizáciu cez OpenCode.",
"kiro": "Použite pri integrácii Kiro a centrálnom riadení smerovania modelu z OmniRoute.",
"antigravity": "Použite, keď musí byť premávka Antigravity/Kiro zachytená cez MITM a nasmerovaná na OmniRoute.",
"copilot": "Použite, keď chcete UX v štýle chatu Copilot pri presadzovaní kľúčov OmniRoute a pravidiel smerovania."
"copilot": "Použite, keď chcete UX v štýle chatu Copilot pri presadzovaní kľúčov OmniRoute a pravidiel smerovania.",
"windsurf": "Use when you want an AI-first IDE with Codeium/Windsurf models routed through OmniRoute."
},
"toolDescriptions": {
"antigravity": "Google Antigravity IDE s MITM",
@ -655,7 +659,8 @@
"opencode": "OpenCode AI coding agent (Terminal)",
"kiro": "Amazon Kiro — AI-powered IDE",
"windsurf": "Windsurf AI Code Editor",
"copilot": "GitHub Copilot AI Assistant"
"copilot": "GitHub Copilot AI Assistant",
"qwen": "Alibaba Qwen Code CLI"
},
"guides": {
"cursor": {
@ -890,6 +895,16 @@
"when": "Use when you want perfectly even spread — each model used once before repeating.",
"avoid": "Avoid when models have different quality or latency and order matters.",
"example": "Example: Multiple accounts of the same model to distribute usage evenly."
},
"p2c": {
"example": "Example: High-throughput inference across 4+ equivalent model endpoints.",
"when": "Use when you want low-latency selection using Power-of-Two-Choices algorithm.",
"avoid": "Avoid for small combos with 2 or fewer models — no benefit over round-robin."
},
"context-relay": {
"when": "Use when long sessions must survive account rotation without losing the working context.",
"avoid": "Avoid when account switching is rare or when you do not want extra summarization requests.",
"example": "Example: Codex sessions that rotate across multiple accounts near quota exhaustion."
}
},
"advancedHelp": {
@ -1009,7 +1024,117 @@
"wizardStep3Title": "Choose Strategy",
"wizardStep3Desc": "Pick how requests are distributed across your models - 13 strategies available",
"wizardStep4Title": "Review & Save",
"wizardStep4Desc": "Review your configuration and activate the combo"
"wizardStep4Desc": "Review your configuration and activate the combo",
"weightLatencyInv": "Latency",
"builderStage": {
"review": {
"description": "Final validation before saving",
"label": "Review"
},
"strategy": {
"description": "Routing behavior and advanced settings",
"label": "Strategy"
},
"intelligent": {
"label": "Smart Routing",
"description": "Auto-routing candidate pool, presets, and scoring"
},
"steps": {
"description": "Provider, model, and account selection",
"label": "Steps"
},
"basics": {
"label": "Basics",
"description": "Name and starting template"
}
},
"activeModePack": "Active Mode Pack",
"reviewAgentFlags": "Agent Flags",
"advancedWeightsTitle": "Advanced: Scoring Weights",
"builderSelectModel": "Select model",
"builderProviderFirst": "Pick provider first",
"weightStability": "Stability",
"candidatePoolLabel": "Candidate Pool",
"strategyRules": "Rules (6-Factor Scoring)",
"intelligentPanelTitle": "Intelligent Routing Dashboard",
"weightQuota": "Quota",
"builderFlowTitle": "Combo Builder Flow",
"contextRelaySummaryModel": "Summary Model",
"reviewName": "Name",
"providerScores": "Provider Scores",
"noExcludedProviders": "No providers are currently excluded.",
"builderModel": "Model",
"emailVisibilityStateOff": "Off",
"reviewIntelligentTitle": "Intelligent Routing Config",
"cooldownMinutes": "Cooldown: {minutes}m",
"explorationRateHint": "{percent}% of requests can explore non-optimal providers.",
"builderAddStep": "Add step",
"reviewSteps": "Steps",
"reviewNoSteps": "No steps configured",
"incidentMode": "Incident Mode",
"reviewProviders": "Providers",
"budgetCapPlaceholder": "No limit",
"filterAll": "All",
"intelligentPanelDesc": "Real-time scoring and health status for this auto-routing combo.",
"reviewAdvanced": "Advanced Settings",
"builderStagePending": "Pending",
"filterDeterministic": "Deterministic",
"weightCostInv": "Cost",
"filterIntelligent": "Intelligent",
"allProvidersHealthy": "Providers are reporting healthy routing conditions.",
"builderProvider": "Provider",
"candidatePoolHint": "Select which providers this engine should evaluate. Leave empty to use all active providers.",
"contextRelay": "Context Relay",
"candidatePoolEmpty": "No active providers available yet.",
"statusOverview": "Status Overview",
"weightHealth": "Health",
"filterEmptyTitle": "No combos match this strategy filter.",
"weightTaskFit": "Task Fit",
"builderTitle": "Build a Combo",
"modePackHint": "Switch presets to bias the routing engine without rebuilding the combo.",
"allProvidersEvaluated": "No candidate pool configured. All active providers are evaluated at runtime.",
"contextRelayMaxMessages": "Max Messages For Summary",
"builderStageVisited": "Stage completed",
"builderBrowseCatalog": "Browse catalog",
"builderStageLocked": "Locked — complete previous stage first",
"reorderHandle": "Drag to reorder",
"builderLegacyEntry": "Legacy entry",
"modePackLabel": "Mode Pack",
"builderComboRefStep": "Add combo reference",
"contextRelayHandoffThresholdHelp": "When quota usage reaches this threshold, OmniRoute generates a structured handoff summary before the active account is exhausted.",
"reviewComboRefs": "Combo References",
"failedReorder": "Failed to reorder models",
"emailVisibilityStateOn": "On",
"excludedProvidersHint": "Providers with an OPEN circuit breaker are temporarily excluded from routing.",
"builderComboRef": "Combo Ref",
"modePackUpdated": "Mode pack updated to {pack}.",
"candidatePoolAllProviders": "All providers",
"routerStrategyLabel": "Router Strategy",
"builderIntelligentDesc": "Configure the multi-factor scoring engine for this auto-routing combo.",
"contextRelaySummaryModelHelp": "Optional override model used only for generating the handoff summary. Leave empty to reuse the active combo model.",
"builderAccount": "Account",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex account rotation. Pair it with multiple accounts of the same provider for the best continuity.",
"explorationRateLabel": "Exploration Rate",
"reviewStrategy": "Strategy",
"budgetCapLabel": "Budget Cap (USD / request)",
"contextRelayMaxMessagesHelp": "Limits how much recent history is condensed into the relay summary.",
"filterEmptyIntelligentDescription": "Create an auto or LKGP combo to populate the intelligent routing dashboard.",
"builderLoadingProviders": "Loading providers...",
"builderAddComboRef": "Add combo reference",
"contextRelayDesc": "Preserves session continuity with handoff summaries when accounts rotate",
"weightTierPriority": "Tier",
"highCircuitBreakerRate": "High circuit breaker trip rate detected.",
"excludedProviders": "Excluded Providers",
"reviewAccounts": "Accounts",
"builderSelectProvider": "Select provider",
"normalOperation": "Normal Operation",
"builderPreview": "Preview",
"builderIntelligentTitle": "Intelligent Routing Configuration",
"reviewSequence": "Model Sequence",
"filterEmptyDeterministicDescription": "Only auto and LKGP combos exist right now. Switch back to All or create a deterministic combo.",
"builderPinnedAccount": "Pinned Account",
"builderStageCurrent": "Current stage",
"contextRelayHandoffThreshold": "Handoff Threshold"
},
"costs": {
"title": "náklady",
@ -1147,7 +1272,9 @@
"a2aQuickStartStep2": "Send JSON-RPC requests to `POST /a2a` using `message/send` or `message/stream`.",
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format",
"musicDesc": "Generate music and audio tracks via ComfyUI (Stable Audio, MusicGen)",
"musicGeneration": "Music Generation"
},
"endpoints": {
"tabProxy": "Endpoint Proxy",
@ -1749,7 +1876,22 @@
"close": "Close",
"statusDeactivated": "Deactivated (Manual)",
"statusBanned": "Banned / Sandbox Violation",
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted"
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted",
"audioTranscriptions": "Audio Transcriptions",
"imagesGenerations": "Images Generations",
"noModelsMatch": "No models match \"{filter}\"",
"repairEnvFailed": "Failed to repair .env",
"deselectAllModels": "Deselect all",
"showEmails": "Show all emails",
"repairEnv": "Repair env",
"modelsActiveCount": "{active}/{total} active",
"hideEmails": "Hide all emails",
"repairEnvSuccess": "OAuth defaults restored",
"repairEnvHint": "Restore missing OAuth defaults into .env without overwriting existing values.",
"repairEnvWorking": "Repairing...",
"selectAllModels": "Select all",
"embeddings": "Embeddings",
"audioSpeech": "Audio Speech"
},
"settings": {
"title": "Nastavenia",
@ -2266,7 +2408,11 @@
"wildcardPatternModeDesc": "Use wildcard aliases with * and ? when a family of models should map to one target.",
"noExactAliasesConfigured": "No exact-match aliases configured.",
"wildcardRulesTitle": "Wildcard Rules",
"noWildcardAliasesConfigured": "No wildcard aliases configured."
"noWildcardAliasesConfigured": "No wildcard aliases configured.",
"contextRelayHandoffThreshold": "Handoff Threshold",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex accounts and uses these values as global defaults for new or unconfigured combos.",
"contextRelaySummaryModel": "Summary Model",
"contextRelayMaxMessages": "Max Messages For Summary"
},
"translator": {
"title": "Prekladateľ",
@ -2692,7 +2838,11 @@
"waitingForOpenAIAuthorization": "Čaká sa na autorizáciu OpenAI...",
"waitingForAntigravityAuthorization": "Čaká sa na antigravitačné povolenie...",
"waitingForQoderAuthorization": "Čaká sa na autorizáciu Qoder...",
"exchangingCodeForTokens": "Výmena kódu za tokeny..."
"exchangingCodeForTokens": "Výmena kódu za tokeny...",
"nodeIncompatibleDesc": "You are running Node.js {version}, which is outside OmniRoute's supported secure runtime policy. Use a patched Node.js 20.x or 22.x LTS release.",
"nodeIncompatibleTitle": "Incompatible Node.js Version",
"nodeIncompatibleFixLabel": "Fix: install a patched Node.js 22 LTS release",
"nodeIncompatibleHint": "OmniRoute requires Node.js 20.20.2+ (20.x LTS) or 22.22.2+ (22.x LTS). Node 22 LTS is recommended."
},
"landing": {
"brandName": "OmniRoute",
@ -3108,7 +3258,26 @@
"peakCached": "Peak cached",
"deduplicatedRequests": "Deduplicated Requests",
"savedCalls": "Saved API Calls",
"totalProcessed": "Total Requests Processed"
"totalProcessed": "Total Requests Processed",
"activityVolume": "Activity",
"cacheRateDesc": "of total requests",
"semanticCacheDisabledDesc": "Semantic cache is disabled. OmniRoute will skip local response reuse until you turn it back on in Settings.",
"entriesLoadError": "Failed to load semantic cache entries.",
"peakCacheRate": "Peak Cache Rate",
"trendHour": "Hour",
"providerCacheRateDesc": "Each provider exposes total input tokens, cache read tokens, and cache write tokens so you can verify the reuse ratio against raw totals.",
"busiestHour": "Busiest Hour",
"cachedRequests24h": "Cached Requests (24h)",
"semanticCacheSectionDesc": "OmniRoute's own deterministic response cache. When enabled, repeated non-streaming temperature=0 requests can be served locally without hitting the upstream provider.",
"hoursTracked": "hours tracked",
"promptCacheSectionDesc": "Shows provider-side prompt caching activity from usage history so you can see where cache control is active and how much input reuse you are getting.",
"noTrendData": "No prompt cache activity has been recorded over the last 24 hours.",
"lastUpdated": "Last updated",
"noPromptCacheData": "No provider-side prompt cache activity has been recorded yet.",
"cacheRate": "Cache Rate",
"semanticCache": "Semantic Cache",
"promptTrendDesc": "Hourly request volume, cache coverage, and cache read volume across the last 24 hours.",
"semanticEntriesDesc": "Persisted semantic cache records currently stored in SQLite. Provider-side prompt cache activity is not listed here."
},
"memory": {
"title": "Memory Management",
@ -3132,7 +3301,8 @@
"factual": "Factual",
"episodic": "Episodic",
"procedural": "Procedural",
"semantic": "Semantic"
"semantic": "Semantic",
"delete": "Delete"
},
"skills": {
"title": "Skills",

View file

@ -136,7 +136,10 @@
"Failed to save pricing": "Det gick inte att spara pris",
"Failed to reset pricing": "Det gick inte att återställa prissättningen",
"apikey": "API-nyckel",
"http": "HTTP"
"http": "HTTP",
"goToDashboard": "Go to Dashboard",
"nothingHere": "Nothing here yet",
"checkSystemStatus": "Check System Status"
},
"sidebar": {
"home": "Hem",
@ -640,7 +643,8 @@
"opencode": "Använd när du föredrar terminalbaserade agentkörningar och skriptautomation via OpenCode.",
"kiro": "Använd när du integrerar Kiro och styr modelldirigering centralt från OmniRoute.",
"antigravity": "Använd när Antigravity/Kiro-trafik måste avlyssnas genom MITM och dirigeras till OmniRoute.",
"copilot": "Använd när du vill ha Copilot chattstil UX samtidigt som du upprätthåller OmniRoute-nycklar och routingregler."
"copilot": "Använd när du vill ha Copilot chattstil UX samtidigt som du upprätthåller OmniRoute-nycklar och routingregler.",
"windsurf": "Use when you want an AI-first IDE with Codeium/Windsurf models routed through OmniRoute."
},
"toolDescriptions": {
"antigravity": "Google Antigravity IDE med MITM",
@ -655,7 +659,8 @@
"opencode": "OpenCode AI coding agent (Terminal)",
"kiro": "Amazon Kiro — AI-powered IDE",
"windsurf": "Windsurf AI Code Editor",
"copilot": "GitHub Copilot AI Assistant"
"copilot": "GitHub Copilot AI Assistant",
"qwen": "Alibaba Qwen Code CLI"
},
"guides": {
"cursor": {
@ -890,6 +895,16 @@
"when": "Use when you want perfectly even spread — each model used once before repeating.",
"avoid": "Avoid when models have different quality or latency and order matters.",
"example": "Example: Multiple accounts of the same model to distribute usage evenly."
},
"p2c": {
"avoid": "Avoid for small combos with 2 or fewer models — no benefit over round-robin.",
"when": "Use when you want low-latency selection using Power-of-Two-Choices algorithm.",
"example": "Example: High-throughput inference across 4+ equivalent model endpoints."
},
"context-relay": {
"when": "Use when long sessions must survive account rotation without losing the working context.",
"example": "Example: Codex sessions that rotate across multiple accounts near quota exhaustion.",
"avoid": "Avoid when account switching is rare or when you do not want extra summarization requests."
}
},
"advancedHelp": {
@ -1009,7 +1024,117 @@
"wizardStep3Title": "Choose Strategy",
"wizardStep3Desc": "Pick how requests are distributed across your models - 13 strategies available",
"wizardStep4Title": "Review & Save",
"wizardStep4Desc": "Review your configuration and activate the combo"
"wizardStep4Desc": "Review your configuration and activate the combo",
"builderModel": "Model",
"builderComboRefStep": "Add combo reference",
"filterIntelligent": "Intelligent",
"builderSelectModel": "Select model",
"reviewStrategy": "Strategy",
"weightCostInv": "Cost",
"weightQuota": "Quota",
"builderFlowTitle": "Combo Builder Flow",
"weightTaskFit": "Task Fit",
"reviewNoSteps": "No steps configured",
"builderStage": {
"review": {
"description": "Final validation before saving",
"label": "Review"
},
"intelligent": {
"description": "Auto-routing candidate pool, presets, and scoring",
"label": "Smart Routing"
},
"basics": {
"description": "Name and starting template",
"label": "Basics"
},
"steps": {
"description": "Provider, model, and account selection",
"label": "Steps"
},
"strategy": {
"description": "Routing behavior and advanced settings",
"label": "Strategy"
}
},
"strategyRules": "Rules (6-Factor Scoring)",
"builderSelectProvider": "Select provider",
"excludedProviders": "Excluded Providers",
"builderTitle": "Build a Combo",
"builderAccount": "Account",
"reviewIntelligentTitle": "Intelligent Routing Config",
"builderBrowseCatalog": "Browse catalog",
"filterEmptyIntelligentDescription": "Create an auto or LKGP combo to populate the intelligent routing dashboard.",
"contextRelayHandoffThresholdHelp": "When quota usage reaches this threshold, OmniRoute generates a structured handoff summary before the active account is exhausted.",
"builderStageLocked": "Locked — complete previous stage first",
"reviewComboRefs": "Combo References",
"weightTierPriority": "Tier",
"routerStrategyLabel": "Router Strategy",
"candidatePoolEmpty": "No active providers available yet.",
"builderAddStep": "Add step",
"modePackHint": "Switch presets to bias the routing engine without rebuilding the combo.",
"filterEmptyTitle": "No combos match this strategy filter.",
"contextRelay": "Context Relay",
"reviewSteps": "Steps",
"providerScores": "Provider Scores",
"contextRelayMaxMessages": "Max Messages For Summary",
"advancedWeightsTitle": "Advanced: Scoring Weights",
"weightLatencyInv": "Latency",
"intelligentPanelDesc": "Real-time scoring and health status for this auto-routing combo.",
"excludedProvidersHint": "Providers with an OPEN circuit breaker are temporarily excluded from routing.",
"budgetCapLabel": "Budget Cap (USD / request)",
"normalOperation": "Normal Operation",
"contextRelaySummaryModelHelp": "Optional override model used only for generating the handoff summary. Leave empty to reuse the active combo model.",
"contextRelayHandoffThreshold": "Handoff Threshold",
"reviewName": "Name",
"contextRelaySummaryModel": "Summary Model",
"filterEmptyDeterministicDescription": "Only auto and LKGP combos exist right now. Switch back to All or create a deterministic combo.",
"cooldownMinutes": "Cooldown: {minutes}m",
"statusOverview": "Status Overview",
"emailVisibilityStateOn": "On",
"modePackLabel": "Mode Pack",
"failedReorder": "Failed to reorder models",
"candidatePoolHint": "Select which providers this engine should evaluate. Leave empty to use all active providers.",
"incidentMode": "Incident Mode",
"builderStagePending": "Pending",
"builderIntelligentTitle": "Intelligent Routing Configuration",
"builderStageCurrent": "Current stage",
"noExcludedProviders": "No providers are currently excluded.",
"reorderHandle": "Drag to reorder",
"activeModePack": "Active Mode Pack",
"builderPinnedAccount": "Pinned Account",
"modePackUpdated": "Mode pack updated to {pack}.",
"builderPreview": "Preview",
"weightStability": "Stability",
"candidatePoolLabel": "Candidate Pool",
"builderStageVisited": "Stage completed",
"highCircuitBreakerRate": "High circuit breaker trip rate detected.",
"reviewSequence": "Model Sequence",
"weightHealth": "Health",
"reviewProviders": "Providers",
"allProvidersEvaluated": "No candidate pool configured. All active providers are evaluated at runtime.",
"builderProvider": "Provider",
"filterAll": "All",
"builderProviderFirst": "Pick provider first",
"candidatePoolAllProviders": "All providers",
"emailVisibilityStateOff": "Off",
"explorationRateHint": "{percent}% of requests can explore non-optimal providers.",
"explorationRateLabel": "Exploration Rate",
"builderComboRef": "Combo Ref",
"builderLoadingProviders": "Loading providers...",
"contextRelayDesc": "Preserves session continuity with handoff summaries when accounts rotate",
"reviewAgentFlags": "Agent Flags",
"allProvidersHealthy": "Providers are reporting healthy routing conditions.",
"budgetCapPlaceholder": "No limit",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex account rotation. Pair it with multiple accounts of the same provider for the best continuity.",
"builderLegacyEntry": "Legacy entry",
"builderIntelligentDesc": "Configure the multi-factor scoring engine for this auto-routing combo.",
"intelligentPanelTitle": "Intelligent Routing Dashboard",
"reviewAdvanced": "Advanced Settings",
"reviewAccounts": "Accounts",
"contextRelayMaxMessagesHelp": "Limits how much recent history is condensed into the relay summary.",
"builderAddComboRef": "Add combo reference",
"filterDeterministic": "Deterministic"
},
"costs": {
"title": "Kostnader",
@ -1147,7 +1272,9 @@
"a2aQuickStartStep2": "Send JSON-RPC requests to `POST /a2a` using `message/send` or `message/stream`.",
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format",
"musicGeneration": "Music Generation",
"musicDesc": "Generate music and audio tracks via ComfyUI (Stable Audio, MusicGen)"
},
"endpoints": {
"tabProxy": "Endpoint Proxy",
@ -1749,7 +1876,22 @@
"close": "Close",
"statusDeactivated": "Deactivated (Manual)",
"statusBanned": "Banned / Sandbox Violation",
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted"
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted",
"embeddings": "Embeddings",
"modelsActiveCount": "{active}/{total} active",
"imagesGenerations": "Images Generations",
"repairEnvHint": "Restore missing OAuth defaults into .env without overwriting existing values.",
"noModelsMatch": "No models match \"{filter}\"",
"selectAllModels": "Select all",
"repairEnvWorking": "Repairing...",
"audioTranscriptions": "Audio Transcriptions",
"hideEmails": "Hide all emails",
"audioSpeech": "Audio Speech",
"repairEnvFailed": "Failed to repair .env",
"repairEnv": "Repair env",
"repairEnvSuccess": "OAuth defaults restored",
"showEmails": "Show all emails",
"deselectAllModels": "Deselect all"
},
"settings": {
"title": "Inställningar",
@ -2266,7 +2408,11 @@
"wildcardPatternModeDesc": "Use wildcard aliases with * and ? when a family of models should map to one target.",
"noExactAliasesConfigured": "No exact-match aliases configured.",
"wildcardRulesTitle": "Wildcard Rules",
"noWildcardAliasesConfigured": "No wildcard aliases configured."
"noWildcardAliasesConfigured": "No wildcard aliases configured.",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex accounts and uses these values as global defaults for new or unconfigured combos.",
"contextRelaySummaryModel": "Summary Model",
"contextRelayMaxMessages": "Max Messages For Summary",
"contextRelayHandoffThreshold": "Handoff Threshold"
},
"translator": {
"title": "Översättare",
@ -2692,7 +2838,11 @@
"waitingForOpenAIAuthorization": "Väntar på OpenAI-auktorisering...",
"waitingForAntigravityAuthorization": "Väntar på antigravitationstillstånd...",
"waitingForQoderAuthorization": "Väntar på Qoder-auktorisering...",
"exchangingCodeForTokens": "Byter ut kod för tokens..."
"exchangingCodeForTokens": "Byter ut kod för tokens...",
"nodeIncompatibleDesc": "You are running Node.js {version}, which is outside OmniRoute's supported secure runtime policy. Use a patched Node.js 20.x or 22.x LTS release.",
"nodeIncompatibleTitle": "Incompatible Node.js Version",
"nodeIncompatibleHint": "OmniRoute requires Node.js 20.20.2+ (20.x LTS) or 22.22.2+ (22.x LTS). Node 22 LTS is recommended.",
"nodeIncompatibleFixLabel": "Fix: install a patched Node.js 22 LTS release"
},
"landing": {
"brandName": "OmniRoute",
@ -3108,7 +3258,26 @@
"peakCached": "Peak cached",
"deduplicatedRequests": "Deduplicated Requests",
"savedCalls": "Saved API Calls",
"totalProcessed": "Total Requests Processed"
"totalProcessed": "Total Requests Processed",
"semanticCacheSectionDesc": "OmniRoute's own deterministic response cache. When enabled, repeated non-streaming temperature=0 requests can be served locally without hitting the upstream provider.",
"providerCacheRateDesc": "Each provider exposes total input tokens, cache read tokens, and cache write tokens so you can verify the reuse ratio against raw totals.",
"semanticCache": "Semantic Cache",
"cacheRateDesc": "of total requests",
"noPromptCacheData": "No provider-side prompt cache activity has been recorded yet.",
"lastUpdated": "Last updated",
"trendHour": "Hour",
"hoursTracked": "hours tracked",
"promptTrendDesc": "Hourly request volume, cache coverage, and cache read volume across the last 24 hours.",
"noTrendData": "No prompt cache activity has been recorded over the last 24 hours.",
"semanticEntriesDesc": "Persisted semantic cache records currently stored in SQLite. Provider-side prompt cache activity is not listed here.",
"busiestHour": "Busiest Hour",
"promptCacheSectionDesc": "Shows provider-side prompt caching activity from usage history so you can see where cache control is active and how much input reuse you are getting.",
"activityVolume": "Activity",
"cacheRate": "Cache Rate",
"entriesLoadError": "Failed to load semantic cache entries.",
"semanticCacheDisabledDesc": "Semantic cache is disabled. OmniRoute will skip local response reuse until you turn it back on in Settings.",
"cachedRequests24h": "Cached Requests (24h)",
"peakCacheRate": "Peak Cache Rate"
},
"memory": {
"title": "Memory Management",
@ -3132,7 +3301,8 @@
"factual": "Factual",
"episodic": "Episodic",
"procedural": "Procedural",
"semantic": "Semantic"
"semantic": "Semantic",
"delete": "Delete"
},
"skills": {
"title": "Skills",

View file

@ -136,7 +136,10 @@
"Failed to save pricing": "บันทึกราคาไม่สำเร็จ",
"Failed to reset pricing": "ไม่สามารถรีเซ็ตราคาได้",
"apikey": "คีย์ API",
"http": "HTTP"
"http": "HTTP",
"goToDashboard": "Go to Dashboard",
"nothingHere": "Nothing here yet",
"checkSystemStatus": "Check System Status"
},
"sidebar": {
"home": "บ้าน",
@ -640,7 +643,8 @@
"opencode": "ใช้เมื่อคุณต้องการเรียกใช้ Terminal-Native Agent และใช้สคริปต์อัตโนมัติผ่าน OpenCode",
"kiro": "ใช้เมื่อรวม Kiro และควบคุมการกำหนดเส้นทางโมเดลจากส่วนกลางจาก OmniRoute",
"antigravity": "ใช้เมื่อต้องสกัดกั้นการรับส่งข้อมูล Antigravity/Kiro ผ่าน MITM และกำหนดเส้นทางไปยัง OmniRoute",
"copilot": "ใช้เมื่อคุณต้องการ UX รูปแบบการแชทของ Copilot ในขณะที่บังคับใช้คีย์ OmniRoute และกฎการกำหนดเส้นทาง"
"copilot": "ใช้เมื่อคุณต้องการ UX รูปแบบการแชทของ Copilot ในขณะที่บังคับใช้คีย์ OmniRoute และกฎการกำหนดเส้นทาง",
"windsurf": "Use when you want an AI-first IDE with Codeium/Windsurf models routed through OmniRoute."
},
"toolDescriptions": {
"antigravity": "Google ต้านแรงโน้มถ่วง IDE พร้อม MITM",
@ -655,7 +659,8 @@
"opencode": "OpenCode AI coding agent (Terminal)",
"kiro": "Amazon Kiro — AI-powered IDE",
"windsurf": "Windsurf AI Code Editor",
"copilot": "GitHub Copilot AI Assistant"
"copilot": "GitHub Copilot AI Assistant",
"qwen": "Alibaba Qwen Code CLI"
},
"guides": {
"cursor": {
@ -890,6 +895,16 @@
"when": "Use when you want perfectly even spread — each model used once before repeating.",
"avoid": "Avoid when models have different quality or latency and order matters.",
"example": "Example: Multiple accounts of the same model to distribute usage evenly."
},
"p2c": {
"when": "Use when you want low-latency selection using Power-of-Two-Choices algorithm.",
"example": "Example: High-throughput inference across 4+ equivalent model endpoints.",
"avoid": "Avoid for small combos with 2 or fewer models — no benefit over round-robin."
},
"context-relay": {
"when": "Use when long sessions must survive account rotation without losing the working context.",
"example": "Example: Codex sessions that rotate across multiple accounts near quota exhaustion.",
"avoid": "Avoid when account switching is rare or when you do not want extra summarization requests."
}
},
"advancedHelp": {
@ -1009,7 +1024,117 @@
"wizardStep3Title": "Choose Strategy",
"wizardStep3Desc": "Pick how requests are distributed across your models - 13 strategies available",
"wizardStep4Title": "Review & Save",
"wizardStep4Desc": "Review your configuration and activate the combo"
"wizardStep4Desc": "Review your configuration and activate the combo",
"reviewIntelligentTitle": "Intelligent Routing Config",
"filterEmptyIntelligentDescription": "Create an auto or LKGP combo to populate the intelligent routing dashboard.",
"failedReorder": "Failed to reorder models",
"candidatePoolLabel": "Candidate Pool",
"routerStrategyLabel": "Router Strategy",
"builderStage": {
"steps": {
"description": "Provider, model, and account selection",
"label": "Steps"
},
"basics": {
"description": "Name and starting template",
"label": "Basics"
},
"review": {
"description": "Final validation before saving",
"label": "Review"
},
"strategy": {
"description": "Routing behavior and advanced settings",
"label": "Strategy"
},
"intelligent": {
"label": "Smart Routing",
"description": "Auto-routing candidate pool, presets, and scoring"
}
},
"candidatePoolEmpty": "No active providers available yet.",
"emailVisibilityStateOn": "On",
"highCircuitBreakerRate": "High circuit breaker trip rate detected.",
"reviewAccounts": "Accounts",
"contextRelayHandoffThreshold": "Handoff Threshold",
"filterDeterministic": "Deterministic",
"reviewComboRefs": "Combo References",
"weightTierPriority": "Tier",
"reviewSequence": "Model Sequence",
"builderProviderFirst": "Pick provider first",
"modePackHint": "Switch presets to bias the routing engine without rebuilding the combo.",
"reviewAgentFlags": "Agent Flags",
"builderStageVisited": "Stage completed",
"reviewName": "Name",
"intelligentPanelDesc": "Real-time scoring and health status for this auto-routing combo.",
"builderLegacyEntry": "Legacy entry",
"builderAccount": "Account",
"builderStagePending": "Pending",
"builderProvider": "Provider",
"builderLoadingProviders": "Loading providers...",
"builderPreview": "Preview",
"builderTitle": "Build a Combo",
"modePackUpdated": "Mode pack updated to {pack}.",
"advancedWeightsTitle": "Advanced: Scoring Weights",
"budgetCapPlaceholder": "No limit",
"reviewNoSteps": "No steps configured",
"contextRelayDesc": "Preserves session continuity with handoff summaries when accounts rotate",
"reviewStrategy": "Strategy",
"excludedProviders": "Excluded Providers",
"modePackLabel": "Mode Pack",
"reorderHandle": "Drag to reorder",
"weightTaskFit": "Task Fit",
"reviewSteps": "Steps",
"excludedProvidersHint": "Providers with an OPEN circuit breaker are temporarily excluded from routing.",
"builderModel": "Model",
"explorationRateLabel": "Exploration Rate",
"reviewProviders": "Providers",
"allProvidersHealthy": "Providers are reporting healthy routing conditions.",
"builderIntelligentTitle": "Intelligent Routing Configuration",
"builderPinnedAccount": "Pinned Account",
"providerScores": "Provider Scores",
"builderAddStep": "Add step",
"contextRelaySummaryModel": "Summary Model",
"strategyRules": "Rules (6-Factor Scoring)",
"weightCostInv": "Cost",
"statusOverview": "Status Overview",
"filterAll": "All",
"budgetCapLabel": "Budget Cap (USD / request)",
"weightQuota": "Quota",
"normalOperation": "Normal Operation",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex account rotation. Pair it with multiple accounts of the same provider for the best continuity.",
"intelligentPanelTitle": "Intelligent Routing Dashboard",
"contextRelay": "Context Relay",
"incidentMode": "Incident Mode",
"builderBrowseCatalog": "Browse catalog",
"builderSelectProvider": "Select provider",
"builderSelectModel": "Select model",
"noExcludedProviders": "No providers are currently excluded.",
"filterEmptyDeterministicDescription": "Only auto and LKGP combos exist right now. Switch back to All or create a deterministic combo.",
"reviewAdvanced": "Advanced Settings",
"contextRelayMaxMessagesHelp": "Limits how much recent history is condensed into the relay summary.",
"weightHealth": "Health",
"builderStageLocked": "Locked — complete previous stage first",
"builderComboRefStep": "Add combo reference",
"builderComboRef": "Combo Ref",
"builderFlowTitle": "Combo Builder Flow",
"allProvidersEvaluated": "No candidate pool configured. All active providers are evaluated at runtime.",
"builderStageCurrent": "Current stage",
"contextRelaySummaryModelHelp": "Optional override model used only for generating the handoff summary. Leave empty to reuse the active combo model.",
"emailVisibilityStateOff": "Off",
"activeModePack": "Active Mode Pack",
"builderAddComboRef": "Add combo reference",
"cooldownMinutes": "Cooldown: {minutes}m",
"filterEmptyTitle": "No combos match this strategy filter.",
"contextRelayMaxMessages": "Max Messages For Summary",
"builderIntelligentDesc": "Configure the multi-factor scoring engine for this auto-routing combo.",
"candidatePoolAllProviders": "All providers",
"filterIntelligent": "Intelligent",
"weightLatencyInv": "Latency",
"explorationRateHint": "{percent}% of requests can explore non-optimal providers.",
"contextRelayHandoffThresholdHelp": "When quota usage reaches this threshold, OmniRoute generates a structured handoff summary before the active account is exhausted.",
"candidatePoolHint": "Select which providers this engine should evaluate. Leave empty to use all active providers.",
"weightStability": "Stability"
},
"costs": {
"title": "ค่าใช้จ่าย",
@ -1147,7 +1272,9 @@
"a2aQuickStartStep2": "Send JSON-RPC requests to `POST /a2a` using `message/send` or `message/stream`.",
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format",
"musicDesc": "Generate music and audio tracks via ComfyUI (Stable Audio, MusicGen)",
"musicGeneration": "Music Generation"
},
"endpoints": {
"tabProxy": "Endpoint Proxy",
@ -1749,7 +1876,22 @@
"close": "Close",
"statusDeactivated": "Deactivated (Manual)",
"statusBanned": "Banned / Sandbox Violation",
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted"
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted",
"repairEnvWorking": "Repairing...",
"noModelsMatch": "No models match \"{filter}\"",
"audioSpeech": "Audio Speech",
"selectAllModels": "Select all",
"repairEnvHint": "Restore missing OAuth defaults into .env without overwriting existing values.",
"repairEnvSuccess": "OAuth defaults restored",
"modelsActiveCount": "{active}/{total} active",
"repairEnvFailed": "Failed to repair .env",
"showEmails": "Show all emails",
"deselectAllModels": "Deselect all",
"repairEnv": "Repair env",
"embeddings": "Embeddings",
"audioTranscriptions": "Audio Transcriptions",
"hideEmails": "Hide all emails",
"imagesGenerations": "Images Generations"
},
"settings": {
"title": "การตั้งค่า",
@ -2266,7 +2408,11 @@
"wildcardPatternModeDesc": "Use wildcard aliases with * and ? when a family of models should map to one target.",
"noExactAliasesConfigured": "No exact-match aliases configured.",
"wildcardRulesTitle": "Wildcard Rules",
"noWildcardAliasesConfigured": "No wildcard aliases configured."
"noWildcardAliasesConfigured": "No wildcard aliases configured.",
"contextRelayHandoffThreshold": "Handoff Threshold",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex accounts and uses these values as global defaults for new or unconfigured combos.",
"contextRelaySummaryModel": "Summary Model",
"contextRelayMaxMessages": "Max Messages For Summary"
},
"translator": {
"title": "นักแปล",
@ -2692,7 +2838,11 @@
"waitingForOpenAIAuthorization": "กำลังรอการอนุญาต OpenAI...",
"waitingForAntigravityAuthorization": "กำลังรอการอนุญาตต้านแรงโน้มถ่วง...",
"waitingForQoderAuthorization": "กำลังรอการอนุญาตจาก Qoder...",
"exchangingCodeForTokens": "การเปลี่ยนรหัสเป็นโทเค็น..."
"exchangingCodeForTokens": "การเปลี่ยนรหัสเป็นโทเค็น...",
"nodeIncompatibleHint": "OmniRoute requires Node.js 20.20.2+ (20.x LTS) or 22.22.2+ (22.x LTS). Node 22 LTS is recommended.",
"nodeIncompatibleDesc": "You are running Node.js {version}, which is outside OmniRoute's supported secure runtime policy. Use a patched Node.js 20.x or 22.x LTS release.",
"nodeIncompatibleFixLabel": "Fix: install a patched Node.js 22 LTS release",
"nodeIncompatibleTitle": "Incompatible Node.js Version"
},
"landing": {
"brandName": "OmniRoute",
@ -3108,7 +3258,26 @@
"peakCached": "Peak cached",
"deduplicatedRequests": "Deduplicated Requests",
"savedCalls": "Saved API Calls",
"totalProcessed": "Total Requests Processed"
"totalProcessed": "Total Requests Processed",
"hoursTracked": "hours tracked",
"cacheRateDesc": "of total requests",
"busiestHour": "Busiest Hour",
"entriesLoadError": "Failed to load semantic cache entries.",
"promptCacheSectionDesc": "Shows provider-side prompt caching activity from usage history so you can see where cache control is active and how much input reuse you are getting.",
"semanticCacheDisabledDesc": "Semantic cache is disabled. OmniRoute will skip local response reuse until you turn it back on in Settings.",
"semanticCache": "Semantic Cache",
"cachedRequests24h": "Cached Requests (24h)",
"noPromptCacheData": "No provider-side prompt cache activity has been recorded yet.",
"semanticEntriesDesc": "Persisted semantic cache records currently stored in SQLite. Provider-side prompt cache activity is not listed here.",
"promptTrendDesc": "Hourly request volume, cache coverage, and cache read volume across the last 24 hours.",
"semanticCacheSectionDesc": "OmniRoute's own deterministic response cache. When enabled, repeated non-streaming temperature=0 requests can be served locally without hitting the upstream provider.",
"providerCacheRateDesc": "Each provider exposes total input tokens, cache read tokens, and cache write tokens so you can verify the reuse ratio against raw totals.",
"trendHour": "Hour",
"peakCacheRate": "Peak Cache Rate",
"noTrendData": "No prompt cache activity has been recorded over the last 24 hours.",
"activityVolume": "Activity",
"cacheRate": "Cache Rate",
"lastUpdated": "Last updated"
},
"memory": {
"title": "Memory Management",
@ -3132,7 +3301,8 @@
"factual": "Factual",
"episodic": "Episodic",
"procedural": "Procedural",
"semantic": "Semantic"
"semantic": "Semantic",
"delete": "Delete"
},
"skills": {
"title": "Skills",

View file

@ -136,7 +136,10 @@
"Failed to save pricing": "Fiyat kaydedilemedi",
"Failed to reset pricing": "Fiyatlandırma sıfırlanamadı",
"apikey": "API Anahtarı",
"http": "HTTP"
"http": "HTTP",
"nothingHere": "Nothing here yet",
"goToDashboard": "Go to Dashboard",
"checkSystemStatus": "Check System Status"
},
"sidebar": {
"home": "Ana Sayfa",
@ -640,7 +643,8 @@
"opencode": "Terminal yerel ajan çalıştırmaları ve OpenCode ile betik tabanlı otomasyon tercih ettiğinizde kullanın.",
"kiro": "Kiro'yu entegre ederken model yönlendirmesini OmniRoute üzerinden merkezi olarak yönetmek istediğinizde kullanın.",
"antigravity": "Antigravity/Kiro trafiğinin MITM üzerinden yakalanıp OmniRoute'a yönlendirilmesi gerektiğinde kullanın.",
"copilot": "OmniRoute anahtarları ve yönlendirme kuralları uygulanırken Copilot sohbet tarzı bir UX istediğinizde kullanın."
"copilot": "OmniRoute anahtarları ve yönlendirme kuralları uygulanırken Copilot sohbet tarzı bir UX istediğinizde kullanın.",
"windsurf": "Use when you want an AI-first IDE with Codeium/Windsurf models routed through OmniRoute."
},
"toolDescriptions": {
"antigravity": "MITM ile Google Antigravity IDE",
@ -655,7 +659,8 @@
"opencode": "OpenCode AI kodlama ajanı (Terminal)",
"kiro": "Amazon Kiro - AI destekli IDE",
"windsurf": "Windsurf AI Code Editor",
"copilot": "GitHub Copilot AI Assistant"
"copilot": "GitHub Copilot AI Assistant",
"qwen": "Alibaba Qwen Code CLI"
},
"guides": {
"cursor": {
@ -890,6 +895,16 @@
"when": "Use when you want perfectly even spread — each model used once before repeating.",
"avoid": "Avoid when models have different quality or latency and order matters.",
"example": "Example: Multiple accounts of the same model to distribute usage evenly."
},
"p2c": {
"avoid": "Avoid for small combos with 2 or fewer models — no benefit over round-robin.",
"when": "Use when you want low-latency selection using Power-of-Two-Choices algorithm.",
"example": "Example: High-throughput inference across 4+ equivalent model endpoints."
},
"context-relay": {
"when": "Use when long sessions must survive account rotation without losing the working context.",
"example": "Example: Codex sessions that rotate across multiple accounts near quota exhaustion.",
"avoid": "Avoid when account switching is rare or when you do not want extra summarization requests."
}
},
"advancedHelp": {
@ -1009,7 +1024,117 @@
"wizardStep3Title": "Choose Strategy",
"wizardStep3Desc": "Pick how requests are distributed across your models - 13 strategies available",
"wizardStep4Title": "Review & Save",
"wizardStep4Desc": "Review your configuration and activate the combo"
"wizardStep4Desc": "Review your configuration and activate the combo",
"intelligentPanelTitle": "Intelligent Routing Dashboard",
"builderStage": {
"intelligent": {
"label": "Smart Routing",
"description": "Auto-routing candidate pool, presets, and scoring"
},
"steps": {
"label": "Steps",
"description": "Provider, model, and account selection"
},
"strategy": {
"label": "Strategy",
"description": "Routing behavior and advanced settings"
},
"review": {
"label": "Review",
"description": "Final validation before saving"
},
"basics": {
"description": "Name and starting template",
"label": "Basics"
}
},
"builderSelectProvider": "Select provider",
"candidatePoolAllProviders": "All providers",
"budgetCapPlaceholder": "No limit",
"builderStagePending": "Pending",
"builderIntelligentDesc": "Configure the multi-factor scoring engine for this auto-routing combo.",
"builderStageVisited": "Stage completed",
"highCircuitBreakerRate": "High circuit breaker trip rate detected.",
"reviewSequence": "Model Sequence",
"weightTaskFit": "Task Fit",
"builderComboRef": "Combo Ref",
"weightStability": "Stability",
"explorationRateLabel": "Exploration Rate",
"reviewComboRefs": "Combo References",
"reviewAgentFlags": "Agent Flags",
"builderPreview": "Preview",
"contextRelayMaxMessagesHelp": "Limits how much recent history is condensed into the relay summary.",
"candidatePoolLabel": "Candidate Pool",
"budgetCapLabel": "Budget Cap (USD / request)",
"builderLoadingProviders": "Loading providers...",
"reviewIntelligentTitle": "Intelligent Routing Config",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex account rotation. Pair it with multiple accounts of the same provider for the best continuity.",
"activeModePack": "Active Mode Pack",
"failedReorder": "Failed to reorder models",
"builderAddComboRef": "Add combo reference",
"routerStrategyLabel": "Router Strategy",
"candidatePoolEmpty": "No active providers available yet.",
"noExcludedProviders": "No providers are currently excluded.",
"builderTitle": "Build a Combo",
"builderComboRefStep": "Add combo reference",
"incidentMode": "Incident Mode",
"builderPinnedAccount": "Pinned Account",
"candidatePoolHint": "Select which providers this engine should evaluate. Leave empty to use all active providers.",
"emailVisibilityStateOff": "Off",
"filterEmptyDeterministicDescription": "Only auto and LKGP combos exist right now. Switch back to All or create a deterministic combo.",
"weightTierPriority": "Tier",
"allProvidersHealthy": "Providers are reporting healthy routing conditions.",
"builderProviderFirst": "Pick provider first",
"modePackHint": "Switch presets to bias the routing engine without rebuilding the combo.",
"builderAddStep": "Add step",
"contextRelayDesc": "Preserves session continuity with handoff summaries when accounts rotate",
"intelligentPanelDesc": "Real-time scoring and health status for this auto-routing combo.",
"reviewSteps": "Steps",
"builderProvider": "Provider",
"weightQuota": "Quota",
"filterEmptyTitle": "No combos match this strategy filter.",
"cooldownMinutes": "Cooldown: {minutes}m",
"filterAll": "All",
"explorationRateHint": "{percent}% of requests can explore non-optimal providers.",
"contextRelayMaxMessages": "Max Messages For Summary",
"normalOperation": "Normal Operation",
"statusOverview": "Status Overview",
"excludedProviders": "Excluded Providers",
"contextRelay": "Context Relay",
"allProvidersEvaluated": "No candidate pool configured. All active providers are evaluated at runtime.",
"contextRelayHandoffThreshold": "Handoff Threshold",
"filterDeterministic": "Deterministic",
"reviewNoSteps": "No steps configured",
"weightCostInv": "Cost",
"filterEmptyIntelligentDescription": "Create an auto or LKGP combo to populate the intelligent routing dashboard.",
"contextRelayHandoffThresholdHelp": "When quota usage reaches this threshold, OmniRoute generates a structured handoff summary before the active account is exhausted.",
"builderIntelligentTitle": "Intelligent Routing Configuration",
"reorderHandle": "Drag to reorder",
"builderLegacyEntry": "Legacy entry",
"modePackLabel": "Mode Pack",
"reviewProviders": "Providers",
"builderStageLocked": "Locked — complete previous stage first",
"contextRelaySummaryModel": "Summary Model",
"builderSelectModel": "Select model",
"contextRelaySummaryModelHelp": "Optional override model used only for generating the handoff summary. Leave empty to reuse the active combo model.",
"strategyRules": "Rules (6-Factor Scoring)",
"reviewAccounts": "Accounts",
"weightHealth": "Health",
"reviewAdvanced": "Advanced Settings",
"builderStageCurrent": "Current stage",
"reviewStrategy": "Strategy",
"filterIntelligent": "Intelligent",
"weightLatencyInv": "Latency",
"builderFlowTitle": "Combo Builder Flow",
"builderBrowseCatalog": "Browse catalog",
"builderModel": "Model",
"modePackUpdated": "Mode pack updated to {pack}.",
"builderAccount": "Account",
"emailVisibilityStateOn": "On",
"advancedWeightsTitle": "Advanced: Scoring Weights",
"excludedProvidersHint": "Providers with an OPEN circuit breaker are temporarily excluded from routing.",
"reviewName": "Name",
"providerScores": "Provider Scores"
},
"costs": {
"title": "Maliyetler",
@ -1147,7 +1272,9 @@
"a2aQuickStartStep2": "JSON-RPC isteklerini `message/send` veya `message/stream` kullanarak `POST /a2a` adresine gönderin.",
"a2aQuickStartStep3": "Görevleri `tasks/get` ve `tasks/cancel` ile izleyin ve yönetin.",
"completionsLegacy": "Tamamlamalar (Eski)",
"completionsLegacyDesc": "Eski OpenAI metin tamamlamaları — hem bilgi istemi dizesini hem de mesaj dizisi biçimini kabul eder"
"completionsLegacyDesc": "Eski OpenAI metin tamamlamaları — hem bilgi istemi dizesini hem de mesaj dizisi biçimini kabul eder",
"musicDesc": "Generate music and audio tracks via ComfyUI (Stable Audio, MusicGen)",
"musicGeneration": "Music Generation"
},
"endpoints": {
"tabProxy": "Uç Nokta Proxy",
@ -1749,7 +1876,22 @@
"close": "Close",
"statusDeactivated": "Deactivated (Manual)",
"statusBanned": "Banned / Sandbox Violation",
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted"
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted",
"deselectAllModels": "Deselect all",
"imagesGenerations": "Images Generations",
"repairEnvHint": "Restore missing OAuth defaults into .env without overwriting existing values.",
"repairEnv": "Repair env",
"showEmails": "Show all emails",
"repairEnvFailed": "Failed to repair .env",
"repairEnvWorking": "Repairing...",
"hideEmails": "Hide all emails",
"audioTranscriptions": "Audio Transcriptions",
"modelsActiveCount": "{active}/{total} active",
"selectAllModels": "Select all",
"noModelsMatch": "No models match \"{filter}\"",
"embeddings": "Embeddings",
"audioSpeech": "Audio Speech",
"repairEnvSuccess": "OAuth defaults restored"
},
"settings": {
"title": "Ayarlar",
@ -2266,7 +2408,11 @@
"wildcardPatternModeDesc": "Use wildcard aliases with * and ? when a family of models should map to one target.",
"noExactAliasesConfigured": "No exact-match aliases configured.",
"wildcardRulesTitle": "Wildcard Rules",
"noWildcardAliasesConfigured": "No wildcard aliases configured."
"noWildcardAliasesConfigured": "No wildcard aliases configured.",
"contextRelaySummaryModel": "Summary Model",
"contextRelayMaxMessages": "Max Messages For Summary",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex accounts and uses these values as global defaults for new or unconfigured combos.",
"contextRelayHandoffThreshold": "Handoff Threshold"
},
"translator": {
"title": "Çeviri",
@ -2692,7 +2838,11 @@
"waitingForOpenAIAuthorization": "OpenAI yetkilendirmesi bekleniyor...",
"waitingForAntigravityAuthorization": "Antigravity yetkilendirmesi bekleniyor...",
"waitingForQoderAuthorization": "Qoder yetkilendirmesi bekleniyor...",
"exchangingCodeForTokens": "Kod jetonlarla değiştiriliyor..."
"exchangingCodeForTokens": "Kod jetonlarla değiştiriliyor...",
"nodeIncompatibleHint": "OmniRoute requires Node.js 20.20.2+ (20.x LTS) or 22.22.2+ (22.x LTS). Node 22 LTS is recommended.",
"nodeIncompatibleTitle": "Incompatible Node.js Version",
"nodeIncompatibleFixLabel": "Fix: install a patched Node.js 22 LTS release",
"nodeIncompatibleDesc": "You are running Node.js {version}, which is outside OmniRoute's supported secure runtime policy. Use a patched Node.js 20.x or 22.x LTS release."
},
"landing": {
"brandName": "OmniRoute",
@ -3108,7 +3258,26 @@
"peakCached": "Peak cached",
"deduplicatedRequests": "Deduplicated Requests",
"savedCalls": "Saved API Calls",
"totalProcessed": "Total Requests Processed"
"totalProcessed": "Total Requests Processed",
"activityVolume": "Activity",
"trendHour": "Hour",
"cacheRate": "Cache Rate",
"noPromptCacheData": "No provider-side prompt cache activity has been recorded yet.",
"busiestHour": "Busiest Hour",
"semanticCacheSectionDesc": "OmniRoute's own deterministic response cache. When enabled, repeated non-streaming temperature=0 requests can be served locally without hitting the upstream provider.",
"cacheRateDesc": "of total requests",
"noTrendData": "No prompt cache activity has been recorded over the last 24 hours.",
"hoursTracked": "hours tracked",
"cachedRequests24h": "Cached Requests (24h)",
"peakCacheRate": "Peak Cache Rate",
"promptCacheSectionDesc": "Shows provider-side prompt caching activity from usage history so you can see where cache control is active and how much input reuse you are getting.",
"lastUpdated": "Last updated",
"entriesLoadError": "Failed to load semantic cache entries.",
"semanticEntriesDesc": "Persisted semantic cache records currently stored in SQLite. Provider-side prompt cache activity is not listed here.",
"promptTrendDesc": "Hourly request volume, cache coverage, and cache read volume across the last 24 hours.",
"semanticCacheDisabledDesc": "Semantic cache is disabled. OmniRoute will skip local response reuse until you turn it back on in Settings.",
"semanticCache": "Semantic Cache",
"providerCacheRateDesc": "Each provider exposes total input tokens, cache read tokens, and cache write tokens so you can verify the reuse ratio against raw totals."
},
"memory": {
"title": "Memory Management",
@ -3132,7 +3301,8 @@
"factual": "Factual",
"episodic": "Episodic",
"procedural": "Procedural",
"semantic": "Semantic"
"semantic": "Semantic",
"delete": "Delete"
},
"skills": {
"title": "Skills",

View file

@ -136,7 +136,10 @@
"Failed to save pricing": "Не вдалося зберегти ціни",
"Failed to reset pricing": "Не вдалося скинути ціни",
"apikey": "Ключ API",
"http": "HTTP"
"http": "HTTP",
"nothingHere": "Nothing here yet",
"checkSystemStatus": "Check System Status",
"goToDashboard": "Go to Dashboard"
},
"sidebar": {
"home": "додому",
@ -640,7 +643,8 @@
"opencode": "Використовуйте, якщо ви віддаєте перевагу запуску агента на терміналі та автоматизації за сценарієм через OpenCode.",
"kiro": "Використовуйте під час інтеграції Kiro та централізованого керування маршрутизацією моделі з OmniRoute.",
"antigravity": "Використовуйте, коли трафік Antigravity/Kiro потрібно перехопити через MITM і направити на OmniRoute.",
"copilot": "Використовуйте, коли вам потрібен UX у стилі чату Copilot із застосуванням ключів OmniRoute і правил маршрутизації."
"copilot": "Використовуйте, коли вам потрібен UX у стилі чату Copilot із застосуванням ключів OmniRoute і правил маршрутизації.",
"windsurf": "Use when you want an AI-first IDE with Codeium/Windsurf models routed through OmniRoute."
},
"toolDescriptions": {
"antigravity": "Google Antigravity IDE з MITM",
@ -655,7 +659,8 @@
"opencode": "OpenCode AI coding agent (Terminal)",
"kiro": "Amazon Kiro — AI-powered IDE",
"windsurf": "Windsurf AI Code Editor",
"copilot": "GitHub Copilot AI Assistant"
"copilot": "GitHub Copilot AI Assistant",
"qwen": "Alibaba Qwen Code CLI"
},
"guides": {
"cursor": {
@ -890,6 +895,16 @@
"when": "Use when you want perfectly even spread — each model used once before repeating.",
"avoid": "Avoid when models have different quality or latency and order matters.",
"example": "Example: Multiple accounts of the same model to distribute usage evenly."
},
"context-relay": {
"avoid": "Avoid when account switching is rare or when you do not want extra summarization requests.",
"when": "Use when long sessions must survive account rotation without losing the working context.",
"example": "Example: Codex sessions that rotate across multiple accounts near quota exhaustion."
},
"p2c": {
"example": "Example: High-throughput inference across 4+ equivalent model endpoints.",
"avoid": "Avoid for small combos with 2 or fewer models — no benefit over round-robin.",
"when": "Use when you want low-latency selection using Power-of-Two-Choices algorithm."
}
},
"advancedHelp": {
@ -1009,7 +1024,117 @@
"wizardStep3Title": "Choose Strategy",
"wizardStep3Desc": "Pick how requests are distributed across your models - 13 strategies available",
"wizardStep4Title": "Review & Save",
"wizardStep4Desc": "Review your configuration and activate the combo"
"wizardStep4Desc": "Review your configuration and activate the combo",
"highCircuitBreakerRate": "High circuit breaker trip rate detected.",
"builderComboRefStep": "Add combo reference",
"builderFlowTitle": "Combo Builder Flow",
"noExcludedProviders": "No providers are currently excluded.",
"reviewProviders": "Providers",
"excludedProviders": "Excluded Providers",
"routerStrategyLabel": "Router Strategy",
"reviewSequence": "Model Sequence",
"builderStage": {
"strategy": {
"label": "Strategy",
"description": "Routing behavior and advanced settings"
},
"steps": {
"label": "Steps",
"description": "Provider, model, and account selection"
},
"intelligent": {
"description": "Auto-routing candidate pool, presets, and scoring",
"label": "Smart Routing"
},
"review": {
"label": "Review",
"description": "Final validation before saving"
},
"basics": {
"label": "Basics",
"description": "Name and starting template"
}
},
"reviewSteps": "Steps",
"builderPinnedAccount": "Pinned Account",
"builderSelectProvider": "Select provider",
"builderSelectModel": "Select model",
"reviewAgentFlags": "Agent Flags",
"builderAccount": "Account",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex account rotation. Pair it with multiple accounts of the same provider for the best continuity.",
"builderStageVisited": "Stage completed",
"contextRelayDesc": "Preserves session continuity with handoff summaries when accounts rotate",
"excludedProvidersHint": "Providers with an OPEN circuit breaker are temporarily excluded from routing.",
"contextRelaySummaryModel": "Summary Model",
"contextRelayHandoffThreshold": "Handoff Threshold",
"filterEmptyDeterministicDescription": "Only auto and LKGP combos exist right now. Switch back to All or create a deterministic combo.",
"emailVisibilityStateOff": "Off",
"candidatePoolLabel": "Candidate Pool",
"advancedWeightsTitle": "Advanced: Scoring Weights",
"filterEmptyTitle": "No combos match this strategy filter.",
"builderAddStep": "Add step",
"incidentMode": "Incident Mode",
"intelligentPanelTitle": "Intelligent Routing Dashboard",
"explorationRateLabel": "Exploration Rate",
"reorderHandle": "Drag to reorder",
"budgetCapLabel": "Budget Cap (USD / request)",
"allProvidersEvaluated": "No candidate pool configured. All active providers are evaluated at runtime.",
"activeModePack": "Active Mode Pack",
"weightQuota": "Quota",
"normalOperation": "Normal Operation",
"builderProviderFirst": "Pick provider first",
"weightCostInv": "Cost",
"builderLoadingProviders": "Loading providers...",
"weightLatencyInv": "Latency",
"reviewAdvanced": "Advanced Settings",
"filterAll": "All",
"builderTitle": "Build a Combo",
"contextRelay": "Context Relay",
"weightTaskFit": "Task Fit",
"contextRelayMaxMessages": "Max Messages For Summary",
"filterIntelligent": "Intelligent",
"weightTierPriority": "Tier",
"modePackUpdated": "Mode pack updated to {pack}.",
"reviewNoSteps": "No steps configured",
"contextRelaySummaryModelHelp": "Optional override model used only for generating the handoff summary. Leave empty to reuse the active combo model.",
"budgetCapPlaceholder": "No limit",
"reviewName": "Name",
"contextRelayMaxMessagesHelp": "Limits how much recent history is condensed into the relay summary.",
"builderStageLocked": "Locked — complete previous stage first",
"weightHealth": "Health",
"builderStageCurrent": "Current stage",
"providerScores": "Provider Scores",
"emailVisibilityStateOn": "On",
"contextRelayHandoffThresholdHelp": "When quota usage reaches this threshold, OmniRoute generates a structured handoff summary before the active account is exhausted.",
"reviewComboRefs": "Combo References",
"allProvidersHealthy": "Providers are reporting healthy routing conditions.",
"builderIntelligentDesc": "Configure the multi-factor scoring engine for this auto-routing combo.",
"explorationRateHint": "{percent}% of requests can explore non-optimal providers.",
"candidatePoolHint": "Select which providers this engine should evaluate. Leave empty to use all active providers.",
"reviewIntelligentTitle": "Intelligent Routing Config",
"failedReorder": "Failed to reorder models",
"builderComboRef": "Combo Ref",
"builderStagePending": "Pending",
"reviewStrategy": "Strategy",
"statusOverview": "Status Overview",
"weightStability": "Stability",
"intelligentPanelDesc": "Real-time scoring and health status for this auto-routing combo.",
"builderPreview": "Preview",
"builderBrowseCatalog": "Browse catalog",
"reviewAccounts": "Accounts",
"builderProvider": "Provider",
"builderAddComboRef": "Add combo reference",
"builderModel": "Model",
"modePackHint": "Switch presets to bias the routing engine without rebuilding the combo.",
"filterDeterministic": "Deterministic",
"builderLegacyEntry": "Legacy entry",
"modePackLabel": "Mode Pack",
"candidatePoolEmpty": "No active providers available yet.",
"builderIntelligentTitle": "Intelligent Routing Configuration",
"filterEmptyIntelligentDescription": "Create an auto or LKGP combo to populate the intelligent routing dashboard.",
"cooldownMinutes": "Cooldown: {minutes}m",
"candidatePoolAllProviders": "All providers",
"strategyRules": "Rules (6-Factor Scoring)"
},
"costs": {
"title": "Витрати",
@ -1147,7 +1272,9 @@
"a2aQuickStartStep2": "Send JSON-RPC requests to `POST /a2a` using `message/send` or `message/stream`.",
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format",
"musicDesc": "Generate music and audio tracks via ComfyUI (Stable Audio, MusicGen)",
"musicGeneration": "Music Generation"
},
"endpoints": {
"tabProxy": "Endpoint Proxy",
@ -1749,7 +1876,22 @@
"close": "Close",
"statusDeactivated": "Deactivated (Manual)",
"statusBanned": "Banned / Sandbox Violation",
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted"
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted",
"embeddings": "Embeddings",
"hideEmails": "Hide all emails",
"noModelsMatch": "No models match \"{filter}\"",
"repairEnvSuccess": "OAuth defaults restored",
"repairEnvWorking": "Repairing...",
"audioTranscriptions": "Audio Transcriptions",
"selectAllModels": "Select all",
"repairEnvHint": "Restore missing OAuth defaults into .env without overwriting existing values.",
"imagesGenerations": "Images Generations",
"audioSpeech": "Audio Speech",
"showEmails": "Show all emails",
"modelsActiveCount": "{active}/{total} active",
"repairEnvFailed": "Failed to repair .env",
"repairEnv": "Repair env",
"deselectAllModels": "Deselect all"
},
"settings": {
"title": "Налаштування",
@ -2266,7 +2408,11 @@
"wildcardPatternModeDesc": "Use wildcard aliases with * and ? when a family of models should map to one target.",
"noExactAliasesConfigured": "No exact-match aliases configured.",
"wildcardRulesTitle": "Wildcard Rules",
"noWildcardAliasesConfigured": "No wildcard aliases configured."
"noWildcardAliasesConfigured": "No wildcard aliases configured.",
"contextRelayMaxMessages": "Max Messages For Summary",
"contextRelaySummaryModel": "Summary Model",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex accounts and uses these values as global defaults for new or unconfigured combos.",
"contextRelayHandoffThreshold": "Handoff Threshold"
},
"translator": {
"title": "Перекладач",
@ -2692,7 +2838,11 @@
"waitingForOpenAIAuthorization": "Очікування авторизації OpenAI...",
"waitingForAntigravityAuthorization": "Очікування авторизації Antigravity...",
"waitingForQoderAuthorization": "Очікування авторизації Qoder...",
"exchangingCodeForTokens": "Обмін коду на токени..."
"exchangingCodeForTokens": "Обмін коду на токени...",
"nodeIncompatibleFixLabel": "Fix: install a patched Node.js 22 LTS release",
"nodeIncompatibleTitle": "Incompatible Node.js Version",
"nodeIncompatibleDesc": "You are running Node.js {version}, which is outside OmniRoute's supported secure runtime policy. Use a patched Node.js 20.x or 22.x LTS release.",
"nodeIncompatibleHint": "OmniRoute requires Node.js 20.20.2+ (20.x LTS) or 22.22.2+ (22.x LTS). Node 22 LTS is recommended."
},
"landing": {
"brandName": "OmniRoute",
@ -3108,7 +3258,26 @@
"peakCached": "Peak cached",
"deduplicatedRequests": "Deduplicated Requests",
"savedCalls": "Saved API Calls",
"totalProcessed": "Total Requests Processed"
"totalProcessed": "Total Requests Processed",
"cacheRateDesc": "of total requests",
"semanticCache": "Semantic Cache",
"cachedRequests24h": "Cached Requests (24h)",
"noPromptCacheData": "No provider-side prompt cache activity has been recorded yet.",
"promptTrendDesc": "Hourly request volume, cache coverage, and cache read volume across the last 24 hours.",
"trendHour": "Hour",
"semanticEntriesDesc": "Persisted semantic cache records currently stored in SQLite. Provider-side prompt cache activity is not listed here.",
"entriesLoadError": "Failed to load semantic cache entries.",
"peakCacheRate": "Peak Cache Rate",
"activityVolume": "Activity",
"semanticCacheDisabledDesc": "Semantic cache is disabled. OmniRoute will skip local response reuse until you turn it back on in Settings.",
"busiestHour": "Busiest Hour",
"providerCacheRateDesc": "Each provider exposes total input tokens, cache read tokens, and cache write tokens so you can verify the reuse ratio against raw totals.",
"hoursTracked": "hours tracked",
"semanticCacheSectionDesc": "OmniRoute's own deterministic response cache. When enabled, repeated non-streaming temperature=0 requests can be served locally without hitting the upstream provider.",
"lastUpdated": "Last updated",
"cacheRate": "Cache Rate",
"noTrendData": "No prompt cache activity has been recorded over the last 24 hours.",
"promptCacheSectionDesc": "Shows provider-side prompt caching activity from usage history so you can see where cache control is active and how much input reuse you are getting."
},
"memory": {
"title": "Memory Management",
@ -3132,7 +3301,8 @@
"factual": "Factual",
"episodic": "Episodic",
"procedural": "Procedural",
"semantic": "Semantic"
"semantic": "Semantic",
"delete": "Delete"
},
"skills": {
"title": "Skills",

View file

@ -136,7 +136,10 @@
"Failed to save pricing": "Không lưu được giá",
"Failed to reset pricing": "Không thể đặt lại giá",
"apikey": "Khóa API",
"http": "HTTP"
"http": "HTTP",
"nothingHere": "Nothing here yet",
"checkSystemStatus": "Check System Status",
"goToDashboard": "Go to Dashboard"
},
"sidebar": {
"home": "Trang chủ",
@ -640,7 +643,8 @@
"opencode": "Sử dụng khi bạn thích chạy tác nhân gốc trên thiết bị đầu cuối và tự động hóa theo kịch bản thông qua OpenCode.",
"kiro": "Sử dụng khi tích hợp Kiro và điều khiển định tuyến mô hình tập trung từ OmniRoute.",
"antigravity": "Sử dụng khi lưu lượng truy cập AntiGravity/Kiro phải bị chặn thông qua MITM và được định tuyến đến OmniRoute.",
"copilot": "Sử dụng khi bạn muốn UX kiểu trò chuyện Copilot trong khi thực thi các khóa OmniRoute và quy tắc định tuyến."
"copilot": "Sử dụng khi bạn muốn UX kiểu trò chuyện Copilot trong khi thực thi các khóa OmniRoute và quy tắc định tuyến.",
"windsurf": "Use when you want an AI-first IDE with Codeium/Windsurf models routed through OmniRoute."
},
"toolDescriptions": {
"antigravity": "IDE chống trọng lực của Google với MITM",
@ -655,7 +659,8 @@
"opencode": "OpenCode AI coding agent (Terminal)",
"kiro": "Amazon Kiro — AI-powered IDE",
"windsurf": "Windsurf AI Code Editor",
"copilot": "GitHub Copilot AI Assistant"
"copilot": "GitHub Copilot AI Assistant",
"qwen": "Alibaba Qwen Code CLI"
},
"guides": {
"cursor": {
@ -890,6 +895,16 @@
"when": "Use when you want perfectly even spread — each model used once before repeating.",
"avoid": "Avoid when models have different quality or latency and order matters.",
"example": "Example: Multiple accounts of the same model to distribute usage evenly."
},
"p2c": {
"example": "Example: High-throughput inference across 4+ equivalent model endpoints.",
"when": "Use when you want low-latency selection using Power-of-Two-Choices algorithm.",
"avoid": "Avoid for small combos with 2 or fewer models — no benefit over round-robin."
},
"context-relay": {
"example": "Example: Codex sessions that rotate across multiple accounts near quota exhaustion.",
"avoid": "Avoid when account switching is rare or when you do not want extra summarization requests.",
"when": "Use when long sessions must survive account rotation without losing the working context."
}
},
"advancedHelp": {
@ -1009,7 +1024,117 @@
"wizardStep3Title": "Choose Strategy",
"wizardStep3Desc": "Pick how requests are distributed across your models - 13 strategies available",
"wizardStep4Title": "Review & Save",
"wizardStep4Desc": "Review your configuration and activate the combo"
"wizardStep4Desc": "Review your configuration and activate the combo",
"reviewProviders": "Providers",
"builderStage": {
"basics": {
"label": "Basics",
"description": "Name and starting template"
},
"steps": {
"description": "Provider, model, and account selection",
"label": "Steps"
},
"strategy": {
"description": "Routing behavior and advanced settings",
"label": "Strategy"
},
"review": {
"label": "Review",
"description": "Final validation before saving"
},
"intelligent": {
"description": "Auto-routing candidate pool, presets, and scoring",
"label": "Smart Routing"
}
},
"filterAll": "All",
"advancedWeightsTitle": "Advanced: Scoring Weights",
"providerScores": "Provider Scores",
"explorationRateLabel": "Exploration Rate",
"intelligentPanelTitle": "Intelligent Routing Dashboard",
"emailVisibilityStateOff": "Off",
"builderSelectProvider": "Select provider",
"filterIntelligent": "Intelligent",
"modePackUpdated": "Mode pack updated to {pack}.",
"activeModePack": "Active Mode Pack",
"weightStability": "Stability",
"contextRelay": "Context Relay",
"candidatePoolEmpty": "No active providers available yet.",
"emailVisibilityStateOn": "On",
"builderComboRef": "Combo Ref",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex account rotation. Pair it with multiple accounts of the same provider for the best continuity.",
"builderAccount": "Account",
"normalOperation": "Normal Operation",
"builderStageCurrent": "Current stage",
"failedReorder": "Failed to reorder models",
"weightQuota": "Quota",
"filterDeterministic": "Deterministic",
"contextRelayHandoffThresholdHelp": "When quota usage reaches this threshold, OmniRoute generates a structured handoff summary before the active account is exhausted.",
"builderSelectModel": "Select model",
"filterEmptyIntelligentDescription": "Create an auto or LKGP combo to populate the intelligent routing dashboard.",
"strategyRules": "Rules (6-Factor Scoring)",
"builderPinnedAccount": "Pinned Account",
"filterEmptyDeterministicDescription": "Only auto and LKGP combos exist right now. Switch back to All or create a deterministic combo.",
"candidatePoolHint": "Select which providers this engine should evaluate. Leave empty to use all active providers.",
"builderStagePending": "Pending",
"builderLoadingProviders": "Loading providers...",
"excludedProviders": "Excluded Providers",
"budgetCapLabel": "Budget Cap (USD / request)",
"contextRelaySummaryModel": "Summary Model",
"intelligentPanelDesc": "Real-time scoring and health status for this auto-routing combo.",
"reviewAdvanced": "Advanced Settings",
"reviewComboRefs": "Combo References",
"reviewNoSteps": "No steps configured",
"reviewSteps": "Steps",
"statusOverview": "Status Overview",
"builderFlowTitle": "Combo Builder Flow",
"allProvidersEvaluated": "No candidate pool configured. All active providers are evaluated at runtime.",
"contextRelayMaxMessages": "Max Messages For Summary",
"reorderHandle": "Drag to reorder",
"weightCostInv": "Cost",
"builderStageLocked": "Locked — complete previous stage first",
"candidatePoolLabel": "Candidate Pool",
"weightTaskFit": "Task Fit",
"weightLatencyInv": "Latency",
"reviewAccounts": "Accounts",
"allProvidersHealthy": "Providers are reporting healthy routing conditions.",
"builderIntelligentTitle": "Intelligent Routing Configuration",
"modePackLabel": "Mode Pack",
"explorationRateHint": "{percent}% of requests can explore non-optimal providers.",
"routerStrategyLabel": "Router Strategy",
"builderStageVisited": "Stage completed",
"candidatePoolAllProviders": "All providers",
"contextRelayMaxMessagesHelp": "Limits how much recent history is condensed into the relay summary.",
"builderModel": "Model",
"builderBrowseCatalog": "Browse catalog",
"builderPreview": "Preview",
"budgetCapPlaceholder": "No limit",
"contextRelayHandoffThreshold": "Handoff Threshold",
"contextRelayDesc": "Preserves session continuity with handoff summaries when accounts rotate",
"reviewName": "Name",
"cooldownMinutes": "Cooldown: {minutes}m",
"builderProviderFirst": "Pick provider first",
"reviewIntelligentTitle": "Intelligent Routing Config",
"incidentMode": "Incident Mode",
"excludedProvidersHint": "Providers with an OPEN circuit breaker are temporarily excluded from routing.",
"highCircuitBreakerRate": "High circuit breaker trip rate detected.",
"contextRelaySummaryModelHelp": "Optional override model used only for generating the handoff summary. Leave empty to reuse the active combo model.",
"weightHealth": "Health",
"builderAddComboRef": "Add combo reference",
"reviewAgentFlags": "Agent Flags",
"modePackHint": "Switch presets to bias the routing engine without rebuilding the combo.",
"builderIntelligentDesc": "Configure the multi-factor scoring engine for this auto-routing combo.",
"weightTierPriority": "Tier",
"builderLegacyEntry": "Legacy entry",
"builderAddStep": "Add step",
"noExcludedProviders": "No providers are currently excluded.",
"builderTitle": "Build a Combo",
"builderProvider": "Provider",
"reviewSequence": "Model Sequence",
"reviewStrategy": "Strategy",
"builderComboRefStep": "Add combo reference",
"filterEmptyTitle": "No combos match this strategy filter."
},
"costs": {
"title": "Chi phí",
@ -1147,7 +1272,9 @@
"a2aQuickStartStep2": "Send JSON-RPC requests to `POST /a2a` using `message/send` or `message/stream`.",
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format",
"musicGeneration": "Music Generation",
"musicDesc": "Generate music and audio tracks via ComfyUI (Stable Audio, MusicGen)"
},
"endpoints": {
"tabProxy": "Endpoint Proxy",
@ -1749,7 +1876,22 @@
"close": "Close",
"statusDeactivated": "Deactivated (Manual)",
"statusBanned": "Banned / Sandbox Violation",
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted"
"statusCreditsExhausted": "Insufficient Balance / Quota Exhausted",
"audioTranscriptions": "Audio Transcriptions",
"audioSpeech": "Audio Speech",
"noModelsMatch": "No models match \"{filter}\"",
"repairEnvWorking": "Repairing...",
"deselectAllModels": "Deselect all",
"hideEmails": "Hide all emails",
"repairEnvFailed": "Failed to repair .env",
"repairEnvSuccess": "OAuth defaults restored",
"embeddings": "Embeddings",
"repairEnvHint": "Restore missing OAuth defaults into .env without overwriting existing values.",
"repairEnv": "Repair env",
"selectAllModels": "Select all",
"imagesGenerations": "Images Generations",
"showEmails": "Show all emails",
"modelsActiveCount": "{active}/{total} active"
},
"settings": {
"title": "Cài đặt",
@ -2266,7 +2408,11 @@
"wildcardPatternModeDesc": "Use wildcard aliases with * and ? when a family of models should map to one target.",
"noExactAliasesConfigured": "No exact-match aliases configured.",
"wildcardRulesTitle": "Wildcard Rules",
"noWildcardAliasesConfigured": "No wildcard aliases configured."
"noWildcardAliasesConfigured": "No wildcard aliases configured.",
"contextRelayHandoffThreshold": "Handoff Threshold",
"contextRelayProviderNote": "Context Relay currently generates handoffs for Codex accounts and uses these values as global defaults for new or unconfigured combos.",
"contextRelaySummaryModel": "Summary Model",
"contextRelayMaxMessages": "Max Messages For Summary"
},
"translator": {
"title": "Người phiên dịch",
@ -2692,7 +2838,11 @@
"waitingForOpenAIAuthorization": "Đang chờ ủy quyền OpenAI...",
"waitingForAntigravityAuthorization": "Đang chờ ủy quyền chống hấp dẫn...",
"waitingForQoderAuthorization": "Đang chờ ủy quyền Qoder...",
"exchangingCodeForTokens": "Đổi mã lấy token..."
"exchangingCodeForTokens": "Đổi mã lấy token...",
"nodeIncompatibleFixLabel": "Fix: install a patched Node.js 22 LTS release",
"nodeIncompatibleTitle": "Incompatible Node.js Version",
"nodeIncompatibleDesc": "You are running Node.js {version}, which is outside OmniRoute's supported secure runtime policy. Use a patched Node.js 20.x or 22.x LTS release.",
"nodeIncompatibleHint": "OmniRoute requires Node.js 20.20.2+ (20.x LTS) or 22.22.2+ (22.x LTS). Node 22 LTS is recommended."
},
"landing": {
"brandName": "OmniRoute",
@ -3108,7 +3258,26 @@
"peakCached": "Peak cached",
"deduplicatedRequests": "Deduplicated Requests",
"savedCalls": "Saved API Calls",
"totalProcessed": "Total Requests Processed"
"totalProcessed": "Total Requests Processed",
"lastUpdated": "Last updated",
"hoursTracked": "hours tracked",
"semanticCacheSectionDesc": "OmniRoute's own deterministic response cache. When enabled, repeated non-streaming temperature=0 requests can be served locally without hitting the upstream provider.",
"promptCacheSectionDesc": "Shows provider-side prompt caching activity from usage history so you can see where cache control is active and how much input reuse you are getting.",
"semanticCache": "Semantic Cache",
"promptTrendDesc": "Hourly request volume, cache coverage, and cache read volume across the last 24 hours.",
"busiestHour": "Busiest Hour",
"noPromptCacheData": "No provider-side prompt cache activity has been recorded yet.",
"cachedRequests24h": "Cached Requests (24h)",
"semanticEntriesDesc": "Persisted semantic cache records currently stored in SQLite. Provider-side prompt cache activity is not listed here.",
"entriesLoadError": "Failed to load semantic cache entries.",
"cacheRate": "Cache Rate",
"semanticCacheDisabledDesc": "Semantic cache is disabled. OmniRoute will skip local response reuse until you turn it back on in Settings.",
"trendHour": "Hour",
"peakCacheRate": "Peak Cache Rate",
"activityVolume": "Activity",
"noTrendData": "No prompt cache activity has been recorded over the last 24 hours.",
"cacheRateDesc": "of total requests",
"providerCacheRateDesc": "Each provider exposes total input tokens, cache read tokens, and cache write tokens so you can verify the reuse ratio against raw totals."
},
"memory": {
"title": "Memory Management",
@ -3132,7 +3301,8 @@
"factual": "Factual",
"episodic": "Episodic",
"procedural": "Procedural",
"semantic": "Semantic"
"semantic": "Semantic",
"delete": "Delete"
},
"skills": {
"title": "Skills",

View file

@ -659,7 +659,8 @@
"opencode": "OpenCode AI 编码智能体(终端)",
"kiro": "Amazon Kiro - AI 驱动 IDE",
"windsurf": "Windsurf AI Code Editor",
"copilot": "GitHub Copilot AI Assistant"
"copilot": "GitHub Copilot AI Assistant",
"qwen": "Alibaba Qwen Code CLI"
},
"guides": {
"cursor": {
@ -903,6 +904,36 @@
"when": "适用于希望实现绝对均匀分配的场景,每个模型在重复前都会恰好使用一次。",
"avoid": "如果模型之间的质量或延迟差异较大,且调用顺序很重要,则不建议使用。",
"example": "例如:同一模型挂载多个账户,用于更均匀地分摊使用量。"
},
"p2c": {
"when": "当您希望使用 Power-of-Two-Choices 算法进行低延迟选择时使用。",
"avoid": "对于少于等于 2 个模型的小型组合避免使用 — 与轮询相比没有优势。",
"example": "示例:在 4 个或更多等效模型端点之间进行高吞吐量推理。"
},
"context-relay": {
"when": "当长会话必须在账户轮换时保持工作上下文不丢失时使用。",
"avoid": "当账户切换很少发生或您不希望额外的摘要请求时避免使用。",
"example": "示例:在接近配额耗尽时轮换多个账户的 Codex 会话。"
},
"fill-first": {
"when": "当您希望在转移到下一个提供商之前完全耗尽一个提供商的配额时使用。",
"avoid": "当您需要在提供商之间进行请求级负载均衡时避免使用。",
"example": "示例:在使用完所有 200 美元的 Deepgram 额度后再回退到 Groq。"
},
"auto": {
"when": "当您有一个首选模型且只希望在失败时才回退到备用模型时使用。",
"avoid": "当您需要在多个模型之间平衡负载时避免使用。",
"example": "示例:主力编码模型搭配更便宜的备用模型以应对故障。"
},
"lkgp": {
"when": "当您有一个首选模型且只希望在失败时才回退到备用模型时使用。",
"avoid": "当您需要在多个模型之间平衡负载时避免使用。",
"example": "示例:主力编码模型搭配更便宜的备用模型以应对故障。"
},
"context-optimized": {
"when": "当您有一个首选模型且只希望在失败时才回退到备用模型时使用。",
"avoid": "当您需要在多个模型之间平衡负载时避免使用。",
"example": "示例:主力编码模型搭配更便宜的备用模型以应对故障。"
}
},
"advancedHelp": {
@ -982,6 +1013,25 @@
"candidatePoolHint": "选择引擎应评估的供应商。留空则使用所有活跃供应商。",
"candidatePoolEmpty": "暂无可用活跃供应商。",
"candidatePoolAllProviders": "所有供应商",
"builderStagesDescription": "按顺序完成各个阶段以定义组合、构建步骤、选择路由策略并审查结果。",
"builderStepsDescription": "按顺序构建每个组合步骤:提供商、模型,然后是账户。这允许在不同账户上重复使用相同的提供商和模型。",
"selectProvider": "选择提供商",
"selectProviderPlaceholder": "选择提供商",
"selectModel": "选择模型",
"selectModelPlaceholder": "请先选择提供商",
"selectAccount": "选择账户",
"autoSelectAccount": "运行时自动选择账户",
"previewNextStep": "选择提供商和模型以预览下一步。",
"addStep": "添加步骤",
"comboReference": "组合引用",
"selectComboToReference": "选择要引用的现有组合",
"addComboReference": "添加组合引用",
"browseLegacyCatalog": "浏览旧版模型目录",
"addStepBeforeContinue": "在继续到下一阶段之前,请至少添加一个步骤。",
"modePackPerformance": "性能优先",
"modePackBudget": "预算优先",
"modePackBalanced": "均衡",
"modePackCustom": "自定义",
"modePackLabel": "模式包",
"routerStrategyLabel": "路由策略",
"strategyRules": "规则6 因子评分)",
@ -1041,12 +1091,54 @@
"tip2": "为高难度提示保留一个质量更高的回退模型。",
"tip3": "适合批处理或后台任务等成本是主要指标的场景。"
},
"fill-first": {
"title": "配额耗尽策略",
"description": "在切换到链中的下一个提供商之前,先耗尽一个提供商的配额。",
"tip1": "按免费配额大小排列模型 — 最大的放在第一位。",
"tip2": "启用健康检查以跳过已耗尽的提供商。",
"tip3": "非常适合免费层级堆叠Deepgram → Groq → NIM。"
},
"p2c": {
"title": "双选负载均衡",
"description": "每次请求从随机候选中选出负载较轻的一个 — 低延迟,高扩展性。",
"tip1": "配合 4 个或更多模型使用效果最佳。",
"tip2": "需要在设置中启用延迟遥测。",
"tip3": "是高吞吐量组合中轮询的绝佳替代方案。"
},
"context-relay": {
"title": "会话连续性优先",
"description": "当预期账户轮换且下一个账户必须继承简化的任务摘要时效果最佳。",
"tip1": "与为同一模型系列轮换账户的提供商配合使用。",
"tip2": "将交接阈值设置在硬配额截止值以下,以便有时间生成摘要。",
"tip3": "仅在主模型太贵或不稳定时,才设置专用摘要模型。"
},
"strict-random": {
"title": "洗牌池分配",
"description": "每轮中每个模型都会被恰好使用一次,然后再重新洗牌。",
"tip1": "至少使用 2 个模型,才能体现分配效果。",
"tip2": "最适合性能相近的模型。",
"tip3": "非常适合在多个 API 账户之间做负载均衡。"
},
"auto": {
"title": "稳妥基线",
"description": "使用一个主模型,并保持回退链路简短且可靠。",
"tip1": "把最可靠的模型放在第一位。",
"tip2": "保留 1 到 2 个质量相近的备用模型。",
"tip3": "开启安全重试,吸收临时性的提供商故障。"
},
"lkgp": {
"title": "稳妥基线",
"description": "使用一个主模型,并保持回退链路简短且可靠。",
"tip1": "把最可靠的模型放在第一位。",
"tip2": "保留 1 到 2 个质量相近的备用模型。",
"tip3": "开启安全重试,吸收临时性的提供商故障。"
},
"context-optimized": {
"title": "稳妥基线",
"description": "使用一个主模型,并保持回退链路简短且可靠。",
"tip1": "把最可靠的模型放在第一位。",
"tip2": "保留 1 到 2 个质量相近的备用模型。",
"tip3": "开启安全重试,吸收临时性的提供商故障。"
}
},
"templateFreeStack": "免费栈($0",
@ -1072,6 +1164,28 @@
"reorderHandle": "拖拽排序",
"failedReorder": "模型重排序失败",
"builderFlowTitle": "组合构建流程",
"builderStage": {
"basics": {
"label": "基础",
"description": "名称和起始模板"
},
"steps": {
"label": "步骤",
"description": "提供商、模型和账户选择"
},
"strategy": {
"label": "策略",
"description": "路由行为和高级设置"
},
"intelligent": {
"label": "智能路由",
"description": "自动路由候选池、预设和评分"
},
"review": {
"label": "审查",
"description": "保存前的最终验证"
}
},
"builderStageVisited": "阶段已完成",
"builderStageCurrent": "当前阶段",
"builderStagePending": "待处理",
@ -1101,7 +1215,16 @@
"reviewAdvanced": "高级设置",
"reviewAgentFlags": "Agent 标志",
"reviewSequence": "模型序列",
"reviewNoSteps": "未配置任何步骤"
"reviewNoSteps": "未配置任何步骤",
"agentFeaturesTitle": "智能代理功能",
"agentFeaturesDescription": "— 可选,用于智能体/工具工作流",
"agentFeaturesSystemMessageOverride": "系统消息覆盖",
"agentFeaturesSystemMessagePlaceholder": "覆盖通过此组合路由的所有请求的系统提示…",
"agentFeaturesSystemMessageHint": "替换客户端发送的任何系统消息。留空则透传客户端系统消息。",
"agentFeaturesToolFilterRegex": "工具过滤器正则",
"agentFeaturesToolFilterHint": "只有名称匹配此正则的工具才会转发给供应商。留空则转发所有工具。",
"agentFeaturesContextCacheProtection": "上下文缓存保护",
"agentFeaturesContextCacheHint": "跨轮次锁定供应商/模型以保持缓存会话。内部标签在转发给供应商前会被移除。"
},
"costs": {
"title": "成本",
@ -1130,7 +1253,7 @@
"enableCloud": "启用云端",
"modelsAcrossEndpoints": "{endpoints} 个端点共提供 {models} 个模型",
"chatDesc": "支持所有提供商的流式与非流式聊天",
"embeddings": "嵌入向量",
"embeddings": "Embeddings",
"embeddingsDesc": "用于搜索和 RAG 流程的文本向量",
"imageGeneration": "图像生成",
"imageDesc": "根据文本提示生成图像",
@ -1456,7 +1579,7 @@
"rateLimit": "速率限制",
"remaining": "剩余",
"requestsPerMinute": "请求/分钟",
"tokensPerMinute": "令牌/分钟",
"tokensPerMinute": "Tokens/分钟",
"dailyLimit": "每日限额"
},
"logs": {
@ -1822,6 +1945,10 @@
"email": "电子邮件",
"healthCheckMinutes": "健康检查(分钟)",
"healthCheckHint": "主动令牌刷新间隔。 0 = 禁用。",
"selectAllModels": "全选",
"deselectAllModels": "取消全选",
"modelsActiveCount": "{active}/{total} 已启用",
"noModelsMatch": "没有匹配 \"{filter}\" 的模型",
"groupLabel": "环境",
"groupPlaceholder": "例如eKaizen、Personal",
"failedTestConnection": "测试连接失败",
@ -1850,7 +1977,11 @@
"statusBanned": "已封禁 / 沙箱违规",
"statusCreditsExhausted": "余额不足 / 配额已耗尽",
"showEmails": "显示所有邮箱",
"hideEmails": "隐藏所有邮箱"
"hideEmails": "隐藏所有邮箱",
"imagesGenerations": "Images Generations",
"audioSpeech": "Audio Speech",
"audioTranscriptions": "Audio Transcriptions",
"embeddings": "Embeddings"
},
"settings": {
"title": "设置",
@ -3289,5 +3420,258 @@
"timeoutDesc": "等待响应的最长时间",
"networkAccess": "网络访问",
"networkAccessDesc": "允许发起出站网络请求"
},
"proxyConfigModal": {
"levelGlobal": "全局",
"levelProvider": "供应商",
"levelCombo": "组合",
"levelKey": "密钥",
"levelDirect": "直接(无代理)",
"titleGlobal": "全局代理配置",
"titleLevel": "{level} 代理 — {label}",
"loading": "正在加载代理配置...",
"inheritingFrom": "继承自",
"source": "来源",
"savedProxy": "已保存代理",
"custom": "自定义",
"selectSavedProxyPlaceholder": "选择已保存的代理...",
"proxyType": "代理类型",
"host": "主机",
"hostPlaceholder": "1.2.3.4 或 proxy.example.com",
"port": "端口",
"authOptional": "认证(可选)",
"username": "用户名",
"usernamePlaceholder": "用户名",
"password": "密码",
"passwordPlaceholder": "密码",
"connected": "已连接",
"ip": "IP:",
"connectionFailed": "连接失败",
"testConnection": "测试连接",
"clear": "清除",
"cancel": "取消",
"save": "保存",
"errorSelectSavedProxy": "请先选择已保存的代理。",
"errorSelectProxyFirst": "请先选择代理。",
"errorProxyNotFound": "所选代理未找到。",
"errorClearSavedProxy": "清除已保存代理失败",
"errorSaveProxy": "保存代理配置失败",
"errorClearProxy": "清除代理配置失败",
"errorSocks5Hidden": "SOCKS5 已配置但已隐藏,因为 NEXT_PUBLIC_ENABLE_SOCKS5_PROXY=false。"
},
"oauthModal": {
"title": "连接 {providerName}",
"waiting": "等待授权",
"completeAuthInPopup": "在弹出窗口中完成授权。",
"popupClosedHint": "如果弹出窗口关闭而没有重定向回来(例如 Qoder此对话框将自动切换到手动 URL 输入模式。",
"popupBlocked": "弹出窗口被阻止?手动输入 URL",
"deviceCodeVisitUrl": "访问下面的 URL 并输入代码:",
"deviceCodeVerificationUrl": "验证 URL",
"deviceCodeYourCode": "您的代码",
"deviceCodeWaiting": "等待授权...",
"googleOAuthWarning": "远程访问 + Google OAuth默认凭据仅接受重定向到 <code>localhost</code>。授权后,您的浏览器将尝试打开 <code>localhost</code> — 复制该完整 URL 并粘贴到下方。要完全远程使用而无需此手动步骤,<a>配置您自己的 OAuth 凭据</a>。",
"remoteAccessInfo": "远程访问:由于您是远程访问 OmniRoute授权后您会看到一个错误页面localhost 未找到)。这是正常的 — 只需从浏览器地址栏复制完整 URL 并粘贴到下方。",
"step1OpenUrl": "步骤 1在浏览器中打开此 URL",
"copy": "复制",
"step2PasteCallback": "步骤 2在此处粘贴回调 URL 或授权代码",
"step2Hint": "授权后,粘贴完整的回调 URL。对于 Claude Code 和 Cline您也可以直接粘贴身份验证代码例如 <code>code#state</code>。",
"connect": "连接",
"cancel": "取消",
"success": "连接成功!",
"successMessage": "您的 {providerName} 账户已连接。",
"done": "完成",
"error": "连接失败",
"tryAgain": "重试"
},
"cursorAuthModal": {
"title": "连接 Cursor IDE",
"autoDetecting": "自动检测令牌中...",
"readingFromCursor": "正在从 Cursor IDE 或 cursor-agent 读取",
"tokensAutoDetected": "已成功从 Cursor IDE 自动检测到令牌!",
"cursorNotDetected": "未检测到 Cursor IDE。请手动粘贴您的令牌。",
"accessToken": "访问令牌",
"required": "*",
"accessTokenPlaceholder": "访问令牌将自动填充...",
"machineId": "机器 ID",
"optional": "(可选)",
"machineIdPlaceholder": "机器 ID 将自动填充...",
"importing": "正在导入...",
"importToken": "导入令牌",
"cancel": "取消",
"errorAutoDetect": "无法自动检测令牌",
"errorAutoDetectFailed": "自动检测令牌失败",
"errorEnterToken": "请输入访问令牌",
"errorImportFailed": "导入失败"
},
"pricingModal": {
"title": "定价配置",
"loading": "正在加载定价数据...",
"pricingRatesFormat": "定价费率格式",
"ratesDescription": "所有费率均为 <strong>每百万令牌美元</strong>$/1M 令牌)。示例:输入费率为 2.50 表示每 1,000,000 个输入令牌收费 2.50 美元。",
"model": "模型",
"input": "输入",
"output": "输出",
"cached": "缓存",
"reasoning": "推理",
"cacheCreation": "缓存创建",
"noPricingData": "无定价数据可用",
"resetToDefaults": "重置为默认值",
"cancel": "取消",
"saving": "正在保存...",
"saveChanges": "保存更改",
"resetConfirm": "将所有定价重置为默认值?此操作无法撤销。",
"errorSaveFailed": "保存定价失败",
"errorResetFailed": "重置定价失败"
},
"proxyRegistry": {
"title": "代理注册表",
"description": "存储可重用的代理并跟踪分配。",
"importLegacy": "导入旧版",
"bulkAssign": "批量分配",
"addProxy": "添加代理",
"loading": "正在加载代理...",
"noProxies": "暂无保存的代理。",
"tableName": "名称",
"tableEndpoint": "端点",
"tableStatus": "状态",
"tableHealth": "健康状态24小时",
"tableUsage": "使用情况",
"tableActions": "操作",
"test": "测试",
"edit": "编辑",
"delete": "删除",
"modalCreateTitle": "创建代理",
"modalEditTitle": "编辑代理",
"labelName": "名称",
"labelType": "类型",
"labelHost": "主机",
"labelPort": "端口",
"labelUsername": "用户名",
"labelPassword": "密码",
"labelRegion": "区域",
"labelStatus": "状态",
"labelNotes": "备注",
"usernamePlaceholderEdit": "留空以保留当前用户名",
"passwordPlaceholderEdit": "留空以保留当前密码",
"statusActive": "活跃",
"statusInactive": "非活跃",
"cancel": "取消",
"save": "保存",
"bulkModalTitle": "批量代理分配",
"bulkLabelScope": "范围",
"bulkLabelProxy": "代理",
"bulkClearAssignment": "(清除分配)",
"bulkLabelScopeIds": "范围 ID逗号或换行符分隔",
"bulkScopeIdsPlaceholder": "provider-openai,provider-anthropic",
"bulkApply": "应用",
"errorLoadFailed": "加载代理注册表失败",
"errorNameHostRequired": "名称和主机为必填项",
"errorSaveFailed": "保存代理失败",
"errorDeleteFailed": "删除代理失败",
"errorForceDeleteConfirm": "此代理仍在分配中。强制删除并移除所有分配?",
"errorMigrateFailed": "迁移旧版代理配置失败",
"errorBulkFailed": "执行批量分配失败",
"success": "✓",
"failure": "✗",
"failed": "失败",
"successRate": "{rate}% 成功",
"avgLatency": "{latency} 毫秒平均",
"assignmentsCount": "{count} 个分配",
"noData": "—",
"testSuccess": "✓ {ip}",
"testLatency": "{latency}毫秒",
"testFailure": "✗ {error}"
},
"playground": {
"title": "模型演练场",
"description": "直接从仪表板测试任何模型。选择提供商、模型和端点类型,然后发送请求以查看原始响应。",
"endpoint": "端点",
"provider": "提供商",
"model": "模型",
"accountKey": "账户 / 密钥",
"autoAccounts": "自动({count} 个账户)",
"noAccounts": "无账户",
"send": "发送",
"cancel": "取消",
"audioFile": "音频文件",
"attachImages": "附加图片(视觉)",
"multipartFormData": "multipart/form-data",
"upToImages": "最多 4 张图片",
"selectAudioFile": "选择音频文件进行转录mp3、wav、m4a、ogg、flac…",
"clearAll": "清除全部",
"request": "请求",
"response": "响应",
"transcription": "转录",
"copy": "复制",
"resetToDefault": "重置为默认",
"downloadAudio": "下载音频",
"copyText": "复制文本",
"transcriptionHint": "转录使用 multipart/form-data。上传上面的音频文件 — 下面的 JSON 控制额外参数(模型、语言)。",
"imagesGenerated": "生成了 {count} 张图片",
"generatedImage": "生成图片 {index}",
"save": "保存",
"endpointOptions": {
"chat": "聊天补全",
"responses": "响应",
"images": "图片生成",
"embeddings": "Embeddings",
"speech": "文本转语音",
"transcription": "音频转录",
"video": "视频生成",
"music": "音乐生成",
"rerank": "Rerank",
"search": "网页搜索"
}
},
"requestLogger": {
"recording": "正在录制",
"paused": "已暂停",
"pipelineLogsOn": "管道日志开启",
"pipelineLogsOff": "管道日志关闭",
"updatingPipelineLogs": "正在更新管道日志...",
"searchPlaceholder": "搜索模型、提供商、账户、API密钥、组合...",
"allProviders": "所有提供商",
"allModels": "所有模型",
"allAccounts": "所有账户",
"allApiKeys": "所有API密钥",
"total": "总计",
"ok": "成功",
"err": "错误",
"combo": "组合",
"keys": "密钥",
"shown": "显示",
"sortNewest": "最新",
"sortOldest": "最早",
"sortTokensDesc": "令牌 ↓",
"sortTokensAsc": "令牌 ↑",
"sortDurationDesc": "时长 ↓",
"sortDurationAsc": "时长 ↑",
"sortStatusDesc": "状态 ↓",
"sortStatusAsc": "状态 ↑",
"sortModelAsc": "模型 A-Z",
"sortModelDesc": "模型 Z-A",
"statusFilters": {
"all": "全部",
"error": "错误",
"success": "成功",
"combo": "组合"
},
"columns": {
"status": "状态",
"model": "模型",
"requested": "请求",
"provider": "提供商",
"protocol": "请求协议",
"account": "账户",
"apiKey": "API密钥",
"combo": "组合",
"tokens": "Tokens",
"duration": "时长",
"time": "时间"
},
"loadingLogs": "正在加载日志...",
"noLogs": "暂无日志记录。进行一些API调用以在此处查看它们。",
"noMatchingLogs": "没有匹配当前筛选器的日志。",
"callLogsInfo": "调用日志也保存为JSON文件到{dataDir},并根据{retentionDays}和{maxEntries}进行轮换。"
}
}

View file

@ -2,6 +2,7 @@
import { useState, useEffect } from "react";
import PropTypes from "prop-types";
import { useTranslations } from "next-intl";
import Modal from "./Modal";
import Button from "./Button";
import Input from "./Input";
@ -11,6 +12,7 @@ import Input from "./Input";
* Auto-detect and import token from Cursor IDE's local SQLite database
*/
export default function CursorAuthModal({ isOpen, onSuccess, onClose }) {
const t = useTranslations("cursorAuthModal");
const [accessToken, setAccessToken] = useState("");
const [machineId, setMachineId] = useState("");
const [error, setError] = useState(null);
@ -36,10 +38,10 @@ export default function CursorAuthModal({ isOpen, onSuccess, onClose }) {
setMachineId(data.machineId || "");
setAutoDetected(true);
} else {
setError(data.error || "Could not auto-detect tokens");
setError(data.error || t("errorAutoDetect"));
}
} catch (err) {
setError("Failed to auto-detect tokens");
setError(t("errorAutoDetectFailed"));
} finally {
setAutoDetecting(false);
}
@ -50,7 +52,7 @@ export default function CursorAuthModal({ isOpen, onSuccess, onClose }) {
const handleImportToken = async () => {
if (!accessToken.trim()) {
setError("Please enter an access token");
setError(t("errorEnterToken"));
return;
}
@ -70,7 +72,7 @@ export default function CursorAuthModal({ isOpen, onSuccess, onClose }) {
const data = await res.json();
if (!res.ok) {
throw new Error(data.error || "Import failed");
throw new Error(data.error || t("errorImportFailed"));
}
// Success - close modal and trigger refresh
@ -84,7 +86,7 @@ export default function CursorAuthModal({ isOpen, onSuccess, onClose }) {
};
return (
<Modal isOpen={isOpen} title="Connect Cursor IDE" onClose={onClose}>
<Modal isOpen={isOpen} title={t("title")} onClose={onClose}>
<div className="flex flex-col gap-4">
{/* Auto-detecting state */}
{autoDetecting && (
@ -94,8 +96,8 @@ export default function CursorAuthModal({ isOpen, onSuccess, onClose }) {
progress_activity
</span>
</div>
<h3 className="text-lg font-semibold mb-2">Auto-detecting tokens...</h3>
<p className="text-sm text-text-muted">Reading from Cursor IDE or cursor-agent</p>
<h3 className="text-lg font-semibold mb-2">{t("autoDetecting")}</h3>
<p className="text-sm text-text-muted">{t("readingFromCursor")}</p>
</div>
)}
@ -110,7 +112,7 @@ export default function CursorAuthModal({ isOpen, onSuccess, onClose }) {
check_circle
</span>
<p className="text-sm text-green-800 dark:text-green-200">
Tokens auto-detected from Cursor IDE successfully!
{t("tokensAutoDetected")}
</p>
</div>
</div>
@ -124,7 +126,7 @@ export default function CursorAuthModal({ isOpen, onSuccess, onClose }) {
info
</span>
<p className="text-sm text-blue-800 dark:text-blue-200">
Cursor IDE not detected. Please paste your tokens manually.
{t("cursorNotDetected")}
</p>
</div>
</div>
@ -133,12 +135,12 @@ export default function CursorAuthModal({ isOpen, onSuccess, onClose }) {
{/* Access Token Input */}
<div>
<label className="block text-sm font-medium mb-2">
Access Token <span className="text-red-500">*</span>
{t("accessToken")} <span className="text-red-500">{t("required")}</span>
</label>
<textarea
value={accessToken}
onChange={(e) => setAccessToken(e.target.value)}
placeholder="Access token will be auto-filled..."
placeholder={t("accessTokenPlaceholder")}
rows={3}
className="w-full px-3 py-2 text-sm font-mono border border-border rounded-lg bg-background focus:outline-none focus:border-primary resize-none"
/>
@ -147,12 +149,12 @@ export default function CursorAuthModal({ isOpen, onSuccess, onClose }) {
{/* Machine ID Input (optional — not needed for cursor-agent imports) */}
<div>
<label className="block text-sm font-medium mb-2">
Machine ID <span className="text-text-muted text-xs">(optional)</span>
{t("machineId")} <span className="text-text-muted text-xs">{t("optional")}</span>
</label>
<Input
value={machineId}
onChange={(e) => setMachineId(e.target.value)}
placeholder="Machine ID will be auto-filled..."
placeholder={t("machineIdPlaceholder")}
className="font-mono text-sm"
/>
</div>
@ -171,10 +173,10 @@ export default function CursorAuthModal({ isOpen, onSuccess, onClose }) {
fullWidth
disabled={importing || !accessToken.trim()}
>
{importing ? "Importing..." : "Import Token"}
{importing ? t("importing") : t("importToken")}
</Button>
<Button onClick={onClose} variant="ghost" fullWidth>
Cancel
{t("cancel")}
</Button>
</div>
</>

View file

@ -2,6 +2,7 @@
import { useState, useEffect, useRef, useCallback } from "react";
import PropTypes from "prop-types";
import { useTranslations } from "next-intl";
import Modal from "./Modal";
import Button from "./Button";
import Input from "./Input";
@ -31,6 +32,7 @@ export default function OAuthModal({
onClose,
idcConfig,
}: OAuthModalProps) {
const t = useTranslations("oauthModal");
const [step, setStep] = useState("waiting"); // waiting | input | success | error
const [authData, setAuthData] = useState(null);
const [callbackUrl, setCallbackUrl] = useState("");
@ -569,7 +571,12 @@ export default function OAuthModal({
if (!provider || !providerInfo) return null;
return (
<Modal isOpen={isOpen} title={`Connect ${providerInfo.name}`} onClose={onClose} size="lg">
<Modal
isOpen={isOpen}
title={t("title", { providerName: providerInfo.name })}
onClose={onClose}
size="lg"
>
<div className="flex flex-col gap-4">
{/* Waiting Step (Localhost - popup mode) */}
{step === "waiting" && !isDeviceCode && (
@ -579,16 +586,11 @@ export default function OAuthModal({
progress_activity
</span>
</div>
<h3 className="text-lg font-semibold mb-2">Waiting for Authorization</h3>
<p className="text-sm text-text-muted mb-2">
Complete the authorization in the popup window.
</p>
<p className="text-xs text-text-muted mb-4 opacity-70">
If the popup closes without redirecting back (e.g. Qoder), this dialog will
automatically switch to manual URL input mode.
</p>
<h3 className="text-lg font-semibold mb-2">{t("waiting")}</h3>
<p className="text-sm text-text-muted mb-2">{t("completeAuthInPopup")}</p>
<p className="text-xs text-text-muted mb-4 opacity-70">{t("popupClosedHint")}</p>
<Button variant="ghost" onClick={() => setStep("input")}>
Popup blocked? Enter URL manually
{t("popupBlocked")}
</Button>
</div>
)}
@ -597,11 +599,9 @@ export default function OAuthModal({
{step === "waiting" && isDeviceCode && deviceData && (
<>
<div className="text-center py-4">
<p className="text-sm text-text-muted mb-4">
Visit the URL below and enter the code:
</p>
<p className="text-sm text-text-muted mb-4">{t("deviceCodeVisitUrl")}</p>
<div className="bg-sidebar p-4 rounded-lg mb-4">
<p className="text-xs text-text-muted mb-1">Verification URL</p>
<p className="text-xs text-text-muted mb-1">{t("deviceCodeVerificationUrl")}</p>
<div className="flex items-center gap-2">
<code className="flex-1 text-sm break-all">{deviceData.verification_uri}</code>
<Button
@ -613,7 +613,7 @@ export default function OAuthModal({
</div>
</div>
<div className="bg-primary/10 p-4 rounded-lg">
<p className="text-xs text-text-muted mb-1">Your Code</p>
<p className="text-xs text-text-muted mb-1">{t("deviceCodeYourCode")}</p>
<div className="flex items-center justify-center gap-2">
<p className="text-2xl font-mono font-bold text-primary">
{deviceData.user_code}
@ -630,7 +630,7 @@ export default function OAuthModal({
{polling && (
<div className="flex items-center justify-center gap-2 text-sm text-text-muted">
<span className="material-symbols-outlined animate-spin">progress_activity</span>
Waiting for authorization...
{t("deviceCodeWaiting")}
</div>
)}
</>
@ -646,33 +646,27 @@ export default function OAuthModal({
<span className="material-symbols-outlined text-sm align-middle mr-1">
warning
</span>
<strong>Remote access + Google OAuth:</strong> The default credentials only accept
redirects to <code>localhost</code>. After authorizing, your browser will try to
open <code>localhost</code> copy that full URL and paste it below. For fully
remote use without this manual step,{" "}
<a
href="https://github.com/diegosouzapw/OmniRoute#oauth-on-a-remote-server"
target="_blank"
rel="noreferrer"
className="underline"
>
configure your own OAuth credentials
</a>
.
<strong
dangerouslySetInnerHTML={{
__html: t("googleOAuthWarning")
.replace(
"<a>",
'<a href="https://github.com/diegosouzapw/OmniRoute#oauth-on-a-remote-server" target="_blank" rel="noreferrer" class="underline">'
)
.replace("</a>", "</a>"),
}}
/>
</div>
)}
{/* Generic remote info for other providers */}
{!isTrueLocalhost && !GOOGLE_OAUTH_PROVIDERS.has(provider) && (
<div className="rounded-lg border border-blue-500/30 bg-blue-500/10 p-3 text-xs text-blue-200">
<span className="material-symbols-outlined text-sm align-middle mr-1">info</span>
<strong>Remote access:</strong> Since you&apos;re accessing OmniRoute remotely,
after authorizing you&apos;ll see an error page (localhost not found). That&apos;s
expected just copy the full URL from your browser&apos;s address bar and paste
it below.
{t("remoteAccessInfo")}
</div>
)}
<div>
<p className="text-sm font-medium mb-2">Step 1: Open this URL in your browser</p>
<p className="text-sm font-medium mb-2">{t("step1OpenUrl")}</p>
<div className="flex gap-2">
<Input
value={authData?.authUrl || ""}
@ -684,19 +678,21 @@ export default function OAuthModal({
icon={copied === "auth_url" ? "check" : "content_copy"}
onClick={() => copy(authData?.authUrl, "auth_url")}
>
Copy
{t("copy")}
</Button>
</div>
</div>
<div>
<p className="text-sm font-medium mb-2">
Step 2: Paste the callback URL or auth code here
</p>
<p className="text-sm font-medium mb-2">{t("step2PasteCallback")}</p>
<p className="text-xs text-text-muted mb-2">
After authorization, paste the full callback URL. For Claude Code and Cline, you
can also paste the Authentication Code directly, for example{" "}
<code>code#state</code>.
<span
dangerouslySetInnerHTML={{
__html: t("step2Hint")
.replace("<code>", "<code>")
.replace("</code>", "</code>"),
}}
/>
</p>
<Input
value={callbackUrl}
@ -713,10 +709,10 @@ export default function OAuthModal({
<div className="flex gap-2">
<Button onClick={handleManualSubmit} fullWidth disabled={!callbackUrl || !authData}>
Connect
{t("connect")}
</Button>
<Button onClick={onClose} variant="ghost" fullWidth>
Cancel
{t("cancel")}
</Button>
</div>
</>
@ -730,12 +726,12 @@ export default function OAuthModal({
check_circle
</span>
</div>
<h3 className="text-lg font-semibold mb-2">Connected Successfully!</h3>
<h3 className="text-lg font-semibold mb-2">{t("success")}</h3>
<p className="text-sm text-text-muted mb-4">
Your {providerInfo.name} account has been connected.
{t("successMessage", { providerName: providerInfo.name })}
</p>
<Button onClick={onClose} fullWidth>
Done
{t("done")}
</Button>
</div>
)}
@ -746,14 +742,14 @@ export default function OAuthModal({
<div className="size-16 mx-auto mb-4 rounded-full bg-red-100 dark:bg-red-900/30 flex items-center justify-center">
<span className="material-symbols-outlined text-3xl text-red-600">error</span>
</div>
<h3 className="text-lg font-semibold mb-2">Connection Failed</h3>
<h3 className="text-lg font-semibold mb-2">{t("error")}</h3>
<p className="text-sm text-red-600 mb-4">{error}</p>
<div className="flex gap-2">
<Button onClick={startOAuthFlow} variant="secondary" fullWidth>
Try Again
{t("tryAgain")}
</Button>
<Button onClick={onClose} variant="ghost" fullWidth>
Cancel
{t("cancel")}
</Button>
</div>
</div>

View file

@ -1,9 +1,11 @@
"use client";
import { useState, useEffect } from "react";
import { useTranslations } from "next-intl";
import { getDefaultPricing, formatCost } from "@/shared/constants/pricing";
export default function PricingModal({ isOpen, onClose, onSave }) {
const t = useTranslations("pricingModal");
const [pricingData, setPricingData] = useState({});
const [loading, setLoading] = useState(true);
const [saving, setSaving] = useState(false);
@ -62,18 +64,18 @@ export default function PricingModal({ isOpen, onClose, onSave }) {
onClose();
} else {
const error = await response.json();
alert(`Failed to save pricing: ${error.error}`);
alert(`${t("errorSaveFailed")}: ${error.error}`);
}
} catch (error) {
console.error("Failed to save pricing:", error);
alert("Failed to save pricing");
alert(t("errorSaveFailed"));
} finally {
setSaving(false);
}
};
const handleReset = async () => {
if (!confirm("Reset all pricing to defaults? This cannot be undone.")) return;
if (!confirm(t("resetConfirm"))) return;
try {
const response = await fetch("/api/pricing", { method: "DELETE" });
@ -83,7 +85,7 @@ export default function PricingModal({ isOpen, onClose, onSave }) {
}
} catch (error) {
console.error("Failed to reset pricing:", error);
alert("Failed to reset pricing");
alert(t("errorResetFailed"));
}
};
@ -98,7 +100,7 @@ export default function PricingModal({ isOpen, onClose, onSave }) {
<div className="bg-bg-base border border-border rounded-lg shadow-xl max-w-6xl w-full max-h-[90vh] overflow-hidden flex flex-col">
{/* Header */}
<div className="p-4 border-b border-border flex items-center justify-between">
<h2 className="text-xl font-semibold">Pricing Configuration</h2>
<h2 className="text-xl font-semibold">{t("title")}</h2>
<button
onClick={onClose}
className="text-text-muted hover:text-text text-2xl leading-none"
@ -110,15 +112,20 @@ export default function PricingModal({ isOpen, onClose, onSave }) {
{/* Content */}
<div className="flex-1 overflow-auto p-4">
{loading ? (
<div className="text-center py-8 text-text-muted">Loading pricing data...</div>
<div className="text-center py-8 text-text-muted">{t("loading")}</div>
) : (
<div className="space-y-6">
{/* Instructions */}
<div className="bg-bg-subtle border border-border rounded-lg p-3 text-sm">
<p className="font-medium mb-1">Pricing Rates Format</p>
<p className="font-medium mb-1">{t("pricingRatesFormat")}</p>
<p className="text-text-muted">
All rates are in <strong>dollars per million tokens</strong> ($/1M tokens).
Example: Input rate of 2.50 means $2.50 per 1,000,000 input tokens.
<span
dangerouslySetInnerHTML={{
__html: t("ratesDescription")
.replace("<strong>", "<strong>")
.replace("</strong>", "</strong>"),
}}
/>
</p>
</div>
@ -134,12 +141,12 @@ export default function PricingModal({ isOpen, onClose, onSave }) {
<table className="w-full text-sm">
<thead className="bg-bg-hover text-text-muted uppercase text-xs">
<tr>
<th className="px-3 py-2 text-left">Model</th>
<th className="px-3 py-2 text-right">Input</th>
<th className="px-3 py-2 text-right">Output</th>
<th className="px-3 py-2 text-right">Cached</th>
<th className="px-3 py-2 text-right">Reasoning</th>
<th className="px-3 py-2 text-right">Cache Creation</th>
<th className="px-3 py-2 text-left">{t("model")}</th>
<th className="px-3 py-2 text-right">{t("input")}</th>
<th className="px-3 py-2 text-right">{t("output")}</th>
<th className="px-3 py-2 text-right">{t("cached")}</th>
<th className="px-3 py-2 text-right">{t("reasoning")}</th>
<th className="px-3 py-2 text-right">{t("cacheCreation")}</th>
</tr>
</thead>
<tbody className="divide-y divide-border">
@ -170,7 +177,7 @@ export default function PricingModal({ isOpen, onClose, onSave }) {
})}
{allProviders.length === 0 && (
<div className="text-center py-8 text-text-muted">No pricing data available</div>
<div className="text-center py-8 text-text-muted">{t("noPricingData")}</div>
)}
</div>
)}
@ -183,7 +190,7 @@ export default function PricingModal({ isOpen, onClose, onSave }) {
className="px-4 py-2 text-sm text-red-500 hover:bg-red-500/10 rounded border border-red-500/20 transition-colors"
disabled={saving}
>
Reset to Defaults
{t("resetToDefaults")}
</button>
<div className="flex gap-2">
<button
@ -191,14 +198,14 @@ export default function PricingModal({ isOpen, onClose, onSave }) {
className="px-4 py-2 text-sm text-text-muted hover:text-text border border-border rounded transition-colors"
disabled={saving}
>
Cancel
{t("cancel")}
</button>
<button
onClick={handleSave}
className="px-4 py-2 text-sm bg-primary text-white rounded hover:bg-primary/90 transition-colors disabled:opacity-50"
disabled={saving}
>
{saving ? "Saving..." : "Save Changes"}
{saving ? t("saving") : t("saveChanges")}
</button>
</div>
</div>

View file

@ -2,6 +2,7 @@
import { useState, useEffect } from "react";
import PropTypes from "prop-types";
import { useTranslations } from "next-intl";
import Modal from "./Modal";
import Button from "./Button";
@ -15,14 +16,6 @@ const PROXY_TYPES = SOCKS5_UI_ENABLED
? ALL_PROXY_TYPES
: ALL_PROXY_TYPES.filter((type) => type.value !== "socks5");
const LEVEL_LABELS = {
global: "Global",
provider: "Provider",
combo: "Combo",
key: "Key",
direct: "Direct (none)",
};
/**
* ProxyConfigModal Reusable proxy configuration modal for all 4 levels
* @param {Object} props
@ -48,6 +41,7 @@ export default function ProxyConfigModal({
levelLabel?: any;
onSaved?: any;
}) {
const t = useTranslations("proxyConfigModal");
const [mode, setMode] = useState("saved");
const [savedProxies, setSavedProxies] = useState([]);
const [selectedProxyId, setSelectedProxyId] = useState("");
@ -128,9 +122,7 @@ export default function ProxyConfigModal({
setShowAuth(!!(proxy.username || proxy.password));
setHasOwnProxy(true);
if (normalizedType === "socks5" && !SOCKS5_UI_ENABLED) {
setFormError(
"SOCKS5 is configured but hidden because NEXT_PUBLIC_ENABLE_SOCKS5_PROXY=false."
);
setFormError(t("errorSocks5Hidden"));
}
if (!hasSavedAssignment) setMode("custom");
} else {
@ -150,12 +142,15 @@ export default function ProxyConfigModal({
// Determine inheritance source
if (level === "key") {
// Check combo, provider, global
if (config.global) setInheritedFrom({ level: "Global", proxy: config.global });
if (config.global)
setInheritedFrom({ level: t("levelGlobal"), proxy: config.global });
// Provider info requires more context, showing global as fallback
} else if (level === "combo") {
if (config.global) setInheritedFrom({ level: "Global", proxy: config.global });
if (config.global)
setInheritedFrom({ level: t("levelGlobal"), proxy: config.global });
} else if (level === "provider") {
if (config.global) setInheritedFrom({ level: "Global", proxy: config.global });
if (config.global)
setInheritedFrom({ level: t("levelGlobal"), proxy: config.global });
}
}
}
@ -181,7 +176,7 @@ export default function ProxyConfigModal({
const handleSave = async () => {
if (mode === "saved" && !selectedProxyId) {
setFormError("Select a saved proxy before saving.");
setFormError(t("errorSelectSavedProxy"));
return;
}
if (mode === "custom" && !host.trim()) return;
@ -218,7 +213,7 @@ export default function ProxyConfigModal({
});
const clearAssignmentPayload = await clearAssignmentRes.json().catch(() => ({}));
if (!clearAssignmentRes.ok) {
setFormError(clearAssignmentPayload?.error?.message || "Failed to clear saved proxy");
setFormError(clearAssignmentPayload?.error?.message || t("errorClearSavedProxy"));
return;
}
@ -237,7 +232,7 @@ export default function ProxyConfigModal({
}
const payload = await res.json().catch(() => ({}));
if (!res.ok) {
setFormError(payload?.error?.message || "Failed to save proxy configuration");
setFormError(payload?.error?.message || t("errorSaveProxy"));
return;
}
setHasOwnProxy(true);
@ -248,7 +243,7 @@ export default function ProxyConfigModal({
onClose();
} catch (error) {
console.error("Error saving proxy:", error);
setFormError(error.message || "Failed to save proxy configuration");
setFormError(error.message || t("errorSaveProxy"));
} finally {
setSaving(false);
}
@ -274,7 +269,7 @@ export default function ProxyConfigModal({
const res = await fetch(`/api/settings/proxy?${params}`, { method: "DELETE" });
const payload = await res.json().catch(() => ({}));
if (!res.ok) {
setFormError(payload?.error?.message || "Failed to clear proxy configuration");
setFormError(payload?.error?.message || t("errorClearProxy"));
return;
}
resetFields();
@ -285,7 +280,7 @@ export default function ProxyConfigModal({
onClose();
} catch (error) {
console.error("Error clearing proxy:", error);
setFormError(error.message || "Failed to clear proxy configuration");
setFormError(error.message || t("errorClearProxy"));
} finally {
setSaving(false);
}
@ -306,13 +301,13 @@ export default function ProxyConfigModal({
if (mode === "saved") {
if (!selectedProxyId) {
setFormError("Select a saved proxy first.");
setFormError(t("errorSelectProxyFirst"));
setTesting(false);
return;
}
const found = (savedProxies as any[]).find((p: any) => p.id === selectedProxyId);
if (!found) {
setFormError("Selected proxy not found.");
setFormError(t("errorProxyNotFound"));
setTesting(false);
return;
}
@ -342,7 +337,7 @@ export default function ProxyConfigModal({
});
const data = await res.json().catch(() => ({}));
if (!res.ok) {
const message = data?.error?.message || "Connection failed";
const message = data?.error?.message || t("connectionFailed");
setTestResult({ success: false, error: message });
setFormError(message);
return;
@ -350,7 +345,7 @@ export default function ProxyConfigModal({
setTestResult(data);
} catch (error) {
setTestResult({ success: false, error: error.message });
setFormError(error.message || "Connection failed");
setFormError(error.message || t("connectionFailed"));
} finally {
setTesting(false);
}
@ -358,15 +353,13 @@ export default function ProxyConfigModal({
const title =
level === "global"
? "Global Proxy Configuration"
: `${LEVEL_LABELS[level]} Proxy — ${levelLabel || levelId || ""}`;
? t("titleGlobal")
: `${t(`level${level.charAt(0).toUpperCase() + level.slice(1)}` as any)} Proxy — ${levelLabel || levelId || ""}`;
return (
<Modal isOpen={isOpen} onClose={onClose} title={title} maxWidth="lg">
{loading ? (
<div className="py-8 text-center text-text-muted animate-pulse">
Loading proxy configuration...
</div>
<div className="py-8 text-center text-text-muted animate-pulse">{t("loading")}</div>
) : (
<div className="flex flex-col gap-5">
{/* Inheritance indicator */}
@ -376,7 +369,8 @@ export default function ProxyConfigModal({
subdirectory_arrow_right
</span>
<span className="text-blue-300">
Inheriting from <strong>{inheritedFrom.level}</strong>: {inheritedFrom.proxy?.type}
{t("inheritingFrom")} <strong>{inheritedFrom.level}</strong>:{" "}
{inheritedFrom.proxy?.type}
://{inheritedFrom.proxy?.host}:{inheritedFrom.proxy?.port}
</span>
</div>
@ -385,7 +379,7 @@ export default function ProxyConfigModal({
{/* Proxy Type Selector */}
<div>
<label className="text-xs text-text-muted mb-1.5 block uppercase tracking-wider font-medium">
Source
{t("source")}
</label>
<div className="flex gap-2">
<button
@ -396,7 +390,7 @@ export default function ProxyConfigModal({
: "bg-bg-subtle text-text-muted border-border"
}`}
>
Saved Proxy
{t("savedProxy")}
</button>
<button
onClick={() => setMode("custom")}
@ -406,7 +400,7 @@ export default function ProxyConfigModal({
: "bg-bg-subtle text-text-muted border-border"
}`}
>
Custom
{t("custom")}
</button>
</div>
</div>
@ -414,14 +408,14 @@ export default function ProxyConfigModal({
{mode === "saved" && (
<div>
<label className="text-xs text-text-muted mb-1.5 block uppercase tracking-wider font-medium">
Saved Proxy
{t("savedProxy")}
</label>
<select
value={selectedProxyId}
onChange={(e) => setSelectedProxyId(e.target.value)}
className="w-full px-3 py-2.5 rounded-lg bg-bg-subtle border border-border text-sm text-text-primary"
>
<option value="">Select saved proxy...</option>
<option value="">{t("selectSavedProxyPlaceholder")}</option>
{savedProxies.map((item: any) => (
<option key={item.id} value={item.id}>
{item.name} ({item.type}://{item.host}:{item.port})
@ -435,7 +429,7 @@ export default function ProxyConfigModal({
<>
<div>
<label className="text-xs text-text-muted mb-1.5 block uppercase tracking-wider font-medium">
Proxy Type
{t("proxyType")}
</label>
<div className="flex gap-1 bg-bg-subtle rounded-lg p-1 border border-border">
{PROXY_TYPES.map((t) => (
@ -458,19 +452,19 @@ export default function ProxyConfigModal({
<div className="grid grid-cols-3 gap-3">
<div className="col-span-2">
<label className="text-xs text-text-muted mb-1.5 block uppercase tracking-wider font-medium">
Host
{t("host")}
</label>
<input
type="text"
value={host}
onChange={(e) => setHost(e.target.value)}
placeholder="1.2.3.4 or proxy.example.com"
placeholder={t("hostPlaceholder")}
className="w-full px-3 py-2.5 rounded-lg bg-bg-subtle border border-border text-sm text-text-primary placeholder:text-text-muted/50 focus:outline-none focus:border-primary transition-colors"
/>
</div>
<div>
<label className="text-xs text-text-muted mb-1.5 block uppercase tracking-wider font-medium">
Port
{t("port")}
</label>
<input
type="text"
@ -491,31 +485,31 @@ export default function ProxyConfigModal({
<span className="material-symbols-outlined text-base">
{showAuth ? "expand_less" : "expand_more"}
</span>
Authentication (optional)
{t("authOptional")}
</button>
{showAuth && (
<div className="grid grid-cols-2 gap-3 mt-3">
<div>
<label className="text-xs text-text-muted mb-1.5 block uppercase tracking-wider font-medium">
Username
{t("username")}
</label>
<input
type="text"
value={username}
onChange={(e) => setUsername(e.target.value)}
placeholder="Username"
placeholder={t("usernamePlaceholder")}
className="w-full px-3 py-2.5 rounded-lg bg-bg-subtle border border-border text-sm text-text-primary placeholder:text-text-muted/50 focus:outline-none focus:border-primary transition-colors"
/>
</div>
<div>
<label className="text-xs text-text-muted mb-1.5 block uppercase tracking-wider font-medium">
Password
{t("password")}
</label>
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder="Password"
placeholder={t("passwordPlaceholder")}
className="w-full px-3 py-2.5 rounded-lg bg-bg-subtle border border-border text-sm text-text-primary placeholder:text-text-muted/50 focus:outline-none focus:border-primary transition-colors"
/>
</div>
@ -550,15 +544,16 @@ export default function ProxyConfigModal({
<div className="flex-1">
{testResult.success ? (
<div>
<span className="text-sm font-medium text-emerald-400">Connected</span>
<span className="text-sm font-medium text-emerald-400">{t("connected")}</span>
<span className="text-text-muted text-xs ml-2">
IP: <span className="font-mono text-emerald-300">{testResult.publicIp}</span>
{t("ip")}{" "}
<span className="font-mono text-emerald-300">{testResult.publicIp}</span>
{testResult.latencyMs && ` · ${testResult.latencyMs}ms`}
</span>
</div>
) : (
<div className="text-sm text-red-400">
{testResult.error || "Connection failed"}
{testResult.error || t("connectionFailed")}
{testResult.latencyMs && (
<span className="text-text-muted text-xs ml-2">
({testResult.latencyMs}ms)
@ -581,7 +576,7 @@ export default function ProxyConfigModal({
loading={testing}
disabled={mode === "saved" ? !selectedProxyId : !host.trim()}
>
Test Connection
{t("testConnection")}
</Button>
{hasOwnProxy && (
<Button
@ -592,13 +587,13 @@ export default function ProxyConfigModal({
disabled={saving}
className="!text-red-400 hover:!bg-red-500/10"
>
Clear
{t("clear")}
</Button>
)}
</div>
<div className="flex gap-2">
<Button size="sm" variant="secondary" onClick={onClose}>
Cancel
{t("cancel")}
</Button>
<Button
size="sm"
@ -607,7 +602,7 @@ export default function ProxyConfigModal({
loading={saving}
disabled={mode === "saved" ? !selectedProxyId : !host.trim()}
>
Save
{t("save")}
</Button>
</div>
</div>

View file

@ -1,6 +1,7 @@
"use client";
import { useState, useEffect, useCallback, useMemo, useRef } from "react";
import { useTranslations } from "next-intl";
import Card from "./Card";
import RequestLoggerDetail from "./RequestLoggerDetail";
import { copyToClipboard } from "@/shared/utils/clipboard";
@ -42,7 +43,7 @@ const COLUMNS = [
{ key: "time", label: "Time" },
];
const DEFAULT_VISIBLE = Object.fromEntries(COLUMNS.map((c) => [c.key, true]));
// Default visible columns will be generated dynamically with translations
/**
* Get a friendly display label for compatible providers.
@ -112,6 +113,31 @@ function getCacheSourceMeta(cacheSource: unknown) {
}
export default function RequestLoggerV2() {
const t = useTranslations("requestLogger");
// Get translated status filters
const getStatusFilters = () => [
{ key: "all", label: t("statusFilters.all"), icon: "" },
{ key: "error", label: t("statusFilters.error"), icon: "error" },
{ key: "ok", label: t("statusFilters.success"), icon: "check_circle" },
{ key: "combo", label: t("statusFilters.combo"), icon: "hub" },
];
// Get translated columns
const getColumns = () => [
{ key: "status", label: t("columns.status") },
{ key: "model", label: t("columns.model") },
{ key: "requestedModel", label: t("columns.requested") },
{ key: "provider", label: t("columns.provider") },
{ key: "protocol", label: t("columns.protocol") },
{ key: "account", label: t("columns.account") },
{ key: "apiKey", label: t("columns.apiKey") },
{ key: "combo", label: t("columns.combo") },
{ key: "tokens", label: t("columns.tokens") },
{ key: "duration", label: t("columns.duration") },
{ key: "time", label: t("columns.time") },
];
const [logs, setLogs] = useState([]);
const [loading, setLoading] = useState(true);
const [recording, setRecording] = useState(true);
@ -133,12 +159,13 @@ export default function RequestLoggerV2() {
// Column visibility with localStorage persistence
const [visibleColumns, setVisibleColumns] = useState(() => {
if (typeof window === "undefined") return DEFAULT_VISIBLE;
const defaultVisible = Object.fromEntries(getColumns().map((c) => [c.key, true]));
if (typeof window === "undefined") return defaultVisible;
try {
const saved = localStorage.getItem("loggerVisibleColumns");
return saved ? { ...DEFAULT_VISIBLE, ...JSON.parse(saved) } : DEFAULT_VISIBLE;
return saved ? { ...defaultVisible, ...JSON.parse(saved) } : defaultVisible;
} catch {
return DEFAULT_VISIBLE;
return defaultVisible;
}
});
@ -337,7 +364,7 @@ export default function RequestLoggerV2() {
<span
className={`w-2 h-2 rounded-full ${recording ? "bg-red-500 animate-pulse" : "bg-text-muted"}`}
/>
{recording ? "Recording" : "Paused"}
{recording ? t("recording") : t("paused")}
</button>
<button
@ -354,10 +381,10 @@ export default function RequestLoggerV2() {
className={`w-2 h-2 rounded-full ${detailLoggingEnabled ? "bg-amber-500" : "bg-text-muted"}`}
/>
{detailLoggingLoading
? "Updating pipeline logs..."
? t("updatingPipelineLogs")
: detailLoggingEnabled
? "Pipeline Logs On"
: "Pipeline Logs Off"}
? t("pipelineLogsOn")
: t("pipelineLogsOff")}
</button>
{/* Search */}
@ -367,7 +394,7 @@ export default function RequestLoggerV2() {
</span>
<input
type="text"
placeholder="Search model, provider, account, API key, combo..."
placeholder={t("searchPlaceholder")}
value={search}
onChange={(e) => setSearch(e.target.value)}
className="w-full pl-10 pr-4 py-2 rounded-lg bg-bg-subtle border border-border text-sm text-text-primary placeholder:text-text-muted focus:outline-none focus:border-primary"
@ -380,7 +407,7 @@ export default function RequestLoggerV2() {
onChange={(e) => setSelectedProvider(e.target.value)}
className="px-3 py-2 rounded-lg bg-bg-subtle border border-border text-sm text-text-primary focus:outline-none focus:border-primary appearance-none cursor-pointer min-w-[140px]"
>
<option value="">All Providers</option>
<option value="">{t("allProviders")}</option>
{uniqueProviders.map((p) => {
const compatLabel = getProviderDisplayLabel(p, providerNodes);
const pc = PROVIDER_COLORS[p];
@ -398,7 +425,7 @@ export default function RequestLoggerV2() {
onChange={(e) => setSelectedModel(e.target.value)}
className="px-3 py-2 rounded-lg bg-bg-subtle border border-border text-sm text-text-primary focus:outline-none focus:border-primary appearance-none cursor-pointer min-w-[180px]"
>
<option value="">All Models</option>
<option value="">{t("allModels")}</option>
{uniqueModels.map((model) => (
<option key={model} value={model}>
{model}
@ -412,7 +439,7 @@ export default function RequestLoggerV2() {
onChange={(e) => setSelectedAccount(e.target.value)}
className="px-3 py-2 rounded-lg bg-bg-subtle border border-border text-sm text-text-primary focus:outline-none focus:border-primary appearance-none cursor-pointer min-w-[140px]"
>
<option value="">All Accounts</option>
<option value="">{t("allAccounts")}</option>
{uniqueAccounts.map((a) => (
<option key={a} value={a}>
{a}
@ -426,7 +453,7 @@ export default function RequestLoggerV2() {
onChange={(e) => setSelectedApiKey(e.target.value)}
className="px-3 py-2 rounded-lg bg-bg-subtle border border-border text-sm text-text-primary focus:outline-none focus:border-primary appearance-none cursor-pointer min-w-[160px]"
>
<option value="">All API Keys</option>
<option value="">{t("allApiKeys")}</option>
{uniqueApiKeys.map((value) => {
const matched = logs.find((l) => (l.apiKeyId || l.apiKeyName) === value);
const label = formatApiKeyLabel(matched?.apiKeyName, matched?.apiKeyId);
@ -441,28 +468,28 @@ export default function RequestLoggerV2() {
{/* Stats */}
<div className="flex items-center gap-2 text-xs text-text-muted">
<span className="px-2 py-1 rounded bg-bg-subtle border border-border font-mono">
{totalCount} total
{totalCount} {t("total")}
</span>
<span className="px-2 py-1 rounded bg-emerald-500/10 text-emerald-700 dark:text-emerald-400 font-mono">
{okCount} OK
{okCount} {t("ok")}
</span>
{errorCount > 0 && (
<span className="px-2 py-1 rounded bg-red-500/10 text-red-700 dark:text-red-400 font-mono">
{errorCount} ERR
{errorCount} {t("err")}
</span>
)}
{comboCount > 0 && (
<span className="px-2 py-1 rounded bg-violet-500/10 text-violet-700 dark:text-violet-400 font-mono">
{comboCount} combo
{comboCount} {t("combo")}
</span>
)}
{apiKeyCount > 0 && (
<span className="px-2 py-1 rounded bg-primary/10 text-primary font-mono">
{apiKeyCount} keys
{apiKeyCount} {t("keys")}
</span>
)}
<span className="px-2 py-1 rounded bg-bg-subtle border border-border font-mono">
{sortedLogs.length} shown
{sortedLogs.length} {t("shown")}
</span>
</div>
@ -473,18 +500,16 @@ export default function RequestLoggerV2() {
className="px-3 py-2 rounded-lg bg-bg-subtle border border-border text-sm text-text-primary focus:outline-none focus:border-primary appearance-none cursor-pointer min-w-[150px]"
title="Sort logs"
>
<option value="newest">Newest</option>
<option value="oldest">Oldest</option>
<option value="tokens_desc">Tokens </option>
<option value="tokens_asc">Tokens </option>
<option value="duration_desc">Duration </option>
<option value="duration_asc">Duration </option>
<option value="tps_desc">TPS </option>
<option value="tps_asc">TPS </option>
<option value="status_desc">Status </option>
<option value="status_asc">Status </option>
<option value="model_asc">Model A-Z</option>
<option value="model_desc">Model Z-A</option>
<option value="newest">{t("sortNewest")}</option>
<option value="oldest">{t("sortOldest")}</option>
<option value="tokens_desc">{t("sortTokensDesc")}</option>
<option value="tokens_asc">{t("sortTokensAsc")}</option>
<option value="duration_desc">{t("sortDurationDesc")}</option>
<option value="duration_asc">{t("sortDurationAsc")}</option>
<option value="status_desc">{t("sortStatusDesc")}</option>
<option value="status_asc">{t("sortStatusAsc")}</option>
<option value="model_asc">{t("sortModelAsc")}</option>
<option value="model_desc">{t("sortModelDesc")}</option>
</select>
{/* Refresh */}
@ -500,7 +525,7 @@ export default function RequestLoggerV2() {
{/* Quick Filters */}
<div className="flex flex-wrap items-center gap-2">
{/* Status Filters */}
{STATUS_FILTERS.map((f) => (
{getStatusFilters().map((f) => (
<button
key={f.key}
onClick={() => setActiveFilter(activeFilter === f.key ? "all" : f.key)}
@ -557,7 +582,7 @@ export default function RequestLoggerV2() {
{/* Column Visibility Toggles */}
<div className="flex flex-wrap items-center gap-1.5">
<span className="text-[10px] text-text-muted uppercase tracking-wider mr-1">Columns</span>
{COLUMNS.map((col) => (
{getColumns().map((col) => (
<button
key={col.key}
onClick={() => toggleColumn(col.key)}
@ -576,18 +601,16 @@ export default function RequestLoggerV2() {
<Card className="overflow-hidden bg-black/5 dark:bg-black/20">
<div className="p-0 overflow-x-auto max-h-[calc(100vh-320px)] overflow-y-auto">
{loading && logs.length === 0 ? (
<div className="p-8 text-center text-text-muted">Loading logs...</div>
<div className="p-8 text-center text-text-muted">{t("loadingLogs")}</div>
) : logs.length === 0 ? (
<div className="p-8 text-center text-text-muted">
<span className="material-symbols-outlined text-[48px] mb-2 block opacity-40">
receipt_long
</span>
No logs recorded yet. Make some API calls to see them here.
{t("noLogs")}
</div>
) : sortedLogs.length === 0 ? (
<div className="p-8 text-center text-text-muted">
No logs match the current filters.
</div>
<div className="p-8 text-center text-text-muted">{t("noMatchingLogs")}</div>
) : (
<table className="w-full text-left border-collapse text-xs">
<thead
@ -600,7 +623,7 @@ export default function RequestLoggerV2() {
>
{visibleColumns.status && (
<th className="px-3 py-2.5 font-semibold text-text-muted uppercase tracking-wider text-[10px]">
Status
{t("columns.status")}
</th>
)}
{visibleColumns.cacheSource && (
@ -610,42 +633,42 @@ export default function RequestLoggerV2() {
)}
{visibleColumns.model && (
<th className="px-3 py-2.5 font-semibold text-text-muted uppercase tracking-wider text-[10px]">
Model
{t("columns.model")}
</th>
)}
{visibleColumns.requestedModel && (
<th className="px-3 py-2.5 font-semibold text-text-muted uppercase tracking-wider text-[10px]">
Requested
{t("columns.requested")}
</th>
)}
{visibleColumns.provider && (
<th className="px-3 py-2.5 font-semibold text-text-muted uppercase tracking-wider text-[10px]">
Provider
{t("columns.provider")}
</th>
)}
{visibleColumns.protocol && (
<th className="px-3 py-2.5 font-semibold text-text-muted uppercase tracking-wider text-[10px]">
Req Protocol
{t("columns.protocol")}
</th>
)}
{visibleColumns.account && (
<th className="px-3 py-2.5 font-semibold text-text-muted uppercase tracking-wider text-[10px]">
Account
{t("columns.account")}
</th>
)}
{visibleColumns.apiKey && (
<th className="px-3 py-2.5 font-semibold text-text-muted uppercase tracking-wider text-[10px]">
API Key
{t("columns.apiKey")}
</th>
)}
{visibleColumns.combo && (
<th className="px-3 py-2.5 font-semibold text-text-muted uppercase tracking-wider text-[10px]">
Combo
{t("columns.combo")}
</th>
)}
{visibleColumns.tokens && (
<th className="px-3 py-2.5 font-semibold text-text-muted uppercase tracking-wider text-[10px] text-right">
Tokens
{t("columns.tokens")}
</th>
)}
{visibleColumns.tps && (
@ -655,12 +678,12 @@ export default function RequestLoggerV2() {
)}
{visibleColumns.duration && (
<th className="px-3 py-2.5 font-semibold text-text-muted uppercase tracking-wider text-[10px] text-right">
Duration
{t("columns.duration")}
</th>
)}
{visibleColumns.time && (
<th className="px-3 py-2.5 font-semibold text-text-muted uppercase tracking-wider text-[10px] text-right">
Time
{t("columns.time")}
</th>
)}
</tr>
@ -838,8 +861,11 @@ export default function RequestLoggerV2() {
</Card>
<div className="text-[10px] text-text-muted italic">
Call logs are also saved as JSON files to <code>{`{DATA_DIR}/call_logs/`}</code> and rotated
by <code>CALL_LOG_RETENTION_DAYS</code> and <code>CALL_LOG_MAX_ENTRIES</code>.
{t("callLogsInfo", {
dataDir: "{DATA_DIR}/call_logs/",
retentionDays: "CALL_LOG_RETENTION_DAYS",
maxEntries: "CALL_LOG_MAX_ENTRIES",
})}
</div>
{/* Detail Modal */}

View file

@ -1,6 +1,6 @@
"use client";
import { useState, useMemo, useCallback } from "react";
import { useState, useMemo, useCallback, useRef, useEffect } from "react";
import { useLocale } from "next-intl";
import Card from "../Card";
import { getModelColor } from "@/shared/constants/colors";
@ -174,6 +174,8 @@ export function CompactStatGrid({ sections }: { sections: CompactStatSection[] }
// ── ActivityHeatmap ────────────────────────────────────────────────────────
export function ActivityHeatmap({ activityMap }) {
const scrollRef = useRef<HTMLDivElement>(null);
const cells = useMemo(() => {
const today = new Date();
const days = [];
@ -209,6 +211,12 @@ export function ActivityHeatmap({ activityMap }) {
return w;
}, [cells]);
// Auto-scroll to the right edge so the current date is visible
useEffect(() => {
if (scrollRef.current) {
scrollRef.current.scrollLeft = scrollRef.current.scrollWidth;
}
}, [weeks]);
const monthLabels = useMemo(() => {
const labels = [];
let lastMonth = -1;
@ -259,44 +267,51 @@ export function ActivityHeatmap({ activityMap }) {
</span>
</div>
<div className="flex gap-[3px] mb-1 ml-6" style={{ fontSize: "10px" }}>
{monthLabels.map((m, i) => (
<span
key={i}
className="text-text-muted"
style={{
position: "relative",
left: `${m.weekIdx * 13}px`,
marginLeft: i === 0 ? 0 : "-20px",
}}
>
{m.label}
</span>
))}
</div>
<div className="flex gap-[3px] overflow-x-auto">
<div className="flex flex-col gap-[3px] shrink-0 text-[10px] text-text-muted pr-1">
<span className="h-[10px]"></span>
<span className="h-[10px] leading-[10px]">Mon</span>
<span className="h-[10px]"></span>
<span className="h-[10px] leading-[10px]">Wed</span>
<span className="h-[10px]"></span>
<span className="h-[10px] leading-[10px]">Fri</span>
<span className="h-[10px]"></span>
</div>
{weeks.map((week, wi) => (
<div key={wi} className="flex flex-col gap-[3px]">
{week.map((day, di) => (
<div
key={di}
title={day ? `${day.date}: ${fmtFull(day.value)} tokens` : ""}
className={`w-[10px] h-[10px] rounded-[2px] ${day ? getCellColor(day.value) : "bg-transparent"}`}
/>
<div
ref={scrollRef}
className="overflow-x-auto"
>
<div className="w-max">
<div className="flex gap-[3px] mb-1 ml-6" style={{ fontSize: "10px" }}>
{monthLabels.map((m, i) => (
<span
key={i}
className="text-text-muted"
style={{
position: "relative",
left: `${m.weekIdx * 13}px`,
marginLeft: i === 0 ? 0 : "-20px",
}}
>
{m.label}
</span>
))}
</div>
))}
<div className="flex gap-[3px]">
<div className="flex flex-col gap-[3px] shrink-0 text-[10px] text-text-muted pr-1 sticky left-0 z-10 bg-surface">
<span className="h-[10px]"></span>
<span className="h-[10px] leading-[10px]">Mon</span>
<span className="h-[10px]"></span>
<span className="h-[10px] leading-[10px]">Wed</span>
<span className="h-[10px]"></span>
<span className="h-[10px] leading-[10px]">Fri</span>
<span className="h-[10px]"></span>
</div>
{weeks.map((week, wi) => (
<div key={wi} className="flex flex-col gap-[3px]">
{week.map((day, di) => (
<div
key={di}
title={day ? `${day.date}: ${fmtFull(day.value)} tokens` : ""}
className={`w-[10px] h-[10px] rounded-[2px] ${day ? getCellColor(day.value) : "bg-transparent"}`}
/>
))}
</div>
))}
</div>
</div>
</div>
<div className="flex items-center gap-1 mt-2 ml-6 text-[10px] text-text-muted">

View file

@ -179,6 +179,90 @@ test("chatCore sanitization normalizes max_output_tokens into max_tokens", async
assert.equal("max_tokens" in untouched.call.body, false);
});
test("chatCore sanitization preserves max_output_tokens for openai-responses targets", async () => {
// When the target provider uses openai-responses format (e.g. Codex),
// max_output_tokens is the canonical field and must NOT be normalized to
// max_tokens. Normalizing it breaks Responses→Responses passthrough because
// the translator (which converts max_tokens back) is skipped for same-format.
const { call } = await invokeChatCore({
endpoint: "/v1/responses",
body: {
model: "gpt-5.4",
max_output_tokens: 4096,
input: [{ role: "user", content: "hello" }],
},
responseFactory: () =>
new Response(
JSON.stringify({
id: "resp_test",
object: "response",
status: "completed",
model: "gpt-5.4",
output: [
{ type: "message", role: "assistant", content: [{ type: "output_text", text: "ok" }] },
],
usage: { input_tokens: 1, output_tokens: 1, total_tokens: 2 },
}),
{ status: 200, headers: { "Content-Type": "application/json" } }
),
});
// max_output_tokens should survive sanitization for Responses targets
assert.equal("max_tokens" in call.body, false, "max_tokens must not be injected for Responses targets");
// Reverse normalization: max_tokens → max_output_tokens for Responses targets
const fromMaxTokens = await invokeChatCore({
endpoint: "/v1/responses",
body: {
model: "gpt-5.4",
max_tokens: 2048,
input: [{ role: "user", content: "hello" }],
},
responseFactory: () =>
new Response(
JSON.stringify({
id: "resp_test2",
object: "response",
status: "completed",
model: "gpt-5.4",
output: [
{ type: "message", role: "assistant", content: [{ type: "output_text", text: "ok" }] },
],
usage: { input_tokens: 1, output_tokens: 1, total_tokens: 2 },
}),
{ status: 200, headers: { "Content-Type": "application/json" } }
),
});
assert.equal("max_tokens" in fromMaxTokens.call.body, false, "max_tokens should be converted to max_output_tokens");
// Reverse normalization: max_completion_tokens → max_output_tokens for Responses targets
const fromMaxCompletion = await invokeChatCore({
endpoint: "/v1/responses",
body: {
model: "gpt-5.4",
max_completion_tokens: 8192,
input: [{ role: "user", content: "hello" }],
},
responseFactory: () =>
new Response(
JSON.stringify({
id: "resp_test3",
object: "response",
status: "completed",
model: "gpt-5.4",
output: [
{ type: "message", role: "assistant", content: [{ type: "output_text", text: "ok" }] },
],
usage: { input_tokens: 1, output_tokens: 1, total_tokens: 2 },
}),
{ status: 200, headers: { "Content-Type": "application/json" } }
),
});
assert.equal("max_completion_tokens" in fromMaxCompletion.call.body, false, "max_completion_tokens should be converted to max_output_tokens");
});
test("chatCore sanitization strips empty message names and filters empty tool names", async () => {
// Note: `input` field is tested separately because its presence triggers
// Responses format detection (PR #1002), which changes message handling.