From 0c42c462b0405edcf473da02d7c21d56dc944e19 Mon Sep 17 00:00:00 2001 From: Arvin Xu Date: Thu, 19 Sep 2024 01:45:55 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat:=20support=20native=20Artifact?= =?UTF-8?q?s=20just=20like=20Claude=20(#3985)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ✨ feat: 支持 AntThinking 渲染 * 🚧 wip: 支持 antArtifact 渲染 * 展示 * 展示 * 基本完成流式解析 * 基本完成流式解析 * ✨ feat: support svg render * ✅ test: fix test * 优化 lobeThinking 的解析 * i18n * fix regex * 💄 style: improve ui * 🚸 style: improve ux * i18n * 💄 style: improve svg renderer * 💄 style: improve svg renderer * ✨ feat: 优化 html 类 renderer 效果 * ✨ feat: 支持 react renderer * 💄 style: add tailwindcss * fix style * ✨ feat: 支持下载和复制图片 * ✅ test: fix tests * i18n * add tests --- locales/ar/chat.json | 6 + locales/ar/portal.json | 16 + locales/bg-BG/chat.json | 6 + locales/bg-BG/portal.json | 16 + locales/de-DE/chat.json | 6 + locales/de-DE/portal.json | 16 + locales/en-US/chat.json | 6 + locales/en-US/portal.json | 16 + locales/es-ES/chat.json | 6 + locales/es-ES/portal.json | 16 + locales/fr-FR/chat.json | 6 + locales/fr-FR/portal.json | 16 + locales/it-IT/chat.json | 6 + locales/it-IT/portal.json | 16 + locales/ja-JP/chat.json | 6 + locales/ja-JP/portal.json | 16 + locales/ko-KR/chat.json | 6 + locales/ko-KR/portal.json | 16 + locales/nl-NL/chat.json | 6 + locales/nl-NL/portal.json | 16 + locales/pl-PL/chat.json | 6 + locales/pl-PL/portal.json | 16 + locales/pt-BR/chat.json | 6 + locales/pt-BR/portal.json | 16 + locales/ru-RU/chat.json | 6 + locales/ru-RU/portal.json | 16 + locales/tr-TR/chat.json | 6 + locales/tr-TR/portal.json | 16 + locales/vi-VN/chat.json | 6 + locales/vi-VN/portal.json | 16 + locales/zh-CN/chat.json | 6 + locales/zh-CN/portal.json | 18 +- locales/zh-TW/chat.json | 6 + locales/zh-TW/portal.json | 16 + package.json | 2 + .../@portal/Artifacts/Body/Renderer/HTML.tsx | 25 ++ .../@portal/Artifacts/Body/Renderer/React.tsx | 30 ++ .../@portal/Artifacts/Body/Renderer/SVG.tsx | 114 ++++++ .../@portal/Artifacts/Body/Renderer/index.tsx | 25 ++ .../@portal/Artifacts/Body/index.tsx | 79 ++++ .../(workspace)/@portal/Artifacts/Header.tsx | 69 ++++ .../(workspace)/@portal/Artifacts/index.ts | 10 + .../@portal/Artifacts/useEnable.ts | 4 + .../(workspace)/@portal/FilePreview/index.ts | 3 +- .../ArtifactList/Item/index.tsx | 0 .../ArtifactList/Item/style.ts | 0 .../ArtifactList/index.tsx | 0 .../Body/{Artifacts => Plugins}/index.tsx | 2 +- .../(workspace)/@portal/Home/Body/index.tsx | 4 +- .../@portal/MessageDetail/index.ts | 3 +- .../@portal/Plugins/Body/ToolRender.tsx | 2 +- .../@portal/Plugins/Body/index.tsx | 2 +- .../(workspace)/@portal/Plugins/Footer.tsx | 2 +- .../chat/(workspace)/@portal/Plugins/index.ts | 3 +- .../(workspace)/@portal/Plugins/useEnable.ts | 2 +- .../(workspace)/@portal/_layout/Desktop.tsx | 6 +- .../(workspace)/@portal/features/Body.tsx | 27 ++ .../chat/(workspace)/@portal/router.tsx | 4 +- .../(main)/chat/(workspace)/@portal/type.ts | 7 + .../(workspace)/_layout/Desktop/Portal.tsx | 5 +- src/components/SidebarHeader/index.tsx | 2 +- src/config/modelProviders/anthropic.ts | 4 + src/const/layoutTokens.ts | 2 +- src/const/plugin.test.ts | 80 +++++ src/const/plugin.ts | 12 + .../Messages/Tool/Inspector/index.tsx | 2 +- .../Conversation/Messages/Tool/index.tsx | 2 +- .../components/ChatItem/index.tsx | 26 +- .../components/ChatItem/utils.test.ts | 150 ++++++++ .../Conversation/components/ChatItem/utils.ts | 28 ++ .../LobeArtifact/Render/Icon.tsx | 96 +++++ .../LobeArtifact/Render/index.tsx | 129 +++++++ .../MarkdownElements/LobeArtifact/index.ts | 10 + .../LobeArtifact/rehypePlugin.ts | 74 ++++ .../MarkdownElements/LobeThinking/Render.tsx | 86 +++++ .../MarkdownElements/LobeThinking/index.ts | 12 + .../LobeThinking/rehypePlugin.test.ts | 124 +++++++ .../LobeThinking/rehypePlugin.ts | 51 +++ .../components/MarkdownElements/index.ts | 4 + .../components/MarkdownElements/type.ts | 7 + src/locales/default/chat.ts | 7 + src/locales/default/portal.ts | 18 +- src/store/chat/slices/message/selectors.ts | 58 +-- src/store/chat/slices/portal/action.ts | 17 +- src/store/chat/slices/portal/initialState.ts | 11 + .../chat/slices/portal/selectors.test.ts | 36 +- src/store/chat/slices/portal/selectors.ts | 68 +++- src/styles/loading.ts | 28 ++ src/tools/artifacts/index.ts | 13 + src/tools/artifacts/systemRole.ts | 338 ++++++++++++++++++ src/tools/index.ts | 6 + src/utils/clipboard.ts | 53 +++ 92 files changed, 2286 insertions(+), 74 deletions(-) create mode 100644 src/app/(main)/chat/(workspace)/@portal/Artifacts/Body/Renderer/HTML.tsx create mode 100644 src/app/(main)/chat/(workspace)/@portal/Artifacts/Body/Renderer/React.tsx create mode 100644 src/app/(main)/chat/(workspace)/@portal/Artifacts/Body/Renderer/SVG.tsx create mode 100644 src/app/(main)/chat/(workspace)/@portal/Artifacts/Body/Renderer/index.tsx create mode 100644 src/app/(main)/chat/(workspace)/@portal/Artifacts/Body/index.tsx create mode 100644 src/app/(main)/chat/(workspace)/@portal/Artifacts/Header.tsx create mode 100644 src/app/(main)/chat/(workspace)/@portal/Artifacts/index.ts create mode 100644 src/app/(main)/chat/(workspace)/@portal/Artifacts/useEnable.ts rename src/app/(main)/chat/(workspace)/@portal/Home/Body/{Artifacts => Plugins}/ArtifactList/Item/index.tsx (100%) rename src/app/(main)/chat/(workspace)/@portal/Home/Body/{Artifacts => Plugins}/ArtifactList/Item/style.ts (100%) rename src/app/(main)/chat/(workspace)/@portal/Home/Body/{Artifacts => Plugins}/ArtifactList/index.tsx (100%) rename src/app/(main)/chat/(workspace)/@portal/Home/Body/{Artifacts => Plugins}/index.tsx (95%) create mode 100644 src/app/(main)/chat/(workspace)/@portal/features/Body.tsx create mode 100644 src/app/(main)/chat/(workspace)/@portal/type.ts create mode 100644 src/const/plugin.test.ts create mode 100644 src/features/Conversation/components/ChatItem/utils.test.ts create mode 100644 src/features/Conversation/components/ChatItem/utils.ts create mode 100644 src/features/Conversation/components/MarkdownElements/LobeArtifact/Render/Icon.tsx create mode 100644 src/features/Conversation/components/MarkdownElements/LobeArtifact/Render/index.tsx create mode 100644 src/features/Conversation/components/MarkdownElements/LobeArtifact/index.ts create mode 100644 src/features/Conversation/components/MarkdownElements/LobeArtifact/rehypePlugin.ts create mode 100644 src/features/Conversation/components/MarkdownElements/LobeThinking/Render.tsx create mode 100644 src/features/Conversation/components/MarkdownElements/LobeThinking/index.ts create mode 100644 src/features/Conversation/components/MarkdownElements/LobeThinking/rehypePlugin.test.ts create mode 100644 src/features/Conversation/components/MarkdownElements/LobeThinking/rehypePlugin.ts create mode 100644 src/features/Conversation/components/MarkdownElements/index.ts create mode 100644 src/features/Conversation/components/MarkdownElements/type.ts create mode 100644 src/styles/loading.ts create mode 100644 src/tools/artifacts/index.ts create mode 100644 src/tools/artifacts/systemRole.ts create mode 100644 src/utils/clipboard.ts diff --git a/locales/ar/chat.json b/locales/ar/chat.json index 5e5be6aed220..dbce8c9b0905 100644 --- a/locales/ar/chat.json +++ b/locales/ar/chat.json @@ -6,6 +6,12 @@ "agentDefaultMessageWithSystemRole": "مرحبًا، أنا **{{name}}**، {{systemRole}}، دعنا نبدأ الدردشة!", "agentDefaultMessageWithoutEdit": "مرحبًا، أنا **{{name}}**، دعنا نبدأ المحادثة!", "agentsAndConversations": "الوكلاء والمحادثات", + "artifact": { + "generating": "جاري الإنشاء", + "thinking": "جاري التفكير", + "thought": "عملية التفكير", + "unknownTitle": "عمل غير مسمى" + }, "backToBottom": "العودة إلى الأسفل", "chatList": { "longMessageDetail": "عرض التفاصيل" diff --git a/locales/ar/portal.json b/locales/ar/portal.json index 0ab243843915..3280f1773927 100644 --- a/locales/ar/portal.json +++ b/locales/ar/portal.json @@ -6,11 +6,27 @@ "file": "ملف" } }, + "Plugins": "ملحقات", "actions": { "genAiMessage": "إنشاء رسالة مساعد ذكاء اصطناعي", "summary": "ملخص", "summaryTooltip": "ملخص للمحتوى الحالي" }, + "artifacts": { + "display": { + "code": "رمز", + "preview": "معاينة" + }, + "svg": { + "copyAsImage": "نسخ كصورة", + "copyFail": "فشل النسخ، سبب الخطأ: {{error}}", + "copySuccess": "تم نسخ الصورة بنجاح", + "download": { + "png": "تحميل كـ PNG", + "svg": "تحميل كـ SVG" + } + } + }, "emptyArtifactList": "قائمة القطع الأثرية الحالية فارغة، يرجى استخدام الإضافات في الجلسة ومن ثم التحقق مرة أخرى", "emptyKnowledgeList": "قائمة المعرفة الحالية فارغة، يرجى فتح قاعدة المعرفة حسب الحاجة في المحادثة قبل العرض", "files": "ملفات", diff --git a/locales/bg-BG/chat.json b/locales/bg-BG/chat.json index 971d4e3dc2c1..6168aacdfe31 100644 --- a/locales/bg-BG/chat.json +++ b/locales/bg-BG/chat.json @@ -6,6 +6,12 @@ "agentDefaultMessageWithSystemRole": "Здравей, аз съм **{{name}}**, {{systemRole}}. Нека започнем да чатим!", "agentDefaultMessageWithoutEdit": "Здравей, аз съм **{{name}}** и нека започнем разговора!", "agentsAndConversations": "агенти и разговори", + "artifact": { + "generating": "Генериране", + "thinking": "В процес на мислене", + "thought": "Процес на мислене", + "unknownTitle": "Неназован артефакт" + }, "backToBottom": "Върни се в началото", "chatList": { "longMessageDetail": "Вижте детайлите" diff --git a/locales/bg-BG/portal.json b/locales/bg-BG/portal.json index f259a1e2ea9b..da254d05e40c 100644 --- a/locales/bg-BG/portal.json +++ b/locales/bg-BG/portal.json @@ -6,11 +6,27 @@ "file": "Файл" } }, + "Plugins": "Плъгини", "actions": { "genAiMessage": "Създаване на съобщение на помощника", "summary": "Обобщение", "summaryTooltip": "Обобщение на текущото съдържание" }, + "artifacts": { + "display": { + "code": "Код", + "preview": "Преглед" + }, + "svg": { + "copyAsImage": "Копирай като изображение", + "copyFail": "Копирането не успя, причина за грешката: {{error}}", + "copySuccess": "Изображението е копирано успешно", + "download": { + "png": "Изтегли като PNG", + "svg": "Изтегли като SVG" + } + } + }, "emptyArtifactList": "Списъкът с текущите артефакти е празен. Моля, използвайте добавки в разговора и след това проверете отново.", "emptyKnowledgeList": "Текущият списък с познания е празен. Моля, активирайте базата данни на познанията по време на сесията, за да я прегледате.", "files": "файлове", diff --git a/locales/de-DE/chat.json b/locales/de-DE/chat.json index b18cd94703ac..ccb00f0d4986 100644 --- a/locales/de-DE/chat.json +++ b/locales/de-DE/chat.json @@ -6,6 +6,12 @@ "agentDefaultMessageWithSystemRole": "Hallo, ich bin **{{name}}**, {{systemRole}}. Lass uns chatten!", "agentDefaultMessageWithoutEdit": "Hallo, ich bin **{{name}}**. Lassen Sie uns ins Gespräch kommen!", "agentsAndConversations": "Agenten und Unterhaltungen", + "artifact": { + "generating": "Wird generiert", + "thinking": "Denken", + "thought": "Denkenprozess", + "unknownTitle": "Unbenanntes Werk" + }, "backToBottom": "Zurück zum Ende", "chatList": { "longMessageDetail": "Details anzeigen" diff --git a/locales/de-DE/portal.json b/locales/de-DE/portal.json index 8490e0dc3cb8..a34ae2da5de1 100644 --- a/locales/de-DE/portal.json +++ b/locales/de-DE/portal.json @@ -6,11 +6,27 @@ "file": "Datei" } }, + "Plugins": "Plugins", "actions": { "genAiMessage": "Assistenten-Nachricht erstellen", "summary": "Zusammenfassung", "summaryTooltip": "Zusammenfassung des aktuellen Inhalts" }, + "artifacts": { + "display": { + "code": "Code", + "preview": "Vorschau" + }, + "svg": { + "copyAsImage": "Als Bild kopieren", + "copyFail": "Kopieren fehlgeschlagen, Fehlerursache: {{error}}", + "copySuccess": "Bild erfolgreich kopiert", + "download": { + "png": "Als PNG herunterladen", + "svg": "Als SVG herunterladen" + } + } + }, "emptyArtifactList": "Die Liste der Artefakte ist derzeit leer. Bitte verwenden Sie Plugins in der Sitzung und überprüfen Sie sie erneut.", "emptyKnowledgeList": "Die aktuelle Wissensliste ist leer. Bitte aktivieren Sie die Wissensdatenbank nach Bedarf in der Sitzung, um sie anzuzeigen.", "files": "Dateien", diff --git a/locales/en-US/chat.json b/locales/en-US/chat.json index 9db04515a095..d6ba15d7e8a3 100644 --- a/locales/en-US/chat.json +++ b/locales/en-US/chat.json @@ -6,6 +6,12 @@ "agentDefaultMessageWithSystemRole": "Hello, I'm **{{name}}**, {{systemRole}}. Let's start chatting!", "agentDefaultMessageWithoutEdit": "Hello, I'm **{{name}}**, let's start chatting!", "agentsAndConversations": "Assistants and Conversations", + "artifact": { + "generating": "Generating", + "thinking": "Thinking", + "thought": "Thought Process", + "unknownTitle": "Untitled Work" + }, "backToBottom": "Back to bottom", "chatList": { "longMessageDetail": "View Details" diff --git a/locales/en-US/portal.json b/locales/en-US/portal.json index 852545ed610c..a02b51c6b7a3 100644 --- a/locales/en-US/portal.json +++ b/locales/en-US/portal.json @@ -6,11 +6,27 @@ "file": "File" } }, + "Plugins": "Plugins", "actions": { "genAiMessage": "Generate Assistant Message", "summary": "Summary", "summaryTooltip": "Summarize current content" }, + "artifacts": { + "display": { + "code": "Code", + "preview": "Preview" + }, + "svg": { + "copyAsImage": "Copy as Image", + "copyFail": "Copy failed, reason: {{error}}", + "copySuccess": "Image copied successfully", + "download": { + "png": "Download as PNG", + "svg": "Download as SVG" + } + } + }, "emptyArtifactList": "The current Artifacts list is empty. Please use plugins in the session as needed before viewing.", "emptyKnowledgeList": "The current knowledge list is empty. Please enable the knowledge base as needed during the conversation before viewing.", "files": "Files", diff --git a/locales/es-ES/chat.json b/locales/es-ES/chat.json index fe76585270d8..5aadf260a72c 100644 --- a/locales/es-ES/chat.json +++ b/locales/es-ES/chat.json @@ -6,6 +6,12 @@ "agentDefaultMessageWithSystemRole": "Hola, soy **{{name}}**, {{systemRole}}, ¡comencemos a chatear!", "agentDefaultMessageWithoutEdit": "¡Hola, soy **{{name}}**! Comencemos nuestra conversación.", "agentsAndConversations": "agentesYConversaciones", + "artifact": { + "generating": "Generando", + "thinking": "Pensando", + "thought": "Proceso de pensamiento", + "unknownTitle": "Obra sin título" + }, "backToBottom": "Volver al fondo", "chatList": { "longMessageDetail": "Ver detalles" diff --git a/locales/es-ES/portal.json b/locales/es-ES/portal.json index 4b62721e0a7d..4dec581564a8 100644 --- a/locales/es-ES/portal.json +++ b/locales/es-ES/portal.json @@ -6,11 +6,27 @@ "file": "Archivo" } }, + "Plugins": "Complementos", "actions": { "genAiMessage": "Crear mensaje de IA", "summary": "Resumen", "summaryTooltip": "Resumir el contenido actual" }, + "artifacts": { + "display": { + "code": "Código", + "preview": "Vista previa" + }, + "svg": { + "copyAsImage": "Copiar como imagen", + "copyFail": "Error al copiar, motivo del error: {{error}}", + "copySuccess": "Imagen copiada con éxito", + "download": { + "png": "Descargar como PNG", + "svg": "Descargar como SVG" + } + } + }, "emptyArtifactList": "La lista de Artefactos actual está vacía. Por favor, utilice los complementos en la conversación y vuelva a intentarlo.", "emptyKnowledgeList": "La lista de conocimientos actual está vacía. Por favor, activa la base de conocimientos según sea necesario en la conversación antes de volver a revisar.", "files": "archivos", diff --git a/locales/fr-FR/chat.json b/locales/fr-FR/chat.json index 4bfd91d7356c..33498bfeef84 100644 --- a/locales/fr-FR/chat.json +++ b/locales/fr-FR/chat.json @@ -6,6 +6,12 @@ "agentDefaultMessageWithSystemRole": "Bonjour, je suis **{{name}}**, {{systemRole}}. Commençons la conversation !", "agentDefaultMessageWithoutEdit": "Bonjour, je suis **{{name}}**. Commençons notre conversation !", "agentsAndConversations": "Agents et conversations", + "artifact": { + "generating": "Génération en cours", + "thinking": "En réflexion", + "thought": "Processus de pensée", + "unknownTitle": "Œuvre sans nom" + }, "backToBottom": "Retour en bas", "chatList": { "longMessageDetail": "Voir les détails" diff --git a/locales/fr-FR/portal.json b/locales/fr-FR/portal.json index dfe9bf550766..9c925134570c 100644 --- a/locales/fr-FR/portal.json +++ b/locales/fr-FR/portal.json @@ -6,11 +6,27 @@ "file": "Fichier" } }, + "Plugins": "Plugins", "actions": { "genAiMessage": "Créer un message d'assistant", "summary": "Résumé", "summaryTooltip": "Résumé du contenu actuel" }, + "artifacts": { + "display": { + "code": "Code", + "preview": "Aperçu" + }, + "svg": { + "copyAsImage": "Copier en tant qu'image", + "copyFail": "Échec de la copie, raison de l'erreur : {{error}}", + "copySuccess": "Image copiée avec succès", + "download": { + "png": "Télécharger en tant que PNG", + "svg": "Télécharger en tant que SVG" + } + } + }, "emptyArtifactList": "La liste des Artifacts est actuellement vide. Veuillez utiliser les plugins dans la conversation avant de consulter à nouveau.", "emptyKnowledgeList": "La liste des connaissances est actuellement vide. Veuillez activer la base de connaissances selon vos besoins dans la conversation avant de consulter.", "files": "Fichiers", diff --git a/locales/it-IT/chat.json b/locales/it-IT/chat.json index 6f5a043f2b91..525ac6d9c011 100644 --- a/locales/it-IT/chat.json +++ b/locales/it-IT/chat.json @@ -6,6 +6,12 @@ "agentDefaultMessageWithSystemRole": "Ciao, sono **{{name}}**, {{systemRole}}, iniziamo a chattare!", "agentDefaultMessageWithoutEdit": "Ciao, sono **{{name}}**. Cominciamo a chiacchierare!", "agentsAndConversations": "Assistenti e Conversazioni", + "artifact": { + "generating": "Generazione in corso", + "thinking": "In fase di riflessione", + "thought": "Processo di pensiero", + "unknownTitle": "Opera non nominata" + }, "backToBottom": "Torna in fondo", "chatList": { "longMessageDetail": "Visualizza dettagli" diff --git a/locales/it-IT/portal.json b/locales/it-IT/portal.json index daba88af1c19..151d67fef659 100644 --- a/locales/it-IT/portal.json +++ b/locales/it-IT/portal.json @@ -6,11 +6,27 @@ "file": "File" } }, + "Plugins": "Plugin", "actions": { "genAiMessage": "Genera messaggio AI", "summary": "Sommario", "summaryTooltip": "Sommario del contenuto attuale" }, + "artifacts": { + "display": { + "code": "Codice", + "preview": "Anteprima" + }, + "svg": { + "copyAsImage": "Copia come immagine", + "copyFail": "Copia fallita, motivo dell'errore: {{error}}", + "copySuccess": "Immagine copiata con successo", + "download": { + "png": "Scarica come PNG", + "svg": "Scarica come SVG" + } + } + }, "emptyArtifactList": "La lista degli Artefatti attuale è vuota, si prega di utilizzare i plugin necessari durante la sessione e poi controllare di nuovo", "emptyKnowledgeList": "L'elenco delle conoscenze attuale è vuoto. Si prega di attivare il database delle conoscenze durante la conversazione per visualizzarlo.", "files": "File", diff --git a/locales/ja-JP/chat.json b/locales/ja-JP/chat.json index 82720c3756f5..34eb81b7c2bf 100644 --- a/locales/ja-JP/chat.json +++ b/locales/ja-JP/chat.json @@ -6,6 +6,12 @@ "agentDefaultMessageWithSystemRole": "こんにちは、私は **{{name}}** です、{{systemRole}}、さあ、チャットを始めましょう!", "agentDefaultMessageWithoutEdit": "こんにちは、私は**{{name}}**です。会話しましょう!", "agentsAndConversations": "エージェントと会話", + "artifact": { + "generating": "生成中", + "thinking": "思考中", + "thought": "思考過程", + "unknownTitle": "未命名の作品" + }, "backToBottom": "現在に戻る", "chatList": { "longMessageDetail": "詳細を見る" diff --git a/locales/ja-JP/portal.json b/locales/ja-JP/portal.json index 2d3b05cad761..ba3b4b3c8a3a 100644 --- a/locales/ja-JP/portal.json +++ b/locales/ja-JP/portal.json @@ -6,11 +6,27 @@ "file": "ファイル" } }, + "Plugins": "プラグイン", "actions": { "genAiMessage": "AIメッセージを生成", "summary": "サマリー", "summaryTooltip": "現在の内容を要約" }, + "artifacts": { + "display": { + "code": "コード", + "preview": "プレビュー" + }, + "svg": { + "copyAsImage": "画像としてコピー", + "copyFail": "コピーに失敗しました。エラーの理由: {{error}}", + "copySuccess": "画像のコピーに成功しました", + "download": { + "png": "PNGとしてダウンロード", + "svg": "SVGとしてダウンロード" + } + } + }, "emptyArtifactList": "現在、アーティファクトリストは空です。プラグインを使用してセッション中に追加してください。", "emptyKnowledgeList": "現在の知識リストは空です。会話中に必要に応じて知識ベースを開いてからご覧ください。", "files": "ファイル", diff --git a/locales/ko-KR/chat.json b/locales/ko-KR/chat.json index 6583725ba2f3..19c7a9c3db2b 100644 --- a/locales/ko-KR/chat.json +++ b/locales/ko-KR/chat.json @@ -6,6 +6,12 @@ "agentDefaultMessageWithSystemRole": "안녕하세요, 저는 **{{name}}**입니다. {{systemRole}}입니다. 대화를 시작해 봅시다!", "agentDefaultMessageWithoutEdit": "안녕하세요, 저는 **{{name}}**입니다. 대화를 시작해보세요!", "agentsAndConversations": "에이전트 및 대화", + "artifact": { + "generating": "생성 중", + "thinking": "생각 중", + "thought": "사고 과정", + "unknownTitle": "제목 없음" + }, "backToBottom": "하단으로 이동", "chatList": { "longMessageDetail": "자세히 보기" diff --git a/locales/ko-KR/portal.json b/locales/ko-KR/portal.json index 4320256d87b9..bb9c1a777690 100644 --- a/locales/ko-KR/portal.json +++ b/locales/ko-KR/portal.json @@ -6,11 +6,27 @@ "file": "파일" } }, + "Plugins": "플러그인", "actions": { "genAiMessage": "AI 메시지 생성", "summary": "요약", "summaryTooltip": "현재 콘텐츠를 요약합니다" }, + "artifacts": { + "display": { + "code": "코드", + "preview": "미리보기" + }, + "svg": { + "copyAsImage": "이미지로 복사", + "copyFail": "복사 실패, 오류 원인: {{error}}", + "copySuccess": "이미지 복사 성공", + "download": { + "png": "PNG로 다운로드", + "svg": "SVG로 다운로드" + } + } + }, "emptyArtifactList": "현재 아티팩트 목록이 비어 있습니다. 플러그인을 사용한 후에 다시 확인해주세요.", "emptyKnowledgeList": "현재 지식 목록이 비어 있습니다. 대화 중에 필요에 따라 지식 베이스를 활성화한 후 다시 확인해 주세요.", "files": "파일", diff --git a/locales/nl-NL/chat.json b/locales/nl-NL/chat.json index e5f407ec66f3..5fd75ec8db6f 100644 --- a/locales/nl-NL/chat.json +++ b/locales/nl-NL/chat.json @@ -6,6 +6,12 @@ "agentDefaultMessageWithSystemRole": "Hallo, ik ben **{{name}}**, {{systemRole}}, laten we beginnen met praten!", "agentDefaultMessageWithoutEdit": "Hallo, ik ben **{{name}}**. Laten we beginnen met een gesprek!", "agentsAndConversations": "agenten en gesprekken", + "artifact": { + "generating": "Genereren", + "thinking": "Denken", + "thought": "Denken proces", + "unknownTitle": "Onbenoemd werk" + }, "backToBottom": "Terug naar onderen", "chatList": { "longMessageDetail": "Bekijk details" diff --git a/locales/nl-NL/portal.json b/locales/nl-NL/portal.json index cf1dd5f6fa04..3ffe58c88d1b 100644 --- a/locales/nl-NL/portal.json +++ b/locales/nl-NL/portal.json @@ -6,11 +6,27 @@ "file": "Bestand" } }, + "Plugins": "Plugins", "actions": { "genAiMessage": "Creëer assistentbericht", "summary": "Samenvatting", "summaryTooltip": "Samenvatting van de huidige inhoud" }, + "artifacts": { + "display": { + "code": "Code", + "preview": "Voorbeeld" + }, + "svg": { + "copyAsImage": "Kopieer als afbeelding", + "copyFail": "Kopiëren mislukt, foutmelding: {{error}}", + "copySuccess": "Afbeelding succesvol gekopieerd", + "download": { + "png": "Download als PNG", + "svg": "Download als SVG" + } + } + }, "emptyArtifactList": "De huidige lijst met Artifacts is leeg. Gebruik plugins in de sessie en bekijk deze later opnieuw.", "emptyKnowledgeList": "De huidige kennislijst is leeg. Gelieve de kennisbank in de sessie te openen voordat u deze bekijkt.", "files": "Bestanden", diff --git a/locales/pl-PL/chat.json b/locales/pl-PL/chat.json index 36f89c816196..891ce02e31ed 100644 --- a/locales/pl-PL/chat.json +++ b/locales/pl-PL/chat.json @@ -6,6 +6,12 @@ "agentDefaultMessageWithSystemRole": "Cześć, jestem **{{name}}**, {{systemRole}}, zacznijmy rozmowę!", "agentDefaultMessageWithoutEdit": "Cześć, jestem **{{name}}**. Zacznijmy rozmowę!", "agentsAndConversations": "Agenci i rozmowy", + "artifact": { + "generating": "Generowanie", + "thinking": "Myślenie", + "thought": "Proces myślenia", + "unknownTitle": "Nienazwane dzieło" + }, "backToBottom": "Przewiń na dół", "chatList": { "longMessageDetail": "Zobacz szczegóły" diff --git a/locales/pl-PL/portal.json b/locales/pl-PL/portal.json index 7b22cd5c99c0..1dbd5fec267e 100644 --- a/locales/pl-PL/portal.json +++ b/locales/pl-PL/portal.json @@ -6,11 +6,27 @@ "file": "Plik" } }, + "Plugins": "Wtyczki", "actions": { "genAiMessage": "Tworzenie wiadomości AI", "summary": "Podsumowanie", "summaryTooltip": "Podsumowanie bieżącej zawartości" }, + "artifacts": { + "display": { + "code": "Kod", + "preview": "Podgląd" + }, + "svg": { + "copyAsImage": "Skopiuj jako obraz", + "copyFail": "Kopiowanie nie powiodło się, powód błędu: {{error}}", + "copySuccess": "Obraz skopiowany pomyślnie", + "download": { + "png": "Pobierz jako PNG", + "svg": "Pobierz jako SVG" + } + } + }, "emptyArtifactList": "Obecna lista Artefaktów jest pusta. Proszę użyć wtyczek w trakcie sesji, a następnie sprawdzić ponownie.", "emptyKnowledgeList": "Aktualna lista wiedzy jest pusta. Proszę otworzyć bazę wiedzy w trakcie rozmowy, aby ją przeglądać.", "files": "Pliki", diff --git a/locales/pt-BR/chat.json b/locales/pt-BR/chat.json index ffd257383428..b7425c6f5a3b 100644 --- a/locales/pt-BR/chat.json +++ b/locales/pt-BR/chat.json @@ -6,6 +6,12 @@ "agentDefaultMessageWithSystemRole": "Olá, eu sou **{{name}}**, {{systemRole}}, vamos conversar!", "agentDefaultMessageWithoutEdit": "Olá, sou o **{{name}}**, vamos começar a conversa!", "agentsAndConversations": "Agentes e Conversas", + "artifact": { + "generating": "Gerando", + "thinking": "Pensando", + "thought": "Processo de pensamento", + "unknownTitle": "Obra sem título" + }, "backToBottom": "Voltar para o início", "chatList": { "longMessageDetail": "Ver detalhes" diff --git a/locales/pt-BR/portal.json b/locales/pt-BR/portal.json index 6ed5e8fc4763..6c890f7c2fa3 100644 --- a/locales/pt-BR/portal.json +++ b/locales/pt-BR/portal.json @@ -6,11 +6,27 @@ "file": "Arquivo" } }, + "Plugins": "Plugins", "actions": { "genAiMessage": "Gerar mensagem de IA", "summary": "Resumo", "summaryTooltip": "Resumir o conteúdo atual" }, + "artifacts": { + "display": { + "code": "Código", + "preview": "Prévia" + }, + "svg": { + "copyAsImage": "Copiar como imagem", + "copyFail": "Falha ao copiar, motivo do erro: {{error}}", + "copySuccess": "Imagem copiada com sucesso", + "download": { + "png": "Baixar como PNG", + "svg": "Baixar como SVG" + } + } + }, "emptyArtifactList": "A lista de Artefatos atual está vazia. Por favor, use os plugins conforme necessário durante a sessão e depois verifique novamente.", "emptyKnowledgeList": "A lista de conhecimentos atual está vazia. Por favor, ative o repositório de conhecimentos conforme necessário durante a conversa antes de visualizar.", "files": "Arquivos", diff --git a/locales/ru-RU/chat.json b/locales/ru-RU/chat.json index 8ab984276ef9..6af41335644b 100644 --- a/locales/ru-RU/chat.json +++ b/locales/ru-RU/chat.json @@ -6,6 +6,12 @@ "agentDefaultMessageWithSystemRole": "Привет, я **{{name}}**, {{systemRole}}. Давай начнем разговор!", "agentDefaultMessageWithoutEdit": "Привет, я **{{name}}**, давай начнём разговор!", "agentsAndConversations": "Агенты и беседы", + "artifact": { + "generating": "Генерация", + "thinking": "В процессе размышлений", + "thought": "Процесс мышления", + "unknownTitle": "Безымянное произведение" + }, "backToBottom": "Вернуться вниз", "chatList": { "longMessageDetail": "Посмотреть детали" diff --git a/locales/ru-RU/portal.json b/locales/ru-RU/portal.json index 157700d26696..5ffeb145b040 100644 --- a/locales/ru-RU/portal.json +++ b/locales/ru-RU/portal.json @@ -6,11 +6,27 @@ "file": "Файл" } }, + "Plugins": "Плагины", "actions": { "genAiMessage": "Создать сообщение помощника", "summary": "Сводка", "summaryTooltip": "Сводка текущего содержимого" }, + "artifacts": { + "display": { + "code": "Код", + "preview": "Предварительный просмотр" + }, + "svg": { + "copyAsImage": "Скопировать как изображение", + "copyFail": "Не удалось скопировать, причина ошибки: {{error}}", + "copySuccess": "Изображение успешно скопировано", + "download": { + "png": "Скачать как PNG", + "svg": "Скачать как SVG" + } + } + }, "emptyArtifactList": "Список текущих артефактов пуст. Пожалуйста, используйте плагины во время сеанса и затем просмотрите.", "emptyKnowledgeList": "Текущий список знаний пуст. Пожалуйста, откройте базу знаний по мере необходимости в разговоре, прежде чем просматривать.", "files": "файлы", diff --git a/locales/tr-TR/chat.json b/locales/tr-TR/chat.json index a42566fd9b00..3128f4a671b5 100644 --- a/locales/tr-TR/chat.json +++ b/locales/tr-TR/chat.json @@ -6,6 +6,12 @@ "agentDefaultMessageWithSystemRole": "Merhaba, Ben **{{name}}**, {{systemRole}}. Hemen sohbet etmeye başlayalım!", "agentDefaultMessageWithoutEdit": "Merhaba, ben **{{name}}**. Konuşmaya başlayalım!", "agentsAndConversations": "Ajanlar ve Konuşmalar", + "artifact": { + "generating": "Üretiliyor", + "thinking": "Düşünülüyor", + "thought": "Düşünce Süreci", + "unknownTitle": "İsimsiz Eser" + }, "backToBottom": "En alta git", "chatList": { "longMessageDetail": "Detayları görüntüle" diff --git a/locales/tr-TR/portal.json b/locales/tr-TR/portal.json index 59921ce8f29d..11bcdca71053 100644 --- a/locales/tr-TR/portal.json +++ b/locales/tr-TR/portal.json @@ -6,11 +6,27 @@ "file": "Dosya" } }, + "Plugins": "Eklentiler", "actions": { "genAiMessage": "Yapay Zeka Mesajı Oluştur", "summary": "Özet", "summaryTooltip": "Mevcut içeriği özetle" }, + "artifacts": { + "display": { + "code": "Kod", + "preview": "Önizleme" + }, + "svg": { + "copyAsImage": "Resmi Kopyala", + "copyFail": "Kopyalama başarısız, hata nedeni: {{error}}", + "copySuccess": "Resim başarıyla kopyalandı", + "download": { + "png": "PNG olarak indir", + "svg": "SVG olarak indir" + } + } + }, "emptyArtifactList": "Mevcut Artefakt listesi boş, lütfen eklentileri kullanarak oturumda gerektiğinde göz atın", "emptyKnowledgeList": "Mevcut bilgi listesi boş. Lütfen sohbet sırasında ihtiyaç duyduğunuz bilgi havuzunu açtıktan sonra tekrar kontrol edin.", "files": "Dosyalar", diff --git a/locales/vi-VN/chat.json b/locales/vi-VN/chat.json index 95be73622682..d6dfe611ec3c 100644 --- a/locales/vi-VN/chat.json +++ b/locales/vi-VN/chat.json @@ -6,6 +6,12 @@ "agentDefaultMessageWithSystemRole": "Xin chào, tôi là **{{name}}**, {{systemRole}}. Hãy bắt đầu trò chuyện ngay!", "agentDefaultMessageWithoutEdit": "Xin chào, tôi là **{{name}}**, chúng ta hãy bắt đầu trò chuyện nào!", "agentsAndConversations": "Người hỗ trợ và cuộc trò chuyện", + "artifact": { + "generating": "Đang tạo", + "thinking": "Đang suy nghĩ", + "thought": "Quá trình suy nghĩ", + "unknownTitle": "Tác phẩm chưa được đặt tên" + }, "backToBottom": "Quay về dưới cùng", "chatList": { "longMessageDetail": "Xem chi tiết" diff --git a/locales/vi-VN/portal.json b/locales/vi-VN/portal.json index 346713226170..bfb400c87498 100644 --- a/locales/vi-VN/portal.json +++ b/locales/vi-VN/portal.json @@ -6,11 +6,27 @@ "file": "Tập tin" } }, + "Plugins": "Tiện ích", "actions": { "genAiMessage": "Tạo tin nhắn trợ giúp", "summary": "Tóm tắt", "summaryTooltip": "Tóm tắt nội dung hiện tại" }, + "artifacts": { + "display": { + "code": "Mã", + "preview": "Xem trước" + }, + "svg": { + "copyAsImage": "Sao chép dưới dạng hình ảnh", + "copyFail": "Sao chép thất bại, lý do lỗi: {{error}}", + "copySuccess": "Sao chép hình ảnh thành công", + "download": { + "png": "Tải xuống dưới dạng PNG", + "svg": "Tải xuống dưới dạng SVG" + } + } + }, "emptyArtifactList": "Danh sách Tác Phẩm hiện tại đang trống, vui lòng sử dụng các plugin trong cuộc trò chuyện trước khi xem lại", "emptyKnowledgeList": "Danh sách kiến thức hiện tại trống, vui lòng mở kho kiến thức khi cần trong cuộc trò chuyện trước khi xem", "files": "Tập tin", diff --git a/locales/zh-CN/chat.json b/locales/zh-CN/chat.json index b94fb5f3e101..1381ddf29319 100644 --- a/locales/zh-CN/chat.json +++ b/locales/zh-CN/chat.json @@ -6,6 +6,12 @@ "agentDefaultMessageWithSystemRole": "你好,我是 **{{name}}**,{{systemRole}},让我们开始对话吧!", "agentDefaultMessageWithoutEdit": "你好,我是 **{{name}}**,让我们开始对话吧!", "agentsAndConversations": "助手与会话", + "artifact": { + "generating": "生成中", + "thinking": "思考中", + "thought": "思考过程", + "unknownTitle": "未命名作品" + }, "backToBottom": "跳转至当前", "chatList": { "longMessageDetail": "查看详情" diff --git a/locales/zh-CN/portal.json b/locales/zh-CN/portal.json index 278aa2d4254d..666b4c3fc540 100644 --- a/locales/zh-CN/portal.json +++ b/locales/zh-CN/portal.json @@ -6,13 +6,29 @@ "file": "文件" } }, + "Plugins": "插件", "actions": { "genAiMessage": "创建助手消息", "summary": "总结", "summaryTooltip": "总结当前内容" }, + "artifacts": { + "display": { + "code": "代码", + "preview": "预览" + }, + "svg": { + "copyAsImage": "复制为图片", + "copyFail": "复制失败,错误原因:{{error}}", + "copySuccess": "图片复制成功", + "download": { + "png": "下载为 PNG", + "svg": "下载为 SVG" + } + } + }, "emptyArtifactList": "当前 Artifacts 列表为空,请在会话中按需使用插件后再查看", - "emptyKnowledgeList": "当前知识列表为空,请在会话中按需开启知识库后再查看", + "emptyKnowledgeList": "当前知识列表为空", "files": "文件", "messageDetail": "消息详情", "title": "工作区" diff --git a/locales/zh-TW/chat.json b/locales/zh-TW/chat.json index 0988acb9de24..1825a870a54b 100644 --- a/locales/zh-TW/chat.json +++ b/locales/zh-TW/chat.json @@ -6,6 +6,12 @@ "agentDefaultMessageWithSystemRole": "你好,我是 **{{name}}**,{{systemRole}},讓我們開始對話吧!", "agentDefaultMessageWithoutEdit": "你好,我是 **{{name}}**,讓我們開始對話吧!", "agentsAndConversations": "助理與對話", + "artifact": { + "generating": "生成中", + "thinking": "思考中", + "thought": "思考過程", + "unknownTitle": "未命名作品" + }, "backToBottom": "返回底部", "chatList": { "longMessageDetail": "查看詳情" diff --git a/locales/zh-TW/portal.json b/locales/zh-TW/portal.json index ed1697dfb7ce..75079c26d979 100644 --- a/locales/zh-TW/portal.json +++ b/locales/zh-TW/portal.json @@ -6,11 +6,27 @@ "file": "檔案" } }, + "Plugins": "外掛", "actions": { "genAiMessage": "生成助手訊息", "summary": "摘要", "summaryTooltip": "總結目前內容" }, + "artifacts": { + "display": { + "code": "程式碼", + "preview": "預覽" + }, + "svg": { + "copyAsImage": "複製為圖片", + "copyFail": "複製失敗,錯誤原因:{{error}}", + "copySuccess": "圖片複製成功", + "download": { + "png": "下載為 PNG", + "svg": "下載為 SVG" + } + } + }, "emptyArtifactList": "當前文物列表為空,請在會話中按需使用插件後再查看", "emptyKnowledgeList": "當前知識列表為空,請在會話中按需開啟知識庫後再查看", "files": "檔案", diff --git a/package.json b/package.json index d800360d448b..315d09763707 100644 --- a/package.json +++ b/package.json @@ -112,6 +112,7 @@ "@clerk/localizations": "2.0.0", "@clerk/nextjs": "^5.3.3", "@clerk/themes": "^2.1.27", + "@codesandbox/sandpack-react": "^2.19.8", "@cyntler/react-doc-viewer": "^1.16.6", "@google/generative-ai": "^0.16.0", "@icons-pack/react-simple-icons": "9.6.0", @@ -256,6 +257,7 @@ "@types/semver": "^7.5.8", "@types/systemjs": "^6.13.5", "@types/ua-parser-js": "^0.7.39", + "@types/unist": "^3.0.3", "@types/uuid": "^10.0.0", "@types/ws": "^8.5.12", "@vitest/coverage-v8": "~1.2.2", diff --git a/src/app/(main)/chat/(workspace)/@portal/Artifacts/Body/Renderer/HTML.tsx b/src/app/(main)/chat/(workspace)/@portal/Artifacts/Body/Renderer/HTML.tsx new file mode 100644 index 000000000000..8b4455ec25e1 --- /dev/null +++ b/src/app/(main)/chat/(workspace)/@portal/Artifacts/Body/Renderer/HTML.tsx @@ -0,0 +1,25 @@ +import { memo, useEffect, useRef } from 'react'; + +interface HTMLRendererProps { + height?: string; + htmlContent: string; + width?: string; +} +const HTMLRenderer = memo(({ htmlContent, width = '100%', height = '100%' }) => { + const iframeRef = useRef(null); + + useEffect(() => { + if (!iframeRef.current) return; + + const doc = iframeRef.current.contentDocument; + if (!doc) return; + + doc.open(); + doc.write(htmlContent); + doc.close(); + }, [htmlContent]); + + return