From 64204251e806966f45710ce3ccce368205b0cde5 Mon Sep 17 00:00:00 2001 From: shiquda Date: Fri, 25 Apr 2025 08:59:41 +0800 Subject: [PATCH] feat: support preview of MCP call results (#5236) --- src/renderer/src/i18n/locales/en-us.json | 4 +- src/renderer/src/i18n/locales/ja-jp.json | 4 +- src/renderer/src/i18n/locales/ru-ru.json | 4 +- src/renderer/src/i18n/locales/zh-cn.json | 4 +- src/renderer/src/i18n/locales/zh-tw.json | 4 +- src/renderer/src/i18n/translate/el-gr.json | 4 +- src/renderer/src/i18n/translate/es-es.json | 4 +- src/renderer/src/i18n/translate/fr-fr.json | 4 +- src/renderer/src/i18n/translate/pt-pt.json | 4 +- .../src/pages/home/Messages/MessageTools.tsx | 74 ++++++++++++++++--- 10 files changed, 89 insertions(+), 21 deletions(-) diff --git a/src/renderer/src/i18n/locales/en-us.json b/src/renderer/src/i18n/locales/en-us.json index e4782846f0..4d791a7c77 100644 --- a/src/renderer/src/i18n/locales/en-us.json +++ b/src/renderer/src/i18n/locales/en-us.json @@ -562,7 +562,9 @@ "tools": { "completed": "Completed", "invoking": "Invoking", - "error": "Error occurred" + "error": "Error occurred", + "raw": "Raw", + "preview": "Preview" }, "topic.added": "New topic added", "upgrade.success.button": "Restart", diff --git a/src/renderer/src/i18n/locales/ja-jp.json b/src/renderer/src/i18n/locales/ja-jp.json index b575262d9f..69bb120e9c 100644 --- a/src/renderer/src/i18n/locales/ja-jp.json +++ b/src/renderer/src/i18n/locales/ja-jp.json @@ -561,7 +561,9 @@ "tools": { "completed": "完了", "invoking": "呼び出し中", - "error": "エラーが発生しました" + "error": "エラーが発生しました", + "raw": "生データ", + "preview": "プレビュー" }, "topic.added": "新しいトピックが追加されました", "upgrade.success.button": "再起動", diff --git a/src/renderer/src/i18n/locales/ru-ru.json b/src/renderer/src/i18n/locales/ru-ru.json index 758ddd9f0a..2b0eb57997 100644 --- a/src/renderer/src/i18n/locales/ru-ru.json +++ b/src/renderer/src/i18n/locales/ru-ru.json @@ -562,7 +562,9 @@ "tools": { "completed": "Завершено", "invoking": "Вызов", - "error": "Произошла ошибка" + "error": "Произошла ошибка", + "raw": "Исходный", + "preview": "Предпросмотр" }, "topic.added": "Новый топик добавлен", "upgrade.success.button": "Перезапустить", diff --git a/src/renderer/src/i18n/locales/zh-cn.json b/src/renderer/src/i18n/locales/zh-cn.json index 207675f6a9..3593b703c8 100644 --- a/src/renderer/src/i18n/locales/zh-cn.json +++ b/src/renderer/src/i18n/locales/zh-cn.json @@ -562,7 +562,9 @@ "tools": { "completed": "已完成", "invoking": "调用中", - "error": "发生错误" + "error": "发生错误", + "raw": "原始", + "preview": "预览" }, "topic.added": "话题添加成功", "upgrade.success.button": "重启", diff --git a/src/renderer/src/i18n/locales/zh-tw.json b/src/renderer/src/i18n/locales/zh-tw.json index 88ce6e96f8..a237d1f62f 100644 --- a/src/renderer/src/i18n/locales/zh-tw.json +++ b/src/renderer/src/i18n/locales/zh-tw.json @@ -562,7 +562,9 @@ "tools": { "completed": "已完成", "invoking": "調用中", - "error": "發生錯誤" + "error": "發生錯誤", + "raw": "原始碼", + "preview": "預覽" }, "topic.added": "新話題已新增", "upgrade.success.button": "重新啟動", diff --git a/src/renderer/src/i18n/translate/el-gr.json b/src/renderer/src/i18n/translate/el-gr.json index 4b7503e45f..1e6107d8b0 100644 --- a/src/renderer/src/i18n/translate/el-gr.json +++ b/src/renderer/src/i18n/translate/el-gr.json @@ -503,7 +503,9 @@ "switch.disabled": "Παρακαλείστε να περιμένετε τη λήξη της τρέχουσας απάντησης", "tools": { "completed": "Ολοκληρώθηκε", - "invoking": "κλήση σε εξέλιξη" + "invoking": "κλήση σε εξέλιξη", + "raw": "Ακατέργαστο", + "preview": "Προεπισκόπηση" }, "topic.added": "Η θεματική προστέθηκε επιτυχώς", "upgrade.success.button": "Επανεκκίνηση", diff --git a/src/renderer/src/i18n/translate/es-es.json b/src/renderer/src/i18n/translate/es-es.json index 3180cf49d8..dffbd4aa45 100644 --- a/src/renderer/src/i18n/translate/es-es.json +++ b/src/renderer/src/i18n/translate/es-es.json @@ -503,7 +503,9 @@ "switch.disabled": "Espere a que se complete la respuesta actual antes de realizar la operación", "tools": { "completed": "Completado", - "invoking": "En llamada" + "invoking": "En llamada", + "raw": "Crudo", + "preview": "Vista previa" }, "topic.added": "Tema agregado con éxito", "upgrade.success.button": "Reiniciar", diff --git a/src/renderer/src/i18n/translate/fr-fr.json b/src/renderer/src/i18n/translate/fr-fr.json index 1fcc854724..9d25e9a3cd 100644 --- a/src/renderer/src/i18n/translate/fr-fr.json +++ b/src/renderer/src/i18n/translate/fr-fr.json @@ -503,7 +503,9 @@ "switch.disabled": "Veuillez attendre la fin de la réponse actuelle avant de procéder", "tools": { "completed": "Terminé", - "invoking": "En cours d'exécution" + "invoking": "En cours d'exécution", + "raw": "Brut", + "preview": "Aperçu" }, "topic.added": "Thème ajouté avec succès", "upgrade.success.button": "Redémarrer", diff --git a/src/renderer/src/i18n/translate/pt-pt.json b/src/renderer/src/i18n/translate/pt-pt.json index ea00dc9dfd..89c8458bbc 100644 --- a/src/renderer/src/i18n/translate/pt-pt.json +++ b/src/renderer/src/i18n/translate/pt-pt.json @@ -503,7 +503,9 @@ "switch.disabled": "Aguarde a conclusão da resposta atual antes de operar", "tools": { "completed": "Completo", - "invoking": "Em execução" + "invoking": "Em execução", + "raw": "Bruto", + "preview": "Pré-visualização" }, "topic.added": "Tópico adicionado com sucesso", "upgrade.success.button": "Reiniciar", diff --git a/src/renderer/src/pages/home/Messages/MessageTools.tsx b/src/renderer/src/pages/home/Messages/MessageTools.tsx index 23cd0036af..7c33b361a7 100644 --- a/src/renderer/src/pages/home/Messages/MessageTools.tsx +++ b/src/renderer/src/pages/home/Messages/MessageTools.tsx @@ -1,7 +1,7 @@ import { CheckOutlined, ExpandOutlined, LoadingOutlined, WarningOutlined } from '@ant-design/icons' import { useSettings } from '@renderer/hooks/useSettings' import { Message } from '@renderer/types' -import { Collapse, message as antdMessage, Modal, Tooltip } from 'antd' +import { Collapse, message as antdMessage, Modal, Tabs, Tooltip } from 'antd' import { isEmpty } from 'lodash' import { FC, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' @@ -116,6 +116,24 @@ const MessageTools: FC = ({ message }) => { return items } + const renderPreview = (content: string) => { + if (!content) return null + + try { + const parsedResult = JSON.parse(content) + switch (parsedResult.content[0]?.type) { + case 'text': + return {parsedResult.content[0].text} + // TODO: support other types + default: + return {content} + } + } catch (e) { + console.error('failed to render the preview of mcp results:', e) + return {content} + } + } + return ( <> = ({ message }) => { styles={{ body: { maxHeight: '80vh', overflow: 'auto' } }}> {expandedResponse && ( - { - if (expandedResponse) { - navigator.clipboard.writeText(expandedResponse.content) - antdMessage.success({ content: t('message.copied'), key: 'copy-expanded' }) + {/* mode swtich tabs */} + { + navigator.clipboard.writeText( + typeof expandedResponse.content === 'string' + ? expandedResponse.content + : JSON.stringify(expandedResponse.content, null, 2) + ) + antdMessage.success({ content: t('message.copied'), key: 'copy-expanded' }) + }} + aria-label={t('common.copy')}> + + + } + items={[ + { + key: 'preview', + label: t('message.tools.preview'), + children: renderPreview(expandedResponse.content) + }, + { + key: 'raw', + label: t('message.tools.raw'), + children: ( + + {typeof expandedResponse.content === 'string' + ? expandedResponse.content + : JSON.stringify(expandedResponse.content, null, 2)} + + ) } - }} - aria-label={t('common.copy')}> - - - {expandedResponse.content} + ]} + /> )} @@ -267,6 +309,14 @@ const ToolResponseContainer = styled.div` position: relative; ` +const PreviewBlock = styled.div` + margin: 0; + white-space: pre-wrap; + word-break: break-word; + color: var(--color-text); + user-select: text; +` + const CodeBlock = styled.pre` margin: 0; white-space: pre-wrap;