diff --git a/src/renderer/src/i18n/locales/en-us.json b/src/renderer/src/i18n/locales/en-us.json
index bc05799a29..3c233b0578 100644
--- a/src/renderer/src/i18n/locales/en-us.json
+++ b/src/renderer/src/i18n/locales/en-us.json
@@ -773,6 +773,7 @@
"more": "More",
"name": "Name",
"no_results": "No results",
+ "none": "None",
"open": "Open",
"paste": "Paste",
"preview": "Preview",
@@ -817,6 +818,8 @@
"openai-response": "OpenAI-Response"
},
"error": {
+ "availableProviders": "Available Providers",
+ "availableTools": "Available Tools",
"backup": {
"file_format": "Backup file format error"
},
@@ -841,9 +844,13 @@
"quota_exceeded": "Your daily {{quota}} free quota has been exhausted. Please go to the {{provider}} to obtain an API key and configure the API key to continue using.",
"response": "Something went wrong. Please check if you have set your API key in the Settings > Providers"
},
- "data": "data",
+ "content": "Content",
+ "data": "Data",
"detail": "Error Details",
"details": "Details",
+ "errors": "Errors",
+ "finishReason": "Finish Reason",
+ "functionality": "Functionality",
"http": {
"400": "Request failed. Please check if the request parameters are correct. If you have changed the model settings, please reset them to the default settings",
"401": "Authentication failed. Please check if your API key is correct",
@@ -855,16 +862,27 @@
"503": "Service unavailable. Please try again later",
"504": "Gateway timeout. Please try again later"
},
+ "lastError": "Last Error",
+ "maxEmbeddingsPerCall": "Max Embeddings Per Call",
"message": "Error Message",
"missing_user_message": "Cannot switch model response: The original user message has been deleted. Please send a new message to get a response with this model.",
"model": {
"exists": "Model already exists",
"not_exists": "Model does not exist"
},
+ "modelId": "Model ID",
+ "modelType": "Model Type",
"name": "Error name",
"no_api_key": "API key is not configured",
+ "originalError": "Original Error",
+ "originalMessage": "Original Message",
+ "parameter": "Parameter",
"pause_placeholder": "Paused",
+ "prompt": "Prompt",
+ "provider": "Provider",
+ "providerId": "Provider ID",
"provider_disabled": "Model provider is not enabled",
+ "reason": "Reason",
"render": {
"description": "Failed to render message content. Please check if the message content format is correct",
"title": "Render Error"
@@ -872,13 +890,23 @@
"requestBody": "Request Body",
"requestBodyValues": "Request Body Values",
"requestUrl": "Request URL",
+ "response": "Response",
"responseBody": "Response Body",
"responseHeaders": "Response Header",
+ "responses": "Responses",
+ "role": "Role",
"stack": "Stack Trace",
"status": "Status Code",
- "statusCode": "Status code",
+ "statusCode": "Status Code",
+ "statusText": "Status Text",
+ "text": "Text",
+ "toolInput": "Tool Input",
+ "toolName": "Tool Name",
"unknown": "Unknown error",
- "user_message_not_found": "Cannot find original user message to resend"
+ "usage": "Usage",
+ "user_message_not_found": "Cannot find original user message to resend",
+ "value": "Value",
+ "values": "Values"
},
"export": {
"assistant": "Assistant",
diff --git a/src/renderer/src/i18n/locales/zh-cn.json b/src/renderer/src/i18n/locales/zh-cn.json
index 5ba0a6a672..a630bda814 100644
--- a/src/renderer/src/i18n/locales/zh-cn.json
+++ b/src/renderer/src/i18n/locales/zh-cn.json
@@ -773,6 +773,7 @@
"more": "更多",
"name": "名称",
"no_results": "无结果",
+ "none": "无",
"open": "打开",
"paste": "粘贴",
"preview": "预览",
@@ -817,6 +818,8 @@
"openai-response": "OpenAI-Response"
},
"error": {
+ "availableProviders": "可用提供商",
+ "availableTools": "可用工具",
"backup": {
"file_format": "备份文件格式错误"
},
@@ -841,9 +844,13 @@
"quota_exceeded": "您今日免费配额已用尽,请前往 {{provider}} 获取API密钥,配置API密钥后继续使用",
"response": "出错了,如果没有配置 API 密钥,请前往设置 > 模型提供商中配置密钥"
},
+ "content": "内容",
"data": "数据",
"detail": "错误详情",
"details": "详细信息",
+ "errors": "错误",
+ "finishReason": "结束原因",
+ "functionality": "功能",
"http": {
"400": "请求错误,请检查请求参数是否正确。如果修改了模型设置,请重置到默认设置",
"401": "身份验证失败,请检查 API 密钥是否正确",
@@ -855,16 +862,27 @@
"503": "服务不可用,请稍后再试",
"504": "网关超时,请稍后再试"
},
+ "lastError": "最后错误",
+ "maxEmbeddingsPerCall": "每次调用的最大嵌入",
"message": "错误信息",
"missing_user_message": "无法切换模型响应:原始用户消息已被删除。请发送新消息以获取此模型的响应",
"model": {
"exists": "模型已存在",
"not_exists": "模型不存在"
},
+ "modelId": "模型 ID",
+ "modelType": "模型类型",
"name": "错误名称",
"no_api_key": "API 密钥未配置",
+ "originalError": "原错误",
+ "originalMessage": "原消息",
+ "parameter": "参数",
"pause_placeholder": "已中断",
+ "prompt": "提示词",
+ "provider": "提供商",
+ "providerId": "提供商 ID",
"provider_disabled": "模型提供商未启用",
+ "reason": "原因",
"render": {
"description": "消息内容渲染失败,请检查消息内容格式是否正确",
"title": "渲染错误"
@@ -872,13 +890,23 @@
"requestBody": "请求内容",
"requestBodyValues": "请求体",
"requestUrl": "请求路径",
+ "response": "响应",
"responseBody": "响应内容",
"responseHeaders": "响应首部",
+ "responses": "响应",
+ "role": "角色",
"stack": "堆栈信息",
"status": "状态码",
"statusCode": "状态码",
+ "statusText": "状态文本",
+ "text": "文本",
+ "toolInput": "工具输入",
+ "toolName": "工具名",
"unknown": "未知错误",
- "user_message_not_found": "无法找到原始用户消息"
+ "usage": "用量",
+ "user_message_not_found": "无法找到原始用户消息",
+ "value": "值",
+ "values": "值"
},
"export": {
"assistant": "助手",
diff --git a/src/renderer/src/i18n/locales/zh-tw.json b/src/renderer/src/i18n/locales/zh-tw.json
index 66cebe35f5..98bb66b04c 100644
--- a/src/renderer/src/i18n/locales/zh-tw.json
+++ b/src/renderer/src/i18n/locales/zh-tw.json
@@ -773,6 +773,7 @@
"more": "更多",
"name": "名稱",
"no_results": "沒有結果",
+ "none": "無",
"open": "開啟",
"paste": "貼上",
"preview": "預覽",
@@ -817,6 +818,8 @@
"openai-response": "OpenAI-Response"
},
"error": {
+ "availableProviders": "可用提供商",
+ "availableTools": "可用工具",
"backup": {
"file_format": "備份檔案格式錯誤"
},
@@ -841,9 +844,13 @@
"quota_exceeded": "您今日{{quota}}免费配额已用尽,请前往 {{provider}} 获取API密钥,配置API密钥后继续使用",
"response": "出現錯誤。如果尚未設定 API 金鑰,請前往設定 > 模型提供者中設定金鑰"
},
+ "content": "內容",
"data": "数据",
"detail": "錯誤詳情",
"details": "詳細信息",
+ "errors": "錯誤",
+ "finishReason": "結束原因",
+ "functionality": "功能",
"http": {
"400": "請求錯誤,請檢查請求參數是否正確。如果修改了模型設定,請重設到預設設定",
"401": "身份驗證失敗,請檢查 API 金鑰是否正確",
@@ -855,16 +862,27 @@
"503": "服務無法使用,請稍後再試",
"504": "閘道器超時,請稍後再試"
},
+ "lastError": "最後錯誤",
+ "maxEmbeddingsPerCall": "每次調用的最大嵌入",
"message": "錯誤訊息",
"missing_user_message": "無法切換模型回應:原始用戶訊息已被刪除。請發送新訊息以獲得此模型回應。",
"model": {
"exists": "模型已存在",
"not_exists": "模型不存在"
},
+ "modelId": "模型 ID",
+ "modelType": "模型類型",
"name": "錯誤名稱",
"no_api_key": "API 金鑰未設定",
+ "originalError": "原錯誤",
+ "originalMessage": "原消息",
+ "parameter": "參數",
"pause_placeholder": "回應已暫停",
+ "prompt": "提示詞",
+ "provider": "提供商",
+ "providerId": "提供者 ID",
"provider_disabled": "模型供應商未啟用",
+ "reason": "原因",
"render": {
"description": "消息內容渲染失敗,請檢查消息內容格式是否正確",
"title": "渲染錯誤"
@@ -872,13 +890,23 @@
"requestBody": "請求內容",
"requestBodyValues": "请求体",
"requestUrl": "請求路徑",
+ "response": "響應",
"responseBody": "响应内容",
"responseHeaders": "响应首部",
+ "responses": "響應",
+ "role": "角色",
"stack": "堆棧信息",
"status": "狀態碼",
"statusCode": "狀態碼",
+ "statusText": "狀態文本",
+ "text": "文本",
+ "toolInput": "工具輸入",
+ "toolName": "工具名",
"unknown": "未知錯誤",
- "user_message_not_found": "無法找到原始用戶訊息"
+ "usage": "用量",
+ "user_message_not_found": "無法找到原始用戶訊息",
+ "value": "值",
+ "values": "值"
},
"export": {
"assistant": "助手",
diff --git a/src/renderer/src/i18n/translate/el-gr.json b/src/renderer/src/i18n/translate/el-gr.json
index f60bb252d4..2ca2574bf0 100644
--- a/src/renderer/src/i18n/translate/el-gr.json
+++ b/src/renderer/src/i18n/translate/el-gr.json
@@ -773,6 +773,7 @@
"more": "Περισσότερα",
"name": "Όνομα",
"no_results": "Δεν βρέθηκαν αποτελέσματα",
+ "none": "Χωρίς",
"open": "Άνοιγμα",
"paste": "Επικόλληση",
"preview": "Προεπισκόπηση",
@@ -817,6 +818,8 @@
"openai-response": "Απάντηση OpenAI"
},
"error": {
+ "availableProviders": "Διαθέσιμοι πάροχοι",
+ "availableTools": "Διαθέσιμα εργαλεία",
"backup": {
"file_format": "Λάθος μορφή αρχείου που επιστρέφεται"
},
@@ -841,9 +844,13 @@
"quota_exceeded": "Η ημερήσια δωρεάν ποσόστωση {{quota}} tokens σας έχει εξαντληθεί. Παρακαλώ μεταβείτε στο {{provider}} για να λάβετε ένα κλειδί API και να ρυθμίσετε το κλειδί API για να συνεχίσετε τη χρήση.",
"response": "Σφάλμα. Εάν δεν έχετε ρυθμίσει το κλειδί API, πηγαίνετε στο ρυθμισμένα > παρέχοντας το πρόσωπο του μοντέλου"
},
+ "content": "Περιεχόμενο",
"data": "δεδομένα",
"detail": "Λεπτομέρειες σφάλματος",
"details": "Λεπτομέρειες",
+ "errors": "Λάθος",
+ "finishReason": "Αιτία λήξης",
+ "functionality": "λειτουργία",
"http": {
"400": "Σφάλμα ζητήματος, παρακαλώ ελέγξτε αν τα παράμετρα του ζητήματος είναι σωστά. Εάν έχετε αλλάξει τις ρυθμίσεις του μοντέλου, επαναφέρετε τις προεπιλεγμένες ρυθμίσεις.",
"401": "Αποτυχία επιβεβαίωσης ταυτότητας, παρακαλώ ελέγξτε αν η κλειδί API είναι σωστή",
@@ -855,16 +862,27 @@
"503": "Η υπηρεσία δεν είναι διαθέσιμη, παρακαλώ δοκιμάστε ξανά",
"504": "Υπερχρονισμός φάρων, παρακαλώ δοκιμάστε ξανά"
},
+ "lastError": "Τελευταίο σφάλμα",
+ "maxEmbeddingsPerCall": "Μέγιστες ενσωματώσεις ανά κλήση",
"message": "Μήνυμα σφάλματος",
"missing_user_message": "Αδυναμία εναλλαγής απάντησης μοντέλου: το αρχικό μήνυμα χρήστη έχει διαγραφεί. Παρακαλούμε στείλτε ένα νέο μήνυμα για να λάβετε απάντηση από αυτό το μοντέλο",
"model": {
"exists": "Το μοντέλο υπάρχει ήδη",
"not_exists": "Το μοντέλο δεν υπάρχει"
},
+ "modelId": "Αναγνωριστικό μοντέλου",
+ "modelType": "Τύπος μοντέλου",
"name": "Λάθος όνομα",
"no_api_key": "Δεν έχετε ρυθμίσει το κλειδί API",
+ "originalError": "Αρχικό σφάλμα",
+ "originalMessage": "Αρχικό μήνυμα",
+ "parameter": "παράμετροι",
"pause_placeholder": "Διακόπηκε",
+ "prompt": "συμβουλές",
+ "provider": "πάροχος",
+ "providerId": "Αναγνωριστικό παρόχου",
"provider_disabled": "Ο παρεχόμενος παροχός του μοντέλου δεν είναι ενεργοποιημένος",
+ "reason": "αιτία",
"render": {
"description": "Απέτυχε η ώθηση της εξίσωσης, παρακαλώ ελέγξτε το σωστό μορφάτι της",
"title": "Σφάλμα Παρασκήνιου"
@@ -872,13 +890,23 @@
"requestBody": "Περιεχόμενο αιτήματος",
"requestBodyValues": "Σώμα αιτήματος",
"requestUrl": "Μονοπάτι αιτήματος",
+ "response": "απάντηση",
"responseBody": "απάντηση περιεχομένου",
"responseHeaders": "Επικεφαλίδες απόκρισης",
+ "responses": "ανταπόκριση",
+ "role": "ρόλος",
"stack": "Πληροφορίες στοίβας",
"status": "Κωδικός κατάστασης",
"statusCode": "Κωδικός κατάστασης",
+ "statusText": "Κείμενο κατάστασης",
+ "text": "κείμενο",
+ "toolInput": "εισαγωγή εργαλείου",
+ "toolName": "Όνομα εργαλείου",
"unknown": "Άγνωστο σφάλμα",
- "user_message_not_found": "Αδυναμία εύρεσης της αρχικής μηνύματος χρήστη"
+ "usage": "δοσολογία",
+ "user_message_not_found": "Αδυναμία εύρεσης της αρχικής μηνύματος χρήστη",
+ "value": "τιμή",
+ "values": "τιμή"
},
"export": {
"assistant": "βοηθός",
diff --git a/src/renderer/src/i18n/translate/es-es.json b/src/renderer/src/i18n/translate/es-es.json
index fad12693bc..94a6a0d0cd 100644
--- a/src/renderer/src/i18n/translate/es-es.json
+++ b/src/renderer/src/i18n/translate/es-es.json
@@ -773,6 +773,7 @@
"more": "Más",
"name": "Nombre",
"no_results": "Sin resultados",
+ "none": "无",
"open": "Abrir",
"paste": "Pegar",
"preview": "Vista previa",
@@ -817,6 +818,8 @@
"openai-response": "Respuesta de OpenAI"
},
"error": {
+ "availableProviders": "Proveedores disponibles",
+ "availableTools": "Herramientas disponibles",
"backup": {
"file_format": "Formato de archivo de copia de seguridad incorrecto"
},
@@ -841,9 +844,13 @@
"quota_exceeded": "Su cuota gratuita diaria de {{quota}} tokens se ha agotado. Por favor, vaya a {{provider}} para obtener una clave API y configurar la clave API para continuar usando.",
"response": "Ha ocurrido un error, si no ha configurado la clave API, vaya a Configuración > Proveedor de modelos para configurar la clave"
},
+ "content": "contenido",
"data": "datos",
"detail": "Detalles del error",
"details": "Detalles",
+ "errors": "error",
+ "finishReason": "Razón de finalización",
+ "functionality": "función",
"http": {
"400": "Error en la solicitud, revise si los parámetros de la solicitud son correctos. Si modificó la configuración del modelo, restablezca a la configuración predeterminada",
"401": "Fallo en la autenticación, revise si la clave API es correcta",
@@ -855,16 +862,27 @@
"503": "Servicio no disponible, inténtelo de nuevo más tarde",
"504": "Tiempo de espera de la puerta de enlace, inténtelo de nuevo más tarde"
},
- "message": "错误信息",
+ "lastError": "Último error",
+ "maxEmbeddingsPerCall": "máximo de incrustaciones por llamada",
+ "message": "Mensaje de error",
"missing_user_message": "No se puede cambiar la respuesta del modelo: el mensaje original del usuario ha sido eliminado. Envíe un nuevo mensaje para obtener la respuesta de este modelo",
"model": {
"exists": "El modelo ya existe",
"not_exists": "El modelo no existe"
},
+ "modelId": "ID del modelo",
+ "modelType": "Tipo de modelo",
"name": "Nombre de error",
"no_api_key": "La clave API no está configurada",
+ "originalError": "Error original",
+ "originalMessage": "mensaje original",
+ "parameter": "parámetro",
"pause_placeholder": "Interrumpido",
+ "prompt": "prompt",
+ "provider": "proveedor",
+ "providerId": "ID del proveedor",
"provider_disabled": "El proveedor de modelos no está habilitado",
+ "reason": "causa",
"render": {
"description": "Error al renderizar la fórmula, por favor, compruebe si el formato de la fórmula es correcto",
"title": "Error de renderizado"
@@ -872,13 +890,23 @@
"requestBody": "Contenido de la solicitud",
"requestBodyValues": "Cuerpo de la solicitud",
"requestUrl": "Ruta de solicitud",
+ "response": "respuesta",
"responseBody": "Contenido de la respuesta",
"responseHeaders": "Encabezados de respuesta",
+ "responses": "respuesta",
+ "role": "Rol",
"stack": "Información de la pila",
- "status": "código de estado",
- "statusCode": "código de estado",
+ "status": "Estado",
+ "statusCode": "Código de estado",
+ "statusText": "Texto de estado",
+ "text": "Texto",
+ "toolInput": "Herramienta de entrada",
+ "toolName": "Nombre de la herramienta",
"unknown": "Error desconocido",
- "user_message_not_found": "No se pudo encontrar el mensaje original del usuario"
+ "usage": "Cantidad de uso",
+ "user_message_not_found": "No se pudo encontrar el mensaje original del usuario",
+ "value": "Valor",
+ "values": "Valor"
},
"export": {
"assistant": "Asistente",
diff --git a/src/renderer/src/i18n/translate/fr-fr.json b/src/renderer/src/i18n/translate/fr-fr.json
index 7c9df58208..0c929c697d 100644
--- a/src/renderer/src/i18n/translate/fr-fr.json
+++ b/src/renderer/src/i18n/translate/fr-fr.json
@@ -773,6 +773,7 @@
"more": "Plus",
"name": "Nom",
"no_results": "Aucun résultat",
+ "none": "Aucun",
"open": "Ouvrir",
"paste": "Coller",
"preview": "Aperçu",
@@ -817,6 +818,8 @@
"openai-response": "Réponse OpenAI"
},
"error": {
+ "availableProviders": "Fournisseurs disponibles",
+ "availableTools": "Outils disponibles",
"backup": {
"file_format": "Le format du fichier de sauvegarde est incorrect"
},
@@ -841,9 +844,13 @@
"quota_exceeded": "Votre quota gratuit quotidien de {{quota}} tokens a été épuisé. Veuillez vous rendre sur {{provider}} pour obtenir une clé API et configurer la clé API pour continuer à utiliser.",
"response": "Une erreur s'est produite, si l'API n'est pas configurée, veuillez aller dans Paramètres > Fournisseurs de modèles pour configurer la clé"
},
+ "content": "suivre l'instruction du système",
"data": "données",
"detail": "Détails de l'erreur",
"details": "Informations détaillées",
+ "errors": "erreur",
+ "finishReason": "Raison de la fin",
+ "functionality": "fonction",
"http": {
"400": "Erreur de requête, veuillez vérifier si les paramètres de la requête sont corrects. Si vous avez modifié les paramètres du modèle, réinitialisez-les aux paramètres par défaut.",
"401": "Échec de l'authentification, veuillez vérifier que votre clé API est correcte.",
@@ -855,16 +862,27 @@
"503": "Service indisponible, veuillez réessayer plus tard.",
"504": "Délai d'expiration de la passerelle, veuillez réessayer plus tard."
},
+ "lastError": "Dernière erreur",
+ "maxEmbeddingsPerCall": "Maximum d’intégrations par appel",
"message": "Erreur message",
"missing_user_message": "Impossible de changer de modèle de réponse : le message utilisateur d'origine a été supprimé. Veuillez envoyer un nouveau message pour obtenir une réponse de ce modèle.",
"model": {
"exists": "Le modèle existe déjà",
"not_exists": "Le modèle n'existe pas"
},
+ "modelId": "ID du modèle",
+ "modelType": "Type de modèle",
"name": "Nom d'erreur",
"no_api_key": "La clé API n'est pas configurée",
+ "originalError": "Erreur d'origine",
+ "originalMessage": "message original",
+ "parameter": "paramètre",
"pause_placeholder": "Прервано",
+ "prompt": "mot-clé",
+ "provider": "fournisseur",
+ "providerId": "ID du fournisseur",
"provider_disabled": "Le fournisseur de modèles n'est pas activé",
+ "reason": "raison",
"render": {
"description": "La formule n'a pas été rendue avec succès, veuillez vérifier si le format de la formule est correct",
"title": "Erreur de rendu"
@@ -872,13 +890,23 @@
"requestBody": "Contenu de la demande",
"requestBodyValues": "Corps de la requête",
"requestUrl": "Chemin de la requête",
+ "response": "réponse",
"responseBody": "Contenu de la réponse",
"responseHeaders": "En-têtes de réponse",
+ "responses": "réponse",
+ "role": "rôle",
"stack": "Informations de la pile",
"status": "Code d'état",
"statusCode": "Code d'état",
+ "statusText": "Texte d'état",
+ "text": "texte",
+ "toolInput": "entrée de l'outil",
+ "toolName": "Nom de l'outil",
"unknown": "Неизвестная ошибка",
- "user_message_not_found": "Impossible de trouver le message d'utilisateur original"
+ "usage": "Quantité",
+ "user_message_not_found": "Impossible de trouver le message d'utilisateur original",
+ "value": "valeur",
+ "values": "valeur"
},
"export": {
"assistant": "Assistant",
diff --git a/src/renderer/src/i18n/translate/ja-jp.json b/src/renderer/src/i18n/translate/ja-jp.json
index 97d2d4365f..10cd57db6a 100644
--- a/src/renderer/src/i18n/translate/ja-jp.json
+++ b/src/renderer/src/i18n/translate/ja-jp.json
@@ -773,6 +773,7 @@
"more": "もっと",
"name": "名前",
"no_results": "検索結果なし",
+ "none": "無",
"open": "開く",
"paste": "貼り付け",
"preview": "プレビュー",
@@ -817,6 +818,8 @@
"openai-response": "OpenAI-Response"
},
"error": {
+ "availableProviders": "利用可能なプロバイダー",
+ "availableTools": "利用可能なツール",
"backup": {
"file_format": "バックアップファイルの形式エラー"
},
@@ -841,9 +844,13 @@
"quota_exceeded": "本日の{{quota}}無料クォータが使い果たされました。{{provider}}でAPIキーを取得し、APIキーを設定して使用を続けてください。",
"response": "エラーが発生しました。APIキーが設定されていない場合は、設定 > プロバイダーでキーを設定してください"
},
+ "content": "内容",
"data": "データ",
"detail": "エラーの詳細",
"details": "詳細",
+ "errors": "エラー",
+ "finishReason": "終了理由",
+ "functionality": "機能",
"http": {
"400": "リクエストに失敗しました。リクエストパラメータが正しいか確認してください。モデルの設定を変更した場合は、デフォルトの設定にリセットしてください",
"401": "認証に失敗しました。APIキーが正しいか確認してください",
@@ -855,16 +862,27 @@
"503": "サービスが利用できません。後でもう一度試してください",
"504": "ゲートウェイタイムアウトが発生しました。後でもう一度試してください"
},
+ "lastError": "最後のエラー",
+ "maxEmbeddingsPerCall": "1回の呼び出しでの最大埋め込み数",
"message": "エラーメッセージ",
"missing_user_message": "モデル応答を切り替えられません:元のユーザーメッセージが削除されました。このモデルで応答を得るには、新しいメッセージを送信してください",
"model": {
"exists": "モデルが既に存在します",
"not_exists": "モデルが存在しません"
},
+ "modelId": "モデル ID",
+ "modelType": "モデルの種類",
"name": "エラー名",
"no_api_key": "APIキーが設定されていません",
+ "originalError": "元のエラー",
+ "originalMessage": "元のメッセージ",
+ "parameter": "パラメータ",
"pause_placeholder": "応答を一時停止しました",
+ "prompt": "プロンプトを表示する",
+ "provider": "プロバイダー",
+ "providerId": "プロバイダーID",
"provider_disabled": "モデルプロバイダーが有効になっていません",
+ "reason": "原因",
"render": {
"description": "メッセージの内容のレンダリングに失敗しました。メッセージの内容の形式が正しいか確認してください",
"title": "レンダリングエラー"
@@ -872,13 +890,23 @@
"requestBody": "要求されたコンテンツ",
"requestBodyValues": "リクエストボディ",
"requestUrl": "リクエストパス",
+ "response": "応答",
"responseBody": "レスポンス内容",
"responseHeaders": "レスポンスヘッダー",
+ "responses": "応答",
+ "role": "キャラクター",
"stack": "スタック情報",
"status": "ステータスコード",
"statusCode": "ステータスコード",
+ "statusText": "状態テキスト",
+ "text": "テキスト",
+ "toolInput": "\nツール入力\n",
+ "toolName": "ツール名",
"unknown": "不明なエラー",
- "user_message_not_found": "元のユーザーメッセージを見つけることができませんでした"
+ "usage": "用量",
+ "user_message_not_found": "元のユーザーメッセージを見つけることができませんでした",
+ "value": "値",
+ "values": "値"
},
"export": {
"assistant": "アシスタント",
diff --git a/src/renderer/src/i18n/translate/pt-pt.json b/src/renderer/src/i18n/translate/pt-pt.json
index d3c1d61cfb..4127b25391 100644
--- a/src/renderer/src/i18n/translate/pt-pt.json
+++ b/src/renderer/src/i18n/translate/pt-pt.json
@@ -773,6 +773,7 @@
"more": "Mais",
"name": "Nome",
"no_results": "Nenhum resultado",
+ "none": "Nenhum",
"open": "Abrir",
"paste": "Colar",
"preview": "Pré-visualização",
@@ -817,6 +818,8 @@
"openai-response": "Resposta OpenAI"
},
"error": {
+ "availableProviders": "Provedores disponíveis",
+ "availableTools": "Ferramentas disponíveis",
"backup": {
"file_format": "Formato do arquivo de backup está incorreto"
},
@@ -841,9 +844,13 @@
"quota_exceeded": "Sua cota gratuita diária de {{quota}} tokens foi esgotada. Por favor, vá para {{provider}} para obter uma chave API e configurar a chave API para continuar usando.",
"response": "Ocorreu um erro, se a chave da API não foi configurada, por favor vá para Configurações > Provedores de Modelo para configurar a chave"
},
+ "content": "conteúdo",
"data": "dados",
"detail": "Detalhes do erro",
"details": "Detalhes",
+ "errors": "erro",
+ "finishReason": "Motivo de término",
+ "functionality": "funcionalidade",
"http": {
"400": "Erro na solicitação, por favor verifique se os parâmetros da solicitação estão corretos. Se você alterou as configurações do modelo, redefina para as configurações padrão",
"401": "Falha na autenticação, por favor verifique se a chave da API está correta",
@@ -855,16 +862,27 @@
"503": "Serviço indisponível, por favor tente novamente mais tarde",
"504": "Tempo de espera do gateway excedido, por favor tente novamente mais tarde"
},
+ "lastError": "Último erro",
+ "maxEmbeddingsPerCall": "Máximo de incorporações por chamada",
"message": "Mensagem de erro",
"missing_user_message": "Não é possível alternar a resposta do modelo: a mensagem original do usuário foi excluída. Envie uma nova mensagem para obter a resposta deste modelo",
"model": {
"exists": "O modelo já existe",
"not_exists": "O modelo não existe"
},
+ "modelId": "ID do modelo",
+ "modelType": "Tipo de modelo",
"name": "Nome do erro",
"no_api_key": "A chave da API não foi configurada",
+ "originalError": "Erro original",
+ "originalMessage": "Mensagem original",
+ "parameter": "parâmetro",
"pause_placeholder": "Interrompido",
+ "prompt": "prompt",
+ "provider": "fornecedor",
+ "providerId": "ID do fornecedor",
"provider_disabled": "O provedor de modelos está desativado",
+ "reason": "causa",
"render": {
"description": "Falha ao renderizar a fórmula, por favor verifique se o formato da fórmula está correto",
"title": "Erro de Renderização"
@@ -872,13 +890,23 @@
"requestBody": "Conteúdo da solicitação",
"requestBodyValues": "Corpo da solicitação",
"requestUrl": "Caminho da solicitação",
+ "response": "resposta",
"responseBody": "Conteúdo da resposta",
"responseHeaders": "Cabeçalho de resposta",
+ "responses": "resposta",
+ "role": "personagem",
"stack": "Informações da pilha",
"status": "Código de status",
"statusCode": "Código de status",
+ "statusText": "Texto de estado",
+ "text": "texto",
+ "toolInput": "ferramenta de entrada",
+ "toolName": "Nome da ferramenta",
"unknown": "Erro desconhecido",
- "user_message_not_found": "Não foi possível encontrar a mensagem original do usuário"
+ "usage": "dosagem",
+ "user_message_not_found": "Não foi possível encontrar a mensagem original do usuário",
+ "value": "valor",
+ "values": "valor"
},
"export": {
"assistant": "Assistente",
diff --git a/src/renderer/src/i18n/translate/ru-ru.json b/src/renderer/src/i18n/translate/ru-ru.json
index 6bbc1136da..bae0264e88 100644
--- a/src/renderer/src/i18n/translate/ru-ru.json
+++ b/src/renderer/src/i18n/translate/ru-ru.json
@@ -773,6 +773,7 @@
"more": "Ещё",
"name": "Имя",
"no_results": "Результатов не найдено",
+ "none": "без",
"open": "Открыть",
"paste": "Вставить",
"preview": "Предварительный просмотр",
@@ -817,6 +818,8 @@
"openai-response": "OpenAI-Response"
},
"error": {
+ "availableProviders": "Доступные провайдеры",
+ "availableTools": "Доступные инструменты",
"backup": {
"file_format": "Ошибка формата файла резервной копии"
},
@@ -841,9 +844,13 @@
"quota_exceeded": "Ваша ежедневная {{quota}} бесплатная квота исчерпана. Пожалуйста, перейдите в {{provider}} для получения ключа API и настройте ключ API для продолжения использования.",
"response": "Что-то пошло не так. Пожалуйста, проверьте, установлен ли ваш ключ API в Настройки > Провайдеры"
},
+ "content": "Содержание",
"data": "данные",
"detail": "Детали ошибки",
"details": "Подробности",
+ "errors": "ошибка",
+ "finishReason": "Причина завершения",
+ "functionality": "функция",
"http": {
"400": "Не удалось выполнить запрос. Пожалуйста, проверьте, правильно ли настроены параметры запроса. Если вы изменили настройки модели, пожалуйста, сбросьте их до значений по умолчанию",
"401": "Не удалось пройти аутентификацию. Пожалуйста, проверьте, правильно ли настроен ваш ключ API",
@@ -855,16 +862,27 @@
"503": "Серверная ошибка. Пожалуйста, попробуйте позже",
"504": "Серверная ошибка. Пожалуйста, попробуйте позже"
},
+ "lastError": "Последняя ошибка",
+ "maxEmbeddingsPerCall": "Максимальное количество вложений на вызов",
"message": "Сообщение об ошибке",
"missing_user_message": "Невозможно изменить модель ответа: исходное сообщение пользователя было удалено. Пожалуйста, отправьте новое сообщение, чтобы получить ответ от этой модели",
"model": {
"exists": "Модель уже существует",
"not_exists": "Модель не существует"
},
- "name": "错误名称",
+ "modelId": "ID модели",
+ "modelType": "Тип модели",
+ "name": "Название ошибки",
"no_api_key": "Ключ API не настроен",
+ "originalError": "Исходная ошибка",
+ "originalMessage": "исходное сообщение",
+ "parameter": "параметр",
"pause_placeholder": "Получение ответа приостановлено",
+ "prompt": "подсказка",
+ "provider": "поставщик",
+ "providerId": "ID поставщика",
"provider_disabled": "Провайдер моделей не включен",
+ "reason": "причина",
"render": {
"description": "Не удалось рендерить содержимое сообщения. Пожалуйста, проверьте, правильно ли формат содержимого сообщения",
"title": "Ошибка рендеринга"
@@ -872,13 +890,23 @@
"requestBody": "Запрашиваемый контент",
"requestBodyValues": "Тело запроса",
"requestUrl": "Путь запроса",
+ "response": "ответ",
"responseBody": "Содержание ответа",
"responseHeaders": "Заголовки ответа",
+ "responses": "отклик",
+ "role": "роль",
"stack": "Информация стека",
"status": "Код статуса",
"statusCode": "Код состояния",
+ "statusText": "Текст состояния",
+ "text": "текст",
+ "toolInput": "ввод инструмента",
+ "toolName": "имя инструмента",
"unknown": "Неизвестная ошибка",
- "user_message_not_found": "Не удалось найти исходное сообщение пользователя"
+ "usage": "Дозировка",
+ "user_message_not_found": "Не удалось найти исходное сообщение пользователя",
+ "value": "значение",
+ "values": "значение"
},
"export": {
"assistant": "Ассистент",
diff --git a/src/renderer/src/pages/home/Messages/Blocks/ErrorBlock.tsx b/src/renderer/src/pages/home/Messages/Blocks/ErrorBlock.tsx
index f4eb8d1dd6..9fa6359472 100644
--- a/src/renderer/src/pages/home/Messages/Blocks/ErrorBlock.tsx
+++ b/src/renderer/src/pages/home/Messages/Blocks/ErrorBlock.tsx
@@ -6,10 +6,29 @@ import { useAppDispatch } from '@renderer/store'
import { removeBlocksThunk } from '@renderer/store/thunk/messageThunk'
import {
isSerializedAiSdkAPICallError,
+ isSerializedAiSdkDownloadError,
isSerializedAiSdkError,
+ isSerializedAiSdkErrorUnion,
+ isSerializedAiSdkInvalidArgumentError,
+ isSerializedAiSdkInvalidDataContentError,
+ isSerializedAiSdkInvalidMessageRoleError,
+ isSerializedAiSdkInvalidPromptError,
+ isSerializedAiSdkInvalidToolInputError,
+ isSerializedAiSdkJSONParseError,
+ isSerializedAiSdkMessageConversionError,
+ isSerializedAiSdkNoObjectGeneratedError,
+ isSerializedAiSdkNoSpeechGeneratedError,
+ isSerializedAiSdkNoSuchModelError,
+ isSerializedAiSdkNoSuchProviderError,
+ isSerializedAiSdkNoSuchToolError,
+ isSerializedAiSdkRetryError,
+ isSerializedAiSdkToolCallRepairError,
+ isSerializedAiSdkTooManyEmbeddingValuesForCallError,
+ isSerializedAiSdkTypeValidationError,
+ isSerializedAiSdkUnsupportedFunctionalityError,
isSerializedError,
- SerializedAiSdkAPICallError,
SerializedAiSdkError,
+ SerializedAiSdkErrorUnion,
SerializedError
} from '@renderer/types/error'
import type { ErrorMessageBlock, Message } from '@renderer/types/newMessage'
@@ -167,10 +186,7 @@ const ErrorDetailModal: React.FC = ({ open, onClose, erro
const renderErrorDetails = (error?: SerializedError) => {
if (!error) return {t('error.unknown')}
- if (isSerializedAiSdkAPICallError(error)) {
- return
- }
- if (isSerializedAiSdkError(error)) {
+ if (isSerializedAiSdkErrorUnion(error)) {
return
}
return (
@@ -290,7 +306,7 @@ const BuiltinError = ({ error }: { error: SerializedError }) => {
}
// 作为 base,渲染公共字段,应当在 ErrorDetailList 中渲染
-const AiSdkError = ({ error }: { error: SerializedAiSdkError }) => {
+const AiSdkErrorBase = ({ error }: { error: SerializedAiSdkError }) => {
const { t } = useTranslation()
const cause = error.cause
return (
@@ -306,60 +322,289 @@ const AiSdkError = ({ error }: { error: SerializedAiSdkError }) => {
)
}
-const AiApiCallError = ({ error }: { error: SerializedAiSdkAPICallError }) => {
+const AiSdkError = ({ error }: { error: SerializedAiSdkErrorUnion }) => {
const { t } = useTranslation()
- // 这些字段是 unknown 类型,暂且不清楚都可能是什么类型,总之先覆盖下大部分场景
- const requestBodyValues = safeToString(error.requestBodyValues)
- const data = safeToString(error.data)
-
return (
-
+
- {error.url && (
+ {(isSerializedAiSdkAPICallError(error) || isSerializedAiSdkDownloadError(error)) && (
+ <>
+ {error.statusCode && (
+
+ {t('error.statusCode')}:
+ {error.statusCode}
+
+ )}
+ {error.url && (
+
+ {t('error.requestUrl')}:
+ {error.url}
+
+ )}
+ >
+ )}
+
+ {isSerializedAiSdkAPICallError(error) && (
+ <>
+ {error.requestBodyValues && (
+
+ {t('error.requestBodyValues')}:
+
+
+ )}
+
+ {error.responseHeaders && (
+
+ {t('error.responseHeaders')}:
+
+
+ )}
+
+ {error.responseBody && (
+
+ {t('error.responseBody')}:
+
+
+ )}
+
+ {error.data && (
+
+ {t('error.data')}:
+
+
+ )}
+ >
+ )}
+
+ {isSerializedAiSdkDownloadError(error) && (
+ <>
+ {error.statusText && (
+
+ {t('error.statusText')}:
+ {error.statusText}
+
+ )}
+ >
+ )}
+
+ {isSerializedAiSdkInvalidArgumentError(error) && (
+ <>
+ {error.parameter && (
+
+ {t('error.parameter')}:
+ {error.parameter}
+
+ )}
+ >
+ )}
+
+ {(isSerializedAiSdkInvalidArgumentError(error) || isSerializedAiSdkTypeValidationError(error)) && (
+ <>
+ {error.value && (
+
+ {t('error.value')}:
+ {safeToString(error.value)}
+
+ )}
+ >
+ )}
+
+ {isSerializedAiSdkInvalidDataContentError(error) && (
- {t('error.requestUrl')}:
- {error.url}
+ {t('error.content')}:
+ {safeToString(error.content)}
)}
- {requestBodyValues && (
+ {isSerializedAiSdkInvalidMessageRoleError(error) && (
- {t('error.requestBodyValues')}:
-
+ {t('error.role')}:
+ {error.role}
)}
- {error.statusCode && (
+ {isSerializedAiSdkInvalidPromptError(error) && (
- {t('error.statusCode')}:
- {error.statusCode}
-
- )}
- {error.responseHeaders && (
-
- {t('error.responseHeaders')}:
-
+ {t('error.prompt')}:
+ {safeToString(error.prompt)}
)}
- {error.responseBody && (
+ {isSerializedAiSdkInvalidToolInputError(error) && (
+ <>
+ {error.toolName && (
+
+ {t('error.toolName')}:
+ {error.toolName}
+
+ )}
+ {error.toolInput && (
+
+ {t('error.toolInput')}:
+ {error.toolInput}
+
+ )}
+ >
+ )}
+
+ {(isSerializedAiSdkJSONParseError(error) || isSerializedAiSdkNoObjectGeneratedError(error)) && (
- {t('error.responseBody')}:
-
+ {t('error.text')}:
+ {error.text}
)}
- {data && (
+ {isSerializedAiSdkMessageConversionError(error) && (
- {t('error.data')}:
-
+ {t('error.originalMessage')}:
+ {safeToString(error.originalMessage)}
+
+ )}
+
+ {isSerializedAiSdkNoSpeechGeneratedError(error) && (
+
+ {t('error.responses')}:
+ {error.responses.join(', ')}
+
+ )}
+
+ {isSerializedAiSdkNoObjectGeneratedError(error) && (
+ <>
+ {error.response && (
+
+ {t('error.response')}:
+ {safeToString(error.response)}
+
+ )}
+ {error.usage && (
+
+ {t('error.usage')}:
+ {safeToString(error.usage)}
+
+ )}
+ {error.finishReason && (
+
+ {t('error.finishReason')}:
+ {error.finishReason}
+
+ )}
+ >
+ )}
+
+ {(isSerializedAiSdkNoSuchModelError(error) ||
+ isSerializedAiSdkNoSuchProviderError(error) ||
+ isSerializedAiSdkTooManyEmbeddingValuesForCallError(error)) && (
+
+ {t('error.modelId')}:
+ {error.modelId}
+
+ )}
+
+ {(isSerializedAiSdkNoSuchModelError(error) || isSerializedAiSdkNoSuchProviderError(error)) && (
+
+ {t('error.modelType')}:
+ {error.modelType}
+
+ )}
+
+ {isSerializedAiSdkNoSuchProviderError(error) && (
+ <>
+
+ {t('error.providerId')}:
+ {error.providerId}
+
+
+
+ {t('error.availableProviders')}:
+ {error.availableProviders.join(', ')}
+
+ >
+ )}
+
+ {isSerializedAiSdkNoSuchToolError(error) && (
+ <>
+
+ {t('error.toolName')}:
+ {error.toolName}
+
+ {error.availableTools && (
+
+ {t('error.availableTools')}:
+ {error.availableTools?.join(', ') || t('common.none')}
+
+ )}
+ >
+ )}
+
+ {isSerializedAiSdkRetryError(error) && (
+ <>
+ {error.reason && (
+
+ {t('error.reason')}:
+ {error.reason}
+
+ )}
+ {error.lastError && (
+
+ {t('error.lastError')}:
+ {safeToString(error.lastError)}
+
+ )}
+ {error.errors && error.errors.length > 0 && (
+
+ {t('error.errors')}:
+ {error.errors.map((e) => safeToString(e)).join('\n\n')}
+
+ )}
+ >
+ )}
+
+ {isSerializedAiSdkTooManyEmbeddingValuesForCallError(error) && (
+ <>
+ {error.provider && (
+
+ {t('error.provider')}:
+ {error.provider}
+
+ )}
+ {error.maxEmbeddingsPerCall && (
+
+ {t('error.maxEmbeddingsPerCall')}:
+ {error.maxEmbeddingsPerCall}
+
+ )}
+ {error.values && (
+
+ {t('error.values')}:
+ {safeToString(error.values)}
+
+ )}
+ >
+ )}
+
+ {isSerializedAiSdkToolCallRepairError(error) && (
+
+ {t('error.originalError')}:
+ {safeToString(error.originalError)}
+
+ )}
+
+ {isSerializedAiSdkUnsupportedFunctionalityError(error) && (
+
+ {t('error.functionality')}:
+ {error.functionality}
)}
diff --git a/src/renderer/src/types/aiCoreTypes.ts b/src/renderer/src/types/aiCoreTypes.ts
index 614211a5c7..e93218ab9e 100644
--- a/src/renderer/src/types/aiCoreTypes.ts
+++ b/src/renderer/src/types/aiCoreTypes.ts
@@ -1,4 +1,4 @@
-import type { AISDKError, APICallError, ImageModel, LanguageModel } from 'ai'
+import type { ImageModel, LanguageModel } from 'ai'
import { generateObject, generateText, ModelMessage, streamObject, streamText } from 'ai'
export type StreamTextParams = Omit[0], 'model' | 'messages'> &
@@ -27,6 +27,3 @@ export type StreamObjectParams = Omit[0], 'model
export type GenerateObjectParams = Omit[0], 'model'>
export type AiSdkModel = LanguageModel | ImageModel
-
-// 该类型用于格式化错误信息,目前只处理 APICallError,待扩展
-export type AiSdkErrorUnion = AISDKError | APICallError
diff --git a/src/renderer/src/types/error.ts b/src/renderer/src/types/error.ts
index 2439eaa123..c260c9c09f 100644
--- a/src/renderer/src/types/error.ts
+++ b/src/renderer/src/types/error.ts
@@ -1,3 +1,25 @@
+import {
+ AISDKError,
+ APICallError,
+ DownloadError,
+ FinishReason,
+ InvalidArgumentError,
+ InvalidDataContentError,
+ InvalidMessageRoleError,
+ InvalidPromptError,
+ InvalidToolInputError,
+ JSONParseError,
+ MessageConversionError,
+ NoObjectGeneratedError,
+ NoSuchModelError,
+ NoSuchProviderError,
+ NoSuchToolError,
+ RetryError,
+ ToolCallRepairError,
+ TypeValidationError,
+ UnsupportedFunctionalityError
+} from 'ai'
+
import { Serializable } from './serialize'
export interface SerializedError {
@@ -6,7 +28,7 @@ export interface SerializedError {
stack: string | null
[key: string]: Serializable
}
-export const isSerializedError = (error: Record): error is SerializedAiSdkError => {
+export const isSerializedError = (error: Record): error is SerializedError => {
return 'name' in error && 'message' in error && 'stack' in error
}
export interface SerializedAiSdkError extends SerializedError {
@@ -28,5 +50,276 @@ export interface SerializedAiSdkAPICallError extends SerializedAiSdkError {
}
export const isSerializedAiSdkAPICallError = (error: SerializedError): error is SerializedAiSdkAPICallError => {
- return isSerializedAiSdkError(error) && 'url' in error && 'requestBodyValues' in error && 'isRetryable' in error
+ return (
+ isSerializedAiSdkError(error) &&
+ 'url' in error &&
+ 'requestBodyValues' in error &&
+ 'statusCode' in error &&
+ 'responseHeaders' in error &&
+ 'responseBody' in error &&
+ 'isRetryable' in error &&
+ 'data' in error
+ )
+}
+
+export interface SerializedAiSdkDownloadError extends SerializedAiSdkError {
+ readonly url: string
+ readonly statusCode: number | null
+ readonly statusText: string | null
+}
+
+export const isSerializedAiSdkDownloadError = (error: SerializedError): error is SerializedAiSdkDownloadError => {
+ return isSerializedAiSdkError(error) && 'url' in error && 'statusCode' in error && 'statusText' in error
+}
+
+export interface SerializedAiSdkInvalidArgumentError extends SerializedAiSdkError {
+ readonly parameter: string
+ readonly value: Serializable
+}
+
+export const isSerializedAiSdkInvalidArgumentError = (
+ error: SerializedError
+): error is SerializedAiSdkInvalidArgumentError => {
+ return isSerializedAiSdkError(error) && 'parameter' in error && 'value' in error
+}
+
+export interface SerializedAiSdkInvalidDataContentError extends SerializedAiSdkError {
+ readonly content: Serializable
+}
+
+export const isSerializedAiSdkInvalidDataContentError = (
+ error: SerializedError
+): error is SerializedAiSdkInvalidDataContentError => {
+ return isSerializedAiSdkError(error) && 'content' in error
+}
+
+export interface SerializedAiSdkInvalidMessageRoleError extends SerializedAiSdkError {
+ readonly role: string
+}
+
+export const isSerializedAiSdkInvalidMessageRoleError = (
+ error: SerializedError
+): error is SerializedAiSdkInvalidMessageRoleError => {
+ return isSerializedAiSdkError(error) && 'role' in error
+}
+
+export interface SerializedAiSdkInvalidPromptError extends SerializedAiSdkError {
+ readonly prompt: Serializable
+}
+
+export const isSerializedAiSdkInvalidPromptError = (
+ error: SerializedError
+): error is SerializedAiSdkInvalidPromptError => {
+ return isSerializedAiSdkError(error) && 'prompt' in error
+}
+
+export interface SerializedAiSdkInvalidToolInputError extends SerializedAiSdkError {
+ readonly toolName: string
+ readonly toolInput: string
+}
+
+export const isSerializedAiSdkInvalidToolInputError = (
+ error: SerializedError
+): error is SerializedAiSdkInvalidToolInputError => {
+ return isSerializedAiSdkError(error) && 'toolName' in error && 'toolInput' in error
+}
+
+export interface SerializedAiSdkJSONParseError extends SerializedAiSdkError {
+ readonly text: string
+}
+
+export const isSerializedAiSdkJSONParseError = (error: SerializedError): error is SerializedAiSdkJSONParseError => {
+ return isSerializedAiSdkError(error) && 'text' in error
+}
+
+export interface SerializedAiSdkMessageConversionError extends SerializedAiSdkError {
+ readonly originalMessage: Serializable
+}
+
+export const isSerializedAiSdkMessageConversionError = (
+ error: SerializedError
+): error is SerializedAiSdkMessageConversionError => {
+ return isSerializedAiSdkError(error) && 'originalMessage' in error
+}
+
+// This type is not exported by aisdk.
+// See https://github.com/vercel/ai/issues/8466
+export interface SerializedAiSdkNoSpeechGeneratedError extends SerializedAiSdkError {
+ readonly responses: string[]
+}
+
+export const isSerializedAiSdkNoSpeechGeneratedError = (
+ error: SerializedError
+): error is SerializedAiSdkNoSpeechGeneratedError => {
+ return isSerializedAiSdkError(error) && 'responses' in error
+}
+
+export interface SerializedAiSdkNoObjectGeneratedError extends SerializedAiSdkError {
+ readonly text: string | null
+ readonly response: Serializable
+ readonly usage: Serializable
+ readonly finishReason: FinishReason | null
+}
+
+export const isSerializedAiSdkNoObjectGeneratedError = (
+ error: SerializedError
+): error is SerializedAiSdkNoObjectGeneratedError => {
+ return (
+ isSerializedAiSdkError(error) &&
+ 'text' in error &&
+ 'response' in error &&
+ 'usage' in error &&
+ 'finishReason' in error
+ )
+}
+
+export interface SerializedAiSdkNoSuchModelError extends SerializedAiSdkError {
+ readonly modelId: string
+ readonly modelType: NoSuchModelError['modelType']
+}
+
+export const isSerializedAiSdkNoSuchModelError = (error: SerializedError): error is SerializedAiSdkNoSuchModelError => {
+ return isSerializedAiSdkError(error) && 'modelId' in error && 'modelType' in error
+}
+
+export interface SerializedAiSdkNoSuchProviderError extends SerializedAiSdkNoSuchModelError {
+ readonly providerId: string
+ readonly availableProviders: string[]
+}
+
+export const isSerializedAiSdkNoSuchProviderError = (
+ error: SerializedError
+): error is SerializedAiSdkNoSuchProviderError => {
+ return isSerializedAiSdkNoSuchModelError(error) && 'providerId' in error && 'availableProviders' in error
+}
+
+export interface SerializedAiSdkNoSuchToolError extends SerializedAiSdkError {
+ readonly toolName: string
+ readonly availableTools: string[] | null
+}
+
+export const isSerializedAiSdkNoSuchToolError = (error: SerializedError): error is SerializedAiSdkNoSuchToolError => {
+ return isSerializedAiSdkError(error) && 'toolName' in error && 'availableTools' in error
+}
+
+export interface SerializedAiSdkRetryError extends SerializedAiSdkError {
+ readonly reason: string
+ readonly lastError: Serializable
+ readonly errors: Serializable[]
+}
+
+export const isSerializedAiSdkRetryError = (error: SerializedError): error is SerializedAiSdkRetryError => {
+ return isSerializedAiSdkError(error) && 'reason' in error && 'lastError' in error && 'errors' in error
+}
+
+// This type is not exported by aisdk.
+// See: https://github.com/vercel/ai/pull/8464
+export interface SerializedAiSdkTooManyEmbeddingValuesForCallError extends SerializedAiSdkError {
+ readonly provider: string
+ readonly modelId: string
+ readonly maxEmbeddingsPerCall: number
+ readonly values: Serializable[]
+}
+
+export const isSerializedAiSdkTooManyEmbeddingValuesForCallError = (
+ error: SerializedError
+): error is SerializedAiSdkTooManyEmbeddingValuesForCallError => {
+ return (
+ isSerializedAiSdkError(error) &&
+ 'provider' in error &&
+ 'modelId' in error &&
+ 'maxEmbeddingsPerCall' in error &&
+ 'values' in error
+ )
+}
+
+export interface SerializedAiSdkToolCallRepairError extends SerializedAiSdkError {
+ readonly originalError: SerializedAiSdkNoSuchToolError | SerializedAiSdkInvalidToolInputError
+}
+
+export const isSerializedAiSdkToolCallRepairError = (
+ error: SerializedError
+): error is SerializedAiSdkToolCallRepairError => {
+ return isSerializedAiSdkError(error) && 'originalError' in error
+}
+export interface SerializedAiSdkTypeValidationError extends SerializedAiSdkError {
+ readonly value: Serializable
+}
+
+export const isSerializedAiSdkTypeValidationError = (
+ error: SerializedError
+): error is SerializedAiSdkTypeValidationError => {
+ return isSerializedAiSdkError(error) && 'value' in error && !('parameter' in error)
+}
+
+export interface SerializedAiSdkUnsupportedFunctionalityError extends SerializedAiSdkError {
+ readonly functionality: string
+}
+
+export const isSerializedAiSdkUnsupportedFunctionalityError = (
+ error: SerializedError
+): error is SerializedAiSdkUnsupportedFunctionalityError => {
+ return isSerializedAiSdkError(error) && 'functionality' in error
+}
+
+export type AiSdkErrorUnion =
+ | AISDKError
+ | APICallError
+ | DownloadError
+ | InvalidArgumentError
+ | InvalidDataContentError
+ | InvalidMessageRoleError
+ | InvalidPromptError
+ | InvalidToolInputError
+ | JSONParseError
+ | MessageConversionError
+ | NoObjectGeneratedError
+ | NoSuchModelError
+ | NoSuchProviderError
+ | NoSuchToolError
+ | RetryError
+ | ToolCallRepairError
+ | TypeValidationError
+ | UnsupportedFunctionalityError
+
+export type SerializedAiSdkErrorUnion =
+ | SerializedAiSdkAPICallError
+ | SerializedAiSdkDownloadError
+ | SerializedAiSdkInvalidArgumentError
+ | SerializedAiSdkInvalidDataContentError
+ | SerializedAiSdkInvalidMessageRoleError
+ | SerializedAiSdkInvalidPromptError
+ | SerializedAiSdkInvalidToolInputError
+ | SerializedAiSdkJSONParseError
+ | SerializedAiSdkMessageConversionError
+ | SerializedAiSdkNoSpeechGeneratedError
+ | SerializedAiSdkNoObjectGeneratedError
+ | SerializedAiSdkNoSuchModelError
+ | SerializedAiSdkNoSuchProviderError
+ | SerializedAiSdkNoSuchToolError
+ | SerializedAiSdkRetryError
+ | SerializedAiSdkToolCallRepairError
+ | SerializedAiSdkTypeValidationError
+ | SerializedAiSdkUnsupportedFunctionalityError
+
+export const isSerializedAiSdkErrorUnion = (error: SerializedError): error is SerializedAiSdkErrorUnion => {
+ return (
+ isSerializedAiSdkAPICallError(error) ||
+ isSerializedAiSdkDownloadError(error) ||
+ isSerializedAiSdkInvalidArgumentError(error) ||
+ isSerializedAiSdkInvalidDataContentError(error) ||
+ isSerializedAiSdkInvalidMessageRoleError(error) ||
+ isSerializedAiSdkInvalidPromptError(error) ||
+ isSerializedAiSdkInvalidToolInputError(error) ||
+ isSerializedAiSdkJSONParseError(error) ||
+ isSerializedAiSdkMessageConversionError(error) ||
+ isSerializedAiSdkNoObjectGeneratedError(error) ||
+ isSerializedAiSdkNoSuchModelError(error) ||
+ isSerializedAiSdkNoSuchProviderError(error) ||
+ isSerializedAiSdkNoSuchToolError(error) ||
+ isSerializedAiSdkRetryError(error) ||
+ isSerializedAiSdkToolCallRepairError(error) ||
+ isSerializedAiSdkTypeValidationError(error) ||
+ isSerializedAiSdkUnsupportedFunctionalityError(error)
+ )
}
diff --git a/src/renderer/src/utils/error.ts b/src/renderer/src/utils/error.ts
index 759c1cf512..a1640fd99d 100644
--- a/src/renderer/src/utils/error.ts
+++ b/src/renderer/src/utils/error.ts
@@ -1,17 +1,18 @@
-import { loggerService } from '@logger'
import {
+ AiSdkErrorUnion,
isSerializedAiSdkAPICallError,
- SerializedAiSdkAPICallError,
SerializedAiSdkError,
+ SerializedAiSdkInvalidToolInputError,
+ SerializedAiSdkNoSuchToolError,
SerializedError
} from '@renderer/types/error'
-import { AISDKError, APICallError } from 'ai'
+import { InvalidToolInputError, NoSuchToolError } from 'ai'
import { t } from 'i18next'
import z from 'zod'
import { safeSerialize } from './serialize'
-const logger = loggerService.withContext('Utils:error')
+// const logger = loggerService.withContext('Utils:error')
export function getErrorDetails(err: any, seen = new WeakSet()): any {
// Handle circular references
@@ -95,33 +96,77 @@ export const formatMcpError = (error: any) => {
return error.message
}
-export const serializeError = (error: AISDKError): SerializedError => {
- const baseError = {
- name: error.name,
- message: error.message,
+const getBaseError = (error: Error) => {
+ return {
+ name: error.name ?? null,
+ message: error.message ?? null,
stack: error.stack ?? null,
cause: error.cause ? String(error.cause) : null
+ } as const
+}
+
+const serializeInvalidToolInputError = (error: InvalidToolInputError): SerializedAiSdkInvalidToolInputError => {
+ const baseError = getBaseError(error)
+ return {
+ ...baseError,
+ toolName: error.toolName,
+ toolInput: error.toolInput
+ } satisfies SerializedAiSdkInvalidToolInputError
+}
+
+const serializeNoSuchToolError = (error: NoSuchToolError): SerializedAiSdkNoSuchToolError => {
+ const baseError = getBaseError(error)
+ return {
+ ...baseError,
+ toolName: error.toolName ?? null,
+ availableTools: error.availableTools ?? null
+ } satisfies SerializedAiSdkNoSuchToolError
+}
+
+export const serializeError = (error: AiSdkErrorUnion): SerializedError => {
+ // 统一所有可能的错误字段
+ const serializedError: SerializedError = {
+ name: error.name ?? null,
+ message: error.message ?? null,
+ stack: error.stack ?? null,
+ cause: safeSerialize(error.cause)
}
- if (APICallError.isInstance(error)) {
- let content = error.message === '' ? error.responseBody || 'Unknown error' : error.message
- try {
- const obj = JSON.parse(content)
- content = obj.error.message
- } catch (e: any) {
- logger.warn('Error parsing error response body:', e)
- }
- return {
- ...baseError,
- url: error.url,
- requestBodyValues: safeSerialize(error.requestBodyValues),
- statusCode: error.statusCode ?? null,
- responseBody: content,
- isRetryable: error.isRetryable,
- data: safeSerialize(error.data),
- responseHeaders: error.responseHeaders ?? null
- } satisfies SerializedAiSdkAPICallError
- }
- return baseError
+
+ if ('url' in error) serializedError.url = error.url
+ if ('requestBodyValues' in error) serializedError.requestBodyValues = safeSerialize(error.requestBodyValues)
+ if ('statusCode' in error) serializedError.statusCode = error.statusCode ?? null
+ if ('responseBody' in error) serializedError.responseBody = error.responseBody ?? null
+ if ('isRetryable' in error) serializedError.isRetryable = error.isRetryable
+ if ('data' in error) serializedError.data = safeSerialize(error.data)
+ if ('responseHeaders' in error) serializedError.responseHeaders = error.responseHeaders ?? null
+ if ('statusText' in error) serializedError.statusText = error.statusText ?? null
+ if ('parameter' in error) serializedError.parameter = error.parameter
+ if ('value' in error) serializedError.value = safeSerialize(error.value)
+ if ('content' in error) serializedError.content = safeSerialize(error.content)
+ if ('role' in error) serializedError.role = error.role
+ if ('prompt' in error) serializedError.prompt = safeSerialize(error.prompt)
+ if ('toolName' in error) serializedError.toolName = error.toolName
+ if ('toolInput' in error) serializedError.toolInput = error.toolInput
+ if ('text' in error) serializedError.text = error.text ?? null
+ if ('originalMessage' in error) serializedError.originalMessage = safeSerialize(error.originalMessage)
+ if ('response' in error) serializedError.response = error.response ?? null
+ if ('usage' in error) serializedError.usage = safeSerialize(error.usage)
+ if ('finishReason' in error) serializedError.finishReason = error.finishReason ?? null
+ if ('modelId' in error) serializedError.modelId = error.modelId
+ if ('modelType' in error) serializedError.modelType = error.modelType
+ if ('providerId' in error) serializedError.providerId = error.providerId
+ if ('availableProviders' in error) serializedError.availableProviders = error.availableProviders
+ if ('availableTools' in error) serializedError.availableTools = error.availableTools ?? null
+ if ('reason' in error) serializedError.reason = error.reason
+ if ('lastError' in error) serializedError.lastError = safeSerialize(error.lastError)
+ if ('errors' in error) serializedError.errors = error.errors.map((err: unknown) => safeSerialize(err))
+ if ('originalError' in error)
+ serializedError.originalError = InvalidToolInputError.isInstance(error.originalError)
+ ? serializeInvalidToolInputError(error.originalError)
+ : serializeNoSuchToolError(error.originalError)
+ if ('functionality' in error) serializedError.functionality = error.functionality
+
+ return serializedError
}
/**
* 格式化 Zod 验证错误信息为可读的字符串