feat: Introduce combo readiness checks and strategy recommendations, updating i18n messages and e2e tests.

This commit is contained in:
diegosouzapw
2026-03-05 14:38:03 -03:00
parent 2b067c5d00
commit 0d3728efa4
32 changed files with 2273 additions and 98 deletions

View File

@@ -1,6 +1,6 @@
"use client";
import { useState, useEffect, useCallback } from "react";
import { useState, useEffect, useCallback, useRef } from "react";
import {
Card,
Button,
@@ -71,6 +71,63 @@ const ADVANCED_FIELD_HELP_FALLBACK = {
queueTimeout: "How long a request can wait in queue before timeout in round-robin.",
};
const STRATEGY_RECOMMENDATIONS_FALLBACK = {
priority: {
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.",
],
},
weighted: {
title: "Controlled traffic split",
description: "Great for canary rollouts and gradual migration between models.",
tips: [
"Start with conservative split like 90/10.",
"Keep the total at 100% and auto-balance after changes.",
"Monitor success and latency before increasing canary weight.",
],
},
"round-robin": {
title: "Predictable load sharing",
description: "Best when models are equivalent and you need smooth distribution.",
tips: [
"Use at least 2 models.",
"Set concurrency limits to avoid burst overload.",
"Use queue timeout to fail fast under saturation.",
],
},
random: {
title: "Quick spread with low setup",
description: "Use when you need simple distribution without strict guarantees.",
tips: [
"Use models with similar latency profiles.",
"Keep retries enabled to absorb random misses.",
"Prefer this for experimentation, not strict SLAs.",
],
},
"least-used": {
title: "Adaptive balancing",
description: "Routes to less-used models to reduce hotspots over time.",
tips: [
"Works better under continuous traffic.",
"Combine with health checks for safer balancing.",
"Track per-model usage to validate distribution gains.",
],
},
"cost-optimized": {
title: "Budget-first routing",
description: "Routes to lower-cost models when pricing metadata is available.",
tips: [
"Ensure pricing coverage for all selected models.",
"Keep a quality fallback for hard prompts.",
"Use for batch/background jobs where cost is the main KPI.",
],
},
};
const COMBO_USAGE_GUIDE_STORAGE_KEY = "omniroute:combos:hide-usage-guide";
const COMBO_TEMPLATE_FALLBACK = {
@@ -166,6 +223,23 @@ function getStrategyGuideText(t, strategy, field) {
return getI18nOrFallback(t, key, strategyFallback[field]);
}
function getStrategyRecommendationText(t, strategy, field) {
const strategyFallback =
STRATEGY_RECOMMENDATIONS_FALLBACK[strategy] || STRATEGY_RECOMMENDATIONS_FALLBACK.priority;
if (field === "tips") {
return strategyFallback.tips.map((tip, index) =>
getI18nOrFallback(t, `strategyRecommendations.${strategy}.tip${index + 1}`, tip)
);
}
return getI18nOrFallback(
t,
`strategyRecommendations.${strategy}.${field}`,
strategyFallback[field]
);
}
// ─────────────────────────────────────────────
// Helper: normalize model entry (legacy string ↔ new object)
// ─────────────────────────────────────────────
@@ -621,6 +695,58 @@ function StrategyGuidanceCard({ strategy }) {
);
}
function StrategyRecommendationsPanel({ strategy, onApply, showNudge }) {
const t = useTranslations("combos");
const strategyLabel = getStrategyLabel(t, strategy);
const title = getStrategyRecommendationText(t, strategy, "title");
const description = getStrategyRecommendationText(t, strategy, "description");
const tips = getStrategyRecommendationText(t, strategy, "tips");
return (
<div className="rounded-lg border border-black/10 dark:border-white/10 bg-white/70 dark:bg-white/[0.02] p-2.5">
<div className="flex items-start justify-between gap-2">
<div className="min-w-0">
<p className="text-[11px] text-text-muted">
{getI18nOrFallback(t, "recommendationsLabel", "Recommended setup")}
</p>
<p className="text-xs font-semibold text-text-main mt-0.5">
{title} · <span className="text-primary">{strategyLabel}</span>
</p>
<p className="text-[10px] text-text-muted mt-0.5">{description}</p>
</div>
<Button size="sm" variant="ghost" onClick={onApply} className="!h-6 px-2 text-[10px]">
{getI18nOrFallback(t, "applyRecommendations", "Apply recommendations")}
</Button>
</div>
<div className="mt-2 grid grid-cols-1 gap-1">
{tips.map((tip, index) => (
<div
key={`${strategy}-tip-${index + 1}`}
className="flex items-start gap-1 rounded-md bg-black/[0.02] dark:bg-white/[0.03] px-1.5 py-1"
>
<span className="material-symbols-outlined text-[12px] text-primary mt-0.5">check</span>
<p className="text-[10px] text-text-main">{tip}</p>
</div>
))}
</div>
{showNudge && (
<div
data-testid="strategy-change-nudge"
className="mt-2 rounded-md border border-primary/20 bg-primary/10 px-2 py-1 text-[10px] text-primary"
>
{getI18nOrFallback(
t,
"recommendationsUpdated",
"Recommendations updated for {strategy}."
).replace("{strategy}", strategyLabel)}
</div>
)}
</div>
);
}
function FieldLabelWithHelp({ label, help }) {
return (
<div className="flex items-center gap-1 mb-0.5">
@@ -634,6 +760,88 @@ function FieldLabelWithHelp({ label, help }) {
);
}
function ComboReadinessPanel({ checks, blockers }) {
const t = useTranslations("combos");
const hasBlockers = blockers.length > 0;
return (
<div
data-testid="combo-readiness-panel"
className={`rounded-lg border px-2.5 py-2 ${
hasBlockers
? "border-amber-500/30 bg-amber-500/5"
: "border-emerald-500/20 bg-emerald-500/[0.04]"
}`}
>
<div className="flex items-center gap-1.5">
<span
className={`material-symbols-outlined text-[14px] ${
hasBlockers
? "text-amber-600 dark:text-amber-400"
: "text-emerald-600 dark:text-emerald-400"
}`}
>
{hasBlockers ? "rule" : "check_circle"}
</span>
<p className="text-[11px] font-medium text-text-main">
{getI18nOrFallback(t, "readinessTitle", "Ready to save?")}
</p>
</div>
<p className="text-[10px] text-text-muted mt-0.5">
{getI18nOrFallback(
t,
"readinessDescription",
"Review the checklist before creating or updating this combo."
)}
</p>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-1 mt-2">
{checks.map((check) => (
<div
key={check.id}
className="flex items-center gap-1 rounded-md px-1.5 py-1 bg-black/[0.02] dark:bg-white/[0.02]"
>
<span
className={`material-symbols-outlined text-[12px] ${
check.ok ? "text-emerald-500" : "text-amber-500"
}`}
>
{check.ok ? "task_alt" : "pending"}
</span>
<span className="text-[10px] text-text-main">{check.label}</span>
</div>
))}
</div>
{hasBlockers && (
<div
data-testid="combo-save-blockers"
className="mt-2 rounded-md border border-amber-500/30 bg-amber-500/10 px-2 py-1.5"
>
<p className="text-[10px] font-medium text-amber-700 dark:text-amber-300">
{getI18nOrFallback(
t,
"saveBlockedTitle",
"Save is blocked until the following items are fixed:"
)}
</p>
<div className="mt-1 flex flex-col gap-0.5">
{blockers.map((blocker, index) => (
<p
key={`${blocker}-${index}`}
className="text-[10px] text-amber-700 dark:text-amber-300"
>
{blocker}
</p>
))}
</div>
</div>
)}
</div>
);
}
// ─────────────────────────────────────────────
// Combo Card
// ─────────────────────────────────────────────
@@ -885,6 +1093,7 @@ function TestResultsView({ results }) {
function ComboFormModal({ isOpen, combo, onClose, onSave, activeProviders }) {
const t = useTranslations("combos");
const tc = useTranslations("common");
const notify = useNotificationStore();
const [name, setName] = useState(combo?.name || "");
const [models, setModels] = useState(() => {
return (combo?.models || []).map((m) => normalizeModelEntry(m));
@@ -898,6 +1107,8 @@ function ComboFormModal({ isOpen, combo, onClose, onSave, activeProviders }) {
const [providerNodes, setProviderNodes] = useState([]);
const [showAdvanced, setShowAdvanced] = useState(false);
const [config, setConfig] = useState(combo?.config || {});
const [showStrategyNudge, setShowStrategyNudge] = useState(false);
const strategyChangeMountedRef = useRef(false);
// DnD state
const hasPricingForModel = useCallback(
@@ -946,6 +1157,59 @@ function ComboFormModal({ isOpen, combo, onClose, onSave, activeProviders }) {
hasNoModels ||
hasInvalidWeightedTotal ||
hasCostOptimizedWithoutPricing;
const readinessChecks = [
{
id: "name",
ok: !!name.trim() && !nameError,
label: getI18nOrFallback(t, "readinessCheckName", "Combo name is valid"),
},
{
id: "models",
ok: !hasNoModels,
label: getI18nOrFallback(t, "readinessCheckModels", "At least one model is selected"),
},
{
id: "weights",
ok: strategy === "weighted" ? !hasInvalidWeightedTotal : true,
label:
strategy === "weighted"
? getI18nOrFallback(t, "readinessCheckWeights", "Weighted total is 100%")
: getI18nOrFallback(t, "readinessCheckWeightsOptional", "Weight rule not required"),
},
{
id: "pricing",
ok: strategy === "cost-optimized" ? !hasCostOptimizedWithoutPricing : true,
label:
strategy === "cost-optimized"
? getI18nOrFallback(t, "readinessCheckPricing", "Pricing data is available")
: getI18nOrFallback(t, "readinessCheckPricingOptional", "Pricing rule not required"),
},
];
const saveBlockers = [];
if (!name.trim()) {
saveBlockers.push(getI18nOrFallback(t, "saveBlockName", "Define a combo name."));
} else if (nameError) {
saveBlockers.push(nameError);
}
if (hasNoModels) {
saveBlockers.push(getI18nOrFallback(t, "saveBlockModels", "Add at least one model."));
}
if (hasInvalidWeightedTotal) {
saveBlockers.push(
typeof t.has === "function" && t.has("saveBlockWeighted")
? t("saveBlockWeighted", { total: weightTotal })
: `Set weights to 100% (current: ${weightTotal}%).`
);
}
if (hasCostOptimizedWithoutPricing) {
saveBlockers.push(
getI18nOrFallback(
t,
"saveBlockPricing",
"Add pricing for at least one model or choose a different strategy."
)
);
}
const fetchModalData = async () => {
try {
@@ -979,6 +1243,17 @@ function ComboFormModal({ isOpen, combo, onClose, onSave, activeProviders }) {
if (isOpen) fetchModalData();
}, [isOpen]);
useEffect(() => {
if (!strategyChangeMountedRef.current) {
strategyChangeMountedRef.current = true;
return;
}
setShowStrategyNudge(true);
const timeoutId = setTimeout(() => setShowStrategyNudge(false), 2600);
return () => clearTimeout(timeoutId);
}, [strategy]);
const validateName = (value) => {
if (!value.trim()) {
setNameError(t("nameRequired"));
@@ -1031,6 +1306,46 @@ function ComboFormModal({ isOpen, combo, onClose, onSave, activeProviders }) {
);
};
const applyStrategyRecommendations = () => {
const strategyDefaults = {
priority: { maxRetries: 2, retryDelayMs: 1500, healthCheckEnabled: true },
weighted: { maxRetries: 1, retryDelayMs: 1000, healthCheckEnabled: true },
"round-robin": {
maxRetries: 1,
retryDelayMs: 750,
healthCheckEnabled: true,
concurrencyPerModel: 3,
queueTimeoutMs: 30000,
},
random: { maxRetries: 1, retryDelayMs: 1000, healthCheckEnabled: true },
"least-used": { maxRetries: 1, retryDelayMs: 1000, healthCheckEnabled: true },
"cost-optimized": { maxRetries: 1, retryDelayMs: 500, healthCheckEnabled: true },
};
const defaults = strategyDefaults[strategy] || strategyDefaults.priority;
setConfig((prev) => {
const next = { ...prev };
for (const [key, value] of Object.entries(defaults)) {
if (next[key] === undefined || next[key] === null || next[key] === "") {
next[key] = value;
}
}
return next;
});
if (strategy === "weighted" && models.length > 1) {
handleAutoBalance();
}
if (strategy === "round-robin") {
setShowAdvanced(true);
}
notify.success(
getI18nOrFallback(t, "recommendationsApplied", "Recommendations applied to this combo.")
);
};
const applyTemplate = (template) => {
setStrategy(template.strategy);
setConfig((prev) => ({ ...prev, ...template.config }));
@@ -1210,6 +1525,7 @@ function ComboFormModal({ isOpen, combo, onClose, onSave, activeProviders }) {
<button
key={s.value}
onClick={() => setStrategy(s.value)}
data-testid={`strategy-option-${s.value}`}
title={t(s.descKey)}
aria-label={`${getStrategyLabel(t, s.value)}. ${t(s.descKey)}`}
className={`py-1.5 px-2 rounded-md text-xs font-medium transition-all ${
@@ -1231,6 +1547,13 @@ function ComboFormModal({ isOpen, combo, onClose, onSave, activeProviders }) {
<div className="mt-2">
<StrategyGuidanceCard strategy={strategy} />
</div>
<div className="mt-2">
<StrategyRecommendationsPanel
strategy={strategy}
onApply={applyStrategyRecommendations}
showNudge={showStrategyNudge}
/>
</div>
</div>
{/* Models */}
@@ -1449,6 +1772,10 @@ function ComboFormModal({ isOpen, combo, onClose, onSave, activeProviders }) {
</div>
)}
<div className="mt-2">
<ComboReadinessPanel checks={readinessChecks} blockers={saveBlockers} />
</div>
{/* Add Model button */}
<button
onClick={() => setShowModelSelect(true)}

View File

@@ -646,7 +646,68 @@
"pricingMissingShort": "رسم",
"warningRoundRobinSingleModel": "يعتبر Round - robin أكثر فائدة مع طرازين على الأقل.",
"warningCostOptimizedPartialPricing": "فقط {priced} من طرازات {total} لها أسعار. قد يكون التوجيه مدركًا جزئيًا للتكلفة.",
"warningCostOptimizedNoPricing": "لم يتم العثور على بيانات تسعير لهذه المجموعة. قد يتم توجيه التكلفة المحسّنة بشكل غير متوقع."
"warningCostOptimizedNoPricing": "لم يتم العثور على بيانات تسعير لهذه المجموعة. قد يتم توجيه التكلفة المحسّنة بشكل غير متوقع.",
"readinessTitle": "هل أنت مستعد للحفظ؟",
"readinessDescription": "قم بمراجعة قائمة التحقق قبل إنشاء هذا التحرير والسرد أو تحديثه.",
"readinessCheckName": "اسم التحرير والسرد صالح",
"readinessCheckModels": "تم تحديد نموذج واحد على الأقل",
"readinessCheckWeights": "الإجمالي المرجح هو 100%",
"readinessCheckWeightsOptional": "قاعدة الوزن غير مطلوبة",
"readinessCheckPricing": "بيانات التسعير متاحة",
"readinessCheckPricingOptional": "قاعدة التسعير غير مطلوبة",
"saveBlockedTitle": "تم حظر الحفظ حتى يتم إصلاح العناصر التالية:",
"saveBlockName": "تحديد اسم التحرير والسرد.",
"saveBlockModels": "أضف نموذجًا واحدًا على الأقل.",
"saveBlockWeighted": "اضبط الأوزان على 100% (الحالي: {total}%).",
"saveBlockPricing": "أضف أسعارًا لنموذج واحد على الأقل أو اختر استراتيجية مختلفة.",
"recommendationsLabel": "Recommended setup",
"applyRecommendations": "Apply recommendations",
"recommendationsUpdated": "Recommendations updated for {strategy}.",
"recommendationsApplied": "Recommendations applied to this combo.",
"strategyRecommendations": {
"priority": {
"title": "Fail-safe baseline",
"description": "Use one primary model and keep fallback chain short and reliable.",
"tip1": "Put your most reliable model first.",
"tip2": "Keep 1-2 backup models with similar quality.",
"tip3": "Use safe retries to absorb transient provider failures."
},
"weighted": {
"title": "Controlled traffic split",
"description": "Great for canary rollouts and gradual migration between models.",
"tip1": "Start with conservative split like 90/10.",
"tip2": "Keep the total at 100% and auto-balance after changes.",
"tip3": "Monitor success and latency before increasing canary weight."
},
"round-robin": {
"title": "Predictable load sharing",
"description": "Best when models are equivalent and you need smooth distribution.",
"tip1": "Use at least 2 models.",
"tip2": "Set concurrency limits to avoid burst overload.",
"tip3": "Use queue timeout to fail fast under saturation."
},
"random": {
"title": "Quick spread with low setup",
"description": "Use when you need simple distribution without strict guarantees.",
"tip1": "Use models with similar latency profiles.",
"tip2": "Keep retries enabled to absorb random misses.",
"tip3": "Prefer this for experimentation, not strict SLAs."
},
"least-used": {
"title": "Adaptive balancing",
"description": "Routes to less-used models to reduce hotspots over time.",
"tip1": "Works better under continuous traffic.",
"tip2": "Combine with health checks for safer balancing.",
"tip3": "Track per-model usage to validate distribution gains."
},
"cost-optimized": {
"title": "Budget-first routing",
"description": "Routes to lower-cost models when pricing metadata is available.",
"tip1": "Ensure pricing coverage for all selected models.",
"tip2": "Keep a quality fallback for hard prompts.",
"tip3": "Use for batch/background jobs where cost is the main KPI."
}
}
},
"costs": {
"title": "التكاليف",

View File

@@ -646,7 +646,68 @@
"pricingMissingShort": "без цена",
"warningRoundRobinSingleModel": "Round - robin е най - полезен с поне 2 модела.",
"warningCostOptimizedPartialPricing": "Само {priced} от {total} моделите имат ценообразуване. Маршрутизирането може да бъде частично съобразено с разходите.",
"warningCostOptimizedNoPricing": "Няма намерени данни за ценообразуване за тази комбинация. Оптимизираният по отношение на разходите маршрут може да е неочакван."
"warningCostOptimizedNoPricing": "Няма намерени данни за ценообразуване за тази комбинация. Оптимизираният по отношение на разходите маршрут може да е неочакван.",
"readinessTitle": "Готови ли сте да запазите?",
"readinessDescription": "Прегледайте контролния списък, преди да създадете или актуализирате тази комбинация.",
"readinessCheckName": "Комбо името е валидно",
"readinessCheckModels": "Избран е поне един модел",
"readinessCheckWeights": "Претеглената обща сума е 100%",
"readinessCheckWeightsOptional": "Правилото за тегло не се изисква",
"readinessCheckPricing": "Налични са данни за цените",
"readinessCheckPricingOptional": "Правилото за ценообразуване не се изисква",
"saveBlockedTitle": "Запазването е блокирано, докато не бъдат коригирани следните елементи:",
"saveBlockName": "Определете комбо име.",
"saveBlockModels": "Добавете поне един модел.",
"saveBlockWeighted": "Задайте тегла на 100% (текущо: {total}%).",
"saveBlockPricing": "Добавете цена за поне един модел или изберете различна стратегия.",
"recommendationsLabel": "Recommended setup",
"applyRecommendations": "Apply recommendations",
"recommendationsUpdated": "Recommendations updated for {strategy}.",
"recommendationsApplied": "Recommendations applied to this combo.",
"strategyRecommendations": {
"priority": {
"title": "Fail-safe baseline",
"description": "Use one primary model and keep fallback chain short and reliable.",
"tip1": "Put your most reliable model first.",
"tip2": "Keep 1-2 backup models with similar quality.",
"tip3": "Use safe retries to absorb transient provider failures."
},
"weighted": {
"title": "Controlled traffic split",
"description": "Great for canary rollouts and gradual migration between models.",
"tip1": "Start with conservative split like 90/10.",
"tip2": "Keep the total at 100% and auto-balance after changes.",
"tip3": "Monitor success and latency before increasing canary weight."
},
"round-robin": {
"title": "Predictable load sharing",
"description": "Best when models are equivalent and you need smooth distribution.",
"tip1": "Use at least 2 models.",
"tip2": "Set concurrency limits to avoid burst overload.",
"tip3": "Use queue timeout to fail fast under saturation."
},
"random": {
"title": "Quick spread with low setup",
"description": "Use when you need simple distribution without strict guarantees.",
"tip1": "Use models with similar latency profiles.",
"tip2": "Keep retries enabled to absorb random misses.",
"tip3": "Prefer this for experimentation, not strict SLAs."
},
"least-used": {
"title": "Adaptive balancing",
"description": "Routes to less-used models to reduce hotspots over time.",
"tip1": "Works better under continuous traffic.",
"tip2": "Combine with health checks for safer balancing.",
"tip3": "Track per-model usage to validate distribution gains."
},
"cost-optimized": {
"title": "Budget-first routing",
"description": "Routes to lower-cost models when pricing metadata is available.",
"tip1": "Ensure pricing coverage for all selected models.",
"tip2": "Keep a quality fallback for hard prompts.",
"tip3": "Use for batch/background jobs where cost is the main KPI."
}
}
},
"costs": {
"title": "Разходи",

View File

@@ -646,7 +646,68 @@
"pricingMissingShort": "ingen pris",
"warningRoundRobinSingleModel": "Round-robin er mest nyttig med mindst 2 modeller.",
"warningCostOptimizedPartialPricing": "Kun {priced} af {total}-modeller har priser. Routing kan være delvist omkostningsbevidst.",
"warningCostOptimizedNoPricing": "Der blev ikke fundet nogen prisdata for denne kombination. Omkostningsoptimeret kan rute uventet."
"warningCostOptimizedNoPricing": "Der blev ikke fundet nogen prisdata for denne kombination. Omkostningsoptimeret kan rute uventet.",
"readinessTitle": "Klar til at spare?",
"readinessDescription": "Gennemgå tjeklisten, før du opretter eller opdaterer denne kombination.",
"readinessCheckName": "Kombinationsnavnet er gyldigt",
"readinessCheckModels": "Der er valgt mindst én model",
"readinessCheckWeights": "Vægtet total er 100 %",
"readinessCheckWeightsOptional": "Vægtregel ikke påkrævet",
"readinessCheckPricing": "Prisdata er tilgængelige",
"readinessCheckPricingOptional": "Reglen om prissætning er ikke påkrævet",
"saveBlockedTitle": "Gem er blokeret, indtil følgende elementer er rettet:",
"saveBlockName": "Definer et kombinationsnavn.",
"saveBlockModels": "Tilføj mindst én model.",
"saveBlockWeighted": "Indstil vægte til 100 % (aktuelt: {total}%).",
"saveBlockPricing": "Tilføj priser for mindst én model, eller vælg en anden strategi.",
"recommendationsLabel": "Recommended setup",
"applyRecommendations": "Apply recommendations",
"recommendationsUpdated": "Recommendations updated for {strategy}.",
"recommendationsApplied": "Recommendations applied to this combo.",
"strategyRecommendations": {
"priority": {
"title": "Fail-safe baseline",
"description": "Use one primary model and keep fallback chain short and reliable.",
"tip1": "Put your most reliable model first.",
"tip2": "Keep 1-2 backup models with similar quality.",
"tip3": "Use safe retries to absorb transient provider failures."
},
"weighted": {
"title": "Controlled traffic split",
"description": "Great for canary rollouts and gradual migration between models.",
"tip1": "Start with conservative split like 90/10.",
"tip2": "Keep the total at 100% and auto-balance after changes.",
"tip3": "Monitor success and latency before increasing canary weight."
},
"round-robin": {
"title": "Predictable load sharing",
"description": "Best when models are equivalent and you need smooth distribution.",
"tip1": "Use at least 2 models.",
"tip2": "Set concurrency limits to avoid burst overload.",
"tip3": "Use queue timeout to fail fast under saturation."
},
"random": {
"title": "Quick spread with low setup",
"description": "Use when you need simple distribution without strict guarantees.",
"tip1": "Use models with similar latency profiles.",
"tip2": "Keep retries enabled to absorb random misses.",
"tip3": "Prefer this for experimentation, not strict SLAs."
},
"least-used": {
"title": "Adaptive balancing",
"description": "Routes to less-used models to reduce hotspots over time.",
"tip1": "Works better under continuous traffic.",
"tip2": "Combine with health checks for safer balancing.",
"tip3": "Track per-model usage to validate distribution gains."
},
"cost-optimized": {
"title": "Budget-first routing",
"description": "Routes to lower-cost models when pricing metadata is available.",
"tip1": "Ensure pricing coverage for all selected models.",
"tip2": "Keep a quality fallback for hard prompts.",
"tip3": "Use for batch/background jobs where cost is the main KPI."
}
}
},
"costs": {
"title": "Omkostninger",

View File

@@ -646,7 +646,68 @@
"pricingMissingShort": "kein Preis",
"warningRoundRobinSingleModel": "Round-Robin ist bei mindestens zwei Modellen am nützlichsten.",
"warningCostOptimizedPartialPricing": "Nur {priced} der {total} Modelle haben Preise. Die Routenplanung kann teilweise kostenbewusst erfolgen.",
"warningCostOptimizedNoPricing": "Für diese Kombination wurden keine Preisdaten gefunden. Eine kostenoptimierte Route kann unerwartet erfolgen."
"warningCostOptimizedNoPricing": "Für diese Kombination wurden keine Preisdaten gefunden. Eine kostenoptimierte Route kann unerwartet erfolgen.",
"readinessTitle": "Bereit zum Speichern?",
"readinessDescription": "Prüfe die Checkliste, bevor du dieses Combo erstellst oder aktualisierst.",
"readinessCheckName": "Der Combo-Name ist gültig",
"readinessCheckModels": "Mindestens ein Modell ist ausgewählt",
"readinessCheckWeights": "Die Gewichtssumme beträgt 100 %",
"readinessCheckWeightsOptional": "Gewichtungsregel nicht erforderlich",
"readinessCheckPricing": "Preisdaten sind verfügbar",
"readinessCheckPricingOptional": "Preisregel nicht erforderlich",
"saveBlockedTitle": "Speichern ist blockiert, bis diese Punkte behoben sind:",
"saveBlockName": "Definiere einen Namen für das Combo.",
"saveBlockModels": "Füge mindestens ein Modell hinzu.",
"saveBlockWeighted": "Setze die Gewichte auf 100 % (aktuell: {total} %).",
"saveBlockPricing": "Füge Preise für mindestens ein Modell hinzu oder wähle eine andere Strategie.",
"recommendationsLabel": "Empfohlene Konfiguration",
"applyRecommendations": "Empfehlungen anwenden",
"recommendationsUpdated": "Empfehlungen für {strategy} aktualisiert.",
"recommendationsApplied": "Empfehlungen für dieses Combo wurden angewendet.",
"strategyRecommendations": {
"priority": {
"title": "Ausfallsichere Basis",
"description": "Nutze ein primäres Modell und halte die Fallback-Kette kurz und zuverlässig.",
"tip1": "Setze dein zuverlässigstes Modell an erste Stelle.",
"tip2": "Nutze 1-2 Backup-Modelle mit ähnlicher Qualität.",
"tip3": "Aktiviere sichere Retries, um temporäre Provider-Fehler abzufangen."
},
"weighted": {
"title": "Kontrollierte Traffic-Aufteilung",
"description": "Ideal für Canary-Rollouts und schrittweise Modellmigrationen.",
"tip1": "Starte mit einer konservativen Verteilung wie 90/10.",
"tip2": "Halte die Summe bei 100 % und gleiche nach Änderungen automatisch aus.",
"tip3": "Überwache Erfolg und Latenz, bevor du Canary-Gewichte erhöhst."
},
"round-robin": {
"title": "Vorhersehbare Lastverteilung",
"description": "Am besten, wenn Modelle gleichwertig sind und du eine stabile Verteilung brauchst.",
"tip1": "Nutze mindestens 2 Modelle.",
"tip2": "Setze Concurrency-Limits, um Lastspitzen zu vermeiden.",
"tip3": "Nutze Queue-Timeouts, um bei Sättigung schnell zu scheitern."
},
"random": {
"title": "Schnelle Verteilung mit wenig Setup",
"description": "Für einfache Verteilung ohne harte Garantien.",
"tip1": "Nutze Modelle mit ähnlichen Latenzprofilen.",
"tip2": "Lass Retries aktiv, um zufällige Fehlschläge abzufangen.",
"tip3": "Gut für Experimente, nicht für strenge SLAs."
},
"least-used": {
"title": "Adaptives Balancing",
"description": "Routet zu weniger genutzten Modellen und reduziert Hotspots über Zeit.",
"tip1": "Funktioniert besser bei kontinuierlichem Traffic.",
"tip2": "Kombiniere mit Health Checks für sichereres Balancing.",
"tip3": "Verfolge Nutzung pro Modell, um Verteilungsgewinne zu validieren."
},
"cost-optimized": {
"title": "Kostenorientiertes Routing",
"description": "Routet zu günstigeren Modellen, wenn Preisdaten verfügbar sind.",
"tip1": "Sichere Preisabdeckung für alle ausgewählten Modelle.",
"tip2": "Behalte einen Qualitäts-Fallback für schwierige Prompts.",
"tip3": "Ideal für Batch/Hintergrundjobs, bei denen Kosten das Haupt-KPI sind."
}
}
},
"costs": {
"title": "Kosten",

View File

@@ -646,7 +646,68 @@
"pricingMissingShort": "no-price",
"warningRoundRobinSingleModel": "Round-robin is most useful with at least 2 models.",
"warningCostOptimizedPartialPricing": "Only {priced} of {total} models have pricing. Routing may be partially cost-aware.",
"warningCostOptimizedNoPricing": "No pricing data found for this combo. Cost-optimized may route unexpectedly."
"warningCostOptimizedNoPricing": "No pricing data found for this combo. Cost-optimized may route unexpectedly.",
"readinessTitle": "Ready to save?",
"readinessDescription": "Review the checklist before creating or updating this combo.",
"readinessCheckName": "Combo name is valid",
"readinessCheckModels": "At least one model is selected",
"readinessCheckWeights": "Weighted total is 100%",
"readinessCheckWeightsOptional": "Weight rule not required",
"readinessCheckPricing": "Pricing data is available",
"readinessCheckPricingOptional": "Pricing rule not required",
"saveBlockedTitle": "Save is blocked until the following items are fixed:",
"saveBlockName": "Define a combo name.",
"saveBlockModels": "Add at least one model.",
"saveBlockWeighted": "Set weights to 100% (current: {total}%).",
"saveBlockPricing": "Add pricing for at least one model or choose a different strategy.",
"recommendationsLabel": "Recommended setup",
"applyRecommendations": "Apply recommendations",
"recommendationsUpdated": "Recommendations updated for {strategy}.",
"recommendationsApplied": "Recommendations applied to this combo.",
"strategyRecommendations": {
"priority": {
"title": "Fail-safe baseline",
"description": "Use one primary model and keep fallback chain short and reliable.",
"tip1": "Put your most reliable model first.",
"tip2": "Keep 1-2 backup models with similar quality.",
"tip3": "Use safe retries to absorb transient provider failures."
},
"weighted": {
"title": "Controlled traffic split",
"description": "Great for canary rollouts and gradual migration between models.",
"tip1": "Start with conservative split like 90/10.",
"tip2": "Keep the total at 100% and auto-balance after changes.",
"tip3": "Monitor success and latency before increasing canary weight."
},
"round-robin": {
"title": "Predictable load sharing",
"description": "Best when models are equivalent and you need smooth distribution.",
"tip1": "Use at least 2 models.",
"tip2": "Set concurrency limits to avoid burst overload.",
"tip3": "Use queue timeout to fail fast under saturation."
},
"random": {
"title": "Quick spread with low setup",
"description": "Use when you need simple distribution without strict guarantees.",
"tip1": "Use models with similar latency profiles.",
"tip2": "Keep retries enabled to absorb random misses.",
"tip3": "Prefer this for experimentation, not strict SLAs."
},
"least-used": {
"title": "Adaptive balancing",
"description": "Routes to less-used models to reduce hotspots over time.",
"tip1": "Works better under continuous traffic.",
"tip2": "Combine with health checks for safer balancing.",
"tip3": "Track per-model usage to validate distribution gains."
},
"cost-optimized": {
"title": "Budget-first routing",
"description": "Routes to lower-cost models when pricing metadata is available.",
"tip1": "Ensure pricing coverage for all selected models.",
"tip2": "Keep a quality fallback for hard prompts.",
"tip3": "Use for batch/background jobs where cost is the main KPI."
}
}
},
"costs": {
"title": "Costs",

View File

@@ -646,7 +646,68 @@
"pricingMissingShort": "sin precio",
"warningRoundRobinSingleModel": "El round-robin es más útil con al menos 2 modelos.",
"warningCostOptimizedPartialPricing": "Solo {priced} de los modelos {total} tienen precios. El enrutamiento puede tener en cuenta parcialmente los costos.",
"warningCostOptimizedNoPricing": "No se encontraron datos de precios para este combo. El costo optimizado puede enrutarse inesperadamente."
"warningCostOptimizedNoPricing": "No se encontraron datos de precios para este combo. El costo optimizado puede enrutarse inesperadamente.",
"readinessTitle": "¿Listo para guardar?",
"readinessDescription": "Revisa la lista de verificación antes de crear o actualizar este combo.",
"readinessCheckName": "El nombre del combo es válido",
"readinessCheckModels": "Hay al menos un modelo seleccionado",
"readinessCheckWeights": "El total de pesos es 100%",
"readinessCheckWeightsOptional": "La regla de pesos no aplica",
"readinessCheckPricing": "Hay datos de precios disponibles",
"readinessCheckPricingOptional": "La regla de precios no aplica",
"saveBlockedTitle": "El guardado está bloqueado hasta corregir estos puntos:",
"saveBlockName": "Define un nombre para el combo.",
"saveBlockModels": "Añade al menos un modelo.",
"saveBlockWeighted": "Ajusta los pesos a 100% (actual: {total}%).",
"saveBlockPricing": "Añade precios para al menos un modelo o elige otra estrategia.",
"recommendationsLabel": "Configuración recomendada",
"applyRecommendations": "Aplicar recomendaciones",
"recommendationsUpdated": "Recomendaciones actualizadas para {strategy}.",
"recommendationsApplied": "Se aplicaron recomendaciones a este combo.",
"strategyRecommendations": {
"priority": {
"title": "Base tolerante a fallos",
"description": "Usa un modelo principal y mantén una cadena de fallback corta y confiable.",
"tip1": "Coloca primero tu modelo más confiable.",
"tip2": "Mantén 1-2 modelos de respaldo con calidad similar.",
"tip3": "Usa reintentos seguros para absorber fallos transitorios del proveedor."
},
"weighted": {
"title": "Reparto de tráfico controlado",
"description": "Ideal para despliegues canary y migraciones graduales entre modelos.",
"tip1": "Empieza con una división conservadora como 90/10.",
"tip2": "Mantén el total en 100% y autoequilibra tras cambios.",
"tip3": "Monitorea éxito y latencia antes de subir el peso canary."
},
"round-robin": {
"title": "Reparto de carga predecible",
"description": "Mejor cuando los modelos son equivalentes y necesitas distribución estable.",
"tip1": "Usa al menos 2 modelos.",
"tip2": "Define límites de concurrencia para evitar ráfagas.",
"tip3": "Usa timeout de cola para fallar rápido bajo saturación."
},
"random": {
"title": "Distribución rápida con poca configuración",
"description": "Úsala cuando necesites reparto simple sin garantías estrictas.",
"tip1": "Usa modelos con perfiles de latencia similares.",
"tip2": "Mantén reintentos activos para absorber fallos aleatorios.",
"tip3": "Prefiérela para experimentación, no para SLA estrictos."
},
"least-used": {
"title": "Balanceo adaptativo",
"description": "Enruta a modelos menos usados para reducir cuellos de botella con el tiempo.",
"tip1": "Funciona mejor con tráfico continuo.",
"tip2": "Combínala con health checks para un balanceo más seguro.",
"tip3": "Sigue el uso por modelo para validar la distribución."
},
"cost-optimized": {
"title": "Enrutamiento orientado a costo",
"description": "Enruta a modelos más baratos cuando hay metadatos de precio disponibles.",
"tip1": "Asegura cobertura de precios para todos los modelos seleccionados.",
"tip2": "Mantén un fallback de calidad para prompts difíciles.",
"tip3": "Úsala en batch/tareas de fondo donde el costo sea el KPI principal."
}
}
},
"costs": {
"title": "Costos",

View File

@@ -646,7 +646,68 @@
"pricingMissingShort": "ei-hintaa",
"warningRoundRobinSingleModel": "Round-robin on hyödyllisin vähintään kahdella mallilla.",
"warningCostOptimizedPartialPricing": "Vain {priced} {total}-malleista on hinnoiteltu. Reititys voi olla osittain kustannustietoinen.",
"warningCostOptimizedNoPricing": "Tälle yhdistelmälle ei löytynyt hintatietoja. Kustannusoptimoitu voi reitittää odottamatta."
"warningCostOptimizedNoPricing": "Tälle yhdistelmälle ei löytynyt hintatietoja. Kustannusoptimoitu voi reitittää odottamatta.",
"readinessTitle": "Oletko valmis säästämään?",
"readinessDescription": "Tarkista tarkistuslista ennen tämän yhdistelmän luomista tai päivittämistä.",
"readinessCheckName": "Yhdistelmänimi on kelvollinen",
"readinessCheckModels": "Ainakin yksi malli on valittu",
"readinessCheckWeights": "Painotettu kokonaismäärä on 100 %",
"readinessCheckWeightsOptional": "Painosääntöä ei vaadita",
"readinessCheckPricing": "Hintatiedot ovat saatavilla",
"readinessCheckPricingOptional": "Hinnoittelusääntöä ei vaadita",
"saveBlockedTitle": "Tallennus on estetty, kunnes seuraavat kohteet on korjattu:",
"saveBlockName": "Määritä yhdistelmänimi.",
"saveBlockModels": "Lisää vähintään yksi malli.",
"saveBlockWeighted": "Aseta painot 100 %:iin (nykyinen: {total}%).",
"saveBlockPricing": "Lisää hinnoittelu vähintään yhdelle mallille tai valitse toinen strategia.",
"recommendationsLabel": "Recommended setup",
"applyRecommendations": "Apply recommendations",
"recommendationsUpdated": "Recommendations updated for {strategy}.",
"recommendationsApplied": "Recommendations applied to this combo.",
"strategyRecommendations": {
"priority": {
"title": "Fail-safe baseline",
"description": "Use one primary model and keep fallback chain short and reliable.",
"tip1": "Put your most reliable model first.",
"tip2": "Keep 1-2 backup models with similar quality.",
"tip3": "Use safe retries to absorb transient provider failures."
},
"weighted": {
"title": "Controlled traffic split",
"description": "Great for canary rollouts and gradual migration between models.",
"tip1": "Start with conservative split like 90/10.",
"tip2": "Keep the total at 100% and auto-balance after changes.",
"tip3": "Monitor success and latency before increasing canary weight."
},
"round-robin": {
"title": "Predictable load sharing",
"description": "Best when models are equivalent and you need smooth distribution.",
"tip1": "Use at least 2 models.",
"tip2": "Set concurrency limits to avoid burst overload.",
"tip3": "Use queue timeout to fail fast under saturation."
},
"random": {
"title": "Quick spread with low setup",
"description": "Use when you need simple distribution without strict guarantees.",
"tip1": "Use models with similar latency profiles.",
"tip2": "Keep retries enabled to absorb random misses.",
"tip3": "Prefer this for experimentation, not strict SLAs."
},
"least-used": {
"title": "Adaptive balancing",
"description": "Routes to less-used models to reduce hotspots over time.",
"tip1": "Works better under continuous traffic.",
"tip2": "Combine with health checks for safer balancing.",
"tip3": "Track per-model usage to validate distribution gains."
},
"cost-optimized": {
"title": "Budget-first routing",
"description": "Routes to lower-cost models when pricing metadata is available.",
"tip1": "Ensure pricing coverage for all selected models.",
"tip2": "Keep a quality fallback for hard prompts.",
"tip3": "Use for batch/background jobs where cost is the main KPI."
}
}
},
"costs": {
"title": "Kustannukset",

View File

@@ -646,7 +646,68 @@
"pricingMissingShort": "sans prix",
"warningRoundRobinSingleModel": "Le round-robin est plus utile avec au moins 2 modèles.",
"warningCostOptimizedPartialPricing": "Seuls {priced} des modèles {total} ont un prix. Le routage peut être partiellement axé sur les coûts.",
"warningCostOptimizedNoPricing": "Aucune donnée de prix trouvée pour ce combo. Un itinéraire optimisé en termes de coûts peut être inattendu."
"warningCostOptimizedNoPricing": "Aucune donnée de prix trouvée pour ce combo. Un itinéraire optimisé en termes de coûts peut être inattendu.",
"readinessTitle": "Prêt à enregistrer ?",
"readinessDescription": "Vérifie la checklist avant de créer ou de mettre à jour ce combo.",
"readinessCheckName": "Le nom du combo est valide",
"readinessCheckModels": "Au moins un modèle est sélectionné",
"readinessCheckWeights": "Le total des poids est à 100 %",
"readinessCheckWeightsOptional": "Règle de pondération non requise",
"readinessCheckPricing": "Les données de prix sont disponibles",
"readinessCheckPricingOptional": "Règle de prix non requise",
"saveBlockedTitle": "Lenregistrement est bloqué tant que ces points ne sont pas corrigés :",
"saveBlockName": "Définis un nom pour le combo.",
"saveBlockModels": "Ajoute au moins un modèle.",
"saveBlockWeighted": "Ajuste les pondérations à 100 % (actuel : {total} %).",
"saveBlockPricing": "Ajoute un prix pour au moins un modèle ou choisis une autre stratégie.",
"recommendationsLabel": "Configuration recommandée",
"applyRecommendations": "Appliquer les recommandations",
"recommendationsUpdated": "Recommandations mises à jour pour {strategy}.",
"recommendationsApplied": "Recommandations appliquées à ce combo.",
"strategyRecommendations": {
"priority": {
"title": "Base tolérante aux pannes",
"description": "Utilise un modèle principal et garde une chaîne de fallback courte et fiable.",
"tip1": "Place ton modèle le plus fiable en premier.",
"tip2": "Garde 1 à 2 modèles de secours avec une qualité proche.",
"tip3": "Active des retries sûrs pour absorber les pannes transitoires."
},
"weighted": {
"title": "Répartition de trafic contrôlée",
"description": "Idéal pour les déploiements canary et les migrations progressives.",
"tip1": "Commence avec une répartition prudente comme 90/10.",
"tip2": "Garde le total à 100 % et auto-équilibre après chaque changement.",
"tip3": "Surveille succès et latence avant daugmenter le poids canary."
},
"round-robin": {
"title": "Partage de charge prévisible",
"description": "Parfait quand les modèles sont équivalents et quil faut une distribution stable.",
"tip1": "Utilise au moins 2 modèles.",
"tip2": "Définis des limites de concurrence pour éviter les pics.",
"tip3": "Utilise un timeout de file pour échouer vite en saturation."
},
"random": {
"title": "Répartition rapide avec peu de réglages",
"description": "À utiliser pour une distribution simple sans garanties strictes.",
"tip1": "Choisis des modèles avec des profils de latence similaires.",
"tip2": "Garde les retries actifs pour absorber les échecs aléatoires.",
"tip3": "À privilégier pour lexpérimentation, pas pour des SLA stricts."
},
"least-used": {
"title": "Équilibrage adaptatif",
"description": "Routage vers les modèles les moins utilisés pour réduire les points chauds.",
"tip1": "Fonctionne mieux avec un trafic continu.",
"tip2": "Combine avec les health checks pour un équilibrage plus sûr.",
"tip3": "Suis lusage par modèle pour valider la distribution."
},
"cost-optimized": {
"title": "Routage orienté budget",
"description": "Routage vers les modèles les moins coûteux si les prix sont disponibles.",
"tip1": "Assure une couverture de prix pour tous les modèles sélectionnés.",
"tip2": "Garde un fallback de qualité pour les prompts difficiles.",
"tip3": "Idéal pour batch/tâches de fond où le coût est le KPI principal."
}
}
},
"costs": {
"title": "Coûts",

View File

@@ -646,7 +646,68 @@
"pricingMissingShort": "no-price",
"warningRoundRobinSingleModel": "Round-robin is most useful with at least 2 models.",
"warningCostOptimizedPartialPricing": "Only {priced} of {total} models have pricing. Routing may be partially cost-aware.",
"warningCostOptimizedNoPricing": "No pricing data found for this combo. Cost-optimized may route unexpectedly."
"warningCostOptimizedNoPricing": "No pricing data found for this combo. Cost-optimized may route unexpectedly.",
"readinessTitle": "Ready to save?",
"readinessDescription": "Review the checklist before creating or updating this combo.",
"readinessCheckName": "Combo name is valid",
"readinessCheckModels": "At least one model is selected",
"readinessCheckWeights": "Weighted total is 100%",
"readinessCheckWeightsOptional": "Weight rule not required",
"readinessCheckPricing": "Pricing data is available",
"readinessCheckPricingOptional": "Pricing rule not required",
"saveBlockedTitle": "Save is blocked until the following items are fixed:",
"saveBlockName": "Define a combo name.",
"saveBlockModels": "Add at least one model.",
"saveBlockWeighted": "Set weights to 100% (current: {total}%).",
"saveBlockPricing": "Add pricing for at least one model or choose a different strategy.",
"recommendationsLabel": "Recommended setup",
"applyRecommendations": "Apply recommendations",
"recommendationsUpdated": "Recommendations updated for {strategy}.",
"recommendationsApplied": "Recommendations applied to this combo.",
"strategyRecommendations": {
"priority": {
"title": "Fail-safe baseline",
"description": "Use one primary model and keep fallback chain short and reliable.",
"tip1": "Put your most reliable model first.",
"tip2": "Keep 1-2 backup models with similar quality.",
"tip3": "Use safe retries to absorb transient provider failures."
},
"weighted": {
"title": "Controlled traffic split",
"description": "Great for canary rollouts and gradual migration between models.",
"tip1": "Start with conservative split like 90/10.",
"tip2": "Keep the total at 100% and auto-balance after changes.",
"tip3": "Monitor success and latency before increasing canary weight."
},
"round-robin": {
"title": "Predictable load sharing",
"description": "Best when models are equivalent and you need smooth distribution.",
"tip1": "Use at least 2 models.",
"tip2": "Set concurrency limits to avoid burst overload.",
"tip3": "Use queue timeout to fail fast under saturation."
},
"random": {
"title": "Quick spread with low setup",
"description": "Use when you need simple distribution without strict guarantees.",
"tip1": "Use models with similar latency profiles.",
"tip2": "Keep retries enabled to absorb random misses.",
"tip3": "Prefer this for experimentation, not strict SLAs."
},
"least-used": {
"title": "Adaptive balancing",
"description": "Routes to less-used models to reduce hotspots over time.",
"tip1": "Works better under continuous traffic.",
"tip2": "Combine with health checks for safer balancing.",
"tip3": "Track per-model usage to validate distribution gains."
},
"cost-optimized": {
"title": "Budget-first routing",
"description": "Routes to lower-cost models when pricing metadata is available.",
"tip1": "Ensure pricing coverage for all selected models.",
"tip2": "Keep a quality fallback for hard prompts.",
"tip3": "Use for batch/background jobs where cost is the main KPI."
}
}
},
"costs": {
"title": "עלויות",

View File

@@ -646,7 +646,68 @@
"pricingMissingShort": "no-price",
"warningRoundRobinSingleModel": "Round-robin is most useful with at least 2 models.",
"warningCostOptimizedPartialPricing": "Only {priced} of {total} models have pricing. Routing may be partially cost-aware.",
"warningCostOptimizedNoPricing": "No pricing data found for this combo. Cost-optimized may route unexpectedly."
"warningCostOptimizedNoPricing": "No pricing data found for this combo. Cost-optimized may route unexpectedly.",
"readinessTitle": "Ready to save?",
"readinessDescription": "Review the checklist before creating or updating this combo.",
"readinessCheckName": "Combo name is valid",
"readinessCheckModels": "At least one model is selected",
"readinessCheckWeights": "Weighted total is 100%",
"readinessCheckWeightsOptional": "Weight rule not required",
"readinessCheckPricing": "Az árképzési adatok rendelkezésre állnak",
"readinessCheckPricingOptional": "Az árképzési szabály nem szükséges",
"saveBlockedTitle": "A mentés a következő elemek kijavításáig le van tiltva:",
"saveBlockName": "Határozzon meg egy kombinált nevet.",
"saveBlockModels": "Adjon hozzá legalább egy modellt.",
"saveBlockWeighted": "Állítsa be a súlyokat 100%-ra (jelenleg: {total}%).",
"saveBlockPricing": "Adjon hozzá árat legalább egy modellhez, vagy válasszon másik stratégiát.",
"recommendationsLabel": "Recommended setup",
"applyRecommendations": "Apply recommendations",
"recommendationsUpdated": "Recommendations updated for {strategy}.",
"recommendationsApplied": "Recommendations applied to this combo.",
"strategyRecommendations": {
"priority": {
"title": "Fail-safe baseline",
"description": "Use one primary model and keep fallback chain short and reliable.",
"tip1": "Put your most reliable model first.",
"tip2": "Keep 1-2 backup models with similar quality.",
"tip3": "Use safe retries to absorb transient provider failures."
},
"weighted": {
"title": "Controlled traffic split",
"description": "Great for canary rollouts and gradual migration between models.",
"tip1": "Start with conservative split like 90/10.",
"tip2": "Keep the total at 100% and auto-balance after changes.",
"tip3": "Monitor success and latency before increasing canary weight."
},
"round-robin": {
"title": "Predictable load sharing",
"description": "Best when models are equivalent and you need smooth distribution.",
"tip1": "Use at least 2 models.",
"tip2": "Set concurrency limits to avoid burst overload.",
"tip3": "Use queue timeout to fail fast under saturation."
},
"random": {
"title": "Quick spread with low setup",
"description": "Use when you need simple distribution without strict guarantees.",
"tip1": "Use models with similar latency profiles.",
"tip2": "Keep retries enabled to absorb random misses.",
"tip3": "Prefer this for experimentation, not strict SLAs."
},
"least-used": {
"title": "Adaptive balancing",
"description": "Routes to less-used models to reduce hotspots over time.",
"tip1": "Works better under continuous traffic.",
"tip2": "Combine with health checks for safer balancing.",
"tip3": "Track per-model usage to validate distribution gains."
},
"cost-optimized": {
"title": "Budget-first routing",
"description": "Routes to lower-cost models when pricing metadata is available.",
"tip1": "Ensure pricing coverage for all selected models.",
"tip2": "Keep a quality fallback for hard prompts.",
"tip3": "Use for batch/background jobs where cost is the main KPI."
}
}
},
"costs": {
"title": "Költségek",

View File

@@ -646,7 +646,68 @@
"pricingMissingShort": "no-price",
"warningRoundRobinSingleModel": "Round-robin is most useful with at least 2 models.",
"warningCostOptimizedPartialPricing": "Only {priced} of {total} models have pricing. Routing may be partially cost-aware.",
"warningCostOptimizedNoPricing": "No pricing data found for this combo. Cost-optimized may route unexpectedly."
"warningCostOptimizedNoPricing": "No pricing data found for this combo. Cost-optimized may route unexpectedly.",
"readinessTitle": "Siap menabung?",
"readinessDescription": "Tinjau daftar periksa sebelum membuat atau memperbarui kombo ini.",
"readinessCheckName": "Nama kombo valid",
"readinessCheckModels": "Setidaknya satu model dipilih",
"readinessCheckWeights": "Total tertimbang adalah 100%",
"readinessCheckWeightsOptional": "Aturan berat tidak diperlukan",
"readinessCheckPricing": "Data harga tersedia",
"readinessCheckPricingOptional": "Aturan penetapan harga tidak diperlukan",
"saveBlockedTitle": "Penyimpanan diblokir hingga item berikut diperbaiki:",
"saveBlockName": "Tentukan nama kombo.",
"saveBlockModels": "Tambahkan setidaknya satu model.",
"saveBlockWeighted": "Tetapkan bobot menjadi 100% (saat ini: {total}%).",
"saveBlockPricing": "Tambahkan harga untuk setidaknya satu model atau pilih strategi lain.",
"recommendationsLabel": "Recommended setup",
"applyRecommendations": "Apply recommendations",
"recommendationsUpdated": "Recommendations updated for {strategy}.",
"recommendationsApplied": "Recommendations applied to this combo.",
"strategyRecommendations": {
"priority": {
"title": "Fail-safe baseline",
"description": "Use one primary model and keep fallback chain short and reliable.",
"tip1": "Put your most reliable model first.",
"tip2": "Keep 1-2 backup models with similar quality.",
"tip3": "Use safe retries to absorb transient provider failures."
},
"weighted": {
"title": "Controlled traffic split",
"description": "Great for canary rollouts and gradual migration between models.",
"tip1": "Start with conservative split like 90/10.",
"tip2": "Keep the total at 100% and auto-balance after changes.",
"tip3": "Monitor success and latency before increasing canary weight."
},
"round-robin": {
"title": "Predictable load sharing",
"description": "Best when models are equivalent and you need smooth distribution.",
"tip1": "Use at least 2 models.",
"tip2": "Set concurrency limits to avoid burst overload.",
"tip3": "Use queue timeout to fail fast under saturation."
},
"random": {
"title": "Quick spread with low setup",
"description": "Use when you need simple distribution without strict guarantees.",
"tip1": "Use models with similar latency profiles.",
"tip2": "Keep retries enabled to absorb random misses.",
"tip3": "Prefer this for experimentation, not strict SLAs."
},
"least-used": {
"title": "Adaptive balancing",
"description": "Routes to less-used models to reduce hotspots over time.",
"tip1": "Works better under continuous traffic.",
"tip2": "Combine with health checks for safer balancing.",
"tip3": "Track per-model usage to validate distribution gains."
},
"cost-optimized": {
"title": "Budget-first routing",
"description": "Routes to lower-cost models when pricing metadata is available.",
"tip1": "Ensure pricing coverage for all selected models.",
"tip2": "Keep a quality fallback for hard prompts.",
"tip3": "Use for batch/background jobs where cost is the main KPI."
}
}
},
"costs": {
"title": "Biaya",

View File

@@ -646,7 +646,68 @@
"pricingMissingShort": "no-price",
"warningRoundRobinSingleModel": "Round-robin is most useful with at least 2 models.",
"warningCostOptimizedPartialPricing": "Only {priced} of {total} models have pricing. Routing may be partially cost-aware.",
"warningCostOptimizedNoPricing": "No pricing data found for this combo. Cost-optimized may route unexpectedly."
"warningCostOptimizedNoPricing": "No pricing data found for this combo. Cost-optimized may route unexpectedly.",
"readinessTitle": "Siap menabung?",
"readinessDescription": "Tinjau daftar periksa sebelum membuat atau memperbarui kombo ini.",
"readinessCheckName": "Nama kombo valid",
"readinessCheckModels": "Setidaknya satu model dipilih",
"readinessCheckWeights": "Total tertimbang adalah 100%",
"readinessCheckWeightsOptional": "Aturan berat tidak diperlukan",
"readinessCheckPricing": "Data harga tersedia",
"readinessCheckPricingOptional": "Aturan penetapan harga tidak diperlukan",
"saveBlockedTitle": "Penyimpanan diblokir hingga item berikut diperbaiki:",
"saveBlockName": "Tentukan nama kombo.",
"saveBlockModels": "Tambahkan setidaknya satu model.",
"saveBlockWeighted": "Tetapkan bobot menjadi 100% (saat ini: {total}%).",
"saveBlockPricing": "Tambahkan harga untuk setidaknya satu model atau pilih strategi lain.",
"recommendationsLabel": "Recommended setup",
"applyRecommendations": "Apply recommendations",
"recommendationsUpdated": "Recommendations updated for {strategy}.",
"recommendationsApplied": "Recommendations applied to this combo.",
"strategyRecommendations": {
"priority": {
"title": "Fail-safe baseline",
"description": "Use one primary model and keep fallback chain short and reliable.",
"tip1": "Put your most reliable model first.",
"tip2": "Keep 1-2 backup models with similar quality.",
"tip3": "Use safe retries to absorb transient provider failures."
},
"weighted": {
"title": "Controlled traffic split",
"description": "Great for canary rollouts and gradual migration between models.",
"tip1": "Start with conservative split like 90/10.",
"tip2": "Keep the total at 100% and auto-balance after changes.",
"tip3": "Monitor success and latency before increasing canary weight."
},
"round-robin": {
"title": "Predictable load sharing",
"description": "Best when models are equivalent and you need smooth distribution.",
"tip1": "Use at least 2 models.",
"tip2": "Set concurrency limits to avoid burst overload.",
"tip3": "Use queue timeout to fail fast under saturation."
},
"random": {
"title": "Quick spread with low setup",
"description": "Use when you need simple distribution without strict guarantees.",
"tip1": "Use models with similar latency profiles.",
"tip2": "Keep retries enabled to absorb random misses.",
"tip3": "Prefer this for experimentation, not strict SLAs."
},
"least-used": {
"title": "Adaptive balancing",
"description": "Routes to less-used models to reduce hotspots over time.",
"tip1": "Works better under continuous traffic.",
"tip2": "Combine with health checks for safer balancing.",
"tip3": "Track per-model usage to validate distribution gains."
},
"cost-optimized": {
"title": "Budget-first routing",
"description": "Routes to lower-cost models when pricing metadata is available.",
"tip1": "Ensure pricing coverage for all selected models.",
"tip2": "Keep a quality fallback for hard prompts.",
"tip3": "Use for batch/background jobs where cost is the main KPI."
}
}
},
"costs": {
"title": "लागत",

View File

@@ -646,7 +646,68 @@
"pricingMissingShort": "no-price",
"warningRoundRobinSingleModel": "Round-robin is most useful with at least 2 models.",
"warningCostOptimizedPartialPricing": "Only {priced} of {total} models have pricing. Routing may be partially cost-aware.",
"warningCostOptimizedNoPricing": "No pricing data found for this combo. Cost-optimized may route unexpectedly."
"warningCostOptimizedNoPricing": "No pricing data found for this combo. Cost-optimized may route unexpectedly.",
"readinessTitle": "Pronto per salvare?",
"readinessDescription": "Rivedi l'elenco di controllo prima di creare o aggiornare questa combinazione.",
"readinessCheckName": "Il nome combinato è valido",
"readinessCheckModels": "È selezionato almeno un modello",
"readinessCheckWeights": "Il totale ponderato è 100%",
"readinessCheckWeightsOptional": "Regola del peso non richiesta",
"readinessCheckPricing": "I dati sui prezzi sono disponibili",
"readinessCheckPricingOptional": "Regola di prezzo non richiesta",
"saveBlockedTitle": "Il salvataggio è bloccato finché non vengono risolti i seguenti elementi:",
"saveBlockName": "Definire un nome per la combinazione.",
"saveBlockModels": "Aggiungi almeno un modello.",
"saveBlockWeighted": "Imposta i pesi al 100% (attuale: {total}%).",
"saveBlockPricing": "Aggiungi il prezzo per almeno un modello o scegli una strategia diversa.",
"recommendationsLabel": "Recommended setup",
"applyRecommendations": "Apply recommendations",
"recommendationsUpdated": "Recommendations updated for {strategy}.",
"recommendationsApplied": "Recommendations applied to this combo.",
"strategyRecommendations": {
"priority": {
"title": "Fail-safe baseline",
"description": "Use one primary model and keep fallback chain short and reliable.",
"tip1": "Put your most reliable model first.",
"tip2": "Keep 1-2 backup models with similar quality.",
"tip3": "Use safe retries to absorb transient provider failures."
},
"weighted": {
"title": "Controlled traffic split",
"description": "Great for canary rollouts and gradual migration between models.",
"tip1": "Start with conservative split like 90/10.",
"tip2": "Keep the total at 100% and auto-balance after changes.",
"tip3": "Monitor success and latency before increasing canary weight."
},
"round-robin": {
"title": "Predictable load sharing",
"description": "Best when models are equivalent and you need smooth distribution.",
"tip1": "Use at least 2 models.",
"tip2": "Set concurrency limits to avoid burst overload.",
"tip3": "Use queue timeout to fail fast under saturation."
},
"random": {
"title": "Quick spread with low setup",
"description": "Use when you need simple distribution without strict guarantees.",
"tip1": "Use models with similar latency profiles.",
"tip2": "Keep retries enabled to absorb random misses.",
"tip3": "Prefer this for experimentation, not strict SLAs."
},
"least-used": {
"title": "Adaptive balancing",
"description": "Routes to less-used models to reduce hotspots over time.",
"tip1": "Works better under continuous traffic.",
"tip2": "Combine with health checks for safer balancing.",
"tip3": "Track per-model usage to validate distribution gains."
},
"cost-optimized": {
"title": "Budget-first routing",
"description": "Routes to lower-cost models when pricing metadata is available.",
"tip1": "Ensure pricing coverage for all selected models.",
"tip2": "Keep a quality fallback for hard prompts.",
"tip3": "Use for batch/background jobs where cost is the main KPI."
}
}
},
"costs": {
"title": "Costi",

View File

@@ -646,7 +646,68 @@
"pricingMissingShort": "no-price",
"warningRoundRobinSingleModel": "Round-robin is most useful with at least 2 models.",
"warningCostOptimizedPartialPricing": "Only {priced} of {total} models have pricing. Routing may be partially cost-aware.",
"warningCostOptimizedNoPricing": "No pricing data found for this combo. Cost-optimized may route unexpectedly."
"warningCostOptimizedNoPricing": "No pricing data found for this combo. Cost-optimized may route unexpectedly.",
"readinessTitle": "保存する準備はできましたか?",
"readinessDescription": "このコンボを作成または更新する前に、チェックリストを確認してください。",
"readinessCheckName": "コンボ名は有効です",
"readinessCheckModels": "少なくとも 1 つのモデルが選択されています",
"readinessCheckWeights": "加重合計は 100%",
"readinessCheckWeightsOptional": "重量ルールは不要です",
"readinessCheckPricing": "価格データが利用可能です",
"readinessCheckPricingOptional": "価格設定ルールは不要です",
"saveBlockedTitle": "次の項目が修正されるまで、保存はブロックされます。",
"saveBlockName": "コンボ名を定義します。",
"saveBlockModels": "少なくとも 1 つのモデルを追加します。",
"saveBlockWeighted": "重みを 100% に設定します (現在: {total}%)。",
"saveBlockPricing": "少なくとも 1 つのモデルに価格を追加するか、別の戦略を選択してください。",
"recommendationsLabel": "Recommended setup",
"applyRecommendations": "Apply recommendations",
"recommendationsUpdated": "Recommendations updated for {strategy}.",
"recommendationsApplied": "Recommendations applied to this combo.",
"strategyRecommendations": {
"priority": {
"title": "Fail-safe baseline",
"description": "Use one primary model and keep fallback chain short and reliable.",
"tip1": "Put your most reliable model first.",
"tip2": "Keep 1-2 backup models with similar quality.",
"tip3": "Use safe retries to absorb transient provider failures."
},
"weighted": {
"title": "Controlled traffic split",
"description": "Great for canary rollouts and gradual migration between models.",
"tip1": "Start with conservative split like 90/10.",
"tip2": "Keep the total at 100% and auto-balance after changes.",
"tip3": "Monitor success and latency before increasing canary weight."
},
"round-robin": {
"title": "Predictable load sharing",
"description": "Best when models are equivalent and you need smooth distribution.",
"tip1": "Use at least 2 models.",
"tip2": "Set concurrency limits to avoid burst overload.",
"tip3": "Use queue timeout to fail fast under saturation."
},
"random": {
"title": "Quick spread with low setup",
"description": "Use when you need simple distribution without strict guarantees.",
"tip1": "Use models with similar latency profiles.",
"tip2": "Keep retries enabled to absorb random misses.",
"tip3": "Prefer this for experimentation, not strict SLAs."
},
"least-used": {
"title": "Adaptive balancing",
"description": "Routes to less-used models to reduce hotspots over time.",
"tip1": "Works better under continuous traffic.",
"tip2": "Combine with health checks for safer balancing.",
"tip3": "Track per-model usage to validate distribution gains."
},
"cost-optimized": {
"title": "Budget-first routing",
"description": "Routes to lower-cost models when pricing metadata is available.",
"tip1": "Ensure pricing coverage for all selected models.",
"tip2": "Keep a quality fallback for hard prompts.",
"tip3": "Use for batch/background jobs where cost is the main KPI."
}
}
},
"costs": {
"title": "コスト",

View File

@@ -646,7 +646,68 @@
"pricingMissingShort": "no-price",
"warningRoundRobinSingleModel": "Round-robin is most useful with at least 2 models.",
"warningCostOptimizedPartialPricing": "Only {priced} of {total} models have pricing. Routing may be partially cost-aware.",
"warningCostOptimizedNoPricing": "No pricing data found for this combo. Cost-optimized may route unexpectedly."
"warningCostOptimizedNoPricing": "No pricing data found for this combo. Cost-optimized may route unexpectedly.",
"readinessTitle": "저장할 준비가 되셨나요?",
"readinessDescription": "이 콤보를 생성하거나 업데이트하기 전에 체크리스트를 검토하세요.",
"readinessCheckName": "콤보 이름이 유효합니다.",
"readinessCheckModels": "모델이 하나 이상 선택되었습니다.",
"readinessCheckWeights": "가중 합계는 100%입니다.",
"readinessCheckWeightsOptional": "가중치 규칙이 필요하지 않음",
"readinessCheckPricing": "가격 데이터를 사용할 수 있습니다.",
"readinessCheckPricingOptional": "가격 책정 규칙이 필요하지 않음",
"saveBlockedTitle": "다음 항목이 수정될 때까지 저장이 차단됩니다.",
"saveBlockName": "콤보 이름을 정의합니다.",
"saveBlockModels": "모델을 하나 이상 추가하세요.",
"saveBlockWeighted": "가중치를 100%(현재: {total}%)로 설정합니다.",
"saveBlockPricing": "하나 이상의 모델에 가격을 추가하거나 다른 전략을 선택하세요.",
"recommendationsLabel": "Recommended setup",
"applyRecommendations": "Apply recommendations",
"recommendationsUpdated": "Recommendations updated for {strategy}.",
"recommendationsApplied": "Recommendations applied to this combo.",
"strategyRecommendations": {
"priority": {
"title": "Fail-safe baseline",
"description": "Use one primary model and keep fallback chain short and reliable.",
"tip1": "Put your most reliable model first.",
"tip2": "Keep 1-2 backup models with similar quality.",
"tip3": "Use safe retries to absorb transient provider failures."
},
"weighted": {
"title": "Controlled traffic split",
"description": "Great for canary rollouts and gradual migration between models.",
"tip1": "Start with conservative split like 90/10.",
"tip2": "Keep the total at 100% and auto-balance after changes.",
"tip3": "Monitor success and latency before increasing canary weight."
},
"round-robin": {
"title": "Predictable load sharing",
"description": "Best when models are equivalent and you need smooth distribution.",
"tip1": "Use at least 2 models.",
"tip2": "Set concurrency limits to avoid burst overload.",
"tip3": "Use queue timeout to fail fast under saturation."
},
"random": {
"title": "Quick spread with low setup",
"description": "Use when you need simple distribution without strict guarantees.",
"tip1": "Use models with similar latency profiles.",
"tip2": "Keep retries enabled to absorb random misses.",
"tip3": "Prefer this for experimentation, not strict SLAs."
},
"least-used": {
"title": "Adaptive balancing",
"description": "Routes to less-used models to reduce hotspots over time.",
"tip1": "Works better under continuous traffic.",
"tip2": "Combine with health checks for safer balancing.",
"tip3": "Track per-model usage to validate distribution gains."
},
"cost-optimized": {
"title": "Budget-first routing",
"description": "Routes to lower-cost models when pricing metadata is available.",
"tip1": "Ensure pricing coverage for all selected models.",
"tip2": "Keep a quality fallback for hard prompts.",
"tip3": "Use for batch/background jobs where cost is the main KPI."
}
}
},
"costs": {
"title": "비용",

View File

@@ -646,7 +646,68 @@
"pricingMissingShort": "no-price",
"warningRoundRobinSingleModel": "Round-robin is most useful with at least 2 models.",
"warningCostOptimizedPartialPricing": "Only {priced} of {total} models have pricing. Routing may be partially cost-aware.",
"warningCostOptimizedNoPricing": "No pricing data found for this combo. Cost-optimized may route unexpectedly."
"warningCostOptimizedNoPricing": "No pricing data found for this combo. Cost-optimized may route unexpectedly.",
"readinessTitle": "Bersedia untuk menyimpan?",
"readinessDescription": "Semak senarai semak sebelum membuat atau mengemas kini kombo ini.",
"readinessCheckName": "Nama kombo adalah sah",
"readinessCheckModels": "Sekurang-kurangnya satu model dipilih",
"readinessCheckWeights": "Jumlah wajaran ialah 100%",
"readinessCheckWeightsOptional": "Peraturan berat tidak diperlukan",
"readinessCheckPricing": "Data harga tersedia",
"readinessCheckPricingOptional": "Peraturan harga tidak diperlukan",
"saveBlockedTitle": "Simpan disekat sehingga item berikut diperbaiki:",
"saveBlockName": "Tentukan nama kombo.",
"saveBlockModels": "Tambah sekurang-kurangnya satu model.",
"saveBlockWeighted": "Tetapkan berat kepada 100% (semasa: {total}%).",
"saveBlockPricing": "Tambahkan harga untuk sekurang-kurangnya satu model atau pilih strategi lain.",
"recommendationsLabel": "Recommended setup",
"applyRecommendations": "Apply recommendations",
"recommendationsUpdated": "Recommendations updated for {strategy}.",
"recommendationsApplied": "Recommendations applied to this combo.",
"strategyRecommendations": {
"priority": {
"title": "Fail-safe baseline",
"description": "Use one primary model and keep fallback chain short and reliable.",
"tip1": "Put your most reliable model first.",
"tip2": "Keep 1-2 backup models with similar quality.",
"tip3": "Use safe retries to absorb transient provider failures."
},
"weighted": {
"title": "Controlled traffic split",
"description": "Great for canary rollouts and gradual migration between models.",
"tip1": "Start with conservative split like 90/10.",
"tip2": "Keep the total at 100% and auto-balance after changes.",
"tip3": "Monitor success and latency before increasing canary weight."
},
"round-robin": {
"title": "Predictable load sharing",
"description": "Best when models are equivalent and you need smooth distribution.",
"tip1": "Use at least 2 models.",
"tip2": "Set concurrency limits to avoid burst overload.",
"tip3": "Use queue timeout to fail fast under saturation."
},
"random": {
"title": "Quick spread with low setup",
"description": "Use when you need simple distribution without strict guarantees.",
"tip1": "Use models with similar latency profiles.",
"tip2": "Keep retries enabled to absorb random misses.",
"tip3": "Prefer this for experimentation, not strict SLAs."
},
"least-used": {
"title": "Adaptive balancing",
"description": "Routes to less-used models to reduce hotspots over time.",
"tip1": "Works better under continuous traffic.",
"tip2": "Combine with health checks for safer balancing.",
"tip3": "Track per-model usage to validate distribution gains."
},
"cost-optimized": {
"title": "Budget-first routing",
"description": "Routes to lower-cost models when pricing metadata is available.",
"tip1": "Ensure pricing coverage for all selected models.",
"tip2": "Keep a quality fallback for hard prompts.",
"tip3": "Use for batch/background jobs where cost is the main KPI."
}
}
},
"costs": {
"title": "Kos",

View File

@@ -646,7 +646,68 @@
"pricingMissingShort": "no-price",
"warningRoundRobinSingleModel": "Round-robin is most useful with at least 2 models.",
"warningCostOptimizedPartialPricing": "Only {priced} of {total} models have pricing. Routing may be partially cost-aware.",
"warningCostOptimizedNoPricing": "No pricing data found for this combo. Cost-optimized may route unexpectedly."
"warningCostOptimizedNoPricing": "No pricing data found for this combo. Cost-optimized may route unexpectedly.",
"readinessTitle": "Klaar om te besparen?",
"readinessDescription": "Bekijk de checklist voordat u deze combo maakt of bijwerkt.",
"readinessCheckName": "Combinatienaam is geldig",
"readinessCheckModels": "Er is minimaal één model geselecteerd",
"readinessCheckWeights": "Gewogen totaal is 100%",
"readinessCheckWeightsOptional": "Gewichtsregel niet vereist",
"readinessCheckPricing": "Er zijn prijsgegevens beschikbaar",
"readinessCheckPricingOptional": "Prijsregel is niet vereist",
"saveBlockedTitle": "Opslaan is geblokkeerd totdat de volgende items zijn opgelost:",
"saveBlockName": "Definieer een combonaam.",
"saveBlockModels": "Voeg ten minste één model toe.",
"saveBlockWeighted": "Stel de gewichten in op 100% (huidig: {total}%).",
"saveBlockPricing": "Voeg prijzen toe voor ten minste één model of kies een andere strategie.",
"recommendationsLabel": "Recommended setup",
"applyRecommendations": "Apply recommendations",
"recommendationsUpdated": "Recommendations updated for {strategy}.",
"recommendationsApplied": "Recommendations applied to this combo.",
"strategyRecommendations": {
"priority": {
"title": "Fail-safe baseline",
"description": "Use one primary model and keep fallback chain short and reliable.",
"tip1": "Put your most reliable model first.",
"tip2": "Keep 1-2 backup models with similar quality.",
"tip3": "Use safe retries to absorb transient provider failures."
},
"weighted": {
"title": "Controlled traffic split",
"description": "Great for canary rollouts and gradual migration between models.",
"tip1": "Start with conservative split like 90/10.",
"tip2": "Keep the total at 100% and auto-balance after changes.",
"tip3": "Monitor success and latency before increasing canary weight."
},
"round-robin": {
"title": "Predictable load sharing",
"description": "Best when models are equivalent and you need smooth distribution.",
"tip1": "Use at least 2 models.",
"tip2": "Set concurrency limits to avoid burst overload.",
"tip3": "Use queue timeout to fail fast under saturation."
},
"random": {
"title": "Quick spread with low setup",
"description": "Use when you need simple distribution without strict guarantees.",
"tip1": "Use models with similar latency profiles.",
"tip2": "Keep retries enabled to absorb random misses.",
"tip3": "Prefer this for experimentation, not strict SLAs."
},
"least-used": {
"title": "Adaptive balancing",
"description": "Routes to less-used models to reduce hotspots over time.",
"tip1": "Works better under continuous traffic.",
"tip2": "Combine with health checks for safer balancing.",
"tip3": "Track per-model usage to validate distribution gains."
},
"cost-optimized": {
"title": "Budget-first routing",
"description": "Routes to lower-cost models when pricing metadata is available.",
"tip1": "Ensure pricing coverage for all selected models.",
"tip2": "Keep a quality fallback for hard prompts.",
"tip3": "Use for batch/background jobs where cost is the main KPI."
}
}
},
"costs": {
"title": "Kosten",

View File

@@ -646,7 +646,68 @@
"pricingMissingShort": "no-price",
"warningRoundRobinSingleModel": "Round-robin is most useful with at least 2 models.",
"warningCostOptimizedPartialPricing": "Only {priced} of {total} models have pricing. Routing may be partially cost-aware.",
"warningCostOptimizedNoPricing": "No pricing data found for this combo. Cost-optimized may route unexpectedly."
"warningCostOptimizedNoPricing": "No pricing data found for this combo. Cost-optimized may route unexpectedly.",
"readinessTitle": "Klar til å spare?",
"readinessDescription": "Se gjennom sjekklisten før du oppretter eller oppdaterer denne kombinasjonen.",
"readinessCheckName": "Kombinasjonsnavnet er gyldig",
"readinessCheckModels": "Minst én modell er valgt",
"readinessCheckWeights": "Vektet total er 100 %",
"readinessCheckWeightsOptional": "Vektregel er ikke nødvendig",
"readinessCheckPricing": "Prisdata er tilgjengelig",
"readinessCheckPricingOptional": "Prisregel er ikke nødvendig",
"saveBlockedTitle": "Lagre er blokkert til følgende elementer er fikset:",
"saveBlockName": "Definer et kombinasjonsnavn.",
"saveBlockModels": "Legg til minst én modell.",
"saveBlockWeighted": "Sett vekter til 100 % (gjeldende: {total}%).",
"saveBlockPricing": "Legg til priser for minst én modell eller velg en annen strategi.",
"recommendationsLabel": "Recommended setup",
"applyRecommendations": "Apply recommendations",
"recommendationsUpdated": "Recommendations updated for {strategy}.",
"recommendationsApplied": "Recommendations applied to this combo.",
"strategyRecommendations": {
"priority": {
"title": "Fail-safe baseline",
"description": "Use one primary model and keep fallback chain short and reliable.",
"tip1": "Put your most reliable model first.",
"tip2": "Keep 1-2 backup models with similar quality.",
"tip3": "Use safe retries to absorb transient provider failures."
},
"weighted": {
"title": "Controlled traffic split",
"description": "Great for canary rollouts and gradual migration between models.",
"tip1": "Start with conservative split like 90/10.",
"tip2": "Keep the total at 100% and auto-balance after changes.",
"tip3": "Monitor success and latency before increasing canary weight."
},
"round-robin": {
"title": "Predictable load sharing",
"description": "Best when models are equivalent and you need smooth distribution.",
"tip1": "Use at least 2 models.",
"tip2": "Set concurrency limits to avoid burst overload.",
"tip3": "Use queue timeout to fail fast under saturation."
},
"random": {
"title": "Quick spread with low setup",
"description": "Use when you need simple distribution without strict guarantees.",
"tip1": "Use models with similar latency profiles.",
"tip2": "Keep retries enabled to absorb random misses.",
"tip3": "Prefer this for experimentation, not strict SLAs."
},
"least-used": {
"title": "Adaptive balancing",
"description": "Routes to less-used models to reduce hotspots over time.",
"tip1": "Works better under continuous traffic.",
"tip2": "Combine with health checks for safer balancing.",
"tip3": "Track per-model usage to validate distribution gains."
},
"cost-optimized": {
"title": "Budget-first routing",
"description": "Routes to lower-cost models when pricing metadata is available.",
"tip1": "Ensure pricing coverage for all selected models.",
"tip2": "Keep a quality fallback for hard prompts.",
"tip3": "Use for batch/background jobs where cost is the main KPI."
}
}
},
"costs": {
"title": "Kostnader",

View File

@@ -581,26 +581,26 @@
"costOpt": "Cost-Opt",
"strategyGuideTitle": "Paano gamitin ang diskarteng ito",
"strategyGuideWhen": "Kailan gagamitin",
"strategyGuideAvoid": "Iwasan kung kailan",
"strategyGuideExample": "Halimbawa",
"strategyGuideAvoid": "Avoid when",
"strategyGuideExample": "Example",
"strategyGuide": {
"priority": {
"when": "Mayroon kang isang ginustong modelo at gusto lang ng fallback sa pagkabigo.",
"avoid": "Kailangan mo ng kahilingan sa pamamahagi sa mga modelo.",
"example": "Pangunahing modelo ng coding na may mas murang backup para sa mga outage."
"when": "You have one preferred model and only want fallback on failure.",
"avoid": "You need request distribution across models.",
"example": "Primary coding model with cheaper backup for outages."
},
"weighted": {
"when": "Kailangan mo ng kontroladong paghahati ng trapiko sa mga modelo.",
"avoid": "Hindi mo mapanatili ang tumpak na mga timbang sa paglipas ng panahon.",
"example": "80% stable na modelo + 20% canary model rollout."
"when": "You need controlled traffic split across models.",
"avoid": "You cannot maintain accurate weights over time.",
"example": "80% stable model + 20% canary model rollout."
},
"round-robin": {
"when": "Gusto mo ng predictable at pantay na pamamahagi.",
"when": "You want predictable and even distribution.",
"avoid": "Masyadong malaki ang pagkakaiba ng mga modelo sa latency o gastos.",
"example": "Parehong modelo sa maraming account upang maikalat ang throughput."
},
"random": {
"when": "Gusto mo ng simpleng pamamahagi na may kaunting setup.",
"when": "You want simple distribution with minimal setup.",
"avoid": "You need strict traffic guarantees.",
"example": "Quick prototyping with equivalent models."
},
@@ -616,7 +616,7 @@
}
},
"advancedHelp": {
"maxRetries": "How many retries are attempted before failing a request.",
"maxRetries": "Ilang muling pagsubok ang sinubukan bago mabigo ang isang kahilingan.",
"retryDelay": "Initial wait between retries. Higher values reduce burst pressure.",
"timeout": "Maximum request duration before aborting.",
"healthcheck": "Skips unhealthy models/providers from routing decisions.",
@@ -625,8 +625,8 @@
},
"templatesTitle": "Quick templates",
"templatesDescription": "Apply a starting profile, then adjust models and config.",
"templateApply": "Apply template",
"templateHighAvailability": "High availability",
"templateApply": "Ilapat ang template",
"templateHighAvailability": "Mataas na kakayahang magamit",
"templateHighAvailabilityDesc": "Priority routing with health checks and safe retries.",
"templateCostSaver": "Cost saver",
"templateCostSaverDesc": "Cost-optimized routing for budget-first workloads.",
@@ -637,7 +637,7 @@
"usageGuideShow": "Show guide",
"quickTestTitle": "Combo ready to validate",
"quickTestDescription": "Run a test now to confirm fallback and latency behavior.",
"testNow": "Test now",
"testNow": "Subukan ngayon",
"pricingCoverage": "Pricing coverage",
"pricingCoverageHint": "Cost-optimized works best when all combo models have pricing.",
"pricingAvailable": "Pricing available",
@@ -646,7 +646,68 @@
"pricingMissingShort": "no-price",
"warningRoundRobinSingleModel": "Round-robin is most useful with at least 2 models.",
"warningCostOptimizedPartialPricing": "Only {priced} of {total} models have pricing. Routing may be partially cost-aware.",
"warningCostOptimizedNoPricing": "No pricing data found for this combo. Cost-optimized may route unexpectedly."
"warningCostOptimizedNoPricing": "No pricing data found for this combo. Cost-optimized may route unexpectedly.",
"readinessTitle": "Handa nang makatipid?",
"readinessDescription": "Suriin ang checklist bago gawin o i-update ang combo na ito.",
"readinessCheckName": "May bisa ang combo name",
"readinessCheckModels": "Hindi bababa sa isang modelo ang napili",
"readinessCheckWeights": "Ang kabuuang timbang ay 100%",
"readinessCheckWeightsOptional": "Hindi kinakailangan ang panuntunan sa timbang",
"readinessCheckPricing": "Available ang data ng pagpepresyo",
"readinessCheckPricingOptional": "Hindi kinakailangan ang panuntunan sa pagpepresyo",
"saveBlockedTitle": "Naka-block ang pag-save hanggang sa maayos ang mga sumusunod na item:",
"saveBlockName": "Tukuyin ang pangalan ng combo.",
"saveBlockModels": "Magdagdag ng kahit isang modelo.",
"saveBlockWeighted": "Itakda ang mga timbang sa 100% (kasalukuyan: {total}%).",
"saveBlockPricing": "Magdagdag ng pagpepresyo para sa hindi bababa sa isang modelo o pumili ng ibang diskarte.",
"recommendationsLabel": "Recommended setup",
"applyRecommendations": "Apply recommendations",
"recommendationsUpdated": "Recommendations updated for {strategy}.",
"recommendationsApplied": "Recommendations applied to this combo.",
"strategyRecommendations": {
"priority": {
"title": "Fail-safe baseline",
"description": "Use one primary model and keep fallback chain short and reliable.",
"tip1": "Put your most reliable model first.",
"tip2": "Keep 1-2 backup models with similar quality.",
"tip3": "Use safe retries to absorb transient provider failures."
},
"weighted": {
"title": "Controlled traffic split",
"description": "Great for canary rollouts and gradual migration between models.",
"tip1": "Start with conservative split like 90/10.",
"tip2": "Keep the total at 100% and auto-balance after changes.",
"tip3": "Monitor success and latency before increasing canary weight."
},
"round-robin": {
"title": "Predictable load sharing",
"description": "Best when models are equivalent and you need smooth distribution.",
"tip1": "Use at least 2 models.",
"tip2": "Set concurrency limits to avoid burst overload.",
"tip3": "Use queue timeout to fail fast under saturation."
},
"random": {
"title": "Quick spread with low setup",
"description": "Use when you need simple distribution without strict guarantees.",
"tip1": "Use models with similar latency profiles.",
"tip2": "Keep retries enabled to absorb random misses.",
"tip3": "Prefer this for experimentation, not strict SLAs."
},
"least-used": {
"title": "Adaptive balancing",
"description": "Routes to less-used models to reduce hotspots over time.",
"tip1": "Works better under continuous traffic.",
"tip2": "Combine with health checks for safer balancing.",
"tip3": "Track per-model usage to validate distribution gains."
},
"cost-optimized": {
"title": "Budget-first routing",
"description": "Routes to lower-cost models when pricing metadata is available.",
"tip1": "Ensure pricing coverage for all selected models.",
"tip2": "Keep a quality fallback for hard prompts.",
"tip3": "Use for batch/background jobs where cost is the main KPI."
}
}
},
"costs": {
"title": "Mga gastos",
@@ -745,7 +806,7 @@
"a2aCardTitle": "A2A Server",
"a2aCardDescription": "Agent2Agent JSON-RPC endpoint",
"protocolToolsLabel": "Tools",
"protocolTasksLabel": "Tasks",
"protocolTasksLabel": "Mga gawain",
"protocolActiveStreamsLabel": "Active streams",
"protocolLastActivity": "Last activity",
"quickStart": "Quick Start",
@@ -758,10 +819,10 @@
"a2aQuickStartTitle": "A2A Quick Start",
"a2aQuickStartStep1": "Discover the agent card at `/.well-known/agent.json`.",
"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`."
"a2aQuickStartStep3": "Subaybayan at kontrolin ang mga gawain gamit ang `tasks/get` at `tasks/cancel`."
},
"mcpDashboard": {
"loading": "Loading MCP dashboard...",
"loading": "Nilo-load ang MCP dashboard...",
"activate": "activate",
"deactivate": "deactivate",
"confirmSwitchCombo": "Confirm {action} combo \"{combo}\"?",
@@ -772,7 +833,7 @@
"applyProfileSuccess": "Profile \"{profile}\" applied.",
"confirmResetBreakers": "Reset all circuit breakers?",
"resetBreakersFailed": "Failed to reset circuit breakers.",
"resetBreakersSuccess": "Circuit breakers reset.",
"resetBreakersSuccess": "Ni-reset ang mga circuit breaker.",
"processStatus": "Process status",
"online": "Online",
"offline": "Offline",
@@ -783,7 +844,7 @@
"totalCalls": "Total calls",
"successRate": "Success rate",
"avgLatency": "Avg latency",
"topTools": "Top tools",
"topTools": "Mga nangungunang tool",
"noToolCalls24h": "No tool calls in the last 24 hours.",
"runtimeDetails": "Runtime details",
"transport": "Transport",
@@ -795,8 +856,8 @@
"operationalControls": "Operational controls",
"switchCombo": "Switch combo",
"inactive": "inactive",
"active": "active",
"activateCombo": "Activate combo",
"active": "aktibo",
"activateCombo": "I-activate ang combo",
"deactivateCombo": "Deactivate combo",
"applyResilienceProfile": "Apply resilience profile",
"profileAggressive": "aggressive",
@@ -818,19 +879,19 @@
"success": "Success",
"failure": "Failure",
"apiKeyIdPlaceholder": "apiKeyId",
"loadingAuditEntries": "Loading audit entries...",
"loadingAuditEntries": "Nilo-load ang mga entry sa pag-audit...",
"noAuditEntriesForFilters": "No audit entries found for current filters.",
"tableTimestamp": "Timestamp",
"tableDuration": "Duration",
"tableResult": "Resulta",
"tableResult": "Result",
"tableApiKey": "API key",
"failed": "nabigo",
"previous": "Nakaraang",
"next": "Susunod"
"failed": "failed",
"previous": "Previous",
"next": "Next"
},
"a2aDashboard": {
"loading": "Nilo-load ang A2A dashboard...",
"confirmCancelTask": "Kanselahin ang gawain {taskId}?",
"loading": "Loading A2A dashboard...",
"confirmCancelTask": "Cancel task {taskId}?",
"cancelTaskFailed": "Nabigong kanselahin ang gawain.",
"cancelTaskSuccess": "Kinansela ang gawain {taskId}.",
"smokeSendFailed": "message/send smoke test failed.",
@@ -844,12 +905,12 @@
"totalTasks": "Total tasks",
"activeStreams": "Active streams",
"lastTask": "Last task",
"taskStateOverview": "Task state overview",
"taskStateOverview": "Pangkalahatang-ideya ng estado ng gawain",
"state": {
"submitted": "submitted",
"submitted": "isinumite",
"working": "working",
"completed": "completed",
"failed": "nabigo",
"failed": "failed",
"cancelled": "cancelled"
},
"agentCard": "Agent card",
@@ -861,26 +922,26 @@
"quickValidationDescription": "Executes smoke calls through the live `/a2a` endpoint.",
"runMessageSend": "Run message/send",
"runMessageStream": "Run message/stream",
"taskManagement": "Task management",
"taskSummary": "{total} tasks | page {page} of {totalPages}",
"allStates": "all",
"allSkills": "all skills",
"loadingTasks": "Loading tasks...",
"noTasksForFilters": "No tasks found for current filters.",
"tableTask": "Task",
"tableSkill": "Skill",
"tableState": "State",
"tableUpdated": "Updated",
"tableActions": "Actions",
"view": "View",
"cancel": "Cancel",
"previous": "Nakaraang",
"next": "Susunod",
"taskDetail": "Task detail",
"close": "Close",
"taskManagement": "Pamamahala ng gawain",
"taskSummary": "{total} mga gawain | pahina {page} ng {totalPages}",
"allStates": "lahat",
"allSkills": "lahat ng kakayahan",
"loadingTasks": "Naglo-load ng mga gawain...",
"noTasksForFilters": "Walang nakitang mga gawain para sa kasalukuyang mga filter.",
"tableTask": "Gawain",
"tableSkill": "Kasanayan",
"tableState": "Estado",
"tableUpdated": "Na-update",
"tableActions": "Mga aksyon",
"view": "Tingnan",
"cancel": "Kanselahin",
"previous": "Previous",
"next": "Next",
"taskDetail": "Detalye ng gawain",
"close": "Isara",
"metadata": "Metadata",
"events": "Events",
"artifacts": "Artifacts"
"events": "Mga kaganapan",
"artifacts": "Mga artifact"
},
"health": {
"title": "Kalusugan ng System",
@@ -2254,22 +2315,22 @@
"clientClaudeBullet1Prefix": "Gamitin",
"clientClaudeBullet1Middle": "(Claude) o",
"clientClaudeBullet1Suffix": "(Antigravity) prefix.",
"protocolsTitle": "Protocols: MCP & A2A",
"protocolsDescription": "OmniRoute exposes two operational protocols in addition to OpenAI-compatible APIs: MCP for tool execution and A2A for agent-to-agent workflows.",
"protocolsTitle": "Mga Protocol: MCP at A2A",
"protocolsDescription": "Ang OmniRoute ay naglalantad ng dalawang operational protocol bilang karagdagan sa mga OpenAI-compatible na API: MCP para sa tool execution at A2A para sa agent-to-agent na daloy ng trabaho.",
"protocolMcpTitle": "MCP (Model Context Protocol)",
"protocolMcpDesc": "Use MCP over stdio to let clients discover and call OmniRoute tools with audit visibility.",
"protocolMcpStep1": "Start MCP transport with `omniroute --mcp`.",
"protocolMcpStep2": "Point your MCP client to stdio transport.",
"protocolMcpStep3": "Call `omniroute_get_health` and `omniroute_list_combos` to validate connectivity.",
"protocolMcpDesc": "Gamitin ang MCP sa stdio upang hayaan ang mga kliyente na tumuklas at tumawag sa mga tool ng OmniRoute na may visibility sa pag-audit.",
"protocolMcpStep1": "Simulan ang MCP transport gamit ang `omniroute --mcp`.",
"protocolMcpStep2": "Ituro ang iyong MCP client sa stdio transport.",
"protocolMcpStep3": "Tumawag sa `omniroute_get_health` at `omniroute_list_combos` para i-validate ang pagkakakonekta.",
"protocolA2aTitle": "A2A (Agent2Agent)",
"protocolA2aDesc": "Use A2A JSON-RPC to submit tasks synchronously or via SSE streaming.",
"protocolA2aStep1": "Read `/.well-known/agent.json` for agent discovery.",
"protocolA2aStep2": "Send `message/send` or `message/stream` requests to `POST /a2a`.",
"protocolA2aStep3": "Manage task lifecycle with `tasks/get` and `tasks/cancel`.",
"protocolA2aDesc": "Gamitin ang A2A JSON-RPC upang magsumite ng mga gawain nang sabay-sabay o sa pamamagitan ng SSE streaming.",
"protocolA2aStep1": "Basahin ang `/.well-known/agent.json` para sa pagtuklas ng ahente.",
"protocolA2aStep2": "Ipadala ang `message/send` o `message/stream` ng mga kahilingan sa `POST /a2a`.",
"protocolA2aStep3": "Pamahalaan ang lifecycle ng gawain sa `tasks/get` at `tasks/cancel`.",
"protocolTroubleshootingTitle": "Protocol Troubleshooting",
"protocolTroubleshooting1": "If MCP status is offline, verify the stdio process is running and heartbeat file is updating.",
"protocolTroubleshooting2": "If A2A tasks stay in `working`, inspect `/api/a2a/tasks/:id` and stream events for terminal state.",
"protocolTroubleshooting3": "Use `/dashboard/mcp` and `/dashboard/a2a` for operational controls and audit visibility.",
"protocolTroubleshooting1": "Kung offline ang status ng MCP, i-verify na tumatakbo ang proseso ng stdio at nag-a-update ang heartbeat file.",
"protocolTroubleshooting2": "Kung mananatili ang mga gawain sa A2A sa `working`, siyasatin ang `/api/a2a/tasks/:id` at i-stream ang mga kaganapan para sa estado ng terminal.",
"protocolTroubleshooting3": "Gamitin ang `/dashboard/mcp` at `/dashboard/a2a` para sa operational controls at audit visibility.",
"endpointChatNote": "OpenAI-compatible chat endpoint (default).",
"endpointResponsesNote": "Endpoint ng Responses API (Codex, o-series).",
"endpointModelsNote": "Catalog ng modelo para sa lahat ng konektadong provider.",

View File

@@ -646,7 +646,68 @@
"pricingMissingShort": "no-price",
"warningRoundRobinSingleModel": "Round-robin is most useful with at least 2 models.",
"warningCostOptimizedPartialPricing": "Only {priced} of {total} models have pricing. Routing may be partially cost-aware.",
"warningCostOptimizedNoPricing": "No pricing data found for this combo. Cost-optimized may route unexpectedly."
"warningCostOptimizedNoPricing": "No pricing data found for this combo. Cost-optimized may route unexpectedly.",
"readinessTitle": "Gotowy do zapisania?",
"readinessDescription": "Przed utworzeniem lub aktualizacją tej kombinacji przejrzyj listę kontrolną.",
"readinessCheckName": "Nazwa kombinacji jest prawidłowa",
"readinessCheckModels": "Wybrano co najmniej jeden model",
"readinessCheckWeights": "Suma ważona wynosi 100%",
"readinessCheckWeightsOptional": "Reguła wagi nie jest wymagana",
"readinessCheckPricing": "Dane cenowe są dostępne",
"readinessCheckPricingOptional": "Reguła cenowa nie jest wymagana",
"saveBlockedTitle": "Zapisywanie jest zablokowane do czasu naprawienia następujących elementów:",
"saveBlockName": "Zdefiniuj nazwę kombinacji.",
"saveBlockModels": "Dodaj co najmniej jeden model.",
"saveBlockWeighted": "Ustaw wagi na 100% (obecnie: {total}%).",
"saveBlockPricing": "Dodaj cenę dla co najmniej jednego modelu lub wybierz inną strategię.",
"recommendationsLabel": "Recommended setup",
"applyRecommendations": "Apply recommendations",
"recommendationsUpdated": "Recommendations updated for {strategy}.",
"recommendationsApplied": "Recommendations applied to this combo.",
"strategyRecommendations": {
"priority": {
"title": "Fail-safe baseline",
"description": "Use one primary model and keep fallback chain short and reliable.",
"tip1": "Put your most reliable model first.",
"tip2": "Keep 1-2 backup models with similar quality.",
"tip3": "Use safe retries to absorb transient provider failures."
},
"weighted": {
"title": "Controlled traffic split",
"description": "Great for canary rollouts and gradual migration between models.",
"tip1": "Start with conservative split like 90/10.",
"tip2": "Keep the total at 100% and auto-balance after changes.",
"tip3": "Monitor success and latency before increasing canary weight."
},
"round-robin": {
"title": "Predictable load sharing",
"description": "Best when models are equivalent and you need smooth distribution.",
"tip1": "Use at least 2 models.",
"tip2": "Set concurrency limits to avoid burst overload.",
"tip3": "Use queue timeout to fail fast under saturation."
},
"random": {
"title": "Quick spread with low setup",
"description": "Use when you need simple distribution without strict guarantees.",
"tip1": "Use models with similar latency profiles.",
"tip2": "Keep retries enabled to absorb random misses.",
"tip3": "Prefer this for experimentation, not strict SLAs."
},
"least-used": {
"title": "Adaptive balancing",
"description": "Routes to less-used models to reduce hotspots over time.",
"tip1": "Works better under continuous traffic.",
"tip2": "Combine with health checks for safer balancing.",
"tip3": "Track per-model usage to validate distribution gains."
},
"cost-optimized": {
"title": "Budget-first routing",
"description": "Routes to lower-cost models when pricing metadata is available.",
"tip1": "Ensure pricing coverage for all selected models.",
"tip2": "Keep a quality fallback for hard prompts.",
"tip3": "Use for batch/background jobs where cost is the main KPI."
}
}
},
"costs": {
"title": "Koszty",

View File

@@ -646,7 +646,68 @@
"pricingMissingShort": "sem-preço",
"warningRoundRobinSingleModel": "Round-robin é mais útil com pelo menos 2 modelos.",
"warningCostOptimizedPartialPricing": "Apenas {priced} de {total} modelos têm preço. O roteamento pode ficar parcialmente orientado a custo.",
"warningCostOptimizedNoPricing": "Não há dados de preço para este combo. Custo-otimizado pode rotear de forma inesperada."
"warningCostOptimizedNoPricing": "Não há dados de preço para este combo. Custo-otimizado pode rotear de forma inesperada.",
"readinessTitle": "Pronto para salvar?",
"readinessDescription": "Revise a lista de verificação antes de criar ou atualizar este combo.",
"readinessCheckName": "O nome do combo é válido",
"readinessCheckModels": "Pelo menos um modelo está selecionado",
"readinessCheckWeights": "O total dos pesos é 100%",
"readinessCheckWeightsOptional": "Regra de pesos não obrigatória",
"readinessCheckPricing": "Dados de preços disponíveis",
"readinessCheckPricingOptional": "Regra de preços não obrigatória",
"saveBlockedTitle": "O salvamento está bloqueado até corrigir os itens abaixo:",
"saveBlockName": "Defina um nome para o combo.",
"saveBlockModels": "Adicione pelo menos um modelo.",
"saveBlockWeighted": "Ajuste os pesos para 100% (atual: {total}%).",
"saveBlockPricing": "Adicione preço para pelo menos um modelo ou escolha outra estratégia.",
"recommendationsLabel": "Recommended setup",
"applyRecommendations": "Apply recommendations",
"recommendationsUpdated": "Recommendations updated for {strategy}.",
"recommendationsApplied": "Recommendations applied to this combo.",
"strategyRecommendations": {
"priority": {
"title": "Fail-safe baseline",
"description": "Use one primary model and keep fallback chain short and reliable.",
"tip1": "Put your most reliable model first.",
"tip2": "Keep 1-2 backup models with similar quality.",
"tip3": "Use safe retries to absorb transient provider failures."
},
"weighted": {
"title": "Controlled traffic split",
"description": "Great for canary rollouts and gradual migration between models.",
"tip1": "Start with conservative split like 90/10.",
"tip2": "Keep the total at 100% and auto-balance after changes.",
"tip3": "Monitor success and latency before increasing canary weight."
},
"round-robin": {
"title": "Predictable load sharing",
"description": "Best when models are equivalent and you need smooth distribution.",
"tip1": "Use at least 2 models.",
"tip2": "Set concurrency limits to avoid burst overload.",
"tip3": "Use queue timeout to fail fast under saturation."
},
"random": {
"title": "Quick spread with low setup",
"description": "Use when you need simple distribution without strict guarantees.",
"tip1": "Use models with similar latency profiles.",
"tip2": "Keep retries enabled to absorb random misses.",
"tip3": "Prefer this for experimentation, not strict SLAs."
},
"least-used": {
"title": "Adaptive balancing",
"description": "Routes to less-used models to reduce hotspots over time.",
"tip1": "Works better under continuous traffic.",
"tip2": "Combine with health checks for safer balancing.",
"tip3": "Track per-model usage to validate distribution gains."
},
"cost-optimized": {
"title": "Budget-first routing",
"description": "Routes to lower-cost models when pricing metadata is available.",
"tip1": "Ensure pricing coverage for all selected models.",
"tip2": "Keep a quality fallback for hard prompts.",
"tip3": "Use for batch/background jobs where cost is the main KPI."
}
}
},
"costs": {
"title": "Custos",

View File

@@ -646,7 +646,68 @@
"pricingMissingShort": "no-price",
"warningRoundRobinSingleModel": "Round-robin is most useful with at least 2 models.",
"warningCostOptimizedPartialPricing": "Only {priced} of {total} models have pricing. Routing may be partially cost-aware.",
"warningCostOptimizedNoPricing": "No pricing data found for this combo. Cost-optimized may route unexpectedly."
"warningCostOptimizedNoPricing": "No pricing data found for this combo. Cost-optimized may route unexpectedly.",
"readinessTitle": "Pronto para salvar?",
"readinessDescription": "Revise a lista de verificação antes de criar ou atualizar este combo.",
"readinessCheckName": "O nome do combo é válido",
"readinessCheckModels": "Pelo menos um modelo está selecionado",
"readinessCheckWeights": "O total dos pesos é 100%",
"readinessCheckWeightsOptional": "Regra de pesos não obrigatória",
"readinessCheckPricing": "Dados de preços disponíveis",
"readinessCheckPricingOptional": "Regra de preços não obrigatória",
"saveBlockedTitle": "O salvamento está bloqueado até corrigir os itens abaixo:",
"saveBlockName": "Defina um nome para o combo.",
"saveBlockModels": "Adicione pelo menos um modelo.",
"saveBlockWeighted": "Ajuste os pesos para 100% (atual: {total}%).",
"saveBlockPricing": "Adicione preço para pelo menos um modelo ou escolha outra estratégia.",
"recommendationsLabel": "Recommended setup",
"applyRecommendations": "Apply recommendations",
"recommendationsUpdated": "Recommendations updated for {strategy}.",
"recommendationsApplied": "Recommendations applied to this combo.",
"strategyRecommendations": {
"priority": {
"title": "Fail-safe baseline",
"description": "Use one primary model and keep fallback chain short and reliable.",
"tip1": "Put your most reliable model first.",
"tip2": "Keep 1-2 backup models with similar quality.",
"tip3": "Use safe retries to absorb transient provider failures."
},
"weighted": {
"title": "Controlled traffic split",
"description": "Great for canary rollouts and gradual migration between models.",
"tip1": "Start with conservative split like 90/10.",
"tip2": "Keep the total at 100% and auto-balance after changes.",
"tip3": "Monitor success and latency before increasing canary weight."
},
"round-robin": {
"title": "Predictable load sharing",
"description": "Best when models are equivalent and you need smooth distribution.",
"tip1": "Use at least 2 models.",
"tip2": "Set concurrency limits to avoid burst overload.",
"tip3": "Use queue timeout to fail fast under saturation."
},
"random": {
"title": "Quick spread with low setup",
"description": "Use when you need simple distribution without strict guarantees.",
"tip1": "Use models with similar latency profiles.",
"tip2": "Keep retries enabled to absorb random misses.",
"tip3": "Prefer this for experimentation, not strict SLAs."
},
"least-used": {
"title": "Adaptive balancing",
"description": "Routes to less-used models to reduce hotspots over time.",
"tip1": "Works better under continuous traffic.",
"tip2": "Combine with health checks for safer balancing.",
"tip3": "Track per-model usage to validate distribution gains."
},
"cost-optimized": {
"title": "Budget-first routing",
"description": "Routes to lower-cost models when pricing metadata is available.",
"tip1": "Ensure pricing coverage for all selected models.",
"tip2": "Keep a quality fallback for hard prompts.",
"tip3": "Use for batch/background jobs where cost is the main KPI."
}
}
},
"costs": {
"title": "Custos",

View File

@@ -646,7 +646,68 @@
"pricingMissingShort": "no-price",
"warningRoundRobinSingleModel": "Round-robin is most useful with at least 2 models.",
"warningCostOptimizedPartialPricing": "Only {priced} of {total} models have pricing. Routing may be partially cost-aware.",
"warningCostOptimizedNoPricing": "No pricing data found for this combo. Cost-optimized may route unexpectedly."
"warningCostOptimizedNoPricing": "No pricing data found for this combo. Cost-optimized may route unexpectedly.",
"readinessTitle": "Sunteți gata să economisiți?",
"readinessDescription": "Examinați lista de verificare înainte de a crea sau a actualiza această combinație.",
"readinessCheckName": "Numele combinației este valid",
"readinessCheckModels": "Este selectat cel puțin un model",
"readinessCheckWeights": "Totalul ponderat este 100%",
"readinessCheckWeightsOptional": "Regula de greutate nu este necesară",
"readinessCheckPricing": "Datele de preț sunt disponibile",
"readinessCheckPricingOptional": "Regula de preț nu este necesară",
"saveBlockedTitle": "Salvarea este blocată până când următoarele elemente sunt remediate:",
"saveBlockName": "Definiți un nume combinat.",
"saveBlockModels": "Adăugați cel puțin un model.",
"saveBlockWeighted": "Setați ponderi la 100% (actual: {total}%).",
"saveBlockPricing": "Adăugați prețuri pentru cel puțin un model sau alegeți o altă strategie.",
"recommendationsLabel": "Recommended setup",
"applyRecommendations": "Apply recommendations",
"recommendationsUpdated": "Recommendations updated for {strategy}.",
"recommendationsApplied": "Recommendations applied to this combo.",
"strategyRecommendations": {
"priority": {
"title": "Fail-safe baseline",
"description": "Use one primary model and keep fallback chain short and reliable.",
"tip1": "Put your most reliable model first.",
"tip2": "Keep 1-2 backup models with similar quality.",
"tip3": "Use safe retries to absorb transient provider failures."
},
"weighted": {
"title": "Controlled traffic split",
"description": "Great for canary rollouts and gradual migration between models.",
"tip1": "Start with conservative split like 90/10.",
"tip2": "Keep the total at 100% and auto-balance after changes.",
"tip3": "Monitor success and latency before increasing canary weight."
},
"round-robin": {
"title": "Predictable load sharing",
"description": "Best when models are equivalent and you need smooth distribution.",
"tip1": "Use at least 2 models.",
"tip2": "Set concurrency limits to avoid burst overload.",
"tip3": "Use queue timeout to fail fast under saturation."
},
"random": {
"title": "Quick spread with low setup",
"description": "Use when you need simple distribution without strict guarantees.",
"tip1": "Use models with similar latency profiles.",
"tip2": "Keep retries enabled to absorb random misses.",
"tip3": "Prefer this for experimentation, not strict SLAs."
},
"least-used": {
"title": "Adaptive balancing",
"description": "Routes to less-used models to reduce hotspots over time.",
"tip1": "Works better under continuous traffic.",
"tip2": "Combine with health checks for safer balancing.",
"tip3": "Track per-model usage to validate distribution gains."
},
"cost-optimized": {
"title": "Budget-first routing",
"description": "Routes to lower-cost models when pricing metadata is available.",
"tip1": "Ensure pricing coverage for all selected models.",
"tip2": "Keep a quality fallback for hard prompts.",
"tip3": "Use for batch/background jobs where cost is the main KPI."
}
}
},
"costs": {
"title": "Costuri",

View File

@@ -646,7 +646,68 @@
"pricingMissingShort": "no-price",
"warningRoundRobinSingleModel": "Round-robin is most useful with at least 2 models.",
"warningCostOptimizedPartialPricing": "Only {priced} of {total} models have pricing. Routing may be partially cost-aware.",
"warningCostOptimizedNoPricing": "No pricing data found for this combo. Cost-optimized may route unexpectedly."
"warningCostOptimizedNoPricing": "No pricing data found for this combo. Cost-optimized may route unexpectedly.",
"readinessTitle": "Готовы сохранить?",
"readinessDescription": "Прежде чем создавать или обновлять эту комбинацию, просмотрите контрольный список.",
"readinessCheckName": "Имя комбинации действительно",
"readinessCheckModels": "Выбрана хотя бы одна модель",
"readinessCheckWeights": "Взвешенная сумма составляет 100 %.",
"readinessCheckWeightsOptional": "Правило веса не требуется",
"readinessCheckPricing": "Доступны данные о ценах",
"readinessCheckPricingOptional": "Правило ценообразования не требуется",
"saveBlockedTitle": "Сохранение блокируется до тех пор, пока не будут исправлены следующие элементы:",
"saveBlockName": "Определите имя комбинации.",
"saveBlockModels": "Добавьте хотя бы одну модель.",
"saveBlockWeighted": "Установите веса на 100 % (текущее: {total}%).",
"saveBlockPricing": "Добавьте цены хотя бы на одну модель или выберите другую стратегию.",
"recommendationsLabel": "Recommended setup",
"applyRecommendations": "Apply recommendations",
"recommendationsUpdated": "Recommendations updated for {strategy}.",
"recommendationsApplied": "Recommendations applied to this combo.",
"strategyRecommendations": {
"priority": {
"title": "Fail-safe baseline",
"description": "Use one primary model and keep fallback chain short and reliable.",
"tip1": "Put your most reliable model first.",
"tip2": "Keep 1-2 backup models with similar quality.",
"tip3": "Use safe retries to absorb transient provider failures."
},
"weighted": {
"title": "Controlled traffic split",
"description": "Great for canary rollouts and gradual migration between models.",
"tip1": "Start with conservative split like 90/10.",
"tip2": "Keep the total at 100% and auto-balance after changes.",
"tip3": "Monitor success and latency before increasing canary weight."
},
"round-robin": {
"title": "Predictable load sharing",
"description": "Best when models are equivalent and you need smooth distribution.",
"tip1": "Use at least 2 models.",
"tip2": "Set concurrency limits to avoid burst overload.",
"tip3": "Use queue timeout to fail fast under saturation."
},
"random": {
"title": "Quick spread with low setup",
"description": "Use when you need simple distribution without strict guarantees.",
"tip1": "Use models with similar latency profiles.",
"tip2": "Keep retries enabled to absorb random misses.",
"tip3": "Prefer this for experimentation, not strict SLAs."
},
"least-used": {
"title": "Adaptive balancing",
"description": "Routes to less-used models to reduce hotspots over time.",
"tip1": "Works better under continuous traffic.",
"tip2": "Combine with health checks for safer balancing.",
"tip3": "Track per-model usage to validate distribution gains."
},
"cost-optimized": {
"title": "Budget-first routing",
"description": "Routes to lower-cost models when pricing metadata is available.",
"tip1": "Ensure pricing coverage for all selected models.",
"tip2": "Keep a quality fallback for hard prompts.",
"tip3": "Use for batch/background jobs where cost is the main KPI."
}
}
},
"costs": {
"title": "Затраты",

View File

@@ -646,7 +646,68 @@
"pricingMissingShort": "no-price",
"warningRoundRobinSingleModel": "Round-robin is most useful with at least 2 models.",
"warningCostOptimizedPartialPricing": "Only {priced} of {total} models have pricing. Routing may be partially cost-aware.",
"warningCostOptimizedNoPricing": "No pricing data found for this combo. Cost-optimized may route unexpectedly."
"warningCostOptimizedNoPricing": "No pricing data found for this combo. Cost-optimized may route unexpectedly.",
"readinessTitle": "Ste pripravení uložiť?",
"readinessDescription": "Pred vytvorením alebo aktualizáciou tejto kombinácie skontrolujte kontrolný zoznam.",
"readinessCheckName": "Názov kombinácie je platný",
"readinessCheckModels": "Vyberie sa aspoň jeden model",
"readinessCheckWeights": "Vážený súčet je 100 %",
"readinessCheckWeightsOptional": "Nevyžaduje sa pravidlo hmotnosti",
"readinessCheckPricing": "Údaje o cenách sú k dispozícii",
"readinessCheckPricingOptional": "Nevyžaduje sa cenové pravidlo",
"saveBlockedTitle": "Ukladanie je zablokované, kým sa neopravia nasledujúce položky:",
"saveBlockName": "Definujte názov kombinácie.",
"saveBlockModels": "Pridajte aspoň jeden model.",
"saveBlockWeighted": "Nastavte váhy na 100 % (aktuálne: {total}%).",
"saveBlockPricing": "Pridajte cenu aspoň pre jeden model alebo zvoľte inú stratégiu.",
"recommendationsLabel": "Recommended setup",
"applyRecommendations": "Apply recommendations",
"recommendationsUpdated": "Recommendations updated for {strategy}.",
"recommendationsApplied": "Recommendations applied to this combo.",
"strategyRecommendations": {
"priority": {
"title": "Fail-safe baseline",
"description": "Use one primary model and keep fallback chain short and reliable.",
"tip1": "Put your most reliable model first.",
"tip2": "Keep 1-2 backup models with similar quality.",
"tip3": "Use safe retries to absorb transient provider failures."
},
"weighted": {
"title": "Controlled traffic split",
"description": "Great for canary rollouts and gradual migration between models.",
"tip1": "Start with conservative split like 90/10.",
"tip2": "Keep the total at 100% and auto-balance after changes.",
"tip3": "Monitor success and latency before increasing canary weight."
},
"round-robin": {
"title": "Predictable load sharing",
"description": "Best when models are equivalent and you need smooth distribution.",
"tip1": "Use at least 2 models.",
"tip2": "Set concurrency limits to avoid burst overload.",
"tip3": "Use queue timeout to fail fast under saturation."
},
"random": {
"title": "Quick spread with low setup",
"description": "Use when you need simple distribution without strict guarantees.",
"tip1": "Use models with similar latency profiles.",
"tip2": "Keep retries enabled to absorb random misses.",
"tip3": "Prefer this for experimentation, not strict SLAs."
},
"least-used": {
"title": "Adaptive balancing",
"description": "Routes to less-used models to reduce hotspots over time.",
"tip1": "Works better under continuous traffic.",
"tip2": "Combine with health checks for safer balancing.",
"tip3": "Track per-model usage to validate distribution gains."
},
"cost-optimized": {
"title": "Budget-first routing",
"description": "Routes to lower-cost models when pricing metadata is available.",
"tip1": "Ensure pricing coverage for all selected models.",
"tip2": "Keep a quality fallback for hard prompts.",
"tip3": "Use for batch/background jobs where cost is the main KPI."
}
}
},
"costs": {
"title": "náklady",

View File

@@ -646,7 +646,68 @@
"pricingMissingShort": "inget pris",
"warningRoundRobinSingleModel": "Round-robin är mest användbar med minst 2 modeller.",
"warningCostOptimizedPartialPricing": "Endast {priced} av {total} modeller har prissättning. Rutning kan vara delvis kostnadsmedveten.",
"warningCostOptimizedNoPricing": "Inga prisuppgifter hittades för denna kombination. Kostnadsoptimerad kan väga oväntat."
"warningCostOptimizedNoPricing": "Inga prisuppgifter hittades för denna kombination. Kostnadsoptimerad kan väga oväntat.",
"readinessTitle": "Redo att spara?",
"readinessDescription": "Granska checklistan innan du skapar eller uppdaterar den här kombinationen.",
"readinessCheckName": "Kombinationsnamnet är giltigt",
"readinessCheckModels": "Minst en modell är vald",
"readinessCheckWeights": "Den viktade summan är 100 %",
"readinessCheckWeightsOptional": "Viktregel krävs inte",
"readinessCheckPricing": "Prisuppgifter finns tillgängliga",
"readinessCheckPricingOptional": "Prissättningsregel krävs inte",
"saveBlockedTitle": "Spara är blockerad tills följande saker är åtgärdade:",
"saveBlockName": "Definiera ett kombinationsnamn.",
"saveBlockModels": "Lägg till minst en modell.",
"saveBlockWeighted": "Ställ in vikter på 100 % (nuvarande: {total}%).",
"saveBlockPricing": "Lägg till prissättning för minst en modell eller välj en annan strategi.",
"recommendationsLabel": "Recommended setup",
"applyRecommendations": "Apply recommendations",
"recommendationsUpdated": "Recommendations updated for {strategy}.",
"recommendationsApplied": "Recommendations applied to this combo.",
"strategyRecommendations": {
"priority": {
"title": "Fail-safe baseline",
"description": "Use one primary model and keep fallback chain short and reliable.",
"tip1": "Put your most reliable model first.",
"tip2": "Keep 1-2 backup models with similar quality.",
"tip3": "Use safe retries to absorb transient provider failures."
},
"weighted": {
"title": "Controlled traffic split",
"description": "Great for canary rollouts and gradual migration between models.",
"tip1": "Start with conservative split like 90/10.",
"tip2": "Keep the total at 100% and auto-balance after changes.",
"tip3": "Monitor success and latency before increasing canary weight."
},
"round-robin": {
"title": "Predictable load sharing",
"description": "Best when models are equivalent and you need smooth distribution.",
"tip1": "Use at least 2 models.",
"tip2": "Set concurrency limits to avoid burst overload.",
"tip3": "Use queue timeout to fail fast under saturation."
},
"random": {
"title": "Quick spread with low setup",
"description": "Use when you need simple distribution without strict guarantees.",
"tip1": "Use models with similar latency profiles.",
"tip2": "Keep retries enabled to absorb random misses.",
"tip3": "Prefer this for experimentation, not strict SLAs."
},
"least-used": {
"title": "Adaptive balancing",
"description": "Routes to less-used models to reduce hotspots over time.",
"tip1": "Works better under continuous traffic.",
"tip2": "Combine with health checks for safer balancing.",
"tip3": "Track per-model usage to validate distribution gains."
},
"cost-optimized": {
"title": "Budget-first routing",
"description": "Routes to lower-cost models when pricing metadata is available.",
"tip1": "Ensure pricing coverage for all selected models.",
"tip2": "Keep a quality fallback for hard prompts.",
"tip3": "Use for batch/background jobs where cost is the main KPI."
}
}
},
"costs": {
"title": "Kostnader",

View File

@@ -646,7 +646,68 @@
"pricingMissingShort": "no-price",
"warningRoundRobinSingleModel": "Round-robin is most useful with at least 2 models.",
"warningCostOptimizedPartialPricing": "Only {priced} of {total} models have pricing. Routing may be partially cost-aware.",
"warningCostOptimizedNoPricing": "No pricing data found for this combo. Cost-optimized may route unexpectedly."
"warningCostOptimizedNoPricing": "No pricing data found for this combo. Cost-optimized may route unexpectedly.",
"readinessTitle": "พร้อมที่จะบันทึกแล้วหรือยัง?",
"readinessDescription": "ตรวจสอบรายการตรวจสอบก่อนที่จะสร้างหรืออัปเดตคำสั่งผสมนี้",
"readinessCheckName": "ชื่อคำสั่งผสมถูกต้อง",
"readinessCheckModels": "เลือกอย่างน้อยหนึ่งรุ่น",
"readinessCheckWeights": "ยอดรวมถ่วงน้ำหนักคือ 100%",
"readinessCheckWeightsOptional": "ไม่จำเป็นต้องมีกฎน้ำหนัก",
"readinessCheckPricing": "มีข้อมูลราคาอยู่",
"readinessCheckPricingOptional": "ไม่จำเป็นต้องมีกฎการกำหนดราคา",
"saveBlockedTitle": "บันทึกจะถูกบล็อกจนกว่ารายการต่อไปนี้จะได้รับการแก้ไข:",
"saveBlockName": "กำหนดชื่อคอมโบ",
"saveBlockModels": "เพิ่มอย่างน้อยหนึ่งรุ่น",
"saveBlockWeighted": "ตั้งค่าน้ำหนักเป็น 100% (ปัจจุบัน: {total}%)",
"saveBlockPricing": "เพิ่มราคาสำหรับรุ่นอย่างน้อยหนึ่งรุ่นหรือเลือกกลยุทธ์อื่น",
"recommendationsLabel": "Recommended setup",
"applyRecommendations": "Apply recommendations",
"recommendationsUpdated": "Recommendations updated for {strategy}.",
"recommendationsApplied": "Recommendations applied to this combo.",
"strategyRecommendations": {
"priority": {
"title": "Fail-safe baseline",
"description": "Use one primary model and keep fallback chain short and reliable.",
"tip1": "Put your most reliable model first.",
"tip2": "Keep 1-2 backup models with similar quality.",
"tip3": "Use safe retries to absorb transient provider failures."
},
"weighted": {
"title": "Controlled traffic split",
"description": "Great for canary rollouts and gradual migration between models.",
"tip1": "Start with conservative split like 90/10.",
"tip2": "Keep the total at 100% and auto-balance after changes.",
"tip3": "Monitor success and latency before increasing canary weight."
},
"round-robin": {
"title": "Predictable load sharing",
"description": "Best when models are equivalent and you need smooth distribution.",
"tip1": "Use at least 2 models.",
"tip2": "Set concurrency limits to avoid burst overload.",
"tip3": "Use queue timeout to fail fast under saturation."
},
"random": {
"title": "Quick spread with low setup",
"description": "Use when you need simple distribution without strict guarantees.",
"tip1": "Use models with similar latency profiles.",
"tip2": "Keep retries enabled to absorb random misses.",
"tip3": "Prefer this for experimentation, not strict SLAs."
},
"least-used": {
"title": "Adaptive balancing",
"description": "Routes to less-used models to reduce hotspots over time.",
"tip1": "Works better under continuous traffic.",
"tip2": "Combine with health checks for safer balancing.",
"tip3": "Track per-model usage to validate distribution gains."
},
"cost-optimized": {
"title": "Budget-first routing",
"description": "Routes to lower-cost models when pricing metadata is available.",
"tip1": "Ensure pricing coverage for all selected models.",
"tip2": "Keep a quality fallback for hard prompts.",
"tip3": "Use for batch/background jobs where cost is the main KPI."
}
}
},
"costs": {
"title": "ค่าใช้จ่าย",

View File

@@ -646,7 +646,68 @@
"pricingMissingShort": "no-price",
"warningRoundRobinSingleModel": "Round-robin is most useful with at least 2 models.",
"warningCostOptimizedPartialPricing": "Only {priced} of {total} models have pricing. Routing may be partially cost-aware.",
"warningCostOptimizedNoPricing": "No pricing data found for this combo. Cost-optimized may route unexpectedly."
"warningCostOptimizedNoPricing": "No pricing data found for this combo. Cost-optimized may route unexpectedly.",
"readinessTitle": "Готові економити?",
"readinessDescription": "Перегляньте контрольний список, перш ніж створювати або оновлювати цю комбінацію.",
"readinessCheckName": "Ім'я комбінованого тексту дійсне",
"readinessCheckModels": "Вибрано принаймні одну модель",
"readinessCheckWeights": "Зважений підсумок становить 100%",
"readinessCheckWeightsOptional": "Правило ваги не потрібне",
"readinessCheckPricing": "Ціни доступні",
"readinessCheckPricingOptional": "Правило ціноутворення не вимагається",
"saveBlockedTitle": "Збереження заблоковано, доки не будуть виправлені такі елементи:",
"saveBlockName": "Визначте комбіноване ім’я.",
"saveBlockModels": "Додайте хоча б одну модель.",
"saveBlockWeighted": "Встановити ваги на 100% (поточний: {total}%).",
"saveBlockPricing": "Додайте ціну принаймні на одну модель або виберіть іншу стратегію.",
"recommendationsLabel": "Recommended setup",
"applyRecommendations": "Apply recommendations",
"recommendationsUpdated": "Recommendations updated for {strategy}.",
"recommendationsApplied": "Recommendations applied to this combo.",
"strategyRecommendations": {
"priority": {
"title": "Fail-safe baseline",
"description": "Use one primary model and keep fallback chain short and reliable.",
"tip1": "Put your most reliable model first.",
"tip2": "Keep 1-2 backup models with similar quality.",
"tip3": "Use safe retries to absorb transient provider failures."
},
"weighted": {
"title": "Controlled traffic split",
"description": "Great for canary rollouts and gradual migration between models.",
"tip1": "Start with conservative split like 90/10.",
"tip2": "Keep the total at 100% and auto-balance after changes.",
"tip3": "Monitor success and latency before increasing canary weight."
},
"round-robin": {
"title": "Predictable load sharing",
"description": "Best when models are equivalent and you need smooth distribution.",
"tip1": "Use at least 2 models.",
"tip2": "Set concurrency limits to avoid burst overload.",
"tip3": "Use queue timeout to fail fast under saturation."
},
"random": {
"title": "Quick spread with low setup",
"description": "Use when you need simple distribution without strict guarantees.",
"tip1": "Use models with similar latency profiles.",
"tip2": "Keep retries enabled to absorb random misses.",
"tip3": "Prefer this for experimentation, not strict SLAs."
},
"least-used": {
"title": "Adaptive balancing",
"description": "Routes to less-used models to reduce hotspots over time.",
"tip1": "Works better under continuous traffic.",
"tip2": "Combine with health checks for safer balancing.",
"tip3": "Track per-model usage to validate distribution gains."
},
"cost-optimized": {
"title": "Budget-first routing",
"description": "Routes to lower-cost models when pricing metadata is available.",
"tip1": "Ensure pricing coverage for all selected models.",
"tip2": "Keep a quality fallback for hard prompts.",
"tip3": "Use for batch/background jobs where cost is the main KPI."
}
}
},
"costs": {
"title": "Витрати",

View File

@@ -646,7 +646,68 @@
"pricingMissingShort": "no-price",
"warningRoundRobinSingleModel": "Round-robin is most useful with at least 2 models.",
"warningCostOptimizedPartialPricing": "Only {priced} of {total} models have pricing. Routing may be partially cost-aware.",
"warningCostOptimizedNoPricing": "No pricing data found for this combo. Cost-optimized may route unexpectedly."
"warningCostOptimizedNoPricing": "No pricing data found for this combo. Cost-optimized may route unexpectedly.",
"readinessTitle": "Sẵn sàng để lưu?",
"readinessDescription": "Xem lại danh sách kiểm tra trước khi tạo hoặc cập nhật kết hợp này.",
"readinessCheckName": "Tên kết hợp là hợp lệ",
"readinessCheckModels": "Ít nhất một mô hình được chọn",
"readinessCheckWeights": "Tổng trọng số là 100%",
"readinessCheckWeightsOptional": "Không cần quy định trọng lượng",
"readinessCheckPricing": "Dữ liệu giá cả có sẵn",
"readinessCheckPricingOptional": "Quy tắc đặt giá không bắt buộc",
"saveBlockedTitle": "Lưu bị chặn cho đến khi các mục sau được khắc phục:",
"saveBlockName": "Xác định tên kết hợp.",
"saveBlockModels": "Thêm ít nhất một mô hình.",
"saveBlockWeighted": "Đặt trọng số thành 100% (hiện tại: {total}%).",
"saveBlockPricing": "Thêm giá cho ít nhất một mô hình hoặc chọn một chiến lược khác.",
"recommendationsLabel": "Recommended setup",
"applyRecommendations": "Apply recommendations",
"recommendationsUpdated": "Recommendations updated for {strategy}.",
"recommendationsApplied": "Recommendations applied to this combo.",
"strategyRecommendations": {
"priority": {
"title": "Fail-safe baseline",
"description": "Use one primary model and keep fallback chain short and reliable.",
"tip1": "Put your most reliable model first.",
"tip2": "Keep 1-2 backup models with similar quality.",
"tip3": "Use safe retries to absorb transient provider failures."
},
"weighted": {
"title": "Controlled traffic split",
"description": "Great for canary rollouts and gradual migration between models.",
"tip1": "Start with conservative split like 90/10.",
"tip2": "Keep the total at 100% and auto-balance after changes.",
"tip3": "Monitor success and latency before increasing canary weight."
},
"round-robin": {
"title": "Predictable load sharing",
"description": "Best when models are equivalent and you need smooth distribution.",
"tip1": "Use at least 2 models.",
"tip2": "Set concurrency limits to avoid burst overload.",
"tip3": "Use queue timeout to fail fast under saturation."
},
"random": {
"title": "Quick spread with low setup",
"description": "Use when you need simple distribution without strict guarantees.",
"tip1": "Use models with similar latency profiles.",
"tip2": "Keep retries enabled to absorb random misses.",
"tip3": "Prefer this for experimentation, not strict SLAs."
},
"least-used": {
"title": "Adaptive balancing",
"description": "Routes to less-used models to reduce hotspots over time.",
"tip1": "Works better under continuous traffic.",
"tip2": "Combine with health checks for safer balancing.",
"tip3": "Track per-model usage to validate distribution gains."
},
"cost-optimized": {
"title": "Budget-first routing",
"description": "Routes to lower-cost models when pricing metadata is available.",
"tip1": "Ensure pricing coverage for all selected models.",
"tip2": "Keep a quality fallback for hard prompts.",
"tip3": "Use for batch/background jobs where cost is the main KPI."
}
}
},
"costs": {
"title": "Chi phí",

View File

@@ -646,7 +646,68 @@
"pricingMissingShort": "无价格",
"warningRoundRobinSingleModel": "循环法对于至少 2 个模型最有用。",
"warningCostOptimizedPartialPricing": "只有{priced} 和{total} 型号有定价。路由可能是部分成本感知的。",
"warningCostOptimizedNoPricing": "没有找到该组合的定价数据。成本优化的路线可能会出乎意料。"
"warningCostOptimizedNoPricing": "没有找到该组合的定价数据。成本优化的路线可能会出乎意料。",
"readinessTitle": "准备好保存了吗?",
"readinessDescription": "在创建或更新此组合之前查看清单。",
"readinessCheckName": "组合名称有效",
"readinessCheckModels": "至少选择一种型号",
"readinessCheckWeights": "加权总和为100%",
"readinessCheckWeightsOptional": "不需要重量规则",
"readinessCheckPricing": "定价数据可用",
"readinessCheckPricingOptional": "不需要定价规则",
"saveBlockedTitle": "在修复以下项目之前,保存将被阻止:",
"saveBlockName": "定义组合名称。",
"saveBlockModels": "添加至少一种模型。",
"saveBlockWeighted": "将权重设置为 100%(当前:{total}%)。",
"saveBlockPricing": "添加至少一种型号的定价或选择不同的策略。",
"recommendationsLabel": "Recommended setup",
"applyRecommendations": "Apply recommendations",
"recommendationsUpdated": "Recommendations updated for {strategy}.",
"recommendationsApplied": "Recommendations applied to this combo.",
"strategyRecommendations": {
"priority": {
"title": "Fail-safe baseline",
"description": "Use one primary model and keep fallback chain short and reliable.",
"tip1": "Put your most reliable model first.",
"tip2": "Keep 1-2 backup models with similar quality.",
"tip3": "Use safe retries to absorb transient provider failures."
},
"weighted": {
"title": "Controlled traffic split",
"description": "Great for canary rollouts and gradual migration between models.",
"tip1": "Start with conservative split like 90/10.",
"tip2": "Keep the total at 100% and auto-balance after changes.",
"tip3": "Monitor success and latency before increasing canary weight."
},
"round-robin": {
"title": "Predictable load sharing",
"description": "Best when models are equivalent and you need smooth distribution.",
"tip1": "Use at least 2 models.",
"tip2": "Set concurrency limits to avoid burst overload.",
"tip3": "Use queue timeout to fail fast under saturation."
},
"random": {
"title": "Quick spread with low setup",
"description": "Use when you need simple distribution without strict guarantees.",
"tip1": "Use models with similar latency profiles.",
"tip2": "Keep retries enabled to absorb random misses.",
"tip3": "Prefer this for experimentation, not strict SLAs."
},
"least-used": {
"title": "Adaptive balancing",
"description": "Routes to less-used models to reduce hotspots over time.",
"tip1": "Works better under continuous traffic.",
"tip2": "Combine with health checks for safer balancing.",
"tip3": "Track per-model usage to validate distribution gains."
},
"cost-optimized": {
"title": "Budget-first routing",
"description": "Routes to lower-cost models when pricing metadata is available.",
"tip1": "Ensure pricing coverage for all selected models.",
"tip2": "Keep a quality fallback for hard prompts.",
"tip3": "Use for batch/background jobs where cost is the main KPI."
}
}
},
"costs": {
"title": "成本",

View File

@@ -163,6 +163,25 @@ test.describe("Combos flow", () => {
const comboDialog = page.getByRole("dialog").first();
await expect(comboDialog).toBeVisible();
const comboCreateButton = comboDialog
.getByRole("button", { name: /create combo|criar combo/i })
.last();
const readinessPanel = comboDialog.locator('[data-testid="combo-readiness-panel"]');
const saveBlockers = comboDialog.locator('[data-testid="combo-save-blockers"]');
await expect(readinessPanel).toBeVisible();
await expect(saveBlockers).toBeVisible();
await expect(comboCreateButton).toBeDisabled();
const applyRecommendationsButton = comboDialog
.getByRole("button", { name: /apply recommendations|aplicar recomendações/i })
.first();
await expect(applyRecommendationsButton).toBeVisible();
await comboDialog.locator('[data-testid="strategy-option-weighted"]').click();
await expect(comboDialog.locator('[data-testid="strategy-change-nudge"]')).toBeVisible();
await comboDialog.locator('[data-testid="strategy-option-priority"]').click();
await expect(comboDialog.locator('[data-testid="strategy-change-nudge"]')).toBeVisible();
await applyRecommendationsButton.click();
await comboDialog
.getByRole("button", { name: /high availability|alta disponibilidade/i })
@@ -172,11 +191,10 @@ test.describe("Combos flow", () => {
const modelDialog = page.getByRole("dialog").last();
await expect(modelDialog.getByRole("button", { name: /qa test model/i })).toBeVisible();
await modelDialog.getByRole("button", { name: /qa test model/i }).click();
await expect(saveBlockers).toHaveCount(0);
await expect(comboCreateButton).toBeEnabled();
await comboDialog
.getByRole("button", { name: /create combo|criar combo/i })
.last()
.click();
await comboCreateButton.click();
await expect(comboDialog).toBeHidden();
const quickTestButton = page.getByRole("button", { name: /test now|testar agora/i });