diff --git a/README.md b/README.md index f1328a0..cf30de0 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # Earth + [![](/public/icon-128.png)](http://player.bilibili.com/player.html?aid=271181111&bvid=BV1zc411P7vS&cid=1132599638&page=1) + Artificial General Intelligence user interface 普惠AGI交互界面,让更多人可以实现自己的AGI交互界面。 @@ -8,13 +10,13 @@ AGI-UI的使命是改善AGI在PC、Web、Mobile、XR、机器人等领域的人 > 作为AGIUI的首个开源项目,Earth是一个浏览器插件,支持常见的浏览器:Chrome, Firefox, Safari, Edge, Brave等。 - [![](/public/icon-128.png)](http://player.bilibili.com/player.html?aid=271181111&bvid=BV1zc411P7vS&cid=1132599638&page=1) + [![](/examples/demo01.png)](/examples/demo01.mp4) 🔝演示视频 ## 如何使用? -安装步骤,先打开网址下载 https://github.com/AGIUI/Earth/releases/tag/v0.2.2 +安装步骤,先打开网址下载 https://github.com/AGIUI/Earth/releases/tag/v0.3.1 Chrome: @@ -61,31 +63,29 @@ npm run build [browser] ## combo的数据示例 ``` [{ - "checked": true, + "interfaces": [], "combo": 3, "id": "1881e7d386e", "isInfinite": false, "owner": "user", "prompt": { - "bindCurrentPage": false, - "isApi": false, - "isNextUse": true, + "input":'default', + "output": 'default', + "agent":'default' + "api": {}, "queryObj": { "isQuery": false, "query": "", "url": "" }, "text": "给我一个科幻故事,和植物、机器人、爱情有关", - "url": "" - }, - "prompt2": { - "bindCurrentPage": false, - "isApi": false, - "isNextUse": false, - "text": "总结下" + temperature: 0.6, + model: 'ChatGPT', }, "prompt3": { - "text": "嗯" + "text": "嗯", + temperature: 0.6, + model: 'ChatGPT', }, "role": "", "tag": "科幻故事" @@ -98,6 +98,26 @@ v0.2.0 新增绑定当前网页、输出格式,combo编辑器导入导出,提供示例 +v0.3.1 +- combo数据结构调整及编辑器,新增:interfaces(home、contextMenus、showInChat)、input、output + +- combo支持单个导出 + +- API节点 + + + +## TODO + +- PDF节点:读取、创建、阅读器 + +- PPT节点:读取、创建 + +- 高亮网页信息节点(实验功能) + + +## 社区 +[discord](https://discord.gg/7YVVhEQExu) ## 相关资料: diff --git a/config.json b/config.json index da4cfca..5328135 100644 --- a/config.json +++ b/config.json @@ -8,7 +8,9 @@ }], "api": "https://api.openai.com", "displayApiName": "openai", - "models": ["gpt-3.5-turbo"], + "models": [ + "gpt-3.5-turbo" + ], "model": "gpt-3.5-turbo", "canImport": true } diff --git a/examples/demo01.mp4 b/examples/demo01.mp4 new file mode 100644 index 0000000..e0f769d Binary files /dev/null and b/examples/demo01.mp4 differ diff --git a/examples/demo01.png b/examples/demo01.png new file mode 100644 index 0000000..694c8eb Binary files /dev/null and b/examples/demo01.png differ diff --git a/examples/my-combo-1684478981480.json b/examples/my-combo-1684478981480.json new file mode 100644 index 0000000..936f758 --- /dev/null +++ b/examples/my-combo-1684478981480.json @@ -0,0 +1,260 @@ +[{ + "checked": false, + "combo": 3, + "id": "18822914d15", + "isInfinite": false, + "owner": "user", + "prompt": { + "output": "isNextUse", + "input": "isQuery", + "model": "ChatGPT", + "queryObj": { + "isQuery": true, + "query": ".weibo-main .weibo-text", + "url": "m.weibo.cn/search?containerid=100103type%3D1%26q%3D%23AGIUI" + }, + "temperature": 0.14, + "text": "你好,你是谁?", + "url": "" + }, + "prompt2": { + "output": "isNextUse", + "input": "default", + "model": "ChatGPT", + "queryObj": { + "isQuery": false, + "query": "", + "url": "" + }, + "temperature": 0.25, + "text": "你现在是一位著名的科幻作家,写过《流浪地球》的大作,提取关键信息,用中文创作一个科幻故事", + "url": "" + }, + "prompt3": { + "output": "default", + "input": "default", + "model": "ChatGPT", + "queryObj": { + "isQuery": false, + "query": "", + "url": "" + }, + "temperature": 0.13, + "text": "作为读者,根据这个故事,用中文写出你的读后感", + "url": "" + }, + "role": "", + "tag": "根据微博内容创作科幻故事" + }, + { + "checked": false, + "combo": 3, + "id": "1882847a340", + "isInfinite": false, + "owner": "user", + "prompt": { + "output": "isNextUse", + "input": "isQuery", + "model": "ChatGPT", + "queryObj": { + "isQuery": true, + "query": ".weibo-text", + "url": "m.weibo.cn" + }, + "temperature": 0.23, + "text": "7", + "url": "" + }, + "prompt2": { + "output": "isNextUse", + "input": "default", + "model": "ChatGPT", + "queryObj": { + "isQuery": false, + "query": "", + "url": "" + }, + "temperature": 0.13, + "text": "提取人物、关键事件,虚构一个故事,你现在是记者,请编写中文访谈提纲", + "url": "" + }, + "prompt3": { + "output": "default", + "input": "default", + "model": "ChatGPT", + "queryObj": { + "isQuery": false, + "query": "", + "url": "" + }, + "temperature": 0.14, + "text": "你现在是技术专家,为这个访谈提纲增加科技的话题,可以包括人工智能、元宇宙等,用中文写一个访谈的概要和提纲", + "url": "" + }, + "role": "", + "tag": "获取微博最新消息,写一个访谈提纲" + }, + { + "checked": false, + "combo": 2, + "id": "1882cf38f60", + "isInfinite": true, + "owner": "user", + "prompt": { + "output": "isNextUse", + "input": "default", + "model": "ChatGPT", + "queryObj": { + "isQuery": false, + "query": "", + "url": "" + }, + "temperature": 0.6, + "text": "现在你是顶级设计师,对方也是顶级设计师,你会根据上文内容阐述你对设计的理解。如果没有上文,你可以发起交流。", + "url": "" + }, + "prompt2": { + "output": "isNextUse", + "input": "default", + "model": "Bing", + "queryObj": { + "isQuery": false, + "query": "", + "url": "" + }, + "temperature": 0.6, + "text": "现在你是顶级设计师,对方也是顶级设计师,你会根据上文内容阐述你对设计的理解。", + "url": "" + }, + "role": "", + "tag": "Bing和ChatGPT聊天" + }, + { + "checked": true, + "combo": 4, + "id": "188321b6c7b", + "isInfinite": false, + "owner": "user", + "prompt": { + "output": "isNextUse", + "input": "default", + "model": "ChatGPT", + "queryObj": { + "isQuery": false, + "query": "", + "url": "" + }, + "temperature": 0.9, + "text": "按照新闻、体育、汽车、房产、旅游、教育、时尚、科技、财经、娱乐、综合,这几种类别,分类文章类别", + "url": "" + }, + "prompt2": { + "output": "isNextUse", + "input": "bindCurrentPage", + "model": "ChatGPT", + "queryObj": { + "isQuery": false, + "query": "", + "url": "" + }, + "temperature": 0.9, + "text": "根据文章的信息,提取关键词和文章摘要,用中文写", + "url": "" + }, + "prompt3": { + "output": "isNextUse", + "input": "default", + "model": "ChatGPT", + "queryObj": { + "isQuery": false, + "query": "", + "url": "" + }, + "temperature": 0.8, + "text": "用中文提出3个启发人的问题,按照markdown格式输出", + "url": "" + }, + "prompt4": { + "output": "default", + "input": "default", + "model": "ChatGPT", + "queryObj": { + "isQuery": false, + "query": "", + "url": "" + }, + "temperature": 0.9, + "text": "按照文章类别、关键词、摘要、问题,用中文,按照markdown格式输出", + "url": "" + }, + "role": "", + "tag": "阅读理解" + }, + { + "checked": false, + "combo": 1, + "id": "18832a0e3be", + "isInfinite": false, + "owner": "user", + "prompt": { + "api": { + "isApi": false, + "url": "" + }, + "output": "isNextUse", + "input": "default", + "model": "ChatGPT", + "queryObj": { + "isQuery": false, + "query": "", + "url": "" + }, + "temperature": 0.1, + "text": "7", + "url": "" + }, + "role": "", + "tag": "7" + }, + { + "checked": false, + "combo": 2, + "id": "18832c2b1af", + "isInfinite": false, + "owner": "user", + "prompt": { + "api": { + "isApi": false, + "url": "" + }, + "input": "bindCurrentPage", + "model": "ChatGPT", + "output": "markdown", + "queryObj": { + "isQuery": false, + "query": "", + "url": "" + }, + "temperature": 0.3, + "text": "1" + }, + "prompt2": { + "api": { + "isApi": false, + "url": "" + }, + "input": "bindCurrentPageHTML", + "model": "Bing", + "output": "translate-zh", + "queryObj": { + "isQuery": false, + "query": "", + "url": "" + }, + "temperature": 0.6, + "text": "77" + }, + "role": "", + "tag": "1" + } +] \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index f66605f..e54dbe2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "Earth", - "version": "0.1.1", + "version": "0.3.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "Earth", - "version": "0.1.1", + "version": "0.3.0", "license": "MIT", "dependencies": { "@mozilla/readability": "^0.4.2", @@ -16,6 +16,7 @@ "markdown-it": "^13.0.1", "object-hash": "^3.0.0", "ofetch": "^1.0.1", + "pptxgenjs": "^3.12.0", "react": "^18.2.0", "react-dom": "^18.2.0", "styled-components": "^5.3.8", @@ -1335,8 +1336,7 @@ "node_modules/@types/node": { "version": "18.15.10", "resolved": "https://mirrors.cloud.tencent.com/npm/@types/node/-/node-18.15.10.tgz", - "integrity": "sha512-9avDaQJczATcXgfmMAW3MIWArOO7A+m90vuCFLr8AotWf8igO/mRoYukrk2cqZVtv38tHs33retzHEilM7FpeQ==", - "dev": true + "integrity": "sha512-9avDaQJczATcXgfmMAW3MIWArOO7A+m90vuCFLr8AotWf8igO/mRoYukrk2cqZVtv38tHs33retzHEilM7FpeQ==" }, "node_modules/@types/prop-types": { "version": "15.7.5", @@ -3133,8 +3133,7 @@ "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://mirrors.cloud.tencent.com/npm/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, "node_modules/create-require": { "version": "1.1.1", @@ -5450,6 +5449,11 @@ "node": ">=10.19.0" } }, + "node_modules/https": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https/-/https-1.0.0.tgz", + "integrity": "sha512-4EC57ddXrkaF0x83Oj8sM6SLQHAWXw90Skqu2M4AEWENZ3F02dFJE/GARA8igO79tcgYqGrD7ae4f5L3um2lgg==" + }, "node_modules/human-signals": { "version": "1.1.1", "resolved": "https://mirrors.cloud.tencent.com/npm/human-signals/-/human-signals-1.1.1.tgz", @@ -5510,7 +5514,6 @@ "version": "1.0.2", "resolved": "https://mirrors.cloud.tencent.com/npm/image-size/-/image-size-1.0.2.tgz", "integrity": "sha512-xfOoWjceHntRb3qFCrh5ZFORYH8XCdYpASltMhZ/Q0KZiOwjdE/Yl2QCiWdwD+lygV5bMCvauzgu5PxBX/Yerg==", - "dev": true, "dependencies": { "queue": "6.0.2" }, @@ -5524,8 +5527,7 @@ "node_modules/immediate": { "version": "3.0.6", "resolved": "https://mirrors.cloud.tencent.com/npm/immediate/-/immediate-3.0.6.tgz", - "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=", - "dev": true + "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=" }, "node_modules/immutable": { "version": "4.3.0", @@ -5580,8 +5582,7 @@ "node_modules/inherits": { "version": "2.0.4", "resolved": "https://mirrors.cloud.tencent.com/npm/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "node_modules/ini": { "version": "2.0.0", @@ -6261,7 +6262,6 @@ "version": "3.10.1", "resolved": "https://mirrors.cloud.tencent.com/npm/jszip/-/jszip-3.10.1.tgz", "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", - "dev": true, "dependencies": { "lie": "~3.3.0", "pako": "~1.0.2", @@ -6272,14 +6272,12 @@ "node_modules/jszip/node_modules/isarray": { "version": "1.0.0", "resolved": "https://mirrors.cloud.tencent.com/npm/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, "node_modules/jszip/node_modules/readable-stream": { "version": "2.3.8", "resolved": "https://mirrors.cloud.tencent.com/npm/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -6293,8 +6291,7 @@ "node_modules/jszip/node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://mirrors.cloud.tencent.com/npm/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "node_modules/jwa": { "version": "1.4.1", @@ -6385,7 +6382,6 @@ "version": "3.3.0", "resolved": "https://mirrors.cloud.tencent.com/npm/lie/-/lie-3.3.0.tgz", "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", - "dev": true, "dependencies": { "immediate": "~3.0.5" } @@ -7330,8 +7326,7 @@ "node_modules/pako": { "version": "1.0.11", "resolved": "https://mirrors.cloud.tencent.com/npm/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" }, "node_modules/parent-module": { "version": "1.0.1", @@ -7654,6 +7649,17 @@ "resolved": "https://mirrors.cloud.tencent.com/npm/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" }, + "node_modules/pptxgenjs": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/pptxgenjs/-/pptxgenjs-3.12.0.tgz", + "integrity": "sha512-ZozkYKWb1MoPR4ucw3/aFYlHkVIJxo9czikEclcUVnS4Iw/M+r+TEwdlB3fyAWO9JY1USxJDt0Y0/r15IR/RUA==", + "dependencies": { + "@types/node": "^18.7.3", + "https": "^1.0.0", + "image-size": "^1.0.0", + "jszip": "^3.7.1" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://mirrors.cloud.tencent.com/npm/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -7675,8 +7681,7 @@ "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://mirrors.cloud.tencent.com/npm/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, "node_modules/process-warning": { "version": "2.1.0", @@ -7806,7 +7811,6 @@ "version": "6.0.2", "resolved": "https://mirrors.cloud.tencent.com/npm/queue/-/queue-6.0.2.tgz", "integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==", - "dev": true, "dependencies": { "inherits": "~2.0.3" } @@ -8942,8 +8946,7 @@ "node_modules/setimmediate": { "version": "1.0.5", "resolved": "https://mirrors.cloud.tencent.com/npm/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" }, "node_modules/sha.js": { "version": "2.4.11", @@ -9184,7 +9187,6 @@ "version": "1.1.1", "resolved": "https://mirrors.cloud.tencent.com/npm/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, "dependencies": { "safe-buffer": "~5.1.0" } @@ -9192,8 +9194,7 @@ "node_modules/string_decoder/node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://mirrors.cloud.tencent.com/npm/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "node_modules/string-convert": { "version": "0.2.1", @@ -9914,8 +9915,7 @@ "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://mirrors.cloud.tencent.com/npm/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, "node_modules/uuid": { "version": "9.0.0", diff --git a/package.json b/package.json index 2e5dac1..ae222e1 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "Earth", "displayName": "Earth", - "version": "0.2.2", + "version": "0.3.1", "description": "AGIUI for Browser Extension", "license": "MIT", "repository": { @@ -21,6 +21,7 @@ "markdown-it": "^13.0.1", "object-hash": "^3.0.0", "ofetch": "^1.0.1", + "pptxgenjs": "^3.12.0", "react": "^18.2.0", "react-dom": "^18.2.0", "styled-components": "^5.3.8", diff --git a/src/components/Setup.tsx b/src/components/Setup.tsx index cf25659..27c46b2 100644 --- a/src/components/Setup.tsx +++ b/src/components/Setup.tsx @@ -332,7 +332,7 @@ class Setup extends React.Component<{ style={{ width: 500, padding: 20, display: 'flex' }}> - + {/*TODO 清空缓存 ,显示缓存的prompt数量 */} 设置 <p style={{ fontSize: '14px' }}>{this.state.name}</p> : '' - } */} - - - - this._bindCurrentPage(e[0] == 'bindCurrentPage')} /> - - {/* this._bindCurrentPage(e[0] == 'bindCurrentPage')} /> */} - - - this._outputChange(e.target.value)} - value={this.state.output.filter((m: any) => m.checked)[0].value} - optionType="button" - buttonStyle="solid" - size="small" - /> + + +
+ + this._change(e.target.value, 'input')} + value={this.state.input.filter((m: any) => m.checked)[0].value} + optionType="button" + buttonStyle="solid" + size="small" + /> +
+
+ + this._change(e.target.value, 'agent')} + value={this.state.agent.filter((m: any) => m.checked)[0].value} + optionType="button" + buttonStyle="solid" + size="small" + /> +
+
this._change(e.target.value, 'output')} + value={this.state.output.filter((m: any) => m.checked)[0].value} + optionType="button" + buttonStyle="solid" + size="small" + />
+ + this._changeChatbot(res)} + isLoading={this.state.isLoading} + config={this.props.config} + name={''} /> + +
+
diff --git a/src/components/chatbot/ChatBotPanel.tsx b/src/components/chatbot/ChatBotPanel.tsx index 1464152..0843ff0 100644 --- a/src/components/chatbot/ChatBotPanel.tsx +++ b/src/components/chatbot/ChatBotPanel.tsx @@ -148,16 +148,14 @@ class ChatBotPanel extends React.Component { justifyContent: 'space-between', paddingTop: '20px' }}> - this.props.callback(res)} - isLoading={this.state.disabled} - config={this.state.config} - name={''} /> + this.props.callback(e)} items={datas[subject.index+1]} /> + this.props.callback(e)} isLoading={this.state.disabled} + config={this.state.config} leftButton={{ label: 'Combo' }} /> @@ -197,7 +195,7 @@ class ChatBotPanel extends React.Component { })} />, this.setState({ fullscreen:!this.state.fullscreen })} />, diff --git a/src/components/chatbot/ChatBotTalks.tsx b/src/components/chatbot/ChatBotTalks.tsx index 0422665..54fe94c 100644 --- a/src/components/chatbot/ChatBotTalks.tsx +++ b/src/components/chatbot/ChatBotTalks.tsx @@ -1,12 +1,20 @@ import * as React from "react"; -import { Button } from 'antd'; +import { Button, Card, message } from 'antd'; +import { + CopyOutlined, FilePptOutlined +} from '@ant-design/icons'; + import styled from 'styled-components'; import ChatBotConfig from "./ChatBotConfig"; +import PPT from "@components/files/PPT" + /** < ChatBotTalks callback={} items={}/> + * + * export 是否允许导出 * * items:[{ - type, user, html, buttons, + type, user, html, buttons,export }] * items= [ @@ -88,6 +96,7 @@ const Flex: any = styled(Base)` display:${(props: any) => props.display || 'none'}; ` +// 定义聊天对话界面的样式 const Content: any = styled(Flex)` display:flex; height:100%; @@ -111,19 +120,13 @@ const Content: any = styled(Flex)` -webkit-box-shadow:inset 0 0 5px rgba(0, 0,0, 0.2); background:rgba(0, 0,0, 0.2); } - & h1,h2{ - margin: 12px 0; - font-weight: 800; - } - & p,li{ - margin: 6px 0; - } ` const customizeRenderEmpty = (text = 'Data Not Found') => (
- {/* */}

{text}

@@ -145,41 +148,136 @@ const createTalkBubbleStyle = (user = false) => { return r } -const thinkingBtn = (name = '思考中') => -const suggestBtn = (i: string, name: string, callback: any) => +const thinkingBtn = (name = '思考中') => +const suggestBtn = (i: string, name: string, callback: any) => + +const copy = async (data: any) => { + console.log('copy', data) + const div = document.createElement('div'); + div.innerHTML = data.html; + const copyText = div.innerText; + + let type = "text/plain" + try { + const blob: any = new Blob([copyText], { type }); + const data = [new ClipboardItem({ [type]: blob })]; + // 写入剪切板 + await navigator.clipboard.write(data); + message.info('已拷贝'); + } catch (e) { + console.error('Failed to copy: ', e); + } +} + +const createPPT = (data: any) => { + console.log('createPPT', data) + const { type, html } = data; + let div = document.createElement('div'); + div.innerHTML = html; + let items: any = []; + if (type === 'markdown') { -const createListItem = (data: any, index: number) =>
{ - // 状态判断:思考、建议选项、对话 - data.type == 'thinking' ? thinkingBtn(data.hi) : ( - data.type == 'suggest' ? <> + items.push( { - data.buttons - && data.buttons.length > 0 - && data.hi ? - customizeRenderEmpty(data.hi) : '' + title: div.innerText, + } + ); + + } else if (type == 'images') { + items.push( { - data.buttons && data.buttons.length > 0 ? Array.from( - data.buttons, - (button: any, i) => suggestBtn(i + '', button.name, () => button.callback && button.callback()) - ) : '' + title: type, + images: Array.from(div.querySelectorAll('img'), im => { + return { + title: type, + base64: im.src + } + }) } - : (data.html ?

-

: '') - ) + ); + } -}
+ + const p = new PPT(); + p.create('test-by-shadow', items) + +} + +const createListItem = (data: any, index: number) => { + + return
{ + // 状态判断:思考、建议选项、对话 + data.type == 'thinking' ? thinkingBtn(data.hi) : ( + data.type == 'suggest' ? <> + { + data.buttons + && data.buttons.length > 0 + && data.hi ? + customizeRenderEmpty(data.hi) : '' + } + { + data.buttons && data.buttons.length > 0 ? Array.from( + data.buttons, + (button: any, i) => suggestBtn(i + '', button.name, () => button.callback && button.callback()) + ) : '' + } + : (data.html ? + data.user ?

+

:
+} type PropType = { @@ -226,9 +324,11 @@ class ChatBotTalks extends React.Component { this.setState({ items: this._updateItems() }) + } + if ( + this.props.items.length !== prevProps.items.length + ) { this._go2Bottom(); - // this.destroyConnection(); - // this.setupConnection(); } } @@ -241,9 +341,10 @@ class ChatBotTalks extends React.Component { const defaultItems = [ChatBotConfig.createTalkData('help', {})]; // 当this.props.items 为空 - let items: any = !(this.props.items && this.props.items.length > 0) ? defaultItems : [...this.props.items]; + let items: any = (!(this.props.items && this.props.items.length > 0) ? defaultItems : [...this.props.items]).filter(i => i); // console.log('this.props.items',items) items = Array.from(items, (item: any, index: number) => { + // console.log(item) const user = (!!item.user) || false, html = item.html; const buttons = Array.from( @@ -281,6 +382,8 @@ class ChatBotTalks extends React.Component { { diff --git a/src/components/combo/Agent.tsx b/src/components/combo/Agent.tsx new file mode 100644 index 0000000..f2fc13b --- /dev/null +++ b/src/components/combo/Agent.tsx @@ -0,0 +1,50 @@ + +const sleep = (t = 1000) => { + return new Promise((res: any, rej) => { + setTimeout(() => res(), t) + }) +} + +// 解析字符串成json,并高亮信息 +const highlightText = async (text = '', elements: any) => { + let success = false; + try { + // let itemsIndex = JSON.parse(text); + const target = []; + for (const element of elements) { + if (text.match(element.id)) { + element.style = `background-color: #ffffbb; + color: black; + padding: 8px;` + // console.log(element.id, element) + target.push(element) + } + } + + for (const t of target) { + t.scrollIntoView(); + await sleep(2000) + } + + success = true; + } catch (error) { + + } + return success +} + +// 知识星球自动发内容 https://wx.zsxq.com/dweb2/index/group/481225281248 +const postTopicForZsxq = async (text: any) => { + const h: any = document.querySelector('.post-topic-head'); + h.click(); + await sleep(1000) + const inp: any = document.querySelector('.ql-editor'); + inp.innerText = text; + await sleep(1000) + const btn: any = document.querySelector('.submit-btn'); + btn.click() +} + +export { + highlightText,postTopicForZsxq +} \ No newline at end of file diff --git a/src/components/combo/ComboData.tsx b/src/components/combo/ComboData.tsx index 5b4227c..adaffa9 100644 --- a/src/components/combo/ComboData.tsx +++ b/src/components/combo/ComboData.tsx @@ -1,93 +1,129 @@ +import { workflow } from '@components/Workflow' + + const PROMPT_MAX_LENGTH = 720 // output : default,json,markdown +// type:prompt,tasks,query,api,highlight const defaultPrompt = { text: '', - isNextUse: false, - bindCurrentPage: false, + url: '', + api: { + url: '', + protocol: 'https://', + init: { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: "{}", + mode: 'cors', + cache: 'default', + responseType: 'text' + }, + isApi: false + }, queryObj: { - query: '', url: '', isQuery: false + query: '', url: '', protocol: 'https://', isQuery: false }, - isApi: false, - url: '', temperature: 0.6, model: 'ChatGPT', - output:'default' + input: 'default', + output: 'default', + type: 'prompt' } /** - * + * interfaces -- home、contextMenus、showInChat + * app 应用名 + * version版本号 + * app、version 在combo导出的时候会动态写 + * */ const defaultCombo = { tag: '', role: '', combo: 1, - checked: false, + interfaces: [], isInfinite: false, owner: 'official', prompt: defaultPrompt, + version: '0.3.0', + app: 'earth', + id: '' } const comboOptions = [ { label: '开启Prompts Combo', - value: 'Combo', + value: 'combo', }, { label: '作为对话流选项', - value: 'ShowInChat', + value: 'showInChat', }, { - label: '无限循环', - value: 'Infinite', - } -]; - -const promptOptions = [ - { - label: '根据选择器获取网页信息', - value: 'isQuery', - type: 'checkbox' - }, - // { - // label:'API请求', - // value:'isApi' - // }, - { - label: '绑定当前网页', - value: 'bindCurrentPage', - type: 'checkbox' + label: '作为右键菜单选项', + value: 'contextMenus', }, { - label: '作为上下文', - value: 'isNextUse', - type: 'checkbox' + label: '首页', + value: 'home', }, { - label: '温度', - value: 'temperature', - type: 'range' - }, - { - label: '模型', - value: 'model', - type: 'select', - options:[ - { value: 'ChatGPT', label: 'ChatGPT' }, - { value: 'Bing', label: 'Bing' } - ] + label: '无限循环', + value: 'infinite', } ]; -const createPrompts = () => { -} + +const models: any = Array.from(workflow.models, model => { + if (model.value === 'temperature') return { + ...model, type: 'range' + } + if (model.value === 'model') return { + ...model, type: 'select' + } +}) + + + +const inputs: any = Array.from(workflow.inputs, (inp: any) => { + if (!inp.disabled) return { + ...inp, input: true, type: 'checkbox' + } +}).filter(a => a) + +/** + * 默认 - 不传递 + */ +const outputs: any = Array.from(workflow.outputs, (out: any) => { + if (!out.disabled) return { + ...out, output: true, type: 'checkbox' + } +}).filter(a => a) + +const promptOptions: any = Array.from(workflow.agents, agent => { + if (!agent.disabled) return { + ...agent, + children: [], + inputs: inputs.filter((f: any) => f.value), + outputs: outputs.filter((f: any) => f.value), + models: Array.from(models, (m: any) => { + m.value == "temperature" ? m.defaultValue = agent.temperature : ''; + return m + }) + } +}).filter(a => a) + export { PROMPT_MAX_LENGTH, defaultCombo, defaultPrompt, + comboOptions, promptOptions, - comboOptions + inputs, outputs, models } \ No newline at end of file diff --git a/src/components/combo/ComboEditor.tsx b/src/components/combo/ComboEditor.tsx index 6314e5a..a988621 100644 --- a/src/components/combo/ComboEditor.tsx +++ b/src/components/combo/ComboEditor.tsx @@ -4,7 +4,7 @@ import { Button, Typography, Tag, - List,Empty, + List, Empty, } from 'antd'; const { Text } = Typography; @@ -13,13 +13,37 @@ import { CloseOutlined } from '@ant-design/icons'; -import { chromeStorageGet, chromeStorageSet, md5 } from "@components/Utils" +import { chromeStorageGet, chromeStorageSet, md5, getConfig } from "@components/Utils" import { defaultCombo } from '@components/combo/ComboData' import DownloadButton from '@components/buttons/DownloadButton'; import { FlexRow } from "@components/Style"; import OpenFileButton from "@components/buttons/OpenFileButton"; - + +import styled from 'styled-components'; + +const Base: any = styled.div` + & .ant-card-body::-webkit-scrollbar{ + width:2px; + } + & .ant-card-body::-webkit-scrollbar{ + width:2px; + } + & .ant-card-body::-webkit-scrollbar-track{ + border-radius:25px; + -webkit-box-shadow:inset 0 0 5px rgba(255,255,255, 0.5); + background:rgba(255,255,255, 0.5); + } + & .ant-card-body::-webkit-scrollbar-thumb{ + border-radius:15px; + -webkit-box-shadow:inset 0 0 5px rgba(0, 0,0, 0.2); + background:rgba(0, 0,0, 0.2); + } + & .ant-list-item{ + width:100%; + } + ` + type PropType = { myPrompts: any; callback: any; @@ -31,6 +55,8 @@ type StateType = { secondTitle: string; myPrompts: any, showImportModal: boolean; + version: string; + app: string; } interface ComboEditor { @@ -46,7 +72,13 @@ class ComboEditor extends React.Component { secondTitle: '我的Prompts', myPrompts: this.props.myPrompts, showImportModal: false, + version: '', + app: '' } + getConfig().then(json => this.setState({ + app: json.app, + version: json.version + })) } componentDidMount() { @@ -102,25 +134,31 @@ class ComboEditor extends React.Component { }) }; - - - _downloadMyCombo() { - const prompts = this.state.myPrompts.filter((p: any) => p.owner != 'official') + _downloadMyCombo(combos: any = []) { + const data: any = []; + for (const combo of combos) { + combo.version = this.state.version; + combo.app = this.state.app; + // combo.id = ""; + if (!combo.id) combo.id = md5(JSON.stringify(combo)); + data.push(combo) + } - const data = JSON.stringify(prompts) + const name = combos[0].tag; + const id = md5(JSON.stringify(data)); //通过创建a标签实现 const link = document.createElement('a') //encodeURIComponent解决中文乱码 - link.href = `data:application/json;charset=utf-8,\ufeff${encodeURIComponent(data)}` + link.href = `data:application/json;charset=utf-8,\ufeff${encodeURIComponent(JSON.stringify(data))}` - //对下载的文件命名 - const jsonName = `my-combo-${(new Date()).getTime()}` - link.download = jsonName + //下载文件命名 + link.download = `${name}_${id}` document.body.appendChild(link) link.click() document.body.removeChild(link); } + _importMyCombo() { console.log(this.state.myPrompts) const input = document.createElement('input'); @@ -143,7 +181,7 @@ class ComboEditor extends React.Component { chromeStorageGet(['user']).then((items: any) => { let myPrompts = [...that.state.myPrompts]; - let newUser:any = [] + let newUser: any = [] if (items && items.user) { newUser = [...items.user] @@ -155,7 +193,8 @@ class ComboEditor extends React.Component { if (isNew) { newUser.push(n); myPrompts.push(n) - }; + } + ; } chromeStorageSet({ 'user': newUser }); @@ -171,8 +210,9 @@ class ComboEditor extends React.Component { }, false) input.click(); } + render() { - return ( + return ( - + {this.state.secondTitle} -
+
this._downloadMyCombo()} /> + callback={() => this._downloadMyCombo(this.state.myPrompts.filter((p: any) => p.owner != 'official'))} /> this._importMyCombo()} /> @@ -284,13 +324,13 @@ class ComboEditor extends React.Component {
{/* {this.state.showEdit && ReactDOM.createPortal(showEditModal(), document.body as HTMLElement)} */} - + ); } } diff --git a/src/components/combo/ComboModal.tsx b/src/components/combo/ComboModal.tsx index dfdcc02..48c3fdc 100644 --- a/src/components/combo/ComboModal.tsx +++ b/src/components/combo/ComboModal.tsx @@ -7,14 +7,15 @@ import { Checkbox, Form, Popconfirm, - Divider, Select, Slider, Radio + Divider, Select, Slider, Radio, Tabs, message } from 'antd'; + const { Option } = Select; const { TextArea } = Input; -import { md5 } from '@components/Utils' +import { md5, getConfig } from '@components/Utils' -import { PROMPT_MAX_LENGTH, promptOptions, comboOptions, defaultCombo, defaultPrompt } from "@components/combo/ComboData" +import { PROMPT_MAX_LENGTH, promptOptions, inputs, outputs, models, comboOptions, defaultCombo, defaultPrompt } from "@components/combo/ComboData" import styled from 'styled-components'; @@ -22,7 +23,7 @@ const Form1 = styled(Form)` &.ant-form{ display: block!important; } - .ant-form-item-control-input-content{ + &.ant-form-item-control-input-content{ text-align: left!important; } `; @@ -52,7 +53,9 @@ type StateType = { currentPrompt: any; options: any; promptOptions: any; - step:number; + step: number; + app: string; + version: string; } interface ComboModal { @@ -70,9 +73,17 @@ class ComboModal extends React.Component { currentPrompt: this.props.currentPrompt, options: comboOptions, promptOptions, - step:0.1 + step: 0.1, + app: '', + version: '' } console.log('currentPrompt', this.props.currentPrompt) + getConfig().then(json => { + this.setState({ + app: json.app, + version: json.version + }) + }) } componentDidMount() { @@ -101,50 +112,126 @@ class ComboModal extends React.Component { // this.destroyConnection(); } - /** - * 结果 - */ - _onFinish() { + _createTabKey(prompt: any) { + let tabKey = "prompt"; + if (prompt.queryObj && prompt.queryObj.isQuery) { + tabKey = 'isQuery' + } + // if(prompt.queryObj&&prompt.queryObj.isQuery){ + // tabKey='isQuery' + // } + this.setState({ + tabKey + }) + } + + _saveMyCombo() { + const currentPrompt = this.state.currentPrompt let data: any = {}, prompts: any = {}; const promptKeys = Array.from([1, 2, 3, 4, 5, 6, 7], i => `prompt${i != 1 ? i : ''}`); - // console.log('this.state.currentPrompt', JSON.stringify(this.state.currentPrompt, null, 2)) - for (const key in this.state.currentPrompt) { - if (this.state.currentPrompt[key] !== undefined || this.state.currentPrompt[key] !== "") { - if (key.match('prompt')) { - if (promptKeys.includes(key) && ((this.state.currentPrompt[key].text && this.state.currentPrompt[key].text != '') || (this.state.currentPrompt[key].queryObj && this.state.currentPrompt[key].queryObj.isQuery))) prompts[key] = this.state.currentPrompt[key]; + // console.log('_onFinish', JSON.stringify(currentPrompt, null, 2)) + for (const key in currentPrompt) { + if (currentPrompt[key]) { + if (promptKeys.includes(key)) { + // 判断类型 + const type = currentPrompt[key].type; + let isEmpty = false; + if (type == 'api') { + currentPrompt[key].api.isApi = true; + currentPrompt[key].queryObj = { ...defaultPrompt.queryObj }; + currentPrompt[key].text = ''; + } else if (type == 'query') { + currentPrompt[key].api = { ...defaultPrompt.api }; + currentPrompt[key].queryObj.isQuery = true; + currentPrompt[key].text = ''; + } else if (type == 'tasks' || type == 'prompt' || type == 'highlight') { + currentPrompt[key].api = { ...defaultPrompt.api }; + currentPrompt[key].queryObj = { ...defaultPrompt.queryObj }; + isEmpty = !currentPrompt[key].text + } + + if (isEmpty == false) prompts[key] = currentPrompt[key]; + } else { - data[key] = this.state.currentPrompt[key]; + data[key] = currentPrompt[key]; } } } - // console.log('_onFinish', data, this.state.currentPrompt) - const timestamp = new Date().getTime(); - const uniqueId = timestamp.toString(16); - if (data && !data.id) data.id = uniqueId; + // console.log('_onFinish', data, prompts) let combo = 0, newPrompts: any = {}; for (const key in prompts) { if (promptKeys.includes(key)) { combo++; - newPrompts[`prompt${combo == 1 ? '' : combo}`] = prompts[key] + const prompt = prompts[key]; + newPrompts[`prompt${combo == 1 ? '' : combo}`] = prompt + } } data = { - prompt: { - ...defaultCombo, - ...data, - ...newPrompts, - combo - }, - from: 'combo-editor' + ...defaultCombo, + ...data, + ...newPrompts, + combo } + data.version = this.state.version; + data.app = this.state.app; + if (data.id == "" || data.id === undefined) data.id = md5((new Date()).getTime() + ''); + + this.setState({ + currentPrompt: data + }) + + return data; + } + + /** + * 结果 + */ + _onFinish() { + const combo = this._saveMyCombo(); + console.log('_onFinish', combo) + const data = { + prompt: combo, + from: 'combo-editor' + } this.props.callback({ cmd: 'edit-combo-finish', data }) } + _downloadMyCombo() { + const combos = [this._saveMyCombo()]; + + const data: any = []; + for (const combo of combos) { + combo.version = this.state.version; + combo.app = this.state.app; + combo.id = ""; + combo.id = md5(JSON.stringify(combo)); + data.push(combo) + } + + const name = combos[0].tag; + const id = md5(JSON.stringify(data)); + + //通过创建a标签实现 + const link = document.createElement('a') + //encodeURIComponent解决中文乱码 + link.href = `data:application/json;charset=utf-8,\ufeff${encodeURIComponent(JSON.stringify(data))}` + + //下载文件命名 + link.download = `${name}_${id}` + document.body.appendChild(link) + link.click() + document.body.removeChild(link); + + } + + + _handleCancel() { this.setState({ isCombo: false @@ -153,58 +240,50 @@ class ComboModal extends React.Component { cmd: 'edit-combo-cancel' }) } - //临时方案,JSON.parse('{url,query}') - _parseQuery = (text: string, isQuery: boolean) => { - - try { - const { url, query } = JSON.parse(text); - return { url, query, isQuery } - } catch (error) { - - } - return - } /** * * @param value // ['bindCurrentPage','isNextUse'] + * type :input output */ - _handlePromptSetting(promptIndex: number, value: any) { + _handlePromptSetting(promptIndex: number, value: any, type: string) { + const currentPrompt = this.state.currentPrompt; + const key = promptIndex == 0 ? `prompt` : `prompt${promptIndex + 1}`; - let bindCurrentPage = false, isNextUse = false, isQuery = false, isApi = false; + if (currentPrompt[key] == undefined) currentPrompt[key] = { ...defaultPrompt } + + /**单选的 */ + let output = currentPrompt[key].output, + input = currentPrompt[key].input; + + console.log(value) + if (value && value.target && value.target.value) { + if (Array.from(inputs, (o: any) => o.value).includes(value.target.value) && type == 'input') { + input = value.target.value; + } + if (Array.from(outputs, (o: any) => o.value).includes(value.target.value) && type == 'output') { + output = value.target.value; + } - if (value && value.length > 0) { - console.log(value) - bindCurrentPage = value.includes("bindCurrentPage"); - isNextUse = value.includes("isNextUse"); - isQuery = value.includes("isQuery"); - isApi = value.includes("isApi"); }; - let json: any = {}; - const currentPrompt = this.state.currentPrompt; - const key = promptIndex == 0 ? `prompt` : `prompt${promptIndex + 1}`; - // console.log(currentPrompt[key]) - if (currentPrompt[key] == undefined) currentPrompt[key] = { ...defaultPrompt } - // console.log( currentPrompt[key].queryObj,defaultPrompt.queryObj) - // if (isQuery) { - // currentPrompt[key].queryObj.isQuery = isQuery; - // } + let json: any = {}; json[key] = { ...currentPrompt[key], - bindCurrentPage, - isNextUse, queryObj: { ...currentPrompt[key].queryObj, - isQuery + isQuery: input == 'query' }, - isApi + api: { + ...currentPrompt[key].api, + isApi: input == 'api' + }, + input, + output } - // console.log('_handlePromptSetting:', key, JSON.stringify(json, null, 2)) - this._updateCurrentPrompt(json); } @@ -222,42 +301,74 @@ class ComboModal extends React.Component { json[key][type] = value + // if (type == 'model') { + // if (value == "Bing") { + // this.setState({ + // step: 0.5, + // }) + // } else { + // this.setState({ + // step: 0.1, + // }) + // } + // } - if(type == 'model'){ - if(value=="Bing"){ - this.setState({ - step:0.5, - }) - }else { - this.setState({ - step:0.1, - }) - } + this._updateCurrentPrompt(json); + } + + + + _handlePromptTypeSetting(promptIndex = 1, value: any) { + const currentPrompt = this.state.currentPrompt; + const key = promptIndex == 0 ? `prompt` : `prompt${promptIndex + 1}`; + let json: any = {}; + json[key] = { + ...currentPrompt[key], + type: value } + // 如果output只有1个选项,则默认选中 + const out = promptOptions.filter((p: any) => p.key == value)[0].outputs + if (out.length == 1) json[key].output = out[0].value + + // 如果input只有1个选项,则默认选中 + const inp = promptOptions.filter((p: any) => p.key == value)[0].inputs + if (inp.length == 1) json[key].input = inp[0].value + + // console.log(json, currentPrompt) this._updateCurrentPrompt(json); } /** * - * @param value // ['bindCurrentPage', 'Combo', 'ShowInChat'] + * @param value // ['bindCurrentPage', 'Combo', 'showInChat'] */ _handleComboSetting(value: any) { // console.log('_handleComboSetting', value) - let checked = false, isInfinite = false; + let interfaces: string[] = [], + isInfinite = false; if (value && value.length > 0) { - checked = value.includes("ShowInChat"); + if (value.includes("showInChat")) { + interfaces.push("showInChat") + } + if (value.includes("contextMenus")) { + interfaces.push("contextMenus") + } + if (value.includes("home")) { + interfaces.push("home") + } + }; if (value && value.length > 0) { - isInfinite = value.includes('Infinite'); + isInfinite = value.includes('infinite'); } - let currentPrompt = { ...this.state.currentPrompt, checked, isInfinite } + let currentPrompt = { ...this.state.currentPrompt, interfaces, isInfinite } let updateData: any = { currentPrompt } - if (value.includes('Combo')) { + if (value.includes('combo')) { let combo = this.state.currentPrompt.combo || 5; combo = combo <= 1 ? 5 : combo; updateData['currentPrompt'] = { ...updateData['currentPrompt'], combo } @@ -292,143 +403,87 @@ class ComboModal extends React.Component { const prompt = { ...this.state.currentPrompt, ...newData } - console.log('_updateCurrentPrompt', JSON.stringify(prompt, null, 2)) - // for (const key in prompt) { - // if (key.match('prompt') && prompt[key].queryObj && prompt[key].queryObj.isQuery) { - // const q = this._parseQuery(prompt[key].text, prompt[key].queryObj.isQuery); - // if (q) prompt[key].queryObj = q - // } - // } - + // console.log('_updateCurrentPrompt', JSON.stringify(prompt, null, 2)) this.setState({ currentPrompt: prompt }) } } + _addOptions(prompt: any) { + const init = prompt.api.init; + if (typeof (init) == 'object' && init.body && typeof (init.body) == 'string') { + try { + init.body = JSON.parse(init.body) + } catch (error) { - _addOptions(prompt: any) { + } + } const options: any = { - options: [], - temperature: prompt.temperature || 0.6, - model: prompt.model || 'ChatGPT', + input: prompt.input, + output: prompt.output, + // agent: prompt.agent, + temperature: prompt.temperature, + model: prompt.model, url: prompt.queryObj.url, - query: prompt.queryObj.query + query: prompt.queryObj.query, + init: typeof (init) == 'object' ? JSON.stringify(init, null, 2) : init, + type: prompt.type }; - if (prompt.isNextUse) { - options['options'].push('isNextUse'); - } - if (prompt.bindCurrentPage) { - options['options'].push('bindCurrentPage'); - } - if (prompt.queryObj && prompt.queryObj.isQuery) { - options['options'].push('isQuery'); - } + if (prompt.type == 'api') options.url = prompt.api.url; + if (prompt.type == 'query') options.url = prompt.queryObj.url; - // if (prompt.isApi) { - // options.push('isApi'); - // } return options; } - _createOptionUI(index = 1, isQuery = false) { - // console.log('_createOptionUI', index, isQuery) - return <> - { - isQuery ?
- { - const data: any = {}; - const i = index > 1 ? index : ''; - data[`prompt${i}`] = { - ...defaultPrompt, - ...this.state.currentPrompt[`prompt${i}`] - } - data[`prompt${i}`].queryObj.url = e.currentTarget.value.trim(); - // data[`prompt${i}`].queryObj.isQuery = data[`prompt${i}`].queryObj.url && data[`prompt${i}`].queryObj.query; - this._updateCurrentPrompt(data) - }} - /> - - - - { - const data: any = {}; - const i = index > 1 ? index : ''; - data[`prompt${i}`] = { - ...defaultPrompt, - ...this.state.currentPrompt[`prompt${i}`] - } - data[`prompt${i}`].queryObj.query = e.currentTarget.value.trim(); - // data[`prompt${i}`].queryObj.isQuery = data[`prompt${i}`].queryObj.url && data[`prompt${i}`].queryObj.query; - this._updateCurrentPrompt(data) - }} - /> - -
: -