fix(ai): bound the provider test and explain why it failed (#3319)

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Amruth Pillai <im.amruth@gmail.com>
This commit is contained in:
Kaushik N
2026-08-16 12:45:00 +02:00
committed by GitHub
co-authored by Claude Opus 5 Amruth Pillai
parent 104e954b77
commit a4bc2693be
62 changed files with 1231 additions and 82 deletions
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "Verbonde"
msgid "Connection failed"
msgstr "Verbinding het misluk"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "Verbinding geverifieer — verskaffer is gereed vir gebruik."
@@ -4309,6 +4313,10 @@ msgstr "Statistiek"
msgid "Stay"
msgstr "Bly"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "Stop generasie"
@@ -4441,6 +4449,10 @@ msgstr "Getuigskrifte"
msgid "Testing…"
msgstr "Toetsing…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "Teksbelyning"
@@ -5399,4 +5411,3 @@ msgstr "Zoem uit"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "Zoeloe"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "ተገናኝቷል"
msgid "Connection failed"
msgstr "ግንኙነት አልተሳካም"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "ግንኙነት ተረጋግጧል - አቅራቢው ለመጠቀም ዝግጁ ነው።"
@@ -4309,6 +4313,10 @@ msgstr "ስታቲስቲክስ"
msgid "Stay"
msgstr "ቆይ"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "ማመንጨት አቁም"
@@ -4441,6 +4449,10 @@ msgstr "ምስክርነቶች"
msgid "Testing…"
msgstr "ሙከራ…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "የጽሑፍ አሰላለፍ"
@@ -5399,4 +5411,3 @@ msgstr "አጉር"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "ዙሉ"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "متصل"
msgid "Connection failed"
msgstr "فشل الاتصال"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "تم التحقق من الاتصال - المزود جاهز للاستخدام."
@@ -4309,6 +4313,10 @@ msgstr "الإحصاءات"
msgid "Stay"
msgstr "البقاء"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "أوقفوا التوليد"
@@ -4441,6 +4449,10 @@ msgstr "قصص المستخدمين"
msgid "Testing…"
msgstr "اختبار…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "محاذاة النص"
@@ -5399,4 +5411,3 @@ msgstr "تصغير"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "الزولو"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "Qoşuldu"
msgid "Connection failed"
msgstr "Bağlantı uğursuz oldu"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "Bağlantı təsdiqləndi — provayder istifadəyə hazırdır."
@@ -4309,6 +4313,10 @@ msgstr "Statistika"
msgid "Stay"
msgstr "Qal"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "Nəsil verməyi dayandırın"
@@ -4441,6 +4449,10 @@ msgstr "Rəylər"
msgid "Testing…"
msgstr "Test…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "Mətn hizalanması"
@@ -5399,4 +5411,3 @@ msgstr "Uzaqlaşdır"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "Zulu"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "Свързан"
msgid "Connection failed"
msgstr "Връзката не бе успешна"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "Връзката е потвърдена — доставчикът е готов за употреба."
@@ -4309,6 +4313,10 @@ msgstr "Статистика"
msgid "Stay"
msgstr "Остани"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "Спиране на генерирането"
@@ -4441,6 +4449,10 @@ msgstr "Отзиви"
msgid "Testing…"
msgstr "Тестване…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "Подравняване на текста"
@@ -5399,4 +5411,3 @@ msgstr "Намаляване"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "Зулуски"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "সংযুক্ত"
msgid "Connection failed"
msgstr "সংযোগ ব্যর্থ হয়েছে"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "সংযোগ যাচাই করা হয়েছে — পরিষেবা প্রদানকারী ব্যবহারের জন্য প্রস্তুত।"
@@ -4309,6 +4313,10 @@ msgstr "পরিসংখ্যান"
msgid "Stay"
msgstr "থাকুন"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "প্রজন্ম বন্ধ করুন"
@@ -4441,6 +4449,10 @@ msgstr "প্রশংসাপত্র"
msgid "Testing…"
msgstr "পরীক্ষা…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "পাঠ্য সারিবদ্ধকরণ"
@@ -5399,4 +5411,3 @@ msgstr "জুম আউট"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "জুলু"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "Connectat"
msgid "Connection failed"
msgstr "La connexió ha fallat"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "Connexió verificada: el proveïdor està a punt per utilitzar-lo."
@@ -4309,6 +4313,10 @@ msgstr "Estadístiques"
msgid "Stay"
msgstr "Queda't"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "Atura la generació"
@@ -4441,6 +4449,10 @@ msgstr "Testimonis"
msgid "Testing…"
msgstr "Proves…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "Alineació del text"
@@ -5399,4 +5411,3 @@ msgstr "Allunya"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "Zulú"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "Připojeno"
msgid "Connection failed"
msgstr "Připojení se nezdařilo"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "Připojení ověřeno poskytovatel je připraven k použití."
@@ -4309,6 +4313,10 @@ msgstr "Statistiky"
msgid "Stay"
msgstr "Zůstat"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "Zastavit generování"
@@ -4441,6 +4449,10 @@ msgstr "Reference uživatelů"
msgid "Testing…"
msgstr "Testování…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "Zarovnání textu"
@@ -5399,4 +5411,3 @@ msgstr "Oddálit"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "Zulu"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "Forbundet"
msgid "Connection failed"
msgstr "Forbindelsen mislykkedes"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "Forbindelse bekræftet — udbyderen er klar til brug."
@@ -4309,6 +4313,10 @@ msgstr "Statistik"
msgid "Stay"
msgstr "Bliv"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "Stop generation"
@@ -4441,6 +4449,10 @@ msgstr "Udtalelser"
msgid "Testing…"
msgstr "Test…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "Tekstjustering"
@@ -5399,4 +5411,3 @@ msgstr "Zoom ud"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "Zulu"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "Verbunden"
msgid "Connection failed"
msgstr "Verbindung fehlgeschlagen"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "Verbindung bestätigt der Anbieter ist einsatzbereit."
@@ -4309,6 +4313,10 @@ msgstr "Statistiken"
msgid "Stay"
msgstr "Hier bleiben"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "Stoppt die Stromerzeugung"
@@ -4441,6 +4449,10 @@ msgstr "Erfahrungsberichte"
msgid "Testing…"
msgstr "Testen…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "Textausrichtung"
@@ -5399,4 +5411,3 @@ msgstr "Herauszoomen"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "Zulu"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "Συνδεδεμένος"
msgid "Connection failed"
msgstr "Η σύνδεση απέτυχε"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "Η σύνδεση επαληθεύτηκε — ο πάροχος είναι έτοιμος για χρήση."
@@ -4309,6 +4313,10 @@ msgstr "Στατιστικά"
msgid "Stay"
msgstr "Παραμονή"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "Διακοπή δημιουργίας"
@@ -4441,6 +4449,10 @@ msgstr "Αναφορές πελατών"
msgid "Testing…"
msgstr "Δοκιμή…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "Στοίχιση κειμένου"
@@ -5399,4 +5411,3 @@ msgstr "Σμίκρυνση"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "Ζουλού"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "Connected"
msgid "Connection failed"
msgstr "Connection failed"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "Connection verified — provider is ready to use."
@@ -4309,6 +4313,10 @@ msgstr "Statistics"
msgid "Stay"
msgstr "Stay"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "Stop generation"
@@ -4441,6 +4449,10 @@ msgstr "Testimonials"
msgid "Testing…"
msgstr "Testing…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "Text alignment"
@@ -5399,4 +5411,3 @@ msgstr "Zoom out"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "Zulu"
+12
View File
@@ -980,6 +980,10 @@ msgstr "Connected"
msgid "Connection failed"
msgstr "Connection failed"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr "Connection failed."
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "Connection verified — provider is ready to use."
@@ -4304,6 +4308,10 @@ msgstr "Statistics"
msgid "Stay"
msgstr "Stay"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr "Still waiting for {provider}… {elapsedSeconds}s"
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "Stop generation"
@@ -4436,6 +4444,10 @@ msgstr "Testimonials"
msgid "Testing…"
msgstr "Testing…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr "Testing… {elapsedSeconds}s"
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "Text alignment"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "Conectado"
msgid "Connection failed"
msgstr "Falló la conexión"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "Conexión verificada: el proveedor está listo para usarse."
@@ -4309,6 +4313,10 @@ msgstr "Estadísticas"
msgid "Stay"
msgstr "Continuar"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "Detener la generación"
@@ -4441,6 +4449,10 @@ msgstr "Testimonios"
msgid "Testing…"
msgstr "Probando…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "Alineación del texto"
@@ -5399,4 +5411,3 @@ msgstr "Alejar"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "Zulú"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "متصل"
msgid "Connection failed"
msgstr "اتصال ناموفق بود"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "اتصال تأیید شد - ارائه دهنده آماده استفاده است."
@@ -4309,6 +4313,10 @@ msgstr "آمارها"
msgid "Stay"
msgstr "ماندن"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "توقف تولید"
@@ -4441,6 +4449,10 @@ msgstr "نظرات کاربران"
msgid "Testing…"
msgstr "در حال آزمایش…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "ترازبندی متن"
@@ -5399,4 +5411,3 @@ msgstr "کوچک‌نمایی"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "زولو"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "Yhdistetty"
msgid "Connection failed"
msgstr "Yhteys epäonnistui"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "Yhteys vahvistettu — palveluntarjoaja on käyttövalmis."
@@ -4309,6 +4313,10 @@ msgstr "Tilastot"
msgid "Stay"
msgstr "Pysy"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "Lopeta sukupolvi"
@@ -4441,6 +4449,10 @@ msgstr "Suosittelut"
msgid "Testing…"
msgstr "Testaus…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "Tekstin tasaus"
@@ -5399,4 +5411,3 @@ msgstr "Loitonna"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "Zulu"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "Connecté"
msgid "Connection failed"
msgstr "Échec de la connexion"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "Connexion vérifiée — le fournisseur est prêt à l'emploi."
@@ -4309,6 +4313,10 @@ msgstr "Statistiques"
msgid "Stay"
msgstr "Rester"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "Génération stop"
@@ -4441,6 +4449,10 @@ msgstr "Témoignages"
msgid "Testing…"
msgstr "Test…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "Alignement du texte"
@@ -5399,4 +5411,3 @@ msgstr "Zoom arrière"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "Zoulou"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "מְחוּבָּר"
msgid "Connection failed"
msgstr "החיבור נכשל"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "החיבור אומת - הספק מוכן לשימוש."
@@ -4309,6 +4313,10 @@ msgstr "סטטיסטיקה"
msgid "Stay"
msgstr "הישאר"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "עצירת הדור"
@@ -4441,6 +4449,10 @@ msgstr "המלצות"
msgid "Testing…"
msgstr "בדיקות…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "יישור טקסט"
@@ -5399,4 +5411,3 @@ msgstr "התרחקות"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "זולו"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "जुड़े हुए"
msgid "Connection failed"
msgstr "कनेक्शन विफल"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "कनेक्शन सत्यापित हो गया है — सेवा प्रदाता उपयोग के लिए तैयार है।"
@@ -4309,6 +4313,10 @@ msgstr "आंकड़े"
msgid "Stay"
msgstr "रहें"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "पीढ़ी को रोकें"
@@ -4441,6 +4449,10 @@ msgstr "प्रशंसापत्र"
msgid "Testing…"
msgstr "परीक्षण…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "पाठ संरेखण"
@@ -5399,4 +5411,3 @@ msgstr "ज़ूम आउट"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "ज़ुलु"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "Csatlakoztatva"
msgid "Connection failed"
msgstr "Kapcsolódás sikertelen"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "Kapcsolat ellenőrizve a szolgáltató használatra kész."
@@ -4309,6 +4313,10 @@ msgstr "Statisztikák"
msgid "Stay"
msgstr "Maradás"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "Állítsa le a generációt"
@@ -4441,6 +4449,10 @@ msgstr "Visszajelzések"
msgid "Testing…"
msgstr "Tesztelés…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "Szöveg igazítása"
@@ -5399,4 +5411,3 @@ msgstr "Kicsinyítés"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "Zulu"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "Terhubung"
msgid "Connection failed"
msgstr "Koneksi gagal"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "Koneksi terverifikasi — penyedia siap digunakan."
@@ -4309,6 +4313,10 @@ msgstr "Statistik"
msgid "Stay"
msgstr "Tetap"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "Hentikan pembangkitan"
@@ -4441,6 +4449,10 @@ msgstr "Testimoni"
msgid "Testing…"
msgstr "Pengujian…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "Penyelarasan teks"
@@ -5399,4 +5411,3 @@ msgstr "Perkecil"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "Zulu"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "Collegato"
msgid "Connection failed"
msgstr "Connessione fallita"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "Connessione verificata: il provider è pronto all'uso."
@@ -4309,6 +4313,10 @@ msgstr "Statistiche"
msgid "Stay"
msgstr "Rimani"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "Interrompere la generazione"
@@ -4441,6 +4449,10 @@ msgstr "Testimonial"
msgid "Testing…"
msgstr "Test…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "Allineamento del testo"
@@ -5399,4 +5411,3 @@ msgstr "Rimpicciolisci"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "Zulu"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "接続済み"
msgid "Connection failed"
msgstr "接続に失敗しました"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "接続確認済み — プロバイダは使用可能です。"
@@ -4309,6 +4313,10 @@ msgstr "統計"
msgid "Stay"
msgstr "このまま"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "生成を停止"
@@ -4441,6 +4449,10 @@ msgstr "ユーザーの声"
msgid "Testing…"
msgstr "テスト…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "テキストの配置"
@@ -5399,4 +5411,3 @@ msgstr "ズームアウト"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "ズールー語"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "បានភ្ជាប់"
msgid "Connection failed"
msgstr "ការតភ្ជាប់បរាជ័យ"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "ការភ្ជាប់ត្រូវបានផ្ទៀងផ្ទាត់ — អ្នកផ្តល់សេវារួចរាល់សម្រាប់ប្រើប្រាស់។"
@@ -4309,6 +4313,10 @@ msgstr "ស្ថិតិ"
msgid "Stay"
msgstr "ស្ថិត"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "បញ្ឈប់ការបង្កើត"
@@ -4441,6 +4449,10 @@ msgstr "សក្ខីកម្ម"
msgid "Testing…"
msgstr "កំពុងសាកល្បង…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "ការតម្រឹមអត្ថបទ"
@@ -5399,4 +5411,3 @@ msgstr "បង្រួម"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "Zulu"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "ಸಂಪರ್ಕಿಸಲಾಗಿದೆ"
msgid "Connection failed"
msgstr "ಸಂಪರ್ಕ ವಿಫಲವಾಗಿದೆ"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "ಸಂಪರ್ಕವನ್ನು ಪರಿಶೀಲಿಸಲಾಗಿದೆ — ಪೂರೈಕೆದಾರರು ಬಳಸಲು ಸಿದ್ಧರಾಗಿದ್ದಾರೆ."
@@ -4309,6 +4313,10 @@ msgstr "ಅಂಕಿಅಂಶಗಳು"
msgid "Stay"
msgstr "ಇರಿ"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "ಪೀಳಿಗೆಯನ್ನು ನಿಲ್ಲಿಸಿ"
@@ -4441,6 +4449,10 @@ msgstr "ಪ್ರಶಂಸಾಪತ್ರಗಳು"
msgid "Testing…"
msgstr "… ಪರೀಕ್ಷಿಸಲಾಗುತ್ತಿದೆ"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "ಪಠ್ಯ ಜೋಡಣೆ"
@@ -5399,4 +5411,3 @@ msgstr "ಗಾತ್ರ ಕುಗ್ಗಿಸಿ"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "ಜೂಲೂ"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "연결됨"
msgid "Connection failed"
msgstr "연결 실패"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "연결이 확인되었습니다. 공급자를 사용할 준비가 되었습니다."
@@ -4309,6 +4313,10 @@ msgstr "통계"
msgid "Stay"
msgstr "머물기"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "세대 중단"
@@ -4441,6 +4449,10 @@ msgstr "후기"
msgid "Testing…"
msgstr "테스트…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "텍스트 정렬"
@@ -5399,4 +5411,3 @@ msgstr "축소"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "줄루어"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "Prijungtas"
msgid "Connection failed"
msgstr "Ryšys nepavyko"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "Ryšys patvirtintas tiekėjas paruoštas naudoti."
@@ -4309,6 +4313,10 @@ msgstr "Statistika"
msgid "Stay"
msgstr "Likti"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "Sustabdyti generavimą"
@@ -4441,6 +4449,10 @@ msgstr "Atsiliepimai"
msgid "Testing…"
msgstr "Testavimas…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "Teksto lygiavimas"
@@ -5399,4 +5411,3 @@ msgstr "Tolinti"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "Zulų"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "Savienots"
msgid "Connection failed"
msgstr "Savienojums neizdevās"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "Savienojums ir pārbaudīts — pakalpojumu sniedzējs ir gatavs lietošanai."
@@ -4309,6 +4313,10 @@ msgstr "Statistika"
msgid "Stay"
msgstr "Palikt"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "Apturēt paaudzi"
@@ -4441,6 +4449,10 @@ msgstr "Atsauksmes"
msgid "Testing…"
msgstr "Testēšana…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "Teksta izlīdzināšana"
@@ -5399,4 +5411,3 @@ msgstr "Tālināt"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "Zulu"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "ബന്ധിപ്പിച്ചു"
msgid "Connection failed"
msgstr "കണക്ഷൻ പരാജയപ്പെട്ടു"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "കണക്ഷൻ സ്ഥിരീകരിച്ചു — ദാതാവ് ഉപയോഗിക്കാൻ തയ്യാറാണ്."
@@ -4309,6 +4313,10 @@ msgstr "സ്റ്റാറ്റിസ്റ്റിക്സ്"
msgid "Stay"
msgstr "തുടരുക"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "ജനറേഷൻ നിർത്തുക"
@@ -4441,6 +4449,10 @@ msgstr "ടെസ്റ്റിമോണിയലുകൾ"
msgid "Testing…"
msgstr "… പരിശോധിക്കുന്നു"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "വാചക വിന്യാസം"
@@ -5399,4 +5411,3 @@ msgstr "സൂം ഔട്ട് ചെയ്യുക"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "സൂളു"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "जोडलेले"
msgid "Connection failed"
msgstr "कनेक्शन अयशस्वी झाले."
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "कनेक्शन सत्यापित झाले आहे — प्रोव्हायडर वापरासाठी तयार आहे."
@@ -4309,6 +4313,10 @@ msgstr "आकडेवारी"
msgid "Stay"
msgstr "राहा"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "पिढी थांबवा"
@@ -4441,6 +4449,10 @@ msgstr "प्रशस्तिपत्रे"
msgid "Testing…"
msgstr "चाचणी…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "मजकूर संरेखन"
@@ -5399,4 +5411,3 @@ msgstr "बाहेर झूम करा"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "झुलू"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "Bersambung"
msgid "Connection failed"
msgstr "Sambungan gagal"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "Sambungan disahkan — pembekal sedia untuk digunakan."
@@ -4309,6 +4313,10 @@ msgstr "Statistik"
msgid "Stay"
msgstr "Kekal"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "Hentikan penjanaan"
@@ -4441,6 +4449,10 @@ msgstr "Testimoni"
msgid "Testing…"
msgstr "Pengujian…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "Penjajaran teks"
@@ -5399,4 +5411,3 @@ msgstr "Zum keluar"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "Zulu"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "जडित"
msgid "Connection failed"
msgstr "जडान असफल भयो"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "जडान प्रमाणित भयो — प्रदायक प्रयोगको लागि तयार छ।"
@@ -4309,6 +4313,10 @@ msgstr "तथ्याङ्क (Statistics)"
msgid "Stay"
msgstr "रहनुहोस्"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "उत्पादन रोक्नुहोस्"
@@ -4441,6 +4449,10 @@ msgstr "अनुभव कथनहरू (Testimonials)"
msgid "Testing…"
msgstr "परीक्षण…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "पाठ पङ्क्तिबद्धता"
@@ -5399,4 +5411,3 @@ msgstr "जूम आउट"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "जुलु"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "Aangesloten"
msgid "Connection failed"
msgstr "Verbinding mislukt"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "Verbinding geverifieerd — provider is klaar voor gebruik."
@@ -4309,6 +4313,10 @@ msgstr "Statistieken"
msgid "Stay"
msgstr "Blijven"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "Stop de generatie"
@@ -4441,6 +4449,10 @@ msgstr "Getuigenissen"
msgid "Testing…"
msgstr "Testen…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "Tekstuitlijning"
@@ -5399,4 +5411,3 @@ msgstr "Uitzoomen"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "Zulu"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "Tilkoblet"
msgid "Connection failed"
msgstr "Tilkoblingen mislyktes"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "Tilkobling bekreftet leverandøren er klar til bruk."
@@ -4309,6 +4313,10 @@ msgstr "Statistikk"
msgid "Stay"
msgstr "Bli"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "Stopp generering"
@@ -4441,6 +4449,10 @@ msgstr "Uttalelser"
msgid "Testing…"
msgstr "Testing…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "Tekstjustering"
@@ -5399,4 +5411,3 @@ msgstr "Zoom ut"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "Zulu"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "ସଂଯୁକ୍ତ"
msgid "Connection failed"
msgstr "ସଂଯୋଗ ବିଫଳ ହୋଇଛି"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "ସଂଯୋଗ ଯାଞ୍ଚ ହୋଇଛି — ପ୍ରଦାତା ବ୍ୟବହାର କରିବାକୁ ପ୍ରସ୍ତୁତ।"
@@ -4309,6 +4313,10 @@ msgstr "ସଂଖ୍ୟାତ୍ମକ ତଥ୍ୟ"
msgid "Stay"
msgstr "ରୁହନ୍ତୁ"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "ପିଢ଼ିବା ବନ୍ଦ କରନ୍ତୁ"
@@ -4441,6 +4449,10 @@ msgstr "ଟେଷ୍ଟିମୋନିଆଲ୍‌ଗୁଡିକ"
msgid "Testing…"
msgstr "ପରୀକ୍ଷଣ…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "ଟେକ୍ସଟ୍ ଶ୍ରେଣୀବଦ୍ଧତା"
@@ -5399,4 +5411,3 @@ msgstr "ଜୁମ୍ ଆଉଟ୍ କରନ୍ତୁ"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "ଜୁଲୁ"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "Połączony"
msgid "Connection failed"
msgstr "Połączenie nieudane"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "Połączenie zweryfikowane — dostawca jest gotowy do użycia."
@@ -4309,6 +4313,10 @@ msgstr "Statystyki"
msgid "Stay"
msgstr "Zostań"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "Zatrzymaj generację"
@@ -4441,6 +4449,10 @@ msgstr "Referencje"
msgid "Testing…"
msgstr "Testowanie…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "Wyrównanie tekstu"
@@ -5399,4 +5411,3 @@ msgstr "Pomniejsz"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "Zulu"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "Conectado"
msgid "Connection failed"
msgstr "Falha na conexão"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "Conexão verificada — o provedor está pronto para uso."
@@ -4309,6 +4313,10 @@ msgstr "Estatísticas"
msgid "Stay"
msgstr "Ficar"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "Pare a geração"
@@ -4441,6 +4449,10 @@ msgstr "Depoimentos"
msgid "Testing…"
msgstr "Testando…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "Alinhamento de texto"
@@ -5399,4 +5411,3 @@ msgstr "Diminuir zoom"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "Zulu"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "Conectado"
msgid "Connection failed"
msgstr "Falha na ligação"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "Ligação verificada — o fornecedor está pronto a utilizar."
@@ -4309,6 +4313,10 @@ msgstr "Estatísticas"
msgid "Stay"
msgstr "Ficar"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "Pare a geração"
@@ -4441,6 +4449,10 @@ msgstr "Testemunhos"
msgid "Testing…"
msgstr "A testar…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "Alinhamento de texto"
@@ -5399,4 +5411,3 @@ msgstr "Afastar"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "Zulu"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "Conectat"
msgid "Connection failed"
msgstr "Conexiunea a eșuat"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "Conexiune verificată — furnizorul este gata de utilizare."
@@ -4309,6 +4313,10 @@ msgstr "Statistici"
msgid "Stay"
msgstr "Rămâi"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "Opriți generarea"
@@ -4441,6 +4449,10 @@ msgstr "Testimoniale"
msgid "Testing…"
msgstr "Testarea…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "Alinierea textului"
@@ -5399,4 +5411,3 @@ msgstr "Micșorează"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "Zulu"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "Подключено"
msgid "Connection failed"
msgstr "Соединение не удалось."
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "Соединение подтверждено — провайдер готов к использованию."
@@ -4309,6 +4313,10 @@ msgstr "Статистика"
msgid "Stay"
msgstr "Остаться"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "Остановить поколение"
@@ -4441,6 +4449,10 @@ msgstr "Отзывы"
msgid "Testing…"
msgstr "Тестирование…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "выравнивание текста"
@@ -5399,4 +5411,3 @@ msgstr "Уменьшить"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "Зулу"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "Pripojené"
msgid "Connection failed"
msgstr "Pripojenie zlyhalo"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "Pripojenie overené poskytovateľ je pripravený na použitie."
@@ -4309,6 +4313,10 @@ msgstr "Štatistiky"
msgid "Stay"
msgstr "Zostať"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "Zastaviť generovanie"
@@ -4441,6 +4449,10 @@ msgstr "Referencie používateľov"
msgid "Testing…"
msgstr "Testovanie…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "Zarovnanie textu"
@@ -5399,4 +5411,3 @@ msgstr "Oddialiť"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "Zulu"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "Povezan"
msgid "Connection failed"
msgstr "Povezava ni uspela"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "Povezava preverjena ponudnik je pripravljen za uporabo."
@@ -4309,6 +4313,10 @@ msgstr "Statistika"
msgid "Stay"
msgstr "Ostani"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "Ustavi generiranje"
@@ -4441,6 +4449,10 @@ msgstr "Pričevanja"
msgid "Testing…"
msgstr "Testiranje…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "Poravnava besedila"
@@ -5399,4 +5411,3 @@ msgstr "Oddalji"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "Zuluščina"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "I lidhur"
msgid "Connection failed"
msgstr "Lidhja dështoi"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "Lidhja u verifikua — ofruesi është gati për përdorim."
@@ -4309,6 +4313,10 @@ msgstr "Statistikat"
msgid "Stay"
msgstr "Qëndro"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "Ndalo gjenerimin"
@@ -4441,6 +4449,10 @@ msgstr "Dëshmitë"
msgid "Testing…"
msgstr "Testimi…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "Rreshtimi i tekstit"
@@ -5399,4 +5411,3 @@ msgstr "Zvogëlo"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "Zulu"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "Повезано"
msgid "Connection failed"
msgstr "Повезивање није успело"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "Веза је верификована — провајдер је спреман за употребу."
@@ -4309,6 +4313,10 @@ msgstr "Статистика"
msgid "Stay"
msgstr "Остани"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "Заустави генерисање"
@@ -4441,6 +4449,10 @@ msgstr "Сведочења"
msgid "Testing…"
msgstr "Тестирање…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "Поравнање текста"
@@ -5399,4 +5411,3 @@ msgstr "Умањи"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "Зулу"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "Ansluten"
msgid "Connection failed"
msgstr "Anslutningen misslyckades"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "Anslutning verifierad — leverantören är klar att användas."
@@ -4309,6 +4313,10 @@ msgstr "Statistik"
msgid "Stay"
msgstr "Stanna"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "Stoppa genereringen"
@@ -4441,6 +4449,10 @@ msgstr "Vittnesmål"
msgid "Testing…"
msgstr "Testning…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "Textjustering"
@@ -5399,4 +5411,3 @@ msgstr "Zooma ut"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "Zulu"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "இணைக்கப்பட்டது"
msgid "Connection failed"
msgstr "இணைப்பு தோல்வியடைந்தது"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "இணைப்பு சரிபார்க்கப்பட்டது — சேவை வழங்குநர் பயன்பாட்டிற்குத் தயாராக உள்ளது."
@@ -4309,6 +4313,10 @@ msgstr "புள்ளிவிபரங்கள்"
msgid "Stay"
msgstr "தங்கு"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "நிறுத்த உருவாக்கம்"
@@ -4441,6 +4449,10 @@ msgstr "சான்றுரைகள்"
msgid "Testing…"
msgstr "சோதனை…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "உரை சீரமைப்பு"
@@ -5399,4 +5411,3 @@ msgstr "சிறிதாக்கு"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "ஜூலு"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "కనెక్ట్ చేయబడింది"
msgid "Connection failed"
msgstr "కనెక్షన్ విఫలమైంది"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "కనెక్షన్ ధృవీకరించబడింది — ప్రొవైడర్ ఉపయోగించడానికి సిద్ధంగా ఉంది."
@@ -4309,6 +4313,10 @@ msgstr "స్టాటిస్టిక్స్"
msgid "Stay"
msgstr "ఉండు"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "తరాన్ని ఆపండి"
@@ -4441,6 +4449,10 @@ msgstr "టెస్టిమోనియల్స్"
msgid "Testing…"
msgstr "…ని పరీక్షిస్తోంది"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "టెక్స్ట్ అమరిక"
@@ -5399,4 +5411,3 @@ msgstr "జూమ్ అవుట్ చేయండి"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "జులు"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "เชื่อมต่อแล้ว"
msgid "Connection failed"
msgstr "การเชื่อมต่อล้มเหลว"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "การเชื่อมต่อได้รับการยืนยันแล้ว — ผู้ให้บริการพร้อมใช้งาน"
@@ -4309,6 +4313,10 @@ msgstr "สถิติ"
msgid "Stay"
msgstr "อยู่ต่อ"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "หยุดการสร้าง"
@@ -4441,6 +4449,10 @@ msgstr "คำรับรอง"
msgid "Testing…"
msgstr "กำลังทดสอบ…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "การจัดตำแหน่งข้อความ"
@@ -5399,4 +5411,3 @@ msgstr "ซูมออก"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "ซูลู"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "Bağlı"
msgid "Connection failed"
msgstr "Bağlantı başarısız oldu."
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "Bağlantı doğrulandı — sağlayıcı kullanıma hazır."
@@ -4309,6 +4313,10 @@ msgstr "İstatistikler"
msgid "Stay"
msgstr "Kal"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "Üretimi durdurun"
@@ -4441,6 +4449,10 @@ msgstr "Görüşler"
msgid "Testing…"
msgstr "Test ediliyor…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "Metin hizalaması"
@@ -5399,4 +5411,3 @@ msgstr "Uzaklaştır"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "Zulu"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "Підключено"
msgid "Connection failed"
msgstr "Помилка підключення"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "З’єднання перевірено — провайдер готовий до використання."
@@ -4309,6 +4313,10 @@ msgstr "Статистика"
msgid "Stay"
msgstr "Залишитись"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "Зупинити генерацію"
@@ -4441,6 +4449,10 @@ msgstr "Відгуки"
msgid "Testing…"
msgstr "Тестування…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "Вирівнювання тексту"
@@ -5399,4 +5411,3 @@ msgstr "Зменшити"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "Зулу"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "Ulangan"
msgid "Connection failed"
msgstr "Ulanish amalga oshmadi"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "Ulanish tasdiqlandi — provayder foydalanishga tayyor."
@@ -4309,6 +4313,10 @@ msgstr "Statistika"
msgid "Stay"
msgstr "Qolish"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "Avlodni to'xtatish"
@@ -4441,6 +4449,10 @@ msgstr "Fikr-mulohazalar"
msgid "Testing…"
msgstr "Sinov…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "Matnni tekislash"
@@ -5399,4 +5411,3 @@ msgstr "Kichraytirish"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "Zulu"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "Đã kết nối"
msgid "Connection failed"
msgstr "Kết nối thất bại"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "Kết nối đã được xác nhận — nhà cung cấp đã sẵn sàng sử dụng."
@@ -4309,6 +4313,10 @@ msgstr "Thống kê"
msgid "Stay"
msgstr "Ở lại"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "Ngừng sản xuất"
@@ -4441,6 +4449,10 @@ msgstr "Lời nhận xét"
msgid "Testing…"
msgstr "Đang kiểm tra…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "Căn chỉnh văn bản"
@@ -5399,4 +5411,3 @@ msgstr "Thu nhỏ"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "Zulu"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "已连接"
msgid "Connection failed"
msgstr "连接失败"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "连接已验证——服务提供商已准备就绪。"
@@ -4309,6 +4313,10 @@ msgstr "统计数据"
msgid "Stay"
msgstr "留下"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "停止生成"
@@ -4441,6 +4449,10 @@ msgstr "客户评价"
msgid "Testing…"
msgstr "测试…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "文本对齐"
@@ -5399,4 +5411,3 @@ msgstr "缩小"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "祖鲁语"
+12 -1
View File
@@ -985,6 +985,10 @@ msgstr "已連接"
msgid "Connection failed"
msgstr "連線失敗"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr "連線已驗證-服務提供者已準備就緒。"
@@ -4309,6 +4313,10 @@ msgstr "統計資料"
msgid "Stay"
msgstr "留下"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr "停止生成"
@@ -4441,6 +4449,10 @@ msgstr "用戶評價"
msgid "Testing…"
msgstr "測試…"
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr "文字對齊"
@@ -5399,4 +5411,3 @@ msgstr "縮小"
#: src/libs/locale.ts
msgid "Zulu"
msgstr "祖魯語"
+12
View File
@@ -980,6 +980,10 @@ msgstr ""
msgid "Connection failed"
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection failed."
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Connection verified — provider is ready to use."
msgstr ""
@@ -4304,6 +4308,10 @@ msgstr ""
msgid "Stay"
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Still waiting for {provider}… {elapsedSeconds}s"
msgstr ""
#: src/routes/agent/-components/agent-chat.tsx
msgid "Stop generation"
msgstr ""
@@ -4436,6 +4444,10 @@ msgstr ""
msgid "Testing…"
msgstr ""
#: src/features/settings/integrations/components/ai-section.tsx
msgid "Testing… {elapsedSeconds}s"
msgstr ""
#: src/components/input/rich-input.tsx
msgid "Text alignment"
msgstr ""
@@ -4,6 +4,7 @@ import { fireEvent, render, screen, waitFor } from "@testing-library/react";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { i18n } from "@lingui/core";
import { I18nProvider } from "@lingui/react";
import { toast } from "sonner";
type MutationName = "create" | "test" | "update" | "delete";
@@ -191,6 +192,35 @@ describe("AISettingsSection", () => {
expect(updater([created])).toEqual([tested]);
});
// The server returns a provider-side failure as data (see the API package's e2e coverage), so the
// reason has to reach the card rather than being flattened into a generic transport error.
it("shows the server's reason on the card and keeps the toast to the outcome", async () => {
const failed = provider({
enabled: false,
testStatus: "failure",
testError: "OpenAI rejected the API key.",
lastTestedAt: new Date("2026-08-15T00:00:00Z"),
});
providers.data = [provider({})];
mutations.test.mockResolvedValue(failed);
renderSection();
fireEvent.click(screen.getByRole("button", { name: "Test" }));
await waitFor(() => expect(toast.error).toHaveBeenCalled());
// Toast reports only the outcome; the card carries the detail.
expect(toast.error).toHaveBeenCalledWith("Connection failed.");
expect(toast.error).not.toHaveBeenCalledWith(expect.stringContaining("rejected the API key"));
providers.data = [failed];
renderSection();
expect(screen.getAllByText("OpenAI rejected the API key.").length).toBeGreaterThan(0);
expect(screen.getAllByText("Connection failed").length).toBeGreaterThan(0);
});
it("updates a configured provider's model", async () => {
providers.data = [provider({})];
mutations.update.mockResolvedValue(provider({ model: "gpt-5-mini", testStatus: "untested", enabled: false }));
@@ -14,7 +14,7 @@ import {
XCircleIcon,
} from "@phosphor-icons/react";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { useMemo, useState } from "react";
import { useEffect, useMemo, useState } from "react";
import { toast } from "sonner";
import { AI_PROVIDER_DEFAULT_BASE_URLS } from "@reactive-resume/ai/types";
import { Badge } from "@reactive-resume/ui/components/badge";
@@ -193,6 +193,36 @@ function providerLabel(provider: AIProvider) {
return providerOptions.find((option) => option.value === provider)?.label ?? provider;
}
// A provider test can legitimately take tens of seconds against a cold local model. Without a sense
// of time passing, a bare spinner reads as a freeze, so start narrating the wait once it gets long.
const SHOW_ELAPSED_AFTER_SECONDS = 5;
const STILL_WAITING_AFTER_SECONDS = 20;
function useElapsedSeconds(isRunning: boolean) {
const [seconds, setSeconds] = useState(0);
useEffect(() => {
if (!isRunning) {
setSeconds(0);
return;
}
const startedAt = Date.now();
const interval = setInterval(() => setSeconds(Math.floor((Date.now() - startedAt) / 1000)), 1000);
return () => clearInterval(interval);
}, [isRunning]);
return seconds;
}
function testingLabel(elapsedSeconds: number, provider: string) {
if (elapsedSeconds >= STILL_WAITING_AFTER_SECONDS) return t`Still waiting for ${provider}${elapsedSeconds}s`;
if (elapsedSeconds >= SHOW_ELAPSED_AFTER_SECONDS) return t`Testing… ${elapsedSeconds}s`;
return null;
}
function upsertProvider(providers: SavedProvider[] | undefined, provider: SavedProvider) {
if (!providers) return [provider];
if (!providers.some((entry) => entry.id === provider.id)) return [...providers, provider];
@@ -217,6 +247,8 @@ function ProviderRow({ provider }: ProviderRowProps) {
const { mutate: updateProvider, isPending: isUpdating } = useMutation(orpc.aiProviders.update.mutationOptions());
const { mutate: deleteProvider, isPending: isDeleting } = useMutation(orpc.aiProviders.delete.mutationOptions());
const isMutating = isTesting || isUpdating || isDeleting;
const testElapsedSeconds = useElapsedSeconds(isTesting);
const testLabel = testingLabel(testElapsedSeconds, String(providerLabel(provider.provider)));
const saveModel = () => {
const nextModel = model.trim();
if (!nextModel || nextModel === provider.model) {
@@ -314,7 +346,8 @@ function ProviderRow({ provider }: ProviderRowProps) {
if (response.testStatus === "success") {
toast.success(t`Provider connection verified.`);
} else {
toast.error(response.testError ?? t`Could not verify provider connection.`);
// The reason persists on the card below, so the toast only reports the outcome.
toast.error(t`Connection failed.`);
}
void invalidate();
},
@@ -327,7 +360,7 @@ function ProviderRow({ provider }: ProviderRowProps) {
}
>
{isTesting ? <Spinner /> : provider.testStatus === "success" ? <CheckCircleIcon /> : <WarningCircleIcon />}
<Trans>Test</Trans>
{testLabel ?? <Trans>Test</Trans>}
</Button>
<Button
@@ -393,6 +426,7 @@ function CreateProviderForm() {
orpc.aiProviders.test.mutationOptions({ meta: { noInvalidate: true } }),
);
const isSaving = isCreating || isTesting;
const testElapsedSeconds = useElapsedSeconds(isTesting);
// Model/label are prefilled from provider defaults, so step 1 (Provider + API Key) is enough to save.
const model = form.model.trim();
@@ -559,7 +593,13 @@ function CreateProviderForm() {
<div className="mt-4 flex justify-end">
<Button disabled={!canSave || isSaving} onClick={() => void save()}>
{isSaving ? <Spinner /> : <KeyIcon />}
{isTesting ? <Trans>Testing</Trans> : <Trans>Save & Test Provider</Trans>}
{isTesting ? (
(testingLabel(testElapsedSeconds, String(selectedOption?.label ?? form.provider)) ?? (
<Trans>Testing</Trans>
))
) : (
<Trans>Save & Test Provider</Trans>
)}
</Button>
</div>
</div>
+21
View File
@@ -41,3 +41,24 @@ export const AI_PROVIDER_DEFAULT_BASE_URLS: Record<AIProvider, string> = {
ollama: "https://ollama.com/api",
"openai-compatible": "",
};
// Brand names, used when a message has to name the provider outside a translated UI string. Every
// such message opens with this value, so the generic fallback is capitalised to match.
export const AI_PROVIDER_DISPLAY_NAMES: Record<AIProvider, string> = {
openai: "OpenAI",
anthropic: "Anthropic",
gemini: "Google Gemini",
"vercel-ai-gateway": "Vercel AI Gateway",
openrouter: "OpenRouter",
mistral: "Mistral",
cohere: "Cohere",
xai: "xAI",
groq: "Groq",
deepseek: "DeepSeek",
togetherai: "Together AI",
fireworks: "Fireworks AI",
cerebras: "Cerebras",
perplexity: "Perplexity",
ollama: "Ollama",
"openai-compatible": "The provider",
};
@@ -0,0 +1,203 @@
/**
* End-to-end coverage for the provider connection test.
*
* Everything from the oRPC procedure down is the real thing: the router (including its auth
* middleware and error mapping), the service, `testConnection`, the failure classifier, and the
* AES-GCM credential encryption. Only the database and the outbound HTTP call are substituted
* the database with an in-memory row store, the provider with a stubbed `fetch`.
*/
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { createRouterClient } from "@orpc/server";
const { dbMock, dbState } = vi.hoisted(() => {
const state = { rows: [] as Record<string, unknown>[] };
const selectChain = {
from: () => selectChain,
where: () => selectChain,
orderBy: async () => state.rows,
limit: async () => state.rows,
};
const db = {
select: () => selectChain,
update: () => ({
set: (values: Record<string, unknown>) => ({
where: () => {
const applied = state.rows.map((row) => Object.assign(row, values));
return Object.assign(Promise.resolve(applied), { returning: async () => applied });
},
}),
}),
};
return { dbMock: db, dbState: state };
});
vi.mock("@reactive-resume/db/client", () => ({ db: dbMock }));
vi.mock("@reactive-resume/db/schema", () => ({
aiProvider: { id: "ai_provider.id", userId: "ai_provider.user_id" },
user: { id: "user.id" },
}));
vi.mock("drizzle-orm", () => ({
and: (...conditions: unknown[]) => ({ conditions }),
asc: (value: unknown) => ({ value }),
desc: (value: unknown) => ({ value }),
eq: (left: unknown, right: unknown) => ({ left, right }),
sql: () => ({}),
}));
// Real AES-GCM credential encryption runs; it only needs a secret.
vi.mock("@reactive-resume/env/server", () => ({
env: { ENCRYPTION_SECRET: "e2e-encryption-secret", FLAG_ALLOW_UNSAFE_AI_BASE_URL: true },
}));
vi.mock("@reactive-resume/auth/config", () => ({
auth: {
api: {
getSession: async () => ({ user: { id: "user-1", email: "kaushik@example.test" } }),
verifyApiKey: async () => ({ valid: false, key: null }),
},
},
verifyOAuthToken: async () => null,
}));
const { aiProvidersRouter } = await import("./router");
const { encryptCredential } = await import("../ai/credentials");
const client = createRouterClient(aiProvidersRouter, {
context: { locale: "en-US" as const, reqHeaders: new Headers() },
});
function seedProvider(overrides: Record<string, unknown> = {}) {
const credential = encryptCredential("sk-live-demo-key-1234");
dbState.rows = [
{
id: "provider-1",
userId: "user-1",
label: "My provider",
provider: "openai",
model: "gpt-4.1",
baseUrl: "https://api.openai.test/v1",
enabled: false,
testStatus: "untested",
testError: null,
lastTestedAt: null,
lastUsedAt: null,
createdAt: new Date("2026-08-01T00:00:00Z"),
updatedAt: new Date("2026-08-01T00:00:00Z"),
...credential,
...overrides,
},
];
}
function stubProvider(status: number, body: unknown) {
const fetchMock = vi.fn(
() =>
new Response(typeof body === "string" ? body : JSON.stringify(body), {
status,
headers: { "Content-Type": "application/json" },
}),
);
vi.stubGlobal("fetch", fetchMock);
return fetchMock;
}
function chatCompletion(content: string) {
return {
id: "chatcmpl-1",
object: "chat.completion",
created: 1,
model: "gpt-4.1",
choices: [{ index: 0, message: { role: "assistant", content }, finish_reason: "stop" }],
usage: { prompt_tokens: 1, completion_tokens: 1, total_tokens: 2 },
};
}
afterEach(() => {
vi.unstubAllGlobals();
});
describe("POST /ai-providers/{id}/test — end to end", () => {
beforeEach(() => {
seedProvider();
});
it("resolves with a usable provider and enables it", async () => {
stubProvider(200, chatCompletion("1"));
const response = await client.test({ id: "provider-1" });
expect(response.testStatus).toBe("success");
expect(response.testError).toBeNull();
expect(response.enabled).toBe(true);
// The persisted row is what the dashboard reads on the next page load.
expect(dbState.rows[0]).toMatchObject({ testStatus: "success", testError: null, enabled: true });
});
it("resolves — not rejects — when the provider rejects the key, and explains why", async () => {
stubProvider(401, { error: { message: "Incorrect API key provided." } });
// Before this change the procedure threw BAD_GATEWAY, so this call would reject.
const response = await client.test({ id: "provider-1" });
expect(response.testStatus).toBe("failure");
expect(response.testError).toBe("OpenAI rejected the API key.");
expect(response.enabled).toBe(false);
expect(dbState.rows[0]?.testError).toBe("OpenAI rejected the API key.");
});
it("names the model when the provider returns not-found", async () => {
stubProvider(404, {});
const response = await client.test({ id: "provider-1" });
expect(response.testError).toBe('OpenAI has no model named "gpt-4.1", or the base URL is wrong.');
});
it("attributes an outage to the provider and does not retry", async () => {
const fetchMock = stubProvider(503, {});
const response = await client.test({ id: "provider-1" });
expect(response.testError).toBe("OpenAI reported a server error (503). This is a problem on the provider's side.");
expect(fetchMock).toHaveBeenCalledTimes(1);
});
it("separates a reachable provider from a usable one", async () => {
stubProvider(200, chatCompletion("Of course! I am connected."));
const response = await client.test({ id: "provider-1" });
expect(response.testStatus).toBe("failure");
expect(response.testError).toContain("reachable, but the model replied with unexpected output");
});
it("never leaks the decrypted API key into the persisted error", async () => {
stubProvider(400, { error: { message: "Bad request for key sk-live-demo-key-1234" } });
const response = await client.test({ id: "provider-1" });
expect(response.testError).not.toContain("sk-live-demo-key-1234");
expect(response.testError).toContain("***");
});
it("still rejects with BAD_REQUEST when the base URL is not permitted", async () => {
// A blocked address must remain a configuration error, not a provider failure.
seedProvider({ baseUrl: "ftp://api.openai.test/v1" });
stubProvider(200, chatCompletion("1"));
await expect(client.test({ id: "provider-1" })).rejects.toMatchObject({
code: "BAD_REQUEST",
message: "Invalid AI provider configuration.",
});
});
it("rejects with NOT_FOUND when the provider belongs to nobody", async () => {
dbState.rows = [];
await expect(client.test({ id: "provider-1" })).rejects.toMatchObject({ code: "NOT_FOUND" });
});
});
@@ -228,19 +228,21 @@ export const aiProvidersService = {
const apiKey = decryptCredential(provider.encryptedApiKey);
try {
const ok = await testConnection({
const result = await testConnection({
provider: parsedProvider,
model: provider.model,
apiKey,
baseURL: provider.baseUrl ?? "",
});
// A provider that answers "no" is a completed test, not a failed request: it comes back as
// data so the client can show why, instead of a generic transport error.
const [updated] = await db
.update(schema.aiProvider)
.set({
enabled: ok,
testStatus: ok ? "success" : "failure",
testError: ok ? null : "The provider test returned an unexpected response.",
enabled: result.ok,
testStatus: result.ok ? "success" : "failure",
testError: result.ok ? null : result.message,
lastTestedAt: new Date(),
})
.where(and(eq(schema.aiProvider.id, input.id), eq(schema.aiProvider.userId, input.userId)))
@@ -249,6 +251,7 @@ export const aiProvidersService = {
if (!updated) throw new ORPCError("NOT_FOUND");
return toResponse(updated);
} catch (error) {
// Only unexpected failures reach here now: provider-side outcomes come back as data above.
await db
.update(schema.aiProvider)
.set({
+127 -9
View File
@@ -44,8 +44,130 @@ function stubOpenAICompatibleResponse(response?: { content?: string; finishReaso
return { fetchMock, getRequestBody: () => requestBody };
}
function testInput(overrides?: { model?: string; apiKey?: string; baseURL?: string }) {
return {
provider: "openai-compatible" as const,
model: overrides?.model ?? "test-model",
apiKey: overrides?.apiKey ?? "test-key",
baseURL: overrides?.baseURL ?? "https://example.test/v1",
};
}
function stubFailedResponse(status: number, body = "{}") {
const fetchMock = vi.fn(() => new Response(body, { status, headers: { "Content-Type": "application/json" } }));
vi.stubGlobal("fetch", fetchMock);
return fetchMock;
}
function stubRejectedFetch(error: unknown) {
const fetchMock = vi.fn(() => Promise.reject(error));
vi.stubGlobal("fetch", fetchMock);
return fetchMock;
}
const { testConnection } = await import("./service");
describe("AI provider connection test", () => {
it("names the rejected key instead of reporting a transport failure", async () => {
stubFailedResponse(401);
await expect(testConnection(testInput())).resolves.toMatchObject({
ok: false,
message: expect.stringContaining("rejected the API key"),
});
});
it("points at the model when the provider returns a not-found status", async () => {
stubFailedResponse(404);
await expect(testConnection(testInput({ model: "missing-model" }))).resolves.toMatchObject({
ok: false,
message: expect.stringContaining('no model named "missing-model"'),
});
});
it("distinguishes rate limiting from an outage", async () => {
stubFailedResponse(429);
await expect(testConnection(testInput())).resolves.toMatchObject({
ok: false,
message: expect.stringContaining("rate-limited"),
});
});
it("attributes a server error to the provider", async () => {
stubFailedResponse(503);
await expect(testConnection(testInput())).resolves.toMatchObject({
ok: false,
message: expect.stringContaining("server error (503)"),
});
});
it("reports an unreachable base URL rather than the socket error", async () => {
stubRejectedFetch(
Object.assign(new TypeError("fetch failed"), {
cause: Object.assign(new Error("connect ECONNREFUSED 127.0.0.1:11434"), { code: "ECONNREFUSED" }),
}),
);
await expect(testConnection(testInput({ baseURL: "https://example.test/v1" }))).resolves.toMatchObject({
ok: false,
message: expect.stringContaining("Could not reach https://example.test/v1"),
});
});
it("explains a timeout in terms of the wait the user just sat through", async () => {
stubRejectedFetch(new DOMException("The operation was aborted due to timeout", "TimeoutError"));
await expect(testConnection(testInput())).resolves.toMatchObject({
ok: false,
message: expect.stringContaining("did not respond within 30 seconds"),
});
});
it("does not retry, so the test cannot silently multiply its own wait", async () => {
const fetchMock = stubFailedResponse(503);
await testConnection(testInput());
expect(fetchMock).toHaveBeenCalledTimes(1);
});
it("separates a reachable provider from a usable one", async () => {
stubOpenAICompatibleResponse({ content: "Sure! The connection works.", finishReason: "stop" });
await expect(testConnection(testInput())).resolves.toMatchObject({
ok: false,
message: expect.stringContaining("reachable"),
});
});
it("keeps the API key out of a passed-through provider message", async () => {
stubFailedResponse(400, JSON.stringify({ error: { message: "Bad key sk-secret-value-123" } }));
const result = await testConnection(testInput({ apiKey: "sk-secret-value-123" }));
expect(result.ok).toBe(false);
if (!result.ok) expect(result.message).not.toContain("sk-secret-value-123");
});
// The credentials schema accepts a single character, so short keys must be redacted too.
it("redacts a short API key as well", async () => {
stubFailedResponse(400, JSON.stringify({ error: { message: "Bad key tok123" } }));
const result = await testConnection(testInput({ apiKey: "tok123" }));
expect(result.ok).toBe(false);
if (!result.ok) {
expect(result.message).not.toContain("tok123");
expect(result.message).toContain("***");
}
});
});
describe("AI chat service", () => {
it("tests OpenAI-compatible providers without requiring structured output", async () => {
const openAiCompatible = stubOpenAICompatibleResponse();
@@ -57,7 +179,7 @@ describe("AI chat service", () => {
apiKey: "test-key",
baseURL: "https://example.test/v1",
}),
).resolves.toBe(true);
).resolves.toEqual({ ok: true });
expect(openAiCompatible.fetchMock).toHaveBeenCalledTimes(1);
expect(openAiCompatible.getRequestBody()).not.toHaveProperty("response_format");
@@ -67,14 +189,10 @@ describe("AI chat service", () => {
it("explains when the provider test hits the output limit", async () => {
stubOpenAICompatibleResponse({ content: "1. The connection works.", finishReason: "length" });
await expect(
testConnection({
provider: "openai-compatible",
model: "test-model",
apiKey: "test-key",
baseURL: "https://example.test/v1",
}),
).rejects.toThrow("The model returned too much text during the provider test.");
await expect(testConnection(testInput())).resolves.toMatchObject({
ok: false,
message: expect.stringContaining("returned too much text"),
});
});
it("keeps proposal tool history valid for follow-up chat messages", async () => {
+139 -12
View File
@@ -17,7 +17,17 @@ import { createPerplexity } from "@ai-sdk/perplexity";
import { createTogetherAI } from "@ai-sdk/togetherai";
import { createXai } from "@ai-sdk/xai";
import { streamToEventIterator } from "@orpc/server";
import { convertToModelMessages, createGateway, generateText, stepCountIs, streamText, tool } from "ai";
import {
APICallError,
convertToModelMessages,
createGateway,
generateText,
LoadAPIKeyError,
NoSuchModelError,
stepCountIs,
streamText,
tool,
} from "ai";
import { createOllama } from "ollama-ai-provider-v2";
import { match } from "ts-pattern";
import { z } from "zod";
@@ -36,7 +46,7 @@ import {
resumePatchProposalToolInputSchema,
resumePatchProposalToolOutputSchema,
} from "@reactive-resume/ai/tools/patch-proposal";
import { aiProviderSchema } from "@reactive-resume/ai/types";
import { AI_PROVIDER_DEFAULT_BASE_URLS, AI_PROVIDER_DISPLAY_NAMES, aiProviderSchema } from "@reactive-resume/ai/types";
import { applyResumePatches } from "@reactive-resume/resume/patch";
import { resumeAnalysisSchema } from "@reactive-resume/schema/resume/analysis";
import { supportsProviderNativeWebSearch } from "./capabilities";
@@ -83,6 +93,8 @@ type GetModelInput = {
const MAX_AI_FILE_BYTES = 10 * 1024 * 1024; // 10MB
const MAX_AI_FILE_BASE64_CHARS = Math.ceil((MAX_AI_FILE_BYTES * 4) / 3) + 4;
const TEST_CONNECTION_MAX_OUTPUT_TOKENS = 128;
// Long enough for a cold local model to load, short enough that the UI does not look frozen.
const TEST_CONNECTION_TIMEOUT_MS = 30_000;
const DOCX_DOCUMENT_XML_PATH = "word/document.xml";
const ZIP_LOCAL_FILE_HEADER_SIGNATURE = 0x04034b50;
const ZIP_CENTRAL_DIRECTORY_SIGNATURE = 0x02014b50;
@@ -144,20 +156,135 @@ export const fileInputSchema = z.object({
type TestConnectionInput = z.infer<typeof aiCredentialsSchema>;
export async function testConnection(input: TestConnectionInput): Promise<boolean> {
const RESPONSE_OK = "1";
type TestConnectionResult = { ok: true } | { ok: false; message: string };
const result = await generateText({
model: getModel(input),
maxOutputTokens: TEST_CONNECTION_MAX_OUTPUT_TOKENS,
temperature: 0,
messages: [{ role: "user", content: `Respond only with the single character: ${RESPONSE_OK}` }],
const NETWORK_ERROR_CODES = new Set([
"ECONNREFUSED",
"ECONNRESET",
"EAI_AGAIN",
"ENOTFOUND",
"ETIMEDOUT",
"UND_ERR_CONNECT_TIMEOUT",
"UND_ERR_SOCKET",
]);
// Provider SDKs wrap the useful error (a socket failure, an abort) inside a generic one, so the
// signal we need is usually a few `cause` hops down rather than on the error we are handed.
function findInCauseChain<T>(error: unknown, pick: (candidate: unknown) => T | undefined): T | undefined {
let current = error;
for (let depth = 0; depth < 8 && current !== null && current !== undefined; depth++) {
const picked = pick(current);
if (picked !== undefined) return picked;
current = (current as { cause?: unknown }).cause;
}
return undefined;
}
function isTimeout(error: unknown): boolean {
return (
findInCauseChain(error, (candidate) =>
candidate instanceof Error && (candidate.name === "TimeoutError" || candidate.name === "AbortError")
? true
: undefined,
) ?? false
);
}
function findNetworkErrorCode(error: unknown): string | undefined {
return findInCauseChain(error, (candidate) => {
const code = (candidate as { code?: unknown }).code;
return typeof code === "string" && NETWORK_ERROR_CODES.has(code) ? code : undefined;
});
}
if (result.text.trim() === RESPONSE_OK) return true;
if (result.finishReason === "length") throw new Error("The model returned too much text during the provider test.");
// The key is never part of a response body, but a provider echoing the request would leak it into
// the message we persist, so scrub it from anything we did not write ourselves. The schema allows
// keys as short as one character, and a mangled message costs less than a leaked credential, so
// every non-empty key is redacted. The guard only keeps `replaceAll` from splicing "***" between
// every character of the message.
function redactApiKey(message: string, apiKey: string): string {
if (!apiKey) return message;
return false;
return message.replaceAll(apiKey, "***");
}
function describeTestConnectionFailure(input: TestConnectionInput, error: unknown): string {
const provider = AI_PROVIDER_DISPLAY_NAMES[input.provider];
const endpoint = input.baseURL.trim() || AI_PROVIDER_DEFAULT_BASE_URLS[input.provider];
if (isTimeout(error)) {
return `${provider} did not respond within ${TEST_CONNECTION_TIMEOUT_MS / 1000} seconds. The service may be unreachable, or the model may be too slow to load.`;
}
if (findNetworkErrorCode(error)) {
return endpoint
? `Could not reach ${endpoint}. Check that the base URL is correct and the service is running.`
: `${provider} could not be reached. Check that the base URL is correct and the service is running.`;
}
if (LoadAPIKeyError.isInstance(error)) return `${provider} was configured without an API key.`;
if (NoSuchModelError.isInstance(error)) return `${provider} has no model named "${input.model}".`;
if (APICallError.isInstance(error)) {
const status = error.statusCode;
if (status === 401 || status === 403) return `${provider} rejected the API key.`;
if (status === 404) return `${provider} has no model named "${input.model}", or the base URL is wrong.`;
if (status === 429) return `${provider} rate-limited the test. Wait a moment and try again.`;
if (status !== undefined && status >= 500) {
return `${provider} reported a server error (${status}). This is a problem on the provider's side.`;
}
return `${provider} rejected the test request${status === undefined ? "" : ` (${status})`}: ${redactApiKey(error.message, input.apiKey)}`;
}
if (error instanceof Error && error.message) {
return `${provider} could not be tested: ${redactApiKey(error.message, input.apiKey)}`;
}
return `${provider} could not be tested, and reported no reason.`;
}
export async function testConnection(input: TestConnectionInput): Promise<TestConnectionResult> {
const RESPONSE_OK = "1";
const provider = AI_PROVIDER_DISPLAY_NAMES[input.provider];
// Resolved outside the try so the base-URL policy error still reaches the router, which turns it
// into an invalid-configuration response rather than a provider failure.
const model = getModel(input);
let result: Awaited<ReturnType<typeof generateText>>;
try {
result = await generateText({
model,
maxOutputTokens: TEST_CONNECTION_MAX_OUTPUT_TOKENS,
temperature: 0,
// A connection test must not silently multiply its own wait by retrying behind the user.
maxRetries: 0,
abortSignal: AbortSignal.timeout(TEST_CONNECTION_TIMEOUT_MS),
messages: [{ role: "user", content: `Respond only with the single character: ${RESPONSE_OK}` }],
});
} catch (error) {
return { ok: false, message: describeTestConnectionFailure(input, error) };
}
if (result.text.trim() === RESPONSE_OK) return { ok: true };
if (result.finishReason === "length") {
return {
ok: false,
message: `${provider} is reachable, but the model returned too much text during the test. Try a model that follows short instructions.`,
};
}
return {
ok: false,
message: `${provider} is reachable, but the model replied with unexpected output instead of a simple confirmation.`,
};
}
type ParsePdfInput = z.infer<typeof aiCredentialsSchema> & {