mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-08-28 05:27:24 +00:00
fix: handle empty Gemini responses and reasoning loops (#10007)
This commit is contained in:
parent
f9cfc66803
commit
47320dca62
20 changed files with 140 additions and 26 deletions
|
|
@ -199,13 +199,17 @@ export class GeminiHandler extends BaseProvider implements SingleCompletionHandl
|
|||
let lastUsageMetadata: GenerateContentResponseUsageMetadata | undefined
|
||||
let pendingGroundingMetadata: GroundingMetadata | undefined
|
||||
let finalResponse: { responseId?: string } | undefined
|
||||
let finishReason: string | undefined
|
||||
|
||||
let toolCallCounter = 0
|
||||
let hasContent = false
|
||||
let hasReasoning = false
|
||||
|
||||
for await (const chunk of result) {
|
||||
// Track the final structured response (per SDK pattern: candidate.finishReason)
|
||||
if (chunk.candidates && chunk.candidates[0]?.finishReason) {
|
||||
finalResponse = chunk as { responseId?: string }
|
||||
finishReason = chunk.candidates[0].finishReason
|
||||
}
|
||||
// Process candidates and their parts to separate thoughts from content
|
||||
if (chunk.candidates && chunk.candidates.length > 0) {
|
||||
|
|
@ -233,9 +237,11 @@ export class GeminiHandler extends BaseProvider implements SingleCompletionHandl
|
|||
if (part.thought) {
|
||||
// This is a thinking/reasoning part
|
||||
if (part.text) {
|
||||
hasReasoning = true
|
||||
yield { type: "reasoning", text: part.text }
|
||||
}
|
||||
} else if (part.functionCall) {
|
||||
hasContent = true
|
||||
// Gemini sends complete function calls in a single chunk
|
||||
// Emit as partial chunks for consistent handling with NativeToolCallParser
|
||||
const callId = `${part.functionCall.name}-${toolCallCounter}`
|
||||
|
|
@ -263,6 +269,7 @@ export class GeminiHandler extends BaseProvider implements SingleCompletionHandl
|
|||
} else {
|
||||
// This is regular content
|
||||
if (part.text) {
|
||||
hasContent = true
|
||||
yield { type: "text", text: part.text }
|
||||
}
|
||||
}
|
||||
|
|
@ -272,6 +279,7 @@ export class GeminiHandler extends BaseProvider implements SingleCompletionHandl
|
|||
|
||||
// Fallback to the original text property if no candidates structure
|
||||
else if (chunk.text) {
|
||||
hasContent = true
|
||||
yield { type: "text", text: chunk.text }
|
||||
}
|
||||
|
||||
|
|
@ -280,6 +288,21 @@ export class GeminiHandler extends BaseProvider implements SingleCompletionHandl
|
|||
}
|
||||
}
|
||||
|
||||
// If we had reasoning but no content, emit a placeholder text to prevent "Empty assistant response" errors.
|
||||
// This typically happens when the model hits max output tokens while reasoning.
|
||||
if (hasReasoning && !hasContent) {
|
||||
let message = t("common:errors.gemini.thinking_complete_no_output")
|
||||
if (finishReason === "MAX_TOKENS") {
|
||||
message = t("common:errors.gemini.thinking_complete_truncated")
|
||||
} else if (finishReason === "SAFETY") {
|
||||
message = t("common:errors.gemini.thinking_complete_safety")
|
||||
} else if (finishReason === "RECITATION") {
|
||||
message = t("common:errors.gemini.thinking_complete_recitation")
|
||||
}
|
||||
|
||||
yield { type: "text", text: message }
|
||||
}
|
||||
|
||||
if (finalResponse?.responseId) {
|
||||
// Capture responseId so Task.addToApiConversationHistory can store it
|
||||
// alongside the assistant message in api_history.json.
|
||||
|
|
|
|||
|
|
@ -14,6 +14,11 @@ type ReasoningContentBlock = {
|
|||
type ExtendedContentBlockParam = Anthropic.ContentBlockParam | ThoughtSignatureContentBlock | ReasoningContentBlock
|
||||
type ExtendedAnthropicContent = string | ExtendedContentBlockParam[]
|
||||
|
||||
// Extension type to safely add thoughtSignature to Part
|
||||
type PartWithThoughtSignature = Part & {
|
||||
thoughtSignature?: string
|
||||
}
|
||||
|
||||
function isThoughtSignatureContentBlock(block: ExtendedContentBlockParam): block is ThoughtSignatureContentBlock {
|
||||
return block.type === "thoughtSignature"
|
||||
}
|
||||
|
|
@ -47,16 +52,11 @@ export function convertAnthropicContentToGemini(
|
|||
return [{ text: content }]
|
||||
}
|
||||
|
||||
return content.flatMap((block): Part | Part[] => {
|
||||
const parts = content.flatMap((block): Part | Part[] => {
|
||||
// Handle thoughtSignature blocks first
|
||||
if (isThoughtSignatureContentBlock(block)) {
|
||||
if (includeThoughtSignatures && typeof block.thoughtSignature === "string") {
|
||||
// The Google GenAI SDK currently exposes thoughtSignature as an
|
||||
// extension field on Part; model it structurally without widening
|
||||
// the upstream type.
|
||||
return { thoughtSignature: block.thoughtSignature } as Part
|
||||
}
|
||||
// Explicitly omit thoughtSignature when not including it.
|
||||
// We process thought signatures globally and attach them to the relevant parts
|
||||
// or create a placeholder part if no other content exists.
|
||||
return []
|
||||
}
|
||||
|
||||
|
|
@ -135,6 +135,25 @@ export function convertAnthropicContentToGemini(
|
|||
return []
|
||||
}
|
||||
})
|
||||
|
||||
// Post-processing: Ensure thought signature is attached if required
|
||||
if (includeThoughtSignatures && activeThoughtSignature) {
|
||||
const hasSignature = parts.some((p) => "thoughtSignature" in p)
|
||||
|
||||
if (!hasSignature) {
|
||||
if (parts.length > 0) {
|
||||
// Attach to the first part (usually text)
|
||||
// We use the intersection type to allow adding the property safely
|
||||
;(parts[0] as PartWithThoughtSignature).thoughtSignature = activeThoughtSignature
|
||||
} else {
|
||||
// Create a placeholder part if no other content exists
|
||||
const placeholder: PartWithThoughtSignature = { text: "", thoughtSignature: activeThoughtSignature }
|
||||
parts.push(placeholder)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return parts
|
||||
}
|
||||
|
||||
export function convertAnthropicMessageToGemini(
|
||||
|
|
|
|||
6
src/i18n/locales/ca/common.json
generated
6
src/i18n/locales/ca/common.json
generated
|
|
@ -109,7 +109,11 @@
|
|||
"gemini": {
|
||||
"generate_stream": "Error del flux de context de generació de Gemini: {{error}}",
|
||||
"generate_complete_prompt": "Error de finalització de Gemini: {{error}}",
|
||||
"sources": "Fonts:"
|
||||
"sources": "Fonts:",
|
||||
"thinking_complete_no_output": "(Pensament completat, però no s'ha generat cap sortida.)",
|
||||
"thinking_complete_truncated": "(Pensament completat, però la sortida s'ha truncat a causa del límit de fitxes.)",
|
||||
"thinking_complete_safety": "(Pensament completat, però la sortida s'ha bloquejat a causa de la configuració de seguretat.)",
|
||||
"thinking_complete_recitation": "(Pensament completat, però la sortida s'ha bloquejat a causa de la comprovació de recitació.)"
|
||||
},
|
||||
"cerebras": {
|
||||
"authenticationFailed": "Ha fallat l'autenticació de l'API de Cerebras. Comproveu que la vostra clau d'API sigui vàlida i no hagi caducat.",
|
||||
|
|
|
|||
6
src/i18n/locales/de/common.json
generated
6
src/i18n/locales/de/common.json
generated
|
|
@ -106,7 +106,11 @@
|
|||
"gemini": {
|
||||
"generate_stream": "Fehler beim Generieren des Kontext-Streams von Gemini: {{error}}",
|
||||
"generate_complete_prompt": "Fehler bei der Vervollständigung durch Gemini: {{error}}",
|
||||
"sources": "Quellen:"
|
||||
"sources": "Quellen:",
|
||||
"thinking_complete_no_output": "(Denken abgeschlossen, aber es wurde keine Ausgabe generiert.)",
|
||||
"thinking_complete_truncated": "(Denken abgeschlossen, aber die Ausgabe wurde aufgrund des Token-Limits gekürzt.)",
|
||||
"thinking_complete_safety": "(Denken abgeschlossen, aber die Ausgabe wurde aufgrund von Sicherheitseinstellungen blockiert.)",
|
||||
"thinking_complete_recitation": "(Denken abgeschlossen, aber die Ausgabe wurde aufgrund der Rezitationsprüfung blockiert.)"
|
||||
},
|
||||
"cerebras": {
|
||||
"authenticationFailed": "Cerebras API-Authentifizierung fehlgeschlagen. Bitte überprüfe, ob dein API-Schlüssel gültig und nicht abgelaufen ist.",
|
||||
|
|
|
|||
|
|
@ -106,7 +106,11 @@
|
|||
"gemini": {
|
||||
"generate_stream": "Gemini generate context stream error: {{error}}",
|
||||
"generate_complete_prompt": "Gemini completion error: {{error}}",
|
||||
"sources": "Sources:"
|
||||
"sources": "Sources:",
|
||||
"thinking_complete_no_output": "(Thinking complete, but no output was generated.)",
|
||||
"thinking_complete_truncated": "(Thinking complete, but output was truncated due to token limit.)",
|
||||
"thinking_complete_safety": "(Thinking complete, but output was blocked due to safety settings.)",
|
||||
"thinking_complete_recitation": "(Thinking complete, but output was blocked due to recitation check.)"
|
||||
},
|
||||
"cerebras": {
|
||||
"authenticationFailed": "Cerebras API authentication failed. Please check your API key is valid and not expired.",
|
||||
|
|
|
|||
6
src/i18n/locales/es/common.json
generated
6
src/i18n/locales/es/common.json
generated
|
|
@ -106,7 +106,11 @@
|
|||
"gemini": {
|
||||
"generate_stream": "Error del stream de contexto de generación de Gemini: {{error}}",
|
||||
"generate_complete_prompt": "Error de finalización de Gemini: {{error}}",
|
||||
"sources": "Fuentes:"
|
||||
"sources": "Fuentes:",
|
||||
"thinking_complete_no_output": "(Pensamiento completado, pero no se generó salida.)",
|
||||
"thinking_complete_truncated": "(Pensamiento completado, pero la salida fue truncada debido al límite de tokens.)",
|
||||
"thinking_complete_safety": "(Pensamiento completado, pero la salida fue bloqueada debido a la configuración de seguridad.)",
|
||||
"thinking_complete_recitation": "(Pensamiento completado, pero la salida fue bloqueada debido a la comprobación de recitación.)"
|
||||
},
|
||||
"cerebras": {
|
||||
"authenticationFailed": "Falló la autenticación de la API de Cerebras. Verifica que tu clave de API sea válida y no haya expirado.",
|
||||
|
|
|
|||
6
src/i18n/locales/fr/common.json
generated
6
src/i18n/locales/fr/common.json
generated
|
|
@ -106,7 +106,11 @@
|
|||
"gemini": {
|
||||
"generate_stream": "Erreur du flux de contexte de génération Gemini : {{error}}",
|
||||
"generate_complete_prompt": "Erreur d'achèvement de Gemini : {{error}}",
|
||||
"sources": "Sources :"
|
||||
"sources": "Sources :",
|
||||
"thinking_complete_no_output": "(Réflexion terminée, mais aucune sortie générée.)",
|
||||
"thinking_complete_truncated": "(Réflexion terminée, mais la sortie a été tronquée en raison de la limite de jetons.)",
|
||||
"thinking_complete_safety": "(Réflexion terminée, mais la sortie a été bloquée en raison des paramètres de sécurité.)",
|
||||
"thinking_complete_recitation": "(Réflexion terminée, mais la sortie a été bloquée en raison de la vérification de récitation.)"
|
||||
},
|
||||
"cerebras": {
|
||||
"authenticationFailed": "Échec de l'authentification de l'API Cerebras. Vérifiez que votre clé API est valide et n'a pas expiré.",
|
||||
|
|
|
|||
6
src/i18n/locales/hi/common.json
generated
6
src/i18n/locales/hi/common.json
generated
|
|
@ -106,7 +106,11 @@
|
|||
"gemini": {
|
||||
"generate_stream": "जेमिनी जनरेट कॉन्टेक्स्ट स्ट्रीम त्रुटि: {{error}}",
|
||||
"generate_complete_prompt": "जेमिनी समापन त्रुटि: {{error}}",
|
||||
"sources": "स्रोत:"
|
||||
"sources": "स्रोत:",
|
||||
"thinking_complete_no_output": "(सोचना पूरा हुआ, लेकिन कोई आउटपुट नहीं बना।)",
|
||||
"thinking_complete_truncated": "(सोचना पूरा हुआ, लेकिन टोकन सीमा के कारण आउटपुट काट दिया गया।)",
|
||||
"thinking_complete_safety": "(सोचना पूरा हुआ, लेकिन सुरक्षा सेटिंग्स के कारण आउटपुट अवरुद्ध कर दिया गया।)",
|
||||
"thinking_complete_recitation": "(सोचना पूरा हुआ, लेकिन पाठ जाँच के कारण आउटपुट अवरुद्ध कर दिया गया।)"
|
||||
},
|
||||
"cerebras": {
|
||||
"authenticationFailed": "Cerebras API प्रमाणीकरण विफल हुआ। कृपया जांचें कि आपकी API कुंजी वैध है और समाप्त नहीं हुई है।",
|
||||
|
|
|
|||
6
src/i18n/locales/id/common.json
generated
6
src/i18n/locales/id/common.json
generated
|
|
@ -106,7 +106,11 @@
|
|||
"gemini": {
|
||||
"generate_stream": "Kesalahan aliran konteks pembuatan Gemini: {{error}}",
|
||||
"generate_complete_prompt": "Kesalahan penyelesaian Gemini: {{error}}",
|
||||
"sources": "Sumber:"
|
||||
"sources": "Sumber:",
|
||||
"thinking_complete_no_output": "(Berpikir selesai, tetapi tidak ada output yang dihasilkan.)",
|
||||
"thinking_complete_truncated": "(Berpikir selesai, tetapi output terpotong karena batas token.)",
|
||||
"thinking_complete_safety": "(Berpikir selesai, tetapi output diblokir karena pengaturan keamanan.)",
|
||||
"thinking_complete_recitation": "(Berpikir selesai, tetapi output diblokir karena pemeriksaan resitasi.)"
|
||||
},
|
||||
"cerebras": {
|
||||
"authenticationFailed": "Autentikasi API Cerebras gagal. Silakan periksa apakah kunci API Anda valid dan belum kedaluwarsa.",
|
||||
|
|
|
|||
6
src/i18n/locales/it/common.json
generated
6
src/i18n/locales/it/common.json
generated
|
|
@ -106,7 +106,11 @@
|
|||
"gemini": {
|
||||
"generate_stream": "Errore del flusso di contesto di generazione Gemini: {{error}}",
|
||||
"generate_complete_prompt": "Errore di completamento Gemini: {{error}}",
|
||||
"sources": "Fonti:"
|
||||
"sources": "Fonti:",
|
||||
"thinking_complete_no_output": "(Pensiero completato, ma non è stato generato alcun output.)",
|
||||
"thinking_complete_truncated": "(Pensiero completato, ma l'output è stato troncato a causa del limite di token.)",
|
||||
"thinking_complete_safety": "(Pensiero completato, ma l'output è stato bloccato a causa delle impostazioni di sicurezza.)",
|
||||
"thinking_complete_recitation": "(Pensiero completato, ma l'output è stato bloccato a causa del controllo di recitazione.)"
|
||||
},
|
||||
"cerebras": {
|
||||
"authenticationFailed": "Autenticazione API Cerebras fallita. Verifica che la tua chiave API sia valida e non scaduta.",
|
||||
|
|
|
|||
6
src/i18n/locales/ja/common.json
generated
6
src/i18n/locales/ja/common.json
generated
|
|
@ -106,7 +106,11 @@
|
|||
"gemini": {
|
||||
"generate_stream": "Gemini 生成コンテキスト ストリーム エラー: {{error}}",
|
||||
"generate_complete_prompt": "Gemini 完了エラー: {{error}}",
|
||||
"sources": "ソース:"
|
||||
"sources": "ソース:",
|
||||
"thinking_complete_no_output": "(思考完了、出力なし)",
|
||||
"thinking_complete_truncated": "(思考完了、トークン制限により出力切り捨て)",
|
||||
"thinking_complete_safety": "(思考完了、安全設定により出力ブロック)",
|
||||
"thinking_complete_recitation": "(思考完了、引用チェックにより出力ブロック)"
|
||||
},
|
||||
"cerebras": {
|
||||
"authenticationFailed": "Cerebras API認証が失敗しました。APIキーが有効で期限切れではないことを確認してください。",
|
||||
|
|
|
|||
6
src/i18n/locales/ko/common.json
generated
6
src/i18n/locales/ko/common.json
generated
|
|
@ -106,7 +106,11 @@
|
|||
"gemini": {
|
||||
"generate_stream": "Gemini 생성 컨텍스트 스트림 오류: {{error}}",
|
||||
"generate_complete_prompt": "Gemini 완료 오류: {{error}}",
|
||||
"sources": "출처:"
|
||||
"sources": "출처:",
|
||||
"thinking_complete_no_output": "(생각 완료, 출력 없음)",
|
||||
"thinking_complete_truncated": "(생각 완료, 토큰 제한으로 출력 잘림)",
|
||||
"thinking_complete_safety": "(생각 완료, 안전 설정으로 출력 차단됨)",
|
||||
"thinking_complete_recitation": "(생각 완료, 암송 확인으로 출력 차단됨)"
|
||||
},
|
||||
"cerebras": {
|
||||
"authenticationFailed": "Cerebras API 인증에 실패했습니다. API 키가 유효하고 만료되지 않았는지 확인하세요.",
|
||||
|
|
|
|||
6
src/i18n/locales/nl/common.json
generated
6
src/i18n/locales/nl/common.json
generated
|
|
@ -106,7 +106,11 @@
|
|||
"gemini": {
|
||||
"generate_stream": "Fout bij het genereren van contextstream door Gemini: {{error}}",
|
||||
"generate_complete_prompt": "Fout bij het voltooien door Gemini: {{error}}",
|
||||
"sources": "Bronnen:"
|
||||
"sources": "Bronnen:",
|
||||
"thinking_complete_no_output": "(Nadenken voltooid, maar er is geen uitvoer gegenereerd.)",
|
||||
"thinking_complete_truncated": "(Nadenken voltooid, maar uitvoer is afgekapt vanwege tokenlimiet.)",
|
||||
"thinking_complete_safety": "(Nadenken voltooid, maar uitvoer is geblokkeerd vanwege veiligheidsinstellingen.)",
|
||||
"thinking_complete_recitation": "(Nadenken voltooid, maar uitvoer is geblokkeerd vanwege recitatiecontrole.)"
|
||||
},
|
||||
"cerebras": {
|
||||
"authenticationFailed": "Cerebras API-authenticatie mislukt. Controleer of je API-sleutel geldig is en niet verlopen.",
|
||||
|
|
|
|||
6
src/i18n/locales/pl/common.json
generated
6
src/i18n/locales/pl/common.json
generated
|
|
@ -106,7 +106,11 @@
|
|||
"gemini": {
|
||||
"generate_stream": "Błąd strumienia kontekstu generowania Gemini: {{error}}",
|
||||
"generate_complete_prompt": "Błąd uzupełniania Gemini: {{error}}",
|
||||
"sources": "Źródła:"
|
||||
"sources": "Źródła:",
|
||||
"thinking_complete_no_output": "(Myślenie zakończone, ale nie wygenerowano żadnych danych wyjściowych.)",
|
||||
"thinking_complete_truncated": "(Myślenie zakończone, ale dane wyjściowe zostały obcięte z powodu limitu tokenów.)",
|
||||
"thinking_complete_safety": "(Myślenie zakończone, ale dane wyjściowe zostały zablokowane przez ustawienia bezpieczeństwa.)",
|
||||
"thinking_complete_recitation": "(Myślenie zakończone, ale dane wyjściowe zostały zablokowane przez kontrolę recytacji.)"
|
||||
},
|
||||
"cerebras": {
|
||||
"authenticationFailed": "Uwierzytelnianie API Cerebras nie powiodło się. Sprawdź, czy twój klucz API jest ważny i nie wygasł.",
|
||||
|
|
|
|||
6
src/i18n/locales/pt-BR/common.json
generated
6
src/i18n/locales/pt-BR/common.json
generated
|
|
@ -110,7 +110,11 @@
|
|||
"gemini": {
|
||||
"generate_stream": "Erro de fluxo de contexto de geração do Gemini: {{error}}",
|
||||
"generate_complete_prompt": "Erro de conclusão do Gemini: {{error}}",
|
||||
"sources": "Fontes:"
|
||||
"sources": "Fontes:",
|
||||
"thinking_complete_no_output": "(Pensamento concluído, mas nenhuma saída foi gerada.)",
|
||||
"thinking_complete_truncated": "(Pensamento concluído, mas a saída foi truncada devido ao limite de tokens.)",
|
||||
"thinking_complete_safety": "(Pensamento concluído, mas a saída foi bloqueada devido às configurações de segurança.)",
|
||||
"thinking_complete_recitation": "(Pensamento concluído, mas a saída foi bloqueada devido à verificação de recitação.)"
|
||||
},
|
||||
"cerebras": {
|
||||
"authenticationFailed": "Falha na autenticação da API Cerebras. Verifique se sua chave de API é válida e não expirou.",
|
||||
|
|
|
|||
6
src/i18n/locales/ru/common.json
generated
6
src/i18n/locales/ru/common.json
generated
|
|
@ -106,7 +106,11 @@
|
|||
"gemini": {
|
||||
"generate_stream": "Ошибка потока контекста генерации Gemini: {{error}}",
|
||||
"generate_complete_prompt": "Ошибка завершения Gemini: {{error}}",
|
||||
"sources": "Источники:"
|
||||
"sources": "Источники:",
|
||||
"thinking_complete_no_output": "(Размышление завершено, но вывод не сгенерирован.)",
|
||||
"thinking_complete_truncated": "(Размышление завершено, но вывод урезан из-за лимита токенов.)",
|
||||
"thinking_complete_safety": "(Размышление завершено, но вывод заблокирован настройками безопасности.)",
|
||||
"thinking_complete_recitation": "(Размышление завершено, но вывод заблокирован проверкой цитирования.)"
|
||||
},
|
||||
"cerebras": {
|
||||
"authenticationFailed": "Ошибка аутентификации Cerebras API. Убедитесь, что ваш API-ключ действителен и не истек.",
|
||||
|
|
|
|||
6
src/i18n/locales/tr/common.json
generated
6
src/i18n/locales/tr/common.json
generated
|
|
@ -106,7 +106,11 @@
|
|||
"gemini": {
|
||||
"generate_stream": "Gemini oluşturma bağlam akışı hatası: {{error}}",
|
||||
"generate_complete_prompt": "Gemini tamamlama hatası: {{error}}",
|
||||
"sources": "Kaynaklar:"
|
||||
"sources": "Kaynaklar:",
|
||||
"thinking_complete_no_output": "(Düşünme tamamlandı, ancak çıktı oluşturulmadı.)",
|
||||
"thinking_complete_truncated": "(Düşünme tamamlandı, ancak çıktı jeton sınırı nedeniyle kesildi.)",
|
||||
"thinking_complete_safety": "(Düşünme tamamlandı, ancak çıktı güvenlik ayarları nedeniyle engellendi.)",
|
||||
"thinking_complete_recitation": "(Düşünme tamamlandı, ancak çıktı okuma kontrolü nedeniyle engellendi.)"
|
||||
},
|
||||
"cerebras": {
|
||||
"authenticationFailed": "Cerebras API kimlik doğrulama başarısız oldu. API anahtarınızın geçerli olduğunu ve süresi dolmadığını kontrol edin.",
|
||||
|
|
|
|||
6
src/i18n/locales/vi/common.json
generated
6
src/i18n/locales/vi/common.json
generated
|
|
@ -106,7 +106,11 @@
|
|||
"gemini": {
|
||||
"generate_stream": "Lỗi luồng ngữ cảnh tạo Gemini: {{error}}",
|
||||
"generate_complete_prompt": "Lỗi hoàn thành Gemini: {{error}}",
|
||||
"sources": "Nguồn:"
|
||||
"sources": "Nguồn:",
|
||||
"thinking_complete_no_output": "(Đã suy nghĩ xong nhưng không có kết quả đầu ra.)",
|
||||
"thinking_complete_truncated": "(Đã suy nghĩ xong nhưng kết quả bị cắt ngắn do giới hạn token.)",
|
||||
"thinking_complete_safety": "(Đã suy nghĩ xong nhưng kết quả bị chặn do cài đặt an toàn.)",
|
||||
"thinking_complete_recitation": "(Đã suy nghĩ xong nhưng kết quả bị chặn do kiểm tra trích dẫn.)"
|
||||
},
|
||||
"cerebras": {
|
||||
"authenticationFailed": "Xác thực API Cerebras thất bại. Vui lòng kiểm tra khóa API của bạn có hợp lệ và chưa hết hạn.",
|
||||
|
|
|
|||
6
src/i18n/locales/zh-CN/common.json
generated
6
src/i18n/locales/zh-CN/common.json
generated
|
|
@ -111,7 +111,11 @@
|
|||
"gemini": {
|
||||
"generate_stream": "Gemini 生成上下文流错误:{{error}}",
|
||||
"generate_complete_prompt": "Gemini 完成错误:{{error}}",
|
||||
"sources": "来源:"
|
||||
"sources": "来源:",
|
||||
"thinking_complete_no_output": "(思考完成,但未生成输出。)",
|
||||
"thinking_complete_truncated": "(思考完成,但由于 Token 限制输出被截断。)",
|
||||
"thinking_complete_safety": "(思考完成,但由于安全设置输出被阻止。)",
|
||||
"thinking_complete_recitation": "(思考完成,但由于引用检查输出被阻止。)"
|
||||
},
|
||||
"cerebras": {
|
||||
"authenticationFailed": "Cerebras API 身份验证失败。请检查你的 API 密钥是否有效且未过期。",
|
||||
|
|
|
|||
6
src/i18n/locales/zh-TW/common.json
generated
6
src/i18n/locales/zh-TW/common.json
generated
|
|
@ -105,7 +105,11 @@
|
|||
"gemini": {
|
||||
"generate_stream": "Gemini 產生內容串流錯誤:{{error}}",
|
||||
"generate_complete_prompt": "Gemini 完成錯誤:{{error}}",
|
||||
"sources": "來源:"
|
||||
"sources": "來源:",
|
||||
"thinking_complete_no_output": "(思考完成,但未產生輸出。)",
|
||||
"thinking_complete_truncated": "(思考完成,但由於 Token 限制輸出被截斷。)",
|
||||
"thinking_complete_safety": "(思考完成,但由於安全設定輸出被阻止。)",
|
||||
"thinking_complete_recitation": "(思考完成,但由於引用檢查輸出被阻止。)"
|
||||
},
|
||||
"cerebras": {
|
||||
"authenticationFailed": "Cerebras API 驗證失敗。請檢查您的 API 金鑰是否有效且未過期。",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue