From e9720c4b167dc5ddfd9daf446d9f91416a14f6bf Mon Sep 17 00:00:00 2001 From: hzeyuan <599012428@qq.com> Date: Thu, 1 Feb 2024 18:17:06 +0800 Subject: [PATCH] feature: mermaid support --- README.md | 101 +++++++------- apps/extension/package.json | 11 +- apps/extension/src/components/Chat/Chat.tsx | 13 +- .../src/components/Markdown/Mermaid.tsx | 128 ++++++++++++++++++ .../src/components/Markdown/index.tsx | 21 +-- .../src/components/Message/AIMessage.tsx | 6 +- apps/extension/src/constant.ts | 2 +- apps/extension/src/i18n.js | 23 +++- packages/core/constant.ts | 2 +- packages/core/web/openai.ts | 3 + pnpm-lock.yaml | 128 +++++++++++++++++- 11 files changed, 345 insertions(+), 93 deletions(-) create mode 100644 apps/extension/src/components/Markdown/Mermaid.tsx diff --git a/README.md b/README.md index 9db89cf..ef8c221 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,6 @@ OpenGPTs 是一款开源的浏览器插件,支持语音输入,函数调用,多 [![][github-issues-shield]][github-issues-link] [![][github-license-shield]][github-license-link]
- **Share OpenGPTs Repository** [![][share-x-shield]][share-x-link] @@ -39,8 +38,6 @@ OpenGPTs 是一款开源的浏览器插件,支持语音输入,函数调用,多 - - ## 👋🏻 开始和介绍 开源的GPT浏览器插件并不多,但我觉得浏览器插件是AI当前很好的一个形态,所以我们决定开发一个。 @@ -52,23 +49,21 @@ OpenGPTs 是一款开源的浏览器插件,支持语音输入,函数调用,多 - 开发: 👏🏻欢迎任何小伙伴参与进来,关于开发可以查看 [这里](#开发指导) - 联系方式: 请加入我们的QQ群:860859251,邮箱:yixotieq@gmail.com - **野望**:我们的最终设想是希望能够以这个插件为平台📈,把**每个GPTs当成一个Agent**🤖,实现各种业务流程的自动化,最大程度解放大家的生产力🚀,帮助大家更好的摸鱼🐟!哈哈!😄 如果本项目对大家有帮助,欢迎点一下上面的Star🌟,欢迎转发,这是对我们最大的支持!🙌 如果有任何问题,欢迎提issue💬,如果有新的功能,欢迎大家提PR。也欢迎加入我们的开发者群:860859251。👩‍💻 - ## 为什么要做OpenGPTs? 🤔💡
1. 关于AI应用的一些想法 -* 网页对浏览器的权限有限,但插件却可以修改任何页面,所以我觉得插件是做AI产品的一个很好的形态。 -* 我讨论重复的工作,作为一名开发,每次打开F12,都是一些重复工作~,这时候我会幻想AI能否替我解决一些事情。 -* - GPT能否帮我处理网络请求,方便我更好的抓取数据? -* - 能否让GPT来操作dom,来帮我做一些固定的操作,自动发推特,自动b站点赞?或者满足一些人们千奇百怪的需求(重点是让GPT生成这些脚本) -* - AIGC时代,能否有一款AI版的插件系统,上面有各种各样的插件,去广告,甚至改面网页的样貌,每个人都有独一无二的网站。 +- 网页对浏览器的权限有限,但插件却可以修改任何页面,所以我觉得插件是做AI产品的一个很好的形态。 +- 我讨论重复的工作,作为一名开发,每次打开F12,都是一些重复工作~,这时候我会幻想AI能否替我解决一些事情。 +- - GPT能否帮我处理网络请求,方便我更好的抓取数据? +- - 能否让GPT来操作dom,来帮我做一些固定的操作,自动发推特,自动b站点赞?或者满足一些人们千奇百怪的需求(重点是让GPT生成这些脚本) +- - AIGC时代,能否有一款AI版的插件系统,上面有各种各样的插件,去广告,甚至改面网页的样貌,每个人都有独一无二的网站。
@@ -78,68 +73,68 @@ OpenGPTs 是一款开源的浏览器插件,支持语音输入,函数调用,多 ChatGPT很厉害,但ChatGPT的产品交互我觉得可以做的更好,甚至有时候有很多想要吐槽的地方。 与其等Openai更新,不如自己动手,满足自己的功能,结合插件可以实现各式各样的效果。 -* 截图,直接提交,而不是保存图片,在到页面上提交 -* 同时多个GPTs对话,而不是要一个个切换。 -* @功能,GPTs之间能否共享对话,互相调用, 而不是一个回答完后,在粘贴给下一个GPTs -* 同时多个窗口,比如网页中有6个窗口,而不是只有固定一个。 -* 对话自动播放语音,音色可以选择。 -* 直接集成多家大模型,Claude2 gpt3.5,Gemini pro,可以在网页端调用。 + +- 截图,直接提交,而不是保存图片,在到页面上提交 +- 同时多个GPTs对话,而不是要一个个切换。 +- @功能,GPTs之间能否共享对话,互相调用, 而不是一个回答完后,在粘贴给下一个GPTs +- 同时多个窗口,比如网页中有6个窗口,而不是只有固定一个。 +- 对话自动播放语音,音色可以选择。 +- 直接集成多家大模型,Claude2 gpt3.5,Gemini pro,可以在网页端调用。 还有一些很多我感觉很有用的功能。 - ## 2. ✨ 亮点功能: ### 2.1 GPTs模块 | 功能名称 | 功能描述 | 完成 | -| :--------------: | :-----------------------------------------------------------------------------------------------------------------------------------: | :------: | -| 一键同步 | 自动同步官网GPTs所有数据:对话数,收藏数,用户数 | ✅ | -| 批量管理 | 批量管理自己的所有GPTs:自定义排序;批量删除;查询搜索;一键发布到商店;一键复制到剪切板(标题+简介+链接) | ✅ | -| 一键生成 | 输入标题,一键生成GPTs,复刻官网功能,但可以自定义提示词!(后续封装出接口) | ✅ | -| 一键复刻 | 对自己已有GPTs,一键复刻成其他语言,或者通过语言调整其他微调版本 | ✅ | -| 批量删除GPT对话 | 参考[chatGPTBox](https://github.com/josStorer/chatGPTBox),我们为大家提供了批量删除OpenAI对话的功能,这个功能实在是太痛点了! | ✅ | -| 一键调用GPTs对话 | 一次输入,同时调用多个模型,快速对比结果。 | ✅ | -| 排行榜 | 参考[gpts-works](https://github.com/all-in-aigc/gpts-works),我们希望提供一个更加全面和准确的排行榜,让大家更好的选择和推广自己的GPTs | ✅ | -| 更漂亮UI | 提供更漂亮的UI和更便捷的交互模式 | ✅ | - - +| :--------------: | :-----------------------------------------------------------------------------------------------------------------------------------: | :--: | +| 一键同步 | 自动同步官网GPTs所有数据:对话数,收藏数,用户数 | ✅ | +| 批量管理 | 批量管理自己的所有GPTs:自定义排序;批量删除;查询搜索;一键发布到商店;一键复制到剪切板(标题+简介+链接) | ✅ | +| 一键生成 | 输入标题,一键生成GPTs,复刻官网功能,但可以自定义提示词!(后续封装出接口) | ✅ | +| 一键复刻 | 对自己已有GPTs,一键复刻成其他语言,或者通过语言调整其他微调版本 | ✅ | +| 批量删除GPT对话 | 参考[chatGPTBox](https://github.com/josStorer/chatGPTBox),我们为大家提供了批量删除OpenAI对话的功能,这个功能实在是太痛点了! | ✅ | +| 一键调用GPTs对话 | 一次输入,同时调用多个模型,快速对比结果。 | ✅ | +| 排行榜 | 参考[gpts-works](https://github.com/all-in-aigc/gpts-works),我们希望提供一个更加全面和准确的排行榜,让大家更好的选择和推广自己的GPTs | ✅ | +| 更漂亮UI | 提供更漂亮的UI和更便捷的交互模式 | ✅ | ### 2.2 Chat聊天模块 -| 功能名称 | 功能描述 | 完成 | -| :------------------: | :----------------------------------------------------------------------------------------------------------------------------------: | :------: | -| 截图提交 | 直接在聊天界面中提交截图,而不需先保存后上传 | ❌ | -| 多GPTs对话 | 同时与多个GPT模型对话,无需逐一切换,提升交互效率 | ✅ | -| @任意GPTs,模型 | GPTs,模型之间可以共享对话内容,互相调用,实现信息的快速共享和传递,避免重复输入相同信息 | ✅ | -| 多窗口交互 | 在一个界面中开设多个窗口,同时进行多任务操作,提高效率 | ✅ | -| 语音播放 | 对话内容自动转换为语音播放 | ❌ | -| 网页端ChatGPT调用 | 让插件直接在网页端调用ChatGPT, GPT3.5, GPT4.0 GPTs | ✅ | -| 网页端Claude调用 | 让插件直接在网页端调用Claude | ❌ | -| 网页端Gemini Pro调用 | 让插件直接在网页端调用Gemini Pro | ❌ | -| ChatGPT API Key调用 | 使用API key调用, GPT3.5, GPT4.0 | ✅ | -| 聊天历史对话管理 | 提供聊天历史的管理和搜索功能 | ✅ | -| /预设功能 | 提供快捷操作和自定义预设功能选项 | ✅ | -| 流程图生成 | 自动从描述中生成流程图或概念图等视觉内容 | ❌ | -| 函数调用 | 通过命令行直接调用特定函数或服务 | ❌ | -| 多模态输入 | 支持文本、图像、音频等多种输入模式 | ❌ | - - -### 2.3 知识库管理,文件夹系统模态 +| 功能名称 | 功能描述 | 完成 | +| :------------------: | :-------------------------------------------------------------------------------------: | :--: | +| 截图提交 | 直接在聊天界面中提交截图,而不需先保存后上传 | ❌ | +| 多GPTs对话 | 同时与多个GPT模型对话,无需逐一切换,提升交互效率 | ✅ | +| @任意GPTs,模型 | GPTs,模型之间可以共享对话内容,互相调用,实现信息的快速共享和传递,避免重复输入相同信息 | ✅ | +| 多窗口交互 | 在一个界面中开设多个窗口,同时进行多任务操作,提高效率 | ✅ | +| 语音播放 | 对话内容自动转换为语音播放 | ❌ | +| 网页端ChatGPT调用 | 让插件直接在网页端调用ChatGPT, GPT3.5, GPT4.0 GPTs | ✅ | +| 网页端Claude调用 | 让插件直接在网页端调用Claude | ❌ | +| 网页端Gemini Pro调用 | 让插件直接在网页端调用Gemini Pro | ❌ | +| ChatGPT API Key调用 | 使用API key调用, GPT3.5, GPT4.0 | ✅ | +| 聊天历史对话管理 | 提供聊天历史的管理和搜索功能 | ✅ | +| /预设功能 | 提供快捷操作和自定义预设功能选项 | ✅ | +| 流程图生成 | 自动从描述中生成流程图或概念图等视觉内容 | ❌ | +| 函数调用 | 通过命令行直接调用特定函数或服务 | ❌ | +| 多模态输入 | 支持文本、图像、音频等多种输入模式 | ❌ | +| 生成流程图(mermaid) | 支出输出流程图 | ✅ | + +### 2.3 UI通用 + +| 功能名称 | 功能描述 | 完成 | +| :-----------: | :------------------------------------------: | :--: | +| 暗黑/明亮模式 | 提供暗黑/明亮模式,方便用户在不同环境下使用 | ✅ | +| 多语言支持 | 提供多语言支持,方便用户在不同语言环境下使用 | ✅ | + +### 2.4 知识库管理,文件夹系统模态 #### 暂无 - -### 2.4 RPA自动脚本执行,Agent WorkFlow +### 2.5 RPA自动脚本执行,Agent WorkFlow #### 暂无 - - - - ## 极简安装步骤: - 打开[OpenAI官网](https://chat.openai.com/),登录你的OpenAI账号,进行一次GPTs的对话,注意,这里需要有Plus的权限。 diff --git a/apps/extension/package.json b/apps/extension/package.json index ebb5ef9..9092dcf 100644 --- a/apps/extension/package.json +++ b/apps/extension/package.json @@ -1,7 +1,7 @@ { "name": "OpenGPTS", "displayName": "OpenGPTs", - "version": "0.0.2", + "version": "0.0.3", "description": "OpenGPTs- Powerful GPTs Colipot | 强大的gpts管理器", "author": " hzeyuan.github.com ", "scripts": { @@ -31,6 +31,7 @@ "@tiptap/react": "^2.1.13", "@tiptap/starter-kit": "^2.1.13", "ahooks": "^3.7.8", + "ai": "^2.2.28", "antd": "^5.12.1", "cheerio": "1.0.0-rc.12", "copy-to-clipboard": "^3.3.3", @@ -38,9 +39,8 @@ "framer-motion": "^10.16.16", "i18next": "^23.7.16", "jquery": "^3.7.1", - "mermaid": "^10.6.1", - "ai": "^2.2.28", "lodash": "^4.17.21", + "mermaid": "^10.6.1", "nanoid": "^5.0.4", "next": "14.0.2", "nextjs-cors": "^2.2.0", @@ -57,12 +57,11 @@ "react-tabs": "^6.0.2", "rehype-highlight": "^6.0.0", "rehype-katex": "^6.0.3", + "remark-breaks": "^3.0.2", "remark-gfm": "^3.0.1", "remark-math": "^5.1.1", - "remark-breaks": "^3.0.2", "swr": "^2.2.4", "tippy.js": "^6.3.7", - "unist-util-visit-parents": "^6.0.1", "use-debounce": "^10.0.0", "uuid": "^9.0.1", "webextension-polyfill": "^0.10.0", @@ -70,8 +69,8 @@ }, "devDependencies": { "@ianvs/prettier-plugin-sort-imports": "4.1.1", - "@plasmohq/rps": "1.8.7", "@opengpts/types": "workspace:*", + "@plasmohq/rps": "1.8.7", "@types/chrome": "0.0.251", "@types/node": "20.9.0", "@types/react": "18.2.37", diff --git a/apps/extension/src/components/Chat/Chat.tsx b/apps/extension/src/components/Chat/Chat.tsx index b0d8b1e..6a7044c 100644 --- a/apps/extension/src/components/Chat/Chat.tsx +++ b/apps/extension/src/components/Chat/Chat.tsx @@ -210,9 +210,7 @@ export const Chat = forwardRef( ), }); } - console.log("useChat", error); // setError(error.message) - // alert(error.message) }, onResponse: (response) => { handleScrollToBottom(); @@ -270,6 +268,7 @@ export const Chat = forwardRef( //TODO: use model that was mentioned last, if not exist, use default model, temporarily const mentionType = _.get(mention, "type", ""); const modelKey = mentionType === "GPTs" ? "gpt-4-gizmo" : mention?.key ?? model.key; + console.log('modelKey', modelKey) const quoteMessage = getQuoteMessage(chatId); const capturedImage = useScreenCapture.getState().capturedImage; @@ -351,8 +350,8 @@ export const Chat = forwardRef( { ...message, content: `${selection} - ${webSearchPrompt} - ${content}`, +${webSearchPrompt} +${content}`.trim(), }, { options, @@ -383,8 +382,6 @@ export const Chat = forwardRef( setContent(v); }; - const handleHideInputArea = () => { }; - useImperativeHandle(ref, () => { return { handleSubmit: () => inputRef.current.submit(), @@ -407,8 +404,7 @@ export const Chat = forwardRef( }, [messages]); useEffect(() => { - // const model = MODELS.find(({ name }) => name === model.key) - console.log("设置模型为", model?.key); + console.debug("设置模型为", model?.key); if (model) { setMode(model.mode); } @@ -416,7 +412,6 @@ export const Chat = forwardRef( useEffect(() => { const messages = getChatMessages(chatId); - console.log("messages", messages); setMessages(messages); }, [chatId]); diff --git a/apps/extension/src/components/Markdown/Mermaid.tsx b/apps/extension/src/components/Markdown/Mermaid.tsx new file mode 100644 index 0000000..7207a9e --- /dev/null +++ b/apps/extension/src/components/Markdown/Mermaid.tsx @@ -0,0 +1,128 @@ +import React, { useState, useEffect, useRef } from 'react'; +import mermaid from 'mermaid'; +import { SettingOutlined, EditOutlined, EllipsisOutlined, ExportOutlined, CopyOutlined, PlusOutlined, MinusOutlined, RestFilled } from '@ant-design/icons'; +import { Button, Card, Input, Skeleton, Tabs, Tooltip, message } from 'antd'; +import copyToClipboard from 'copy-to-clipboard'; +import { useTranslation } from "react-i18next" + +// 初始化Mermaid的配置 +mermaid.initialize({ + startOnLoad: false, + theme: 'default', + logLevel: 'fatal', + securityLevel: 'strict', + fontFamily: '"trebuchet MS", verdana, arial, sans-serif', + fontSize: 14, + arrowMarkerAbsolute: false, +}); + +const MermaidChartEditor = ({ chart: initialChart, backgroundColor = 'lightcyan' }) => { + const [chart, setChart] = useState(initialChart); + const [loading, setLoading] = useState(false); + const mermaidRef = useRef(null); + const [svgContent, setSvgContent] = useState(''); + const { t } = useTranslation() + const [scale, setScale] = useState(1); + + + + const zoomIn = () => setScale(scale => scale + 0.1); + const zoomOut = () => setScale(scale => Math.max(scale - 0.1, 0.1)); + + useEffect(() => { + setLoading(true); + if (chart) { + // 渲染Mermaid图表 + (async () => { + try { + const { svg, bindFunctions } = await mermaid.render('graphDiv', chart); + setSvgContent(svg); + setLoading(false); + if (bindFunctions && mermaidRef.current) { + bindFunctions(mermaidRef.current); + } + } catch (error) { + console.error('Mermaid rendering error:', error); + setSvgContent('
Mermaid syntax error
'); + setLoading(false); + } + })(); + } + }, [chart]); + + const handleCodeChange = (event) => { + setChart(event.target.value); + }; + + const handleCopyToClipboard = () => { + if (!mermaidRef.current) return; + copyToClipboard(chart); + message.success(t('copy_success')); + } + + const exportToImage = () => { + if (!mermaidRef.current) return; + const svg = mermaidRef.current.innerHTML; + const blob = new Blob([svg], { type: 'image/svg+xml' }); + const url = URL.createObjectURL(blob); + const link = document.createElement('a'); + link.href = url; + link.download = 'mermaid-diagram.svg'; // 或者 '.png' + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + URL.revokeObjectURL(url); + message.success(t('export_success')); + }; + + + const extra =
+
+ +
+
+ + + return ( + + + + +
+
+
+ + + + + + + + ); +}; + +export default MermaidChartEditor; diff --git a/apps/extension/src/components/Markdown/index.tsx b/apps/extension/src/components/Markdown/index.tsx index a56d22b..0b84c87 100644 --- a/apps/extension/src/components/Markdown/index.tsx +++ b/apps/extension/src/components/Markdown/index.tsx @@ -7,43 +7,33 @@ import remarkBreaks from 'remark-breaks' import remarkGfm from 'remark-gfm' import remarkMath from 'remark-math' import { useDebouncedCallback } from 'use-debounce'; -import Mermaid from 'mermaid'; import copyToClipboard from 'copy-to-clipboard' +import Mermaid from './Mermaid' export function PreCode(props: { children: any }) { const ref = useRef(null); const refText = ref.current?.innerText; - const [mermaidCode, setMermaidCode] = useState(""); + const [mermaidCode, setMermaidCode] = useState(``); const renderMermaid = useDebouncedCallback(() => { if (!ref.current) return; const mermaidDom = ref.current.querySelector("code.language-mermaid"); if (mermaidDom) { + console.log("设置mermaidCode", (mermaidDom as HTMLElement).innerText) setMermaidCode((mermaidDom as HTMLElement).innerText); } }, 600); useEffect(() => { setTimeout(renderMermaid, 1); - // eslint-disable-next-line react-hooks/exhaustive-deps }, [refText]); return ( <> {mermaidCode.length > 0 && ( - //@ts-ignore - + )}
-         {
-            if (ref.current) {
-              const code = ref.current.innerText;
-              copyToClipboard(code);
-            }
-          }}
-        >
         {props.children}
       
@@ -52,7 +42,7 @@ export function PreCode(props: { children: any }) { -const Markdown= ({ children }) => { +const Markdown = ({ children }) => { return ( { // }, }} > + {children} ) diff --git a/apps/extension/src/components/Message/AIMessage.tsx b/apps/extension/src/components/Message/AIMessage.tsx index 2067621..545a854 100644 --- a/apps/extension/src/components/Message/AIMessage.tsx +++ b/apps/extension/src/components/Message/AIMessage.tsx @@ -2,6 +2,7 @@ import Markdown from "../Markdown"; import type { OMessage } from "@opengpts/types"; import copy from "copy-to-clipboard"; import { Actions } from "./Actions"; +import _ from "lodash"; export const AIMessage = ({ message, chatId }: { chatId: string; message: OMessage; error?: string }) => { return ( @@ -27,7 +28,10 @@ export const AIMessage = ({ message, chatId }: { chatId: string; message: OMessa >
{message.content ? ( - message.content instanceof String ? {message.content} : message.content + _.isString(message.content)? + {message.content} + + : message.content ) : (
diff --git a/apps/extension/src/constant.ts b/apps/extension/src/constant.ts index 1fc8ce5..baf7b4e 100644 --- a/apps/extension/src/constant.ts +++ b/apps/extension/src/constant.ts @@ -28,7 +28,7 @@ const MODEL_OPTIONS: ModelOptions[] = [{ key: 'chatgpt35API', name: 'ChatGPT (API)', - description: 'ChatGPT (API)', + description: 'ChatGPT 3.5-turbo (API)', mode: 'api', icon: chatgpt3_5Svg }, diff --git a/apps/extension/src/i18n.js b/apps/extension/src/i18n.js index 0e5946d..c813623 100644 --- a/apps/extension/src/i18n.js +++ b/apps/extension/src/i18n.js @@ -83,7 +83,16 @@ const resources = { 'LogError': 'Log error', 'Error': 'Error', 'AlertErrorMessage': 'Alert error message', - "GPTsUnavailableOrDeleted": "This GPTs may have been converted to private or deleted, making it unavailable for use. You can try switching to another GPTs." + "GPTsUnavailableOrDeleted": "This GPTs may have been converted to private or deleted, making it unavailable for use. You can try switching to another GPTs.", + "copy_tooltip": "Copy to clipboard", + "export_tooltip": "Export as image", + "copy_success": "Copied to clipboard successfully!", + "export_success": "Exported as image successfully!", + "Preview": "Preview", + "Code": "Code", + 'zoomIn': 'Zoom In', + 'zoomOut': 'Zoom Out', + 'zoomReset': 'Zoom Reset', } }, zh: { @@ -157,7 +166,17 @@ const resources = { 'LogError': '记录错误', 'Error': '错误', 'AlertErrorMessage': '警告错误信息', - "GPTsUnavailableOrDeleted": "这个GPTs可能已经被转为私有或者被删除了,导致无法使用,你可以尝试切换到其他的GPTs" + "GPTsUnavailableOrDeleted": "这个GPTs可能已经被转为私有或者被删除了,导致无法使用,你可以尝试切换到其他的GPTs", + + "copy_tooltip": "复制到剪贴板", + "export_tooltip": "导出为图片", + "copy_success": "复制到剪贴板成功!", + "export_success": "成功导出为图片!", + "Preview": "预览", + "Code": "代码", + 'zoomIn': '放大', + 'zoomOut': '缩小', + 'zoomReset': '重置', } } }; diff --git a/packages/core/constant.ts b/packages/core/constant.ts index 2c3625b..d6364fe 100644 --- a/packages/core/constant.ts +++ b/packages/core/constant.ts @@ -5,7 +5,7 @@ const WEBSITE_URL = 'https://open-gpts.vercel.app' const MODELS_DICT: Record = { - chatgpt35API: { value: 'gpt-3.5-turbo-16k', desc: 'ChatGPT (API)' }, + chatgpt35API: { value: 'gpt-3.5-turbo-16k', desc: 'ChatGPT 3.5 turbo(API)' }, chatgptFree35: { value: 'text-davinci-002-render-sha', desc: 'ChatGPT (Web)' }, chatgptPlus4Browsing: { value: 'gpt-4', desc: 'ChatGPT (Web, GPT-4, browsing, analysis, DALL·E)' }, chatgptPlus4: { value: 'gpt-4-gizmo', desc: 'ChatGPT (Web, GPT-4, ChatGPT Classic)' }, diff --git a/packages/core/web/openai.ts b/packages/core/web/openai.ts index f52e221..c67f928 100644 --- a/packages/core/web/openai.ts +++ b/packages/core/web/openai.ts @@ -622,6 +622,9 @@ class GPT { }) }).catch(error => { console.log('fetch-sse', error) + if(error.message==='Failed to fetch') { + throw new Error('chatGPT404') + } throw error }); if (session?.autoClean && session?.conversationId) this.conversation?.delete(session?.conversationId) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2367413..94ed7d1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -163,9 +163,6 @@ importers: tippy.js: specifier: ^6.3.7 version: registry.npmmirror.com/tippy.js@6.3.7 - unist-util-visit-parents: - specifier: ^6.0.1 - version: registry.npmmirror.com/unist-util-visit-parents@6.0.1 use-debounce: specifier: ^10.0.0 version: registry.npmmirror.com/use-debounce@10.0.0(react@18.2.0) @@ -221,6 +218,9 @@ importers: typescript: specifier: 5.2.2 version: registry.npmmirror.com/typescript@5.2.2 + webpack-bundle-analyzer: + specifier: ^4.10.1 + version: registry.npmmirror.com/webpack-bundle-analyzer@4.10.1 apps/web: dependencies: @@ -1002,6 +1002,13 @@ packages: engines: {node: '>=10'} dev: false + registry.npmmirror.com/@discoveryjs/json-ext@0.5.7: + resolution: {integrity: sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz} + name: '@discoveryjs/json-ext' + version: 0.5.7 + engines: {node: '>=10.0.0'} + dev: true + registry.npmmirror.com/@dnd-kit/accessibility@3.1.0(react@18.2.0): resolution: {integrity: sha512-ea7IkhKvlJUv9iSHJOnxinBcoOI3ppGnnL+VDJ75O45Nss6HtZd8IdN8touXPDtASfeI2T2LImb8VOZcL47wjQ==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@dnd-kit/accessibility/-/accessibility-3.1.0.tgz} id: registry.npmmirror.com/@dnd-kit/accessibility/3.1.0 @@ -4013,6 +4020,12 @@ packages: config-chain: registry.npmmirror.com/config-chain@1.1.13 dev: false + registry.npmmirror.com/@polka/url@1.0.0-next.24: + resolution: {integrity: sha512-2LuNTFBIO0m7kKIQvvPHN6UE63VjpmL9rnEEaOOaiSPbZK+zUOYIzBAWcED+3XYzhYsd/0mD57VdxAEqqV52CQ==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@polka/url/-/url-1.0.0-next.24.tgz} + name: '@polka/url' + version: 1.0.0-next.24 + dev: true + registry.npmmirror.com/@popperjs/core@2.11.8: resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@popperjs/core/-/core-2.11.8.tgz} name: '@popperjs/core' @@ -5849,6 +5862,13 @@ packages: acorn: registry.npmmirror.com/acorn@8.11.3 dev: true + registry.npmmirror.com/acorn-walk@8.3.2: + resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/acorn-walk/-/acorn-walk-8.3.2.tgz} + name: acorn-walk + version: 8.3.2 + engines: {node: '>=0.4.0'} + dev: true + registry.npmmirror.com/acorn@8.11.3: resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/acorn/-/acorn-8.11.3.tgz} name: acorn @@ -6904,7 +6924,6 @@ packages: name: commander version: 7.2.0 engines: {node: '>= 10'} - dev: false registry.npmmirror.com/commander@8.3.0: resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/commander/-/commander-8.3.0.tgz} @@ -7599,6 +7618,12 @@ packages: version: 1.11.10 dev: false + registry.npmmirror.com/debounce@1.2.1: + resolution: {integrity: sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/debounce/-/debounce-1.2.1.tgz} + name: debounce + version: 1.2.1 + dev: true + registry.npmmirror.com/debug@3.2.7: resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/debug/-/debug-3.2.7.tgz} name: debug @@ -7935,7 +7960,6 @@ packages: resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/duplexer/-/duplexer-0.1.2.tgz} name: duplexer version: 0.1.2 - dev: false registry.npmmirror.com/earcut@2.2.4: resolution: {integrity: sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/earcut/-/earcut-2.2.4.tgz} @@ -9306,6 +9330,15 @@ packages: engines: {node: '>= 10.x'} dev: false + registry.npmmirror.com/gzip-size@6.0.0: + resolution: {integrity: sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/gzip-size/-/gzip-size-6.0.0.tgz} + name: gzip-size + version: 6.0.0 + engines: {node: '>=10'} + dependencies: + duplexer: registry.npmmirror.com/duplexer@0.1.2 + dev: true + registry.npmmirror.com/har-schema@2.0.0: resolution: {integrity: sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/har-schema/-/har-schema-2.0.0.tgz} name: har-schema @@ -9556,6 +9589,12 @@ packages: lru-cache: registry.npmmirror.com/lru-cache@7.18.3 dev: true + registry.npmmirror.com/html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/html-escaper/-/html-escaper-2.0.2.tgz} + name: html-escaper + version: 2.0.2 + dev: true + registry.npmmirror.com/html-parse-stringify@3.0.1: resolution: {integrity: sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz} name: html-parse-stringify @@ -10086,6 +10125,13 @@ packages: isobject: registry.npmmirror.com/isobject@3.0.1 dev: false + registry.npmmirror.com/is-plain-object@5.0.0: + resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/is-plain-object/-/is-plain-object-5.0.0.tgz} + name: is-plain-object + version: 5.0.0 + engines: {node: '>=0.10.0'} + dev: true + registry.npmmirror.com/is-reference@3.0.2: resolution: {integrity: sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/is-reference/-/is-reference-3.0.2.tgz} name: is-reference @@ -12072,6 +12118,13 @@ packages: engines: {node: '>=4'} dev: false + registry.npmmirror.com/mrmime@2.0.0: + resolution: {integrity: sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/mrmime/-/mrmime-2.0.0.tgz} + name: mrmime + version: 2.0.0 + engines: {node: '>=10'} + dev: true + registry.npmmirror.com/ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/ms/-/ms-2.1.2.tgz} name: ms @@ -12596,6 +12649,13 @@ packages: mimic-fn: registry.npmmirror.com/mimic-fn@2.1.0 dev: false + registry.npmmirror.com/opener@1.5.2: + resolution: {integrity: sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/opener/-/opener-1.5.2.tgz} + name: opener + version: 1.5.2 + hasBin: true + dev: true + registry.npmmirror.com/optionator@0.9.3: resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/optionator/-/optionator-0.9.3.tgz} name: optionator @@ -15134,6 +15194,17 @@ packages: is-arrayish: registry.npmmirror.com/is-arrayish@0.3.2 dev: false + registry.npmmirror.com/sirv@2.0.4: + resolution: {integrity: sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/sirv/-/sirv-2.0.4.tgz} + name: sirv + version: 2.0.4 + engines: {node: '>= 10'} + dependencies: + '@polka/url': registry.npmmirror.com/@polka/url@1.0.0-next.24 + mrmime: registry.npmmirror.com/mrmime@2.0.0 + totalist: registry.npmmirror.com/totalist@3.0.1 + dev: true + registry.npmmirror.com/slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/slash/-/slash-3.0.0.tgz} name: slash @@ -15959,6 +16030,13 @@ packages: commander: registry.npmmirror.com/commander@2.20.3 dev: false + registry.npmmirror.com/totalist@3.0.1: + resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/totalist/-/totalist-3.0.1.tgz} + name: totalist + version: 3.0.1 + engines: {node: '>=6'} + dev: true + registry.npmmirror.com/tough-cookie@2.5.0: resolution: {integrity: sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/tough-cookie/-/tough-cookie-2.5.0.tgz} name: tough-cookie @@ -16831,6 +16909,31 @@ packages: version: 4.0.2 dev: false + registry.npmmirror.com/webpack-bundle-analyzer@4.10.1: + resolution: {integrity: sha512-s3P7pgexgT/HTUSYgxJyn28A+99mmLq4HsJepMPzu0R8ImJc52QNqaFYW1Z2z2uIb1/J3eYgaAWVpaC+v/1aAQ==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.10.1.tgz} + name: webpack-bundle-analyzer + version: 4.10.1 + engines: {node: '>= 10.13.0'} + hasBin: true + dependencies: + '@discoveryjs/json-ext': registry.npmmirror.com/@discoveryjs/json-ext@0.5.7 + acorn: registry.npmmirror.com/acorn@8.11.3 + acorn-walk: registry.npmmirror.com/acorn-walk@8.3.2 + commander: registry.npmmirror.com/commander@7.2.0 + debounce: registry.npmmirror.com/debounce@1.2.1 + escape-string-regexp: registry.npmmirror.com/escape-string-regexp@4.0.0 + gzip-size: registry.npmmirror.com/gzip-size@6.0.0 + html-escaper: registry.npmmirror.com/html-escaper@2.0.2 + is-plain-object: registry.npmmirror.com/is-plain-object@5.0.0 + opener: registry.npmmirror.com/opener@1.5.2 + picocolors: registry.npmmirror.com/picocolors@1.0.0 + sirv: registry.npmmirror.com/sirv@2.0.4 + ws: registry.npmmirror.com/ws@7.5.9 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + dev: true + registry.npmmirror.com/whatwg-url@7.1.0: resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/whatwg-url/-/whatwg-url-7.1.0.tgz} name: whatwg-url @@ -16942,6 +17045,21 @@ packages: name: wrappy version: 1.0.2 + registry.npmmirror.com/ws@7.5.9: + resolution: {integrity: sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/ws/-/ws-7.5.9.tgz} + name: ws + version: 7.5.9 + engines: {node: '>=8.3.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dev: true + registry.npmmirror.com/ws@8.14.2(bufferutil@4.0.8)(utf-8-validate@6.0.3): resolution: {integrity: sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/ws/-/ws-8.14.2.tgz} id: registry.npmmirror.com/ws/8.14.2