Skip to content

Commit 2490ba5

Browse files
committed
feat: Introduce combo readiness checks and strategy recommendations, updating i18n messages and e2e tests.
1 parent 79c23df commit 2490ba5

File tree

32 files changed

+2273
-98
lines changed

32 files changed

+2273
-98
lines changed

src/app/(dashboard)/dashboard/combos/page.tsx

Lines changed: 328 additions & 1 deletion
Large diffs are not rendered by default.

src/i18n/messages/ar.json

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -646,7 +646,68 @@
646646
"pricingMissingShort": "رسم",
647647
"warningRoundRobinSingleModel": "يعتبر Round - robin أكثر فائدة مع طرازين على الأقل.",
648648
"warningCostOptimizedPartialPricing": "فقط {priced} من طرازات {total} لها أسعار. قد يكون التوجيه مدركًا جزئيًا للتكلفة.",
649-
"warningCostOptimizedNoPricing": "لم يتم العثور على بيانات تسعير لهذه المجموعة. قد يتم توجيه التكلفة المحسّنة بشكل غير متوقع."
649+
"warningCostOptimizedNoPricing": "لم يتم العثور على بيانات تسعير لهذه المجموعة. قد يتم توجيه التكلفة المحسّنة بشكل غير متوقع.",
650+
"readinessTitle": "هل أنت مستعد للحفظ؟",
651+
"readinessDescription": "قم بمراجعة قائمة التحقق قبل إنشاء هذا التحرير والسرد أو تحديثه.",
652+
"readinessCheckName": "اسم التحرير والسرد صالح",
653+
"readinessCheckModels": "تم تحديد نموذج واحد على الأقل",
654+
"readinessCheckWeights": "الإجمالي المرجح هو 100%",
655+
"readinessCheckWeightsOptional": "قاعدة الوزن غير مطلوبة",
656+
"readinessCheckPricing": "بيانات التسعير متاحة",
657+
"readinessCheckPricingOptional": "قاعدة التسعير غير مطلوبة",
658+
"saveBlockedTitle": "تم حظر الحفظ حتى يتم إصلاح العناصر التالية:",
659+
"saveBlockName": "تحديد اسم التحرير والسرد.",
660+
"saveBlockModels": "أضف نموذجًا واحدًا على الأقل.",
661+
"saveBlockWeighted": "اضبط الأوزان على 100% (الحالي: {total}%).",
662+
"saveBlockPricing": "أضف أسعارًا لنموذج واحد على الأقل أو اختر استراتيجية مختلفة.",
663+
"recommendationsLabel": "Recommended setup",
664+
"applyRecommendations": "Apply recommendations",
665+
"recommendationsUpdated": "Recommendations updated for {strategy}.",
666+
"recommendationsApplied": "Recommendations applied to this combo.",
667+
"strategyRecommendations": {
668+
"priority": {
669+
"title": "Fail-safe baseline",
670+
"description": "Use one primary model and keep fallback chain short and reliable.",
671+
"tip1": "Put your most reliable model first.",
672+
"tip2": "Keep 1-2 backup models with similar quality.",
673+
"tip3": "Use safe retries to absorb transient provider failures."
674+
},
675+
"weighted": {
676+
"title": "Controlled traffic split",
677+
"description": "Great for canary rollouts and gradual migration between models.",
678+
"tip1": "Start with conservative split like 90/10.",
679+
"tip2": "Keep the total at 100% and auto-balance after changes.",
680+
"tip3": "Monitor success and latency before increasing canary weight."
681+
},
682+
"round-robin": {
683+
"title": "Predictable load sharing",
684+
"description": "Best when models are equivalent and you need smooth distribution.",
685+
"tip1": "Use at least 2 models.",
686+
"tip2": "Set concurrency limits to avoid burst overload.",
687+
"tip3": "Use queue timeout to fail fast under saturation."
688+
},
689+
"random": {
690+
"title": "Quick spread with low setup",
691+
"description": "Use when you need simple distribution without strict guarantees.",
692+
"tip1": "Use models with similar latency profiles.",
693+
"tip2": "Keep retries enabled to absorb random misses.",
694+
"tip3": "Prefer this for experimentation, not strict SLAs."
695+
},
696+
"least-used": {
697+
"title": "Adaptive balancing",
698+
"description": "Routes to less-used models to reduce hotspots over time.",
699+
"tip1": "Works better under continuous traffic.",
700+
"tip2": "Combine with health checks for safer balancing.",
701+
"tip3": "Track per-model usage to validate distribution gains."
702+
},
703+
"cost-optimized": {
704+
"title": "Budget-first routing",
705+
"description": "Routes to lower-cost models when pricing metadata is available.",
706+
"tip1": "Ensure pricing coverage for all selected models.",
707+
"tip2": "Keep a quality fallback for hard prompts.",
708+
"tip3": "Use for batch/background jobs where cost is the main KPI."
709+
}
710+
}
650711
},
651712
"costs": {
652713
"title": "التكاليف",

src/i18n/messages/bg.json

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -646,7 +646,68 @@
646646
"pricingMissingShort": "без цена",
647647
"warningRoundRobinSingleModel": "Round - robin е най - полезен с поне 2 модела.",
648648
"warningCostOptimizedPartialPricing": "Само {priced} от {total} моделите имат ценообразуване. Маршрутизирането може да бъде частично съобразено с разходите.",
649-
"warningCostOptimizedNoPricing": "Няма намерени данни за ценообразуване за тази комбинация. Оптимизираният по отношение на разходите маршрут може да е неочакван."
649+
"warningCostOptimizedNoPricing": "Няма намерени данни за ценообразуване за тази комбинация. Оптимизираният по отношение на разходите маршрут може да е неочакван.",
650+
"readinessTitle": "Готови ли сте да запазите?",
651+
"readinessDescription": "Прегледайте контролния списък, преди да създадете или актуализирате тази комбинация.",
652+
"readinessCheckName": "Комбо името е валидно",
653+
"readinessCheckModels": "Избран е поне един модел",
654+
"readinessCheckWeights": "Претеглената обща сума е 100%",
655+
"readinessCheckWeightsOptional": "Правилото за тегло не се изисква",
656+
"readinessCheckPricing": "Налични са данни за цените",
657+
"readinessCheckPricingOptional": "Правилото за ценообразуване не се изисква",
658+
"saveBlockedTitle": "Запазването е блокирано, докато не бъдат коригирани следните елементи:",
659+
"saveBlockName": "Определете комбо име.",
660+
"saveBlockModels": "Добавете поне един модел.",
661+
"saveBlockWeighted": "Задайте тегла на 100% (текущо: {total}%).",
662+
"saveBlockPricing": "Добавете цена за поне един модел или изберете различна стратегия.",
663+
"recommendationsLabel": "Recommended setup",
664+
"applyRecommendations": "Apply recommendations",
665+
"recommendationsUpdated": "Recommendations updated for {strategy}.",
666+
"recommendationsApplied": "Recommendations applied to this combo.",
667+
"strategyRecommendations": {
668+
"priority": {
669+
"title": "Fail-safe baseline",
670+
"description": "Use one primary model and keep fallback chain short and reliable.",
671+
"tip1": "Put your most reliable model first.",
672+
"tip2": "Keep 1-2 backup models with similar quality.",
673+
"tip3": "Use safe retries to absorb transient provider failures."
674+
},
675+
"weighted": {
676+
"title": "Controlled traffic split",
677+
"description": "Great for canary rollouts and gradual migration between models.",
678+
"tip1": "Start with conservative split like 90/10.",
679+
"tip2": "Keep the total at 100% and auto-balance after changes.",
680+
"tip3": "Monitor success and latency before increasing canary weight."
681+
},
682+
"round-robin": {
683+
"title": "Predictable load sharing",
684+
"description": "Best when models are equivalent and you need smooth distribution.",
685+
"tip1": "Use at least 2 models.",
686+
"tip2": "Set concurrency limits to avoid burst overload.",
687+
"tip3": "Use queue timeout to fail fast under saturation."
688+
},
689+
"random": {
690+
"title": "Quick spread with low setup",
691+
"description": "Use when you need simple distribution without strict guarantees.",
692+
"tip1": "Use models with similar latency profiles.",
693+
"tip2": "Keep retries enabled to absorb random misses.",
694+
"tip3": "Prefer this for experimentation, not strict SLAs."
695+
},
696+
"least-used": {
697+
"title": "Adaptive balancing",
698+
"description": "Routes to less-used models to reduce hotspots over time.",
699+
"tip1": "Works better under continuous traffic.",
700+
"tip2": "Combine with health checks for safer balancing.",
701+
"tip3": "Track per-model usage to validate distribution gains."
702+
},
703+
"cost-optimized": {
704+
"title": "Budget-first routing",
705+
"description": "Routes to lower-cost models when pricing metadata is available.",
706+
"tip1": "Ensure pricing coverage for all selected models.",
707+
"tip2": "Keep a quality fallback for hard prompts.",
708+
"tip3": "Use for batch/background jobs where cost is the main KPI."
709+
}
710+
}
650711
},
651712
"costs": {
652713
"title": "Разходи",

src/i18n/messages/da.json

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -646,7 +646,68 @@
646646
"pricingMissingShort": "ingen pris",
647647
"warningRoundRobinSingleModel": "Round-robin er mest nyttig med mindst 2 modeller.",
648648
"warningCostOptimizedPartialPricing": "Kun {priced} af {total}-modeller har priser. Routing kan være delvist omkostningsbevidst.",
649-
"warningCostOptimizedNoPricing": "Der blev ikke fundet nogen prisdata for denne kombination. Omkostningsoptimeret kan rute uventet."
649+
"warningCostOptimizedNoPricing": "Der blev ikke fundet nogen prisdata for denne kombination. Omkostningsoptimeret kan rute uventet.",
650+
"readinessTitle": "Klar til at spare?",
651+
"readinessDescription": "Gennemgå tjeklisten, før du opretter eller opdaterer denne kombination.",
652+
"readinessCheckName": "Kombinationsnavnet er gyldigt",
653+
"readinessCheckModels": "Der er valgt mindst én model",
654+
"readinessCheckWeights": "Vægtet total er 100 %",
655+
"readinessCheckWeightsOptional": "Vægtregel ikke påkrævet",
656+
"readinessCheckPricing": "Prisdata er tilgængelige",
657+
"readinessCheckPricingOptional": "Reglen om prissætning er ikke påkrævet",
658+
"saveBlockedTitle": "Gem er blokeret, indtil følgende elementer er rettet:",
659+
"saveBlockName": "Definer et kombinationsnavn.",
660+
"saveBlockModels": "Tilføj mindst én model.",
661+
"saveBlockWeighted": "Indstil vægte til 100 % (aktuelt: {total}%).",
662+
"saveBlockPricing": "Tilføj priser for mindst én model, eller vælg en anden strategi.",
663+
"recommendationsLabel": "Recommended setup",
664+
"applyRecommendations": "Apply recommendations",
665+
"recommendationsUpdated": "Recommendations updated for {strategy}.",
666+
"recommendationsApplied": "Recommendations applied to this combo.",
667+
"strategyRecommendations": {
668+
"priority": {
669+
"title": "Fail-safe baseline",
670+
"description": "Use one primary model and keep fallback chain short and reliable.",
671+
"tip1": "Put your most reliable model first.",
672+
"tip2": "Keep 1-2 backup models with similar quality.",
673+
"tip3": "Use safe retries to absorb transient provider failures."
674+
},
675+
"weighted": {
676+
"title": "Controlled traffic split",
677+
"description": "Great for canary rollouts and gradual migration between models.",
678+
"tip1": "Start with conservative split like 90/10.",
679+
"tip2": "Keep the total at 100% and auto-balance after changes.",
680+
"tip3": "Monitor success and latency before increasing canary weight."
681+
},
682+
"round-robin": {
683+
"title": "Predictable load sharing",
684+
"description": "Best when models are equivalent and you need smooth distribution.",
685+
"tip1": "Use at least 2 models.",
686+
"tip2": "Set concurrency limits to avoid burst overload.",
687+
"tip3": "Use queue timeout to fail fast under saturation."
688+
},
689+
"random": {
690+
"title": "Quick spread with low setup",
691+
"description": "Use when you need simple distribution without strict guarantees.",
692+
"tip1": "Use models with similar latency profiles.",
693+
"tip2": "Keep retries enabled to absorb random misses.",
694+
"tip3": "Prefer this for experimentation, not strict SLAs."
695+
},
696+
"least-used": {
697+
"title": "Adaptive balancing",
698+
"description": "Routes to less-used models to reduce hotspots over time.",
699+
"tip1": "Works better under continuous traffic.",
700+
"tip2": "Combine with health checks for safer balancing.",
701+
"tip3": "Track per-model usage to validate distribution gains."
702+
},
703+
"cost-optimized": {
704+
"title": "Budget-first routing",
705+
"description": "Routes to lower-cost models when pricing metadata is available.",
706+
"tip1": "Ensure pricing coverage for all selected models.",
707+
"tip2": "Keep a quality fallback for hard prompts.",
708+
"tip3": "Use for batch/background jobs where cost is the main KPI."
709+
}
710+
}
650711
},
651712
"costs": {
652713
"title": "Omkostninger",

src/i18n/messages/de.json

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -646,7 +646,68 @@
646646
"pricingMissingShort": "kein Preis",
647647
"warningRoundRobinSingleModel": "Round-Robin ist bei mindestens zwei Modellen am nützlichsten.",
648648
"warningCostOptimizedPartialPricing": "Nur {priced} der {total} Modelle haben Preise. Die Routenplanung kann teilweise kostenbewusst erfolgen.",
649-
"warningCostOptimizedNoPricing": "Für diese Kombination wurden keine Preisdaten gefunden. Eine kostenoptimierte Route kann unerwartet erfolgen."
649+
"warningCostOptimizedNoPricing": "Für diese Kombination wurden keine Preisdaten gefunden. Eine kostenoptimierte Route kann unerwartet erfolgen.",
650+
"readinessTitle": "Bereit zum Speichern?",
651+
"readinessDescription": "Prüfe die Checkliste, bevor du dieses Combo erstellst oder aktualisierst.",
652+
"readinessCheckName": "Der Combo-Name ist gültig",
653+
"readinessCheckModels": "Mindestens ein Modell ist ausgewählt",
654+
"readinessCheckWeights": "Die Gewichtssumme beträgt 100 %",
655+
"readinessCheckWeightsOptional": "Gewichtungsregel nicht erforderlich",
656+
"readinessCheckPricing": "Preisdaten sind verfügbar",
657+
"readinessCheckPricingOptional": "Preisregel nicht erforderlich",
658+
"saveBlockedTitle": "Speichern ist blockiert, bis diese Punkte behoben sind:",
659+
"saveBlockName": "Definiere einen Namen für das Combo.",
660+
"saveBlockModels": "Füge mindestens ein Modell hinzu.",
661+
"saveBlockWeighted": "Setze die Gewichte auf 100 % (aktuell: {total} %).",
662+
"saveBlockPricing": "Füge Preise für mindestens ein Modell hinzu oder wähle eine andere Strategie.",
663+
"recommendationsLabel": "Empfohlene Konfiguration",
664+
"applyRecommendations": "Empfehlungen anwenden",
665+
"recommendationsUpdated": "Empfehlungen für {strategy} aktualisiert.",
666+
"recommendationsApplied": "Empfehlungen für dieses Combo wurden angewendet.",
667+
"strategyRecommendations": {
668+
"priority": {
669+
"title": "Ausfallsichere Basis",
670+
"description": "Nutze ein primäres Modell und halte die Fallback-Kette kurz und zuverlässig.",
671+
"tip1": "Setze dein zuverlässigstes Modell an erste Stelle.",
672+
"tip2": "Nutze 1-2 Backup-Modelle mit ähnlicher Qualität.",
673+
"tip3": "Aktiviere sichere Retries, um temporäre Provider-Fehler abzufangen."
674+
},
675+
"weighted": {
676+
"title": "Kontrollierte Traffic-Aufteilung",
677+
"description": "Ideal für Canary-Rollouts und schrittweise Modellmigrationen.",
678+
"tip1": "Starte mit einer konservativen Verteilung wie 90/10.",
679+
"tip2": "Halte die Summe bei 100 % und gleiche nach Änderungen automatisch aus.",
680+
"tip3": "Überwache Erfolg und Latenz, bevor du Canary-Gewichte erhöhst."
681+
},
682+
"round-robin": {
683+
"title": "Vorhersehbare Lastverteilung",
684+
"description": "Am besten, wenn Modelle gleichwertig sind und du eine stabile Verteilung brauchst.",
685+
"tip1": "Nutze mindestens 2 Modelle.",
686+
"tip2": "Setze Concurrency-Limits, um Lastspitzen zu vermeiden.",
687+
"tip3": "Nutze Queue-Timeouts, um bei Sättigung schnell zu scheitern."
688+
},
689+
"random": {
690+
"title": "Schnelle Verteilung mit wenig Setup",
691+
"description": "Für einfache Verteilung ohne harte Garantien.",
692+
"tip1": "Nutze Modelle mit ähnlichen Latenzprofilen.",
693+
"tip2": "Lass Retries aktiv, um zufällige Fehlschläge abzufangen.",
694+
"tip3": "Gut für Experimente, nicht für strenge SLAs."
695+
},
696+
"least-used": {
697+
"title": "Adaptives Balancing",
698+
"description": "Routet zu weniger genutzten Modellen und reduziert Hotspots über Zeit.",
699+
"tip1": "Funktioniert besser bei kontinuierlichem Traffic.",
700+
"tip2": "Kombiniere mit Health Checks für sichereres Balancing.",
701+
"tip3": "Verfolge Nutzung pro Modell, um Verteilungsgewinne zu validieren."
702+
},
703+
"cost-optimized": {
704+
"title": "Kostenorientiertes Routing",
705+
"description": "Routet zu günstigeren Modellen, wenn Preisdaten verfügbar sind.",
706+
"tip1": "Sichere Preisabdeckung für alle ausgewählten Modelle.",
707+
"tip2": "Behalte einen Qualitäts-Fallback für schwierige Prompts.",
708+
"tip3": "Ideal für Batch/Hintergrundjobs, bei denen Kosten das Haupt-KPI sind."
709+
}
710+
}
650711
},
651712
"costs": {
652713
"title": "Kosten",

0 commit comments

Comments
 (0)