├── .gitignore ├── BACKGROUND.md ├── LICENSE ├── README.en.md ├── README.md ├── WebChatGPTAPI ├── APIExample.ts ├── WolframLocalServer.py ├── WolframResponseExample.json └── promptsExample.md ├── chatGPTChromeEnhance ├── .eslintrc.json ├── .gitignore ├── LICENSE ├── README.md ├── build.mjs ├── package-lock.json ├── package.json ├── src │ ├── _locales │ │ ├── de │ │ │ └── messages.json │ │ ├── en │ │ │ └── messages.json │ │ ├── es │ │ │ └── messages.json │ │ ├── fr │ │ │ └── messages.json │ │ ├── it │ │ │ └── messages.json │ │ ├── ja │ │ │ └── messages.json │ │ ├── ko │ │ │ └── messages.json │ │ ├── pt_BR │ │ │ └── messages.json │ │ ├── ru │ │ │ └── messages.json │ │ └── zh_CN │ │ │ └── messages.json │ ├── assets │ │ └── icons │ │ │ ├── icon128.png │ │ │ ├── icon16.png │ │ │ └── icon48.png │ ├── background │ │ └── bg.ts │ ├── components │ │ ├── apiEditor.tsx │ │ ├── dropdown.tsx │ │ ├── errorMessage.tsx │ │ ├── footer.tsx │ │ ├── navBar.tsx │ │ ├── promptEditor.tsx │ │ ├── socialIconButton.tsx │ │ ├── toolbar.tsx │ │ └── tooltipWrapper.tsx │ ├── content-scripts │ │ ├── api.ts │ │ └── mainUI.tsx │ ├── declaration.d.ts │ ├── manifest.json │ ├── options │ │ ├── options.html │ │ └── options.tsx │ ├── style │ │ └── base.css │ └── util │ │ ├── apiManager.ts │ │ ├── createShadowRoot.ts │ │ ├── elementFinder.ts │ │ ├── icons.tsx │ │ ├── localization.ts │ │ ├── localizedStrings.json │ │ ├── promptManager.ts │ │ ├── regionOptions.json │ │ ├── timePeriodOptions.json │ │ └── userConfig.ts ├── tailwind.config.js └── tsconfig.json ├── chatGPTEx ├── .dockerignore ├── .gitignore ├── Dockerfile ├── api_class.py ├── apikey.ini.example ├── cn_stopwords.txt ├── docker-compose.yaml ├── entrypoint.sh ├── main.py ├── main_GPT4.py ├── optimizeOpenAI.py ├── prompts │ ├── APIExtraPrompt.txt │ ├── APIPrompt.txt │ ├── ReplySum.txt │ ├── conversationSummary.txt │ ├── prompts.json │ └── summary.txt ├── promptsSearch.py ├── requirements.txt ├── search.py ├── static │ ├── js │ │ ├── newChat.js │ │ ├── prism.js │ │ └── tts.js │ └── styles │ │ ├── ChatGPT_logo.png │ │ ├── FiraCode-Regular.ttf │ │ ├── check.png │ │ ├── person.jpg │ │ ├── prism.css │ │ └── style.css └── templates │ └── index.html ├── img ├── API.jpg ├── APIAnimation.png ├── WebPageBeautification.jpg ├── chatGPTChromeEnhance.png ├── date.jpg ├── math.jpg ├── mathjax.jpg ├── mode.jpg ├── newPage.jpg ├── promptCompletion.gif ├── stream.gif ├── web.jpg ├── webHistory.jpg ├── zhihuq0.jpg ├── zhihuq1.jpg ├── zhihuq2.jpg └── zhihuq3.jpg └── requirements.txt /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .vscode 3 | *.log 4 | *.temp 5 | chatGPTEx/backup/ 6 | -------------------------------------------------------------------------------- /BACKGROUND.md: -------------------------------------------------------------------------------- 1 | # Background 2 | 3 | [简体中文](./README.md) [English](./README.en.md) / Background 4 | 5 | [Toolformer Paper](https://arxiv.org/abs/2302.04761) 6 | 7 | "ChatGPT as Inherent Toolformer" means that ChatGPT has the ability to become a tool for various tasks without requiring additional adjustments. However, ChatGPT has some limitations such as being unable to connect to the internet and difficulty solving math problems. ToolFormer enables language models to use specific tools for different tasks. Can ChatGPT be equipped with ToolFormer's abilities? The challenge is how to adapt ToolFormer's API generation process to ChatGPT. Recent experiments demonstrate that given a specific prompt, ChatGPT has a natural ability to create APIs for text. Therefore, it can be concluded that ChatGPT has inherent ToolFormer capabilities! 8 | 9 | the subproject WebChatGPT enchanced is based on [WebChatGPT chrome extension](https://github.com/qunash/chatgpt-advanced) 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 qunash 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.en.md: -------------------------------------------------------------------------------- 1 | # Ex-ChatGPT - ChatGPT with ToolFormer 2 | 3 | ![language](https://img.shields.io/badge/language-python-blue) ![GitHub](https://img.shields.io/github/license/circlestarzero/EX-chatGPT) ![GitHub last commit](https://img.shields.io/github/last-commit/circlestarzero/EX-chatGPT) ![GitHub Repo stars](https://img.shields.io/github/stars/circlestarzero/EX-chatGPT?style=social) 4 | 5 | [简体中文](./README.md) English / [Background](./BACKGROUND.md) 6 | 7 | ChatGPT can act as a **tool former** without requiring adjustment, generating API requests for questions to assist in answering. Ex-ChatGPT enables ChatGPT to call external APIs, such as **WolframAlpha, Google, and WikiMedia**, to provide more accurate and timely answers. 8 | 9 | This project is divided into `Ex-ChatGPT` and `WebChatGPTEnhance`. The former is a service that uses the `GPT3.5 Turbo API` and **Google,WolframAlpha,WikiMedia APIs**, while the latter is a **browser extension** which update the origin WebChatGPT plugin to Enable adding external API, supportting ChatGPT webpage to call different APIs and prompts 10 | 11 | ## user interface display 12 | 13 | ### ExChatGPT 14 | 15 | ![chatHistory](img/newPage.jpg) 16 | 17 | ### WebChatGPTEnhance 18 | 19 | ![WebChatGPT](img/chatGPTChromeEnhance.png) 20 | 21 | ## Highlights 22 | 23 | - **OAuth2.0 Multi User Management** (In webTest branch) 24 | - **Speech Dialogue Functionality**, utilizing Microsoft Azure API to optimize response time (around 1-2 seconds), featuring both speech recognition and text-to-speech capabilities, supporting multiple languages and voices, and allowing for customized voices. 25 | - **Docker and Proxy support** 26 | - **Redundant backup of chat history** 27 | - Support for OpenAI GPT-3.5 Turbo API 28 | - Ability for ChatGPT to call external API interfaces, such as **Google, WolframAlpha, and WikiMedia** 29 | - Clean up Google search results data to reduce token usage. 30 | - Automatic saving and loading of conversation history with **automatic compression** 31 | - Ability to display the number of tokens used 32 | - **API pool** 33 | - **Markdown and MathJax rendering** 34 | - API call process displayed with an animation, similar to Bing 35 | - Conversation management with **load and chat** modes similar to ChatGPT web page layout 36 | - **Shortcut keys** for quickly selecting modes (`Tab`), line breaks (`Shift+Enter`), sending messages (`Enter`), and selecting message history (`up` and `down`), similar to a terminal. 37 | - `stream` feature is similar to that of a typewriter, it responds faster with results instead of loading everything at once. Stream outputs the results in steps, as shown in the example: 38 | ![stream](img/stream.gif) 39 | - Automatic **prompt completion** in `Chat Mode` with support for fuzzy search, pinyin search, and custom prompt selection.The project comes with prompt from [awesome-chatgpt-prompts](https://github.com/f/awesome-chatgpt-prompts). 40 | ![promptCompletion](img/promptCompletion.gif) 41 | 42 | ## To Do List 43 | 44 | - [ ] Mobile interface adaptation 45 | - [ ] OCR recognition of formula text in images sent by users 46 | - [ ] OAuth2.0 multi-user authentication 47 | - [ ] Call the diffusing model to generate images (achieving similar multimodal effects) 48 | - [ ] Further spider summary and data cleansing of web search results 49 | - [ ] Add code running API, and more APIs 50 | - [ ] Embedding alignment retrieval of chat records/local knowledge databases 51 | 52 | 53 | ## Installation 54 | 55 | ### Ex-chatGPT 56 | 57 | - `pip install` 58 | `pip install -r requirements.txt` 59 | - Copy `apikey.ini.example` and rename it as `apikey.ini`. Then, fill in your `API key` and `proxy` in `apikey.ini`. If you only have one OpenAI API key, you should delete `key1 = sk-xxxx;key2 = sk-xxxx`. 60 | - `Google api key and search engine id` [apply](https://developers.google.com/custom-search/v1/overview?hl=en) 61 | - `wolframAlpha app id key` [apply](https://products.wolframalpha.com/api/) 62 | - `openAI api key`(new feature) or `chatGPT access_token`(old version) [apply](https://platform.openai.com) 63 | - (optional, Text To Speech And Speech recognition) fill in `Azure API key` and `region` [apply](https://learn.microsoft.com/zh-cn/azure/cognitive-services/speech-service) 64 | - run the `main.py` and click the local url like `http://127.0.0.1:1234/` 65 | - change the mode in the selection box, now have `chat,detail,web,webDirect,WebKeyWord` 66 | - **Voice Conversation Chat**(optional feature), select language and voice in `chatGPTEx/static/styles/tts.js`, click the microphone on chat interface to `start/close` conversation mode. 67 | 68 | ### WebChatGPTEnhanceExtension 69 | 70 | - fill you `Googgle api key and client id` in `chatGPTChromeEhance/src/util/apiManager.ts/getDefaultAPI` 71 | - run `npm install` 72 | - run `npm run build-prod` 73 | - get the extension in `chatGPTChromeEhance/build` 74 | - add your `prompts` and `APIs` in option page. 75 | - `APIs` and `prompts` examples are in `/WebChatGPTAPI` 76 | - `wolframAlpha` needs to run local sever - `WebChatGPTAPI/WolframLocalServer.py` 77 | 78 | ## Mode Introduction 79 | 80 | ### Web Mode 81 | 82 | The Web Mode starts by asking ChatGPT a question directly. ChatGPT generates a series of API calls related to the query and uses the first returned result and question to verify and supplement with an API call. Finally, ChatGPT summarizes the information. Web Mode has a better chat ability than just summarizing the response. 83 | 84 | ### Chat Mode 85 | 86 | Chat Mode only calls the OpenAI API interface, similar to the web version of ChatGPT. You can search and choose different prompts by typing `/promtname`, and it supports fuzz search. 87 | 88 | ### WebDirect Mode 89 | 90 | WebDirect Mode first lets ChatGPT generate a series of API calls related to the query. Then, it directly calls a third-party API to search for the answer to each query, and finally, ChatGPT summarizes the information. WebDirect Mode is faster and relatively more accurate for single query information. 91 | 92 | ### Detail Mode 93 | 94 | Detail Mode is an extension of the WebDirect Mode, where an additional API call is made to supplement the current results with further inquiries (such as information not found in the previous search). Finally, ChatGPT summarizes the information. 95 | 96 | ### Keyword Mode 97 | 98 | Keyword Mode generates keywords directly from ChatGPT for querying, using DDG. It doesn't require other API keys. However, its accuracy is relatively poor. 99 | 100 | ## Update Log 101 | 102 | - Clean up Google search results data to reduce token usage. 103 | - Update all API proxy pools and add API restriction cooldown mechanism (Google 403 cooldown for 1 day). 104 | - Voice dialogue function, using Microsoft Azure API, optimized response speed, including voice recognition and text-to-speech, supporting multiple voices and languages, custom voice. 105 | - `stream` feature is similar to that of a typewriter, it responds faster with results instead of loading everything at once. Stream outputs the results in steps, as shown in the example: 106 | ![stream](img/stream.gif) 107 | - Redundant backup of chat history. 108 | - Auto-complete prompt selection in chat mode with **fuzzy search** and **Pinyin search** support. 109 | ![promptCompletion](img/promptCompletion.gif) 110 | 111 | - Update docker and proxy support. 112 | 113 | - Shortcut keys for quick mode selection (`Tab`) and line break (`Shift + Enter`), while `Enter` sends the message. Message history selection (`up`, `down`) is similar to a terminal. 114 | 115 | - Update chat history management sidebar. 116 | ![chatHistory](img/newPage.jpg) 117 | 118 | - Update API calls processing animation. 119 | ![APIAnimation](img/APIAnimation.png) 120 | 121 | - Web page beautification. 122 | ![WebBeautification](img/WebPageBeautification.jpg) 123 | 124 | - Update Markdown and MathJax renderer. 125 | ![MathJax](img/mathjax.jpg) 126 | 127 | - Update chat history token optimizer, and web mode can respond according to chat history. Add token cost counter. 128 | ![history](img/webHistory.jpg) 129 | 130 | - Update web chat mode selection in the webpage and optimize prompt and token cost. Restrict the token limit. 131 | ![mode](img/mode.jpg) 132 | 133 | - Update better support for Chinese queries and add current date info. 134 | ![date](img/date.jpg) 135 | 136 | - Update web chat mode and fix some bugs. 137 | - Update API configuration. 138 | - Update API pool. 139 | - Automatic saving and loading of conversation history, ChatGPT can retrieve previous conversations. 140 | - Update official support for OpenAI GPT3.5 Turbo API, which is super fast and cheap. 141 | - Update extra API calls and search summarizations to provide a more comprehensive and detailed answer. 142 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Ex-ChatGPT - ChatGPT with ToolFormer 2 | 3 | ![language](https://img.shields.io/badge/language-python-blue) ![GitHub](https://img.shields.io/github/license/circlestarzero/EX-chatGPT) ![GitHub last commit](https://img.shields.io/github/last-commit/circlestarzero/EX-chatGPT) ![GitHub Repo stars](https://img.shields.io/github/stars/circlestarzero/EX-chatGPT?style=social) 4 | 5 | 简体中文 [English](./README.en.md) / [Background](./BACKGROUND.md) 6 | 7 | ChatGPT 是一个强大的工具平台,可以无需任何调整就生成 API 请求来协助回答问题。`Ex-ChatGPT` 使得 ChatGPT 能够调用外部 API,例如 **WolframAlpha、Google 和 WikiMedia**,以提供更准确和及时的答案。 8 | 9 | 这个项目分为 `Ex-ChatGPT` 和 `WebChatGPTEnhance` 两部分。前者是一个使用了 `GPT3.5 Turbo API`、**WolframAlpha、Google 和 WikiMedia** 等 API 的服务,能够提供更强大的功能和更准确的答案。后者是一个**浏览器扩展程序**,它更新了原有的 WebChatGPT 插件以支持添加外部 API,支持 ChatGPT 网页调用不同的 API 和提示。 10 | 11 | ## 交互界面 12 | 13 | ### ExChatGPT 14 | 15 | ![chatHistory](img/newPage.jpg) 16 | 17 | ### WebChatGPTEnhance 18 | 19 | ![WebChatGPT](img/chatGPTChromeEnhance.png) 20 | 21 | ## Highlights 22 | 23 | - **OAuth2.0多用户鉴权管理** (见webTest分支) 24 | - **语音对话功能**,使用微软 Azure API,优化响应速度 ( 1-2 秒左右 ) ,包含语音识别和文字转语音,支持多种音色和语言,自定义声音。 25 | - **docker 和 proxy 支持** 26 | - **聊天记录冗余备份** 27 | - 支持 OpenAI GPT-3.5 Turbo API 28 | - 允许 ChatGPT 调用外部 API 接口 ( **Google,WolframAlpha,WikiMedia** ) 29 | - 对 Google 搜索结果进行数据清洗, 减少token占用 30 | - 自动保存载入对话历史,**自动压缩对话** 31 | - **可显示使用的 Token 数量** 32 | - **API池**, **API** 冷却 33 | - **Markdown and MathJax** 渲染 34 | - 调用**API 过程显示动画**, 类似必应 35 | - **历史对话管理**载入,类 chatgpt 页面布局 36 | - **快捷键**快速选择模式 `Tab` 和换行 `Shift+Enter`,`Enter` 发送, `up`,`down` 选择历史发送消息,类似终端 37 | - `stream` 特性,它类似于打字机的效果,可以更快地响应结果。与一次性加载所有内容不同,stream会逐步输出结果。如示例中所示: 38 | ![stream](img/stream.gif) 39 | - `chat` 模式下**prompt 自动补全**选择,支持模糊搜索, 拼音搜索, 支持自定义 prompt, 项目中自带 [awesome-chatgpt-prompts](https://github.com/f/awesome-chatgpt-prompts) 中的 `prompt` 40 | ![promptCompletion](img/promptCompletion.gif) 41 | 42 | ## 计划更新 43 | 44 | - [ ] 移动端界面适配 45 | - [ ] 发送图片OCR识别公式文字 46 | - [x] OAuth2.0多用户鉴权 (见webTest分支) 47 | - [ ] 调用diffusing model生成图片(达到类似多模态效果) 48 | - [ ] 网页搜索结果进一步爬虫总结清洗数据 49 | - [ ] 增加代码运行API,以及更多API 50 | - [ ] 聊天记录/本地知识数据库embedding对齐检索 51 | 52 | ## 安装 53 | 54 | ### Ex-chatGPT Installation 55 | 56 | - `pip install` 57 | `pip install -r requirements.txt` 58 | - 将 `apikey.ini.example` 复制改名为 `apikey.ini`,然后在 `apikey.ini` 中填入你的 API 密钥, 以及代理 ( 如果只有一个 `openAI` 的 `API key`,将 `key1 = sk-xxxx; key2 = sk-xxxx` 删除即可 ) 59 | - `Google api key and search engine id` [申请](https://developers.google.com/custom-search/v1/overview?hl=en) 60 | - `wolframAlpha app id key` [申请](https://products.wolframalpha.com/api/) 61 | - `openAI api key`( 新功能 ) 或 `chatGPT access_token` ( 旧版本 ) [申请](https://platform.openai.com) 62 | - (可选) 在 `apikey.ini` 中填写`Azure API key` 和 `region` [申请](https://learn.microsoft.com/zh-cn/azure/cognitive-services/speech-service) 63 | - 运行 `main.py` 并打开 `http://127.0.0.1:1234/` 64 | - 选择模式 ( 可以使用 `Tab` ) ,例如 `chat,detail,web,webDirect,WebKeyWord` 65 | - `chat` 模式下 使用 `\{promptname} {query}` 格式来模糊搜索选择 prompt 66 | - **快捷键**快速选择模式 `Tab` 和换行 `Shift+Enter`,`Enter` 发送, `up`,`down` 选择历史发送消息,类似终端 67 | - **语音对话聊天**(可选功能), 在 `chatGPTEx/static/styles/tts.js` 中选择语言和音色, 在聊天界面中点击麦克风`启动/关闭`对话模式 68 | 69 | #### Docker 快速部署 70 | 71 | ##### 方法一 使用构建好的镜像 72 | 73 | 1. 创建配置文件目录并拉取配置文件 74 | 75 | `mkdir config && wget https://raw.githubusercontent.com/circlestarzero/EX-chatGPT/main/chatGPTEx/apikey.ini.example -O ./config/apikey.ini` 76 | 77 | 2. 编辑配置文件或者把编辑好的配置文件传到config文件夹下。 78 | 79 | `vim ./config/apikey.ini` 80 | 81 | 3. 拉取docker镜像 82 | 83 | `docker pull 0nlylty/exchatgpt:latest` 84 | 85 | 4. 创建容器 86 | 87 | ```bash 88 | docker run -dit \ 89 | -v ~/config:/config \ 90 | -p 5000:5000 \ 91 | --name exchatgpt \ 92 | --restart unless-stopped \ 93 | 0nlylty/exchatgpt:latest 94 | ``` 95 | 96 | ##### 方法二 自己构建镜像 97 | 98 | 1. 创建配置文件目录并拉取配置文件 99 | 100 | `mkdir config && wget https://raw.githubusercontent.com/circlestarzero/EX-chatGPT/main/chatGPTEx/apikey.ini.example -O ./config/apikey.ini` 101 | 102 | 2. 编辑配置文件或者把编辑好的配置文件传到config文件夹下。 103 | 104 | `vim ./config/apikey.ini` 105 | 106 | 3. 构建并运行 107 | 108 | ``` 109 | # 克隆代码 110 | git clone https://github.com/circlestarzero/EX-chatGPT.git --depth=1 111 | # 进入项目目录 112 | cd EX-chatGPT/chatGPTEx 113 | # 编辑docker-compose.yaml的挂载路径 114 | ~/config:/config # 冒号左边请修改为保存配置的路径 115 | # 配置补充完整后启动 116 | docker compose up -d 117 | ``` 118 | 119 | ##### 使用 120 | 121 | ```bash 122 | # 访问 123 | http://your_ip:5000 124 | 125 | # 查看日志 126 | docker logs -f --tail 100 exchatgpt 127 | ``` 128 | 129 | ### WebChatGPTEnhance Installation 130 | 131 | - 在 `chatGPTChromeEhance/src/util/apiManager.ts/getDefaultAPI` 中填入 Google API 信息 132 | - 运行 `npm install` 133 | - 运行 `npm run build-prod` 134 | - 在 `chatGPTChromeEhance/build` 中获取构建好的扩展 135 | - add your `prompts` and `APIs` in option page. 136 | - `APIs` and `prompts` examples are in `/WebChatGPTAPI` 137 | - `wolframAlpha` needs to run local sever - `WebChatGPTAPI/WolframLocalServer.py` 138 | 139 | ## 模式介绍 140 | 141 | ### Web Mode 142 | 143 | Web Mode 开始时会直接询问 ChatGPT 一个问题。ChatGPT 会生成一系列与查询相关的 API 调用,并使用第一个返回的结果和问题进行验证和补充。最后,ChatGPT 会对信息进行总结。Web Mode 具有比仅总结响应更好的聊天能力。 144 | 145 | ### Chat Mode 146 | 147 | Chat Mode 仅调用 OpenAI API 接口,类似于 ChatGPT 的 Web 版本。您可以通过输入 `/promtname` 来搜索和选择不同的提示,它还支持模糊搜索。 148 | 149 | ### WebDirect Mode 150 | 151 | WebDirect Mode 首先让 ChatGPT 生成一系列与查询相关的 API 调用。然后,它直接调用第三方 API 搜索每个查询的答案,最后 ChatGPT 对信息进行总结。WebDirect Mode 对于单个查询信息更快且相对更准确。 152 | 153 | ### Detail Mode 154 | 155 | Detail Mode 是 WebDirect Mode 的扩展,它会进行额外的 API 调用来补充当前结果中未找到的信息 ( 例如之前未搜索到的信息 ) 。最后,ChatGPT 对信息进行总结。 156 | 157 | ### Keyword Mode 158 | 159 | Keyword Mode 直接从 ChatGPT 中生成关键词进行查询,使用 DDG 进行查询,不需要其他 API 密钥。但是其准确性相对较差。 160 | 161 | ## 更新日志 162 | 163 | - **OAuth2.0多用户鉴权管理** (见webTest分支) 164 | - 对 Google 搜索结果进行数据清洗, 减少token占用 165 | - 更新所有API代理池, 增加API限制冷却机制(Google 403 冷却1天) 166 | - **语音对话功能**, 使用微软azureAPI, 优化响应速度, 包含识别语音和文字转语音, 支持多种音色和语言,自定义声音 167 | - `stream` 特性,它类似于打字机的效果,可以更快地响应结果。与一次性加载所有内容不同,stream会逐步输出结果。如示例中所示: 168 | ![stream](img/stream.gif) 169 | - 聊天记录冗余备份 170 | - chat 模式下 prompt 自动补全选择,支持模糊搜索和拼音搜索 171 | 172 | ![promptCompletion](img/promptCompletion.gif) 173 | 174 | - 更新 Docker 和 proxy 支持 175 | - 支持 OpenAI GPT-3.5 Turbo API,快速且价格低廉 176 | - 提供额外的 API 调用和搜索摘要,以提供更全面和详细的答案 177 | - 使用快捷键快速选择模式 `Tab` 和换行 `Shift+Enter`,同时使用 `Enter` 发送消息。使用 `up` 和 `down` 选择历史发送消息,类似终端操作 178 | - 更新历史对话管理,支持载入、删除和保存历史对话 179 | 180 | ![chatHistory](img/newPage.jpg) 181 | 182 | - 更新 API 调用处理动画 183 | 184 | ![APIAnimation](img/APIAnimation.png) 185 | 186 | - 页面美化 187 | 188 | ![WebBeautification](img/WebPageBeautification.jpg) 189 | 190 | - Markdown 和 MathJax 渲染器 191 | 192 | ![MathJax](img/mathjax.jpg) 193 | 194 | - 更新聊天记录 token 优化器,Web 模式可以根据聊天记录进行响应;添加 token 成本计数器 195 | 196 | ![history](img/webHistory.jpg) 197 | 198 | - 更新 Web 聊天模式选择,优化 prompt 和 token 成本,限制 token 上限 199 | 200 | ![mode](img/mode.jpg) 201 | 202 | - 改进对中文查询的支持,并添加当前日期信息 203 | 204 | ![date](img/date.jpg) 205 | 206 | - 更新 Web 聊天模式并修复一些错误 207 | - 更新 API 配置 208 | - 更新 API 池 209 | - 自动保存载入对话历史,ChatGPT 可联系之前对话 210 | -------------------------------------------------------------------------------- /WebChatGPTAPI/APIExample.ts: -------------------------------------------------------------------------------- 1 | //Word Search API 2 | async function WordSearch(query, numResults, timePeriod, region) { 3 | const headers = new Headers({ 4 | Origin: "https://chat.openai.com", 5 | "X-RapidAPI-Key": "YOUR_KEY", 6 | "X-RapidAPI-Host": "wordsapiv1.p.rapidapi.com", "Content-Type": "application/json", 7 | }); 8 | const url = `https://wordsapiv1.p.rapidapi.com/words/${query}`; 9 | const response = await fetch(url, { method: "GET", headers, }); 10 | const results = await response.json(); console.log(results); return results; 11 | } 12 | 13 | //Google Entity Search API 14 | async function GoogleEntitySearch(query, numResults, timePeriod, region) { 15 | const headers = new Headers({ Origin: "https://chat.openai.com", }); 16 | const searchParams = new URLSearchParams(); 17 | searchParams.set('query', query); 18 | searchParams.set('key', 'YOUR_KEY'); 19 | searchParams.set('indent', 'true'); 20 | searchParams.set('limit', numResults.toString()); 21 | const url = `https://kgsearch.googleapis.com/v1/entities:search?${searchParams.toString()}`; 22 | console.log(url); 23 | const response = await fetch(url, { method: "GET", headers, }); 24 | const results = await response.json(); console.log(results); return results; 25 | } 26 | 27 | //Google search API 28 | async function GoogleSearch(query, numResults, timePeriod, region) { 29 | const headers = new Headers({ Origin: "https://chat.openai.com", }); 30 | const searchParams = new URLSearchParams(); 31 | searchParams.set('q', query); 32 | searchParams.set('key', 'YOUR_KEY'); 33 | searchParams.set('cx', 'YOUR_GOOGLE_CLIENT_ID'); 34 | searchParams.set('c2coff', '0'); 35 | searchParams.set('num', numResults.toString()); 36 | const url = `https://customsearch.googleapis.com/customsearch/v1?${searchParams.toString()}`; 37 | console.log(url); 38 | const response = await fetch(url, { method: "GET", headers, }); 39 | const results = await response.json(); 40 | const items = results.items; 41 | const filteredData = items.map(({ title, link, snippet }) => ({ 42 | title, 43 | link, 44 | snippet 45 | })); 46 | return filteredData; 47 | } 48 | //Google search summarazation API 49 | async function GoogleSearchSimply(query, numResults, timePeriod, region) { 50 | const headers = new Headers({ Origin: "https://chat.openai.com", }); 51 | const searchParams = new URLSearchParams(); 52 | searchParams.set('q', query); 53 | searchParams.set('key', 'YOUR_KEY'); 54 | searchParams.set('cx', 'YOUR_GOOGLE_CLIENT_ID'); 55 | searchParams.set('c2coff', '0'); 56 | searchParams.set('num', numResults.toString()); 57 | const url = `https://customsearch.googleapis.com/customsearch/v1?${searchParams.toString()}`; 58 | console.log(url); 59 | const response = await fetch(url, { method: "GET", headers, }); 60 | const results = await response.json(); 61 | const items = results.items; 62 | const filteredData = items.map(({ title, link, snippet }) => ({ 63 | title, 64 | snippet 65 | })); 66 | return filteredData; 67 | } 68 | 69 | //summarization arcticle API 70 | async function ArcticleSummarazation(query, numResults, timePeriod, region) { 71 | const options = { 72 | method: 'POST', 73 | headers: { 74 | 'content-type': 'application/json', 75 | 'X-RapidAPI-Key': 'YOUR_KEY', 76 | 'X-RapidAPI-Host': 'tldrthis.p.rapidapi.com' 77 | }, 78 | body: `{"url":"${query}","min_length":250,"max_length":300,"is_detailed":false}` 79 | }; 80 | const response = await fetch('https://tldrthis.p.rapidapi.com/v1/model/abstractive/summarize-url/', options); 81 | const results = await response.json(); 82 | const summarize = results.summarize; 83 | console.log(summarize); 84 | return summarize; 85 | } 86 | 87 | 88 | //article extract API 89 | async function arcticleExtraction(query, numResults, timePeriod, region) { 90 | const headers = new Headers({ 91 | Origin: "https://chat.openai.com", 92 | "X-RapidAPI-Key": "YOUR_KEY", 93 | "X-RapidAPI-Host": "lexper.p.rapidapi.com" 94 | }); 95 | const searchParams = new URLSearchParams(); 96 | searchParams.set('url', query); 97 | searchParams.set('js_timeout', '30'); 98 | searchParams.set('media', 'false') 99 | const url = `https://lexper.p.rapidapi.com/v1.1/extract?${searchParams.toString()}`; 100 | const response = await fetch(url, { method: "GET", headers, }); 101 | const results = await response.json(); 102 | let text = results.article.text; 103 | const sentences = text.split(/[,.?!。,?!]/); 104 | while (sentences.length > 0 && text.length > 2000) { 105 | const indexToDelete = Math.floor(Math.random() * sentences.length); 106 | sentences.splice(indexToDelete, 1); 107 | text = sentences.join('.'); 108 | } 109 | return text; 110 | } 111 | 112 | //Wolfram alpha API 113 | async function WolframAlpha(query, numResults, timePeriod, region) { 114 | const response = await fetch( 115 | // YOUR LOCAL SEVER 116 | `http://localhost:1111?query=${query}`, { 117 | method: 'GET', mode: 'no-cors' 118 | }); 119 | const results = response.json(); 120 | console.log(results); 121 | return results; 122 | } 123 | -------------------------------------------------------------------------------- /WebChatGPTAPI/WolframLocalServer.py: -------------------------------------------------------------------------------- 1 | from urllib.parse import urlparse, parse_qs 2 | import http.server 3 | import socketserver 4 | import socket 5 | import requests 6 | import json 7 | cookies = { 8 | # YOUR COOKIE 9 | } 10 | 11 | headers = { 12 | 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7', 13 | 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8', 14 | 'Cache-Control': 'no-cache', 15 | 'Connection': 'keep-alive', 16 | 'DNT': '1', 17 | 'Pragma': 'no-cache', 18 | 'Sec-Fetch-Dest': 'document', 19 | 'Sec-Fetch-Mode': 'navigate', 20 | 'Sec-Fetch-Site': 'none', 21 | 'Sec-Fetch-User': '?1', 22 | 'Upgrade-Insecure-Requests': '1', 23 | 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36', 24 | 'sec-ch-ua': '"Chromium";v="110", "Not A(Brand";v="24", "Google Chrome";v="110"', 25 | 'sec-ch-ua-mobile': '?0', 26 | 'sec-ch-ua-platform': '"macOS"', 27 | } 28 | 29 | 30 | HOST = '127.0.0.1' # Localhost 31 | PORT = 1111 # Port number 32 | TIMEOUT = 5 # 5 second timeout 33 | 34 | 35 | class MyHandler(http.server.BaseHTTPRequestHandler): 36 | def do_OPTIONS(self): 37 | self.send_response(200, "ok") 38 | self.send_header('Access-Control-Allow-Origin', '*') 39 | self.send_header('Access-Control-Allow-Methods', 'GET, OPTIONS') 40 | self.send_header("Access-Control-Allow-Headers", "X-Requested-With") 41 | self.send_header("Access-Control-Allow-Headers", "Content-Type") 42 | self.end_headers() 43 | 44 | def do_GET(self): 45 | parsed_url = urlparse(self.path) 46 | query_params = parse_qs(parsed_url.query) 47 | query = query_params.get('query', [''])[0] 48 | params = { 49 | 'input': query, 50 | 'format': 'plaintext', 51 | 'output': 'JSON', 52 | 'appid': 'YOUR_APP_ID', #GET from WolframAlpha 53 | } 54 | responseFromWolfram = requests.get( 55 | 'https://api.wolframalpha.com/v2/query', params=params, cookies=cookies, headers=headers) 56 | pods = responseFromWolfram.json()['queryresult']['pods'][:5] 57 | print(pods) 58 | pods = json.dumps(pods) 59 | response = f"{pods}".encode() 60 | self.send_response(200) 61 | self.send_header('Access-Control-Allow-Origin', '*') 62 | self.send_header('Access-Control-Allow-Methods', 'GET, OPTIONS') 63 | self.send_header("Access-Control-Allow-Headers", "X-Requested-With") 64 | self.send_header('content-type', 'application/json; charset=utf-8') 65 | self.end_headers() 66 | self.wfile.write(bytes(response)) 67 | 68 | while True: 69 | with socketserver.TCPServer((HOST, PORT), MyHandler) as httpd: 70 | httpd.socket.settimeout(TIMEOUT) 71 | print(f"Serving at port {PORT}") 72 | try: 73 | httpd.serve_forever() 74 | except socket.timeout: 75 | print(f"Timeout after {TIMEOUT} seconds") 76 | -------------------------------------------------------------------------------- /WebChatGPTAPI/WolframResponseExample.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "title": "Input", 4 | "scanner": "Identity", 5 | "id": "Input", 6 | "position": 100, 7 | "error": false, 8 | "numsubpods": 1, 9 | "subpods": [ 10 | { 11 | "title": "", 12 | "plaintext": "log(20)" 13 | } 14 | ], 15 | "expressiontypes": { 16 | "name": "Default" 17 | }, 18 | "infos": { 19 | "text": "log(x) is the natural logarithm", 20 | "links": [ 21 | { 22 | "url": "http://reference.wolfram.com/language/ref/Log.html", 23 | "text": "Documentation", 24 | "title": "Mathematica" 25 | }, 26 | { 27 | "url": "http://functions.wolfram.com/ElementaryFunctions/Log", 28 | "text": "Properties", 29 | "title": "Wolfram Functions Site" 30 | }, 31 | { 32 | "url": "http://mathworld.wolfram.com/NaturalLogarithm.html", 33 | "text": "Definition", 34 | "title": "MathWorld" 35 | } 36 | ] 37 | } 38 | }, 39 | { 40 | "title": "Decimal approximation", 41 | "scanner": "Numeric", 42 | "id": "DecimalApproximation", 43 | "position": 200, 44 | "error": false, 45 | "numsubpods": 1, 46 | "primary": true, 47 | "subpods": [ 48 | { 49 | "title": "", 50 | "plaintext": "2.9957322735539909934352235761425407756766016229890282301540079104..." 51 | } 52 | ], 53 | "expressiontypes": { 54 | "name": "Default" 55 | }, 56 | "states": [ 57 | { 58 | "name": "More digits", 59 | "input": "DecimalApproximation__More digits" 60 | } 61 | ] 62 | }, 63 | { 64 | "title": "Property", 65 | "scanner": "Numeric", 66 | "id": "Property", 67 | "position": 300, 68 | "error": false, 69 | "numsubpods": 1, 70 | "subpods": [ 71 | { 72 | "title": "", 73 | "plaintext": "log(20) is a transcendental number" 74 | } 75 | ], 76 | "expressiontypes": { 77 | "name": "Default" 78 | } 79 | } 80 | ] -------------------------------------------------------------------------------- /WebChatGPTAPI/promptsExample.md: -------------------------------------------------------------------------------- 1 | # API prompt 2 | 3 | Here is my Input you need to Output: 4 | Input: {query} 5 | Instructions: 6 | Your task is to list calls to a Question Answering API to a piece of text. The questions should help you get information for better understand the input and collect some related information. You can call the API by writing "[(API)(question)]" where "question" is the full complete question you want to ask for better answer the input and the question should be as short as possible, and you can turn a large question into smaller ones by call the API more time. 7 | .The API available is ['WikiSearch','Calculator','Google'],you need to choose one to fill in each of the "[(API)(question)]" 8 | Here are some examples of API calls: 9 | { 10 | Input: Joe Biden was born in Scranton, Pennsylvania. 11 | Output: {"calls": [{"API": "Google", "query": "Where was Joe Biden born?"},]} 12 | Input: Coca-Cola, or Coke, is a carbonated soft drink manufactured by the Coca-Cola Company. 13 | Output: {"calls": [{"API": "Google", "query": "What other name is Coca-Cola known by?"}, 14 | {"API": "Google", "query": "Who manufactures Coca-Cola?"}]} 15 | Input: The New England Journal of Medicine is a registered trademark of the MMS. 16 | Output: {"calls":[{"API": "Google", "query": "Who is the publisher of The New England Journal of Medicine?"}]} 17 | Input: Out of 1400 participants, 400 passed the test. 18 | Output: {"calls":[{"API": "Calculator", "query": "400 / 1400"}]} 19 | Input: The name derives from "la tortuga", the Spanish word for turtle. 20 | Output: {"calls": [{"API": "WikiSearch", "query": "tortuga"}]} 21 | Input: The Brown Act is California's law that requires legislative bodies, like city councils, to hold their meetings open to the public. 22 | Output: {"calls": [{"API": "WikiSearch", "query": "Brown Act"}]} 23 | Input: 孔子是怎么火烧赤壁的? 24 | Output: {"calls":[{"API": "WikiSearch","query": "孔子"},{"API": "WikiSearch","query": "火烧赤壁"}]} 25 | Input: 强化学习中的策略梯度是什么,用通俗语言解释下 26 | Output: {"calls": [{"API": "Google", "query": "强化学习中的策略梯度"}]} 27 | } 28 | Remember: dont't really call the api and output any other text, Just output the API call in JSON type 29 | 30 | # Wolfram Alpha prompt 31 | 32 | WolframAlpha JSON results: 33 | 34 | Desiderio Rodriguez 35 | WolframAlpha JSON results: 36 | 37 | {web_results} 38 | 39 | Instructions: Using the provided Wolfram Alpha JSON results, write a comprehensive and detailed corect reply to the given query. Using latex to express the whole results. 40 | Query: {query} 41 | 42 | # Web Extraction prompt 43 | 44 | a WebSite Extraction in JSON type: 45 | {web_results} 46 | 47 | Current date: 2/22/2023 48 | Instructions: Using the provided Extract Website results in JSON type, write a comprehensive reply to the given query in a understandable and relatively detailed language. Make sure to cite results using [the counting of sentence] notation after the reference. 49 | WebsitesURL: {query} 50 | 51 | # word flash card prompt 52 | 53 | Here is the word I give you : "what's the meaning of English word tout" 54 | 55 | Here is the web serach result of the word wraped by big brackets: 56 | {{web_results}} 57 | 58 | I need you to act as a anki helper for my English study for TOEFL exam, I've already give you the word and its search results. You need to help me memorize the words by offer some format of anki card which likes the 'front-back' form by using the codeblocks to enwrap the Front and Back part serparately, and combine some related information from the web result to the back of the anki card to better illustrate it. 59 | 60 | First, in the back of the card you need to illustrate this word in a easy-understanding and consice way whose word limitation is 64 words and maxium 4 different meanings, each meanings should less thant 16 words and give each meaning a setence example as its sublist. 61 | Second, list some synoms of it, which at least 5. 62 | Third, list some deriatives of it, which at least 5. 63 | And The back of the card content need to be the format of lists. 64 | Fourth, give an imagiable vivid scene of the word to help me memorize, which is less than 16 words. 65 | Here is an example wraped by big brackets to help you better understanding: 66 | { 67 | Front: 68 | 69 | ```markdown 70 | forge 71 | /fôrj/ 72 | ``` 73 | 74 | Back: 75 | 76 | ```markdown 77 | # Meanings: 78 | - verb 79 | - make or shape (a metal object) by heating it in a fire or furnace and beating or hammering it. 80 | - "he forged a great suit of black armor" 81 | - create (a relationship or new conditions). 82 | - "the two women forged a close bond" 83 | - noun 84 | - a blacksmith's workshop; a smithy. 85 | - "Tom is learning some skills in his Dad's forge" 86 | 87 | # Synonyms: 88 | create, shape, establish, strengthen, counterfeit, imitate. 89 | 90 | # Deriatives: 91 | unforgettable, reforge, unforgettably, unforgeable, unforgeability 92 | 93 | # Image: 94 | a blacksmith is forge in his workshop. 95 | ``` 96 | 97 | } 98 | Remember, dont't output other unrelated information,just output the card,and output it more understandable and consice way -------------------------------------------------------------------------------- /chatGPTChromeEnhance/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "@typescript-eslint/parser", 3 | "extends": [ 4 | "preact", 5 | "plugin:@typescript-eslint/recommended", 6 | "plugin:tailwindcss/recommended" 7 | ], 8 | "rules": { 9 | "tailwindcss/no-custom-classname": "off" 10 | }, 11 | "ignorePatterns": ["build/"] 12 | } 13 | -------------------------------------------------------------------------------- /chatGPTChromeEnhance/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | .pnpm-debug.log* 9 | 10 | # Diagnostic reports (https://nodejs.org/api/report.html) 11 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 12 | 13 | # Runtime data 14 | pids 15 | *.pid 16 | *.seed 17 | *.pid.lock 18 | 19 | # Directory for instrumented libs generated by jscoverage/JSCover 20 | lib-cov 21 | 22 | # Coverage directory used by tools like istanbul 23 | coverage 24 | *.lcov 25 | 26 | # nyc test coverage 27 | .nyc_output 28 | 29 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 30 | .grunt 31 | 32 | # Bower dependency directory (https://bower.io/) 33 | bower_components 34 | 35 | # node-waf configuration 36 | .lock-wscript 37 | 38 | # Compiled binary addons (https://nodejs.org/api/addons.html) 39 | build/Release 40 | 41 | # Dependency directories 42 | node_modules/ 43 | jspm_packages/ 44 | 45 | # Snowpack dependency directory (https://snowpack.dev/) 46 | web_modules/ 47 | 48 | # TypeScript cache 49 | *.tsbuildinfo 50 | 51 | # Optional npm cache directory 52 | .npm 53 | 54 | # Optional eslint cache 55 | .eslintcache 56 | 57 | # Optional stylelint cache 58 | .stylelintcache 59 | 60 | # Microbundle cache 61 | .rpt2_cache/ 62 | .rts2_cache_cjs/ 63 | .rts2_cache_es/ 64 | .rts2_cache_umd/ 65 | 66 | # Optional REPL history 67 | .node_repl_history 68 | 69 | # Output of 'npm pack' 70 | *.tgz 71 | 72 | # Yarn Integrity file 73 | .yarn-integrity 74 | 75 | # dotenv environment variable files 76 | .env 77 | .env.development.local 78 | .env.test.local 79 | .env.production.local 80 | .env.local 81 | 82 | # parcel-bundler cache (https://parceljs.org/) 83 | .cache 84 | .parcel-cache 85 | 86 | # Next.js build output 87 | .next 88 | out 89 | 90 | # Nuxt.js build / generate output 91 | .nuxt 92 | dist 93 | 94 | # Gatsby files 95 | .cache/ 96 | # Comment in the public line in if your project uses Gatsby and not Next.js 97 | # https://nextjs.org/blog/next-9-1#public-directory-support 98 | # public 99 | 100 | # vuepress build output 101 | .vuepress/dist 102 | 103 | # vuepress v2.x temp and cache directory 104 | .temp 105 | .cache 106 | 107 | # Docusaurus cache and generated files 108 | .docusaurus 109 | 110 | # Serverless directories 111 | .serverless/ 112 | 113 | # FuseBox cache 114 | .fusebox/ 115 | 116 | # DynamoDB Local files 117 | .dynamodb/ 118 | 119 | # TernJS port file 120 | .tern-port 121 | 122 | # Stores VSCode versions used for testing VSCode extensions 123 | .vscode-test 124 | 125 | # yarn v2 126 | .yarn/cache 127 | .yarn/unplugged 128 | .yarn/build-state.yml 129 | .yarn/install-state.gz 130 | .pnp.* -------------------------------------------------------------------------------- /chatGPTChromeEnhance/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 qunash 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /chatGPTChromeEnhance/README.md: -------------------------------------------------------------------------------- 1 | > Below is WebChatGPT illustrations. I add the API manager function to this extension and fix some bugs. 2 | 3 | [link-chrome]: https://chrome.google.com/webstore/detail/chatgpt-advanced/lpfemeioodjbpieminkklglpmhlngfcn 'Chrome Web Store' 4 | [link-firefox]: https://addons.mozilla.org/en-US/firefox/addon/web-chatgpt/ 'Firefox Addons' 5 | 6 |
7 |

WebChatGPT

8 | 9 | [![Discord](https://img.shields.io/discord/1060110102188797992?color=green&label=Join%20server&logo=discord)](https://discord.gg/nmCjvyVpnB) [![Twitter Follow](https://img.shields.io/twitter/follow/hahahahohohe?label=follow%20me&style=social)](https://twitter.com/hahahahohohe) 10 | 11 | 12 | This browser extension `adds web access` capability to [ChatGPT](https://chat.openai.com/). Get much more relevant and up-to-date answers from the chatbot! 13 | 14 | ![image](https://user-images.githubusercontent.com/3750161/214144292-4fb34667-015a-43f3-906d-1d2d065d67f0.png) 15 | 16 | 17 |
18 | 19 | [Chrome][link-chrome] [Firefox][link-firefox] 20 | 21 | [][link-chrome] [Chrome Web Store][link-chrome] 22 |
23 | [][link-firefox] 24 | [Mozilla Add-on][link-firefox] 25 |
26 |
27 | 28 | https://user-images.githubusercontent.com/3750161/214155508-5c1ad4d8-b565-4fe0-9ce7-e68aed11e73d.mp4 29 | 30 | 31 |
32 |

Manual installation

33 | 34 | ### Chrome, Microsoft Edge, etc. 35 | 1. Download prebuilt chrome zip file from [here](https://github.com/qunash/chatgpt-advanced/tree/main/build). 36 | 2. Unzip the file. 37 | 3. Open `chrome://extensions` in Chrome / `edge://extensions` in Microsoft Edge. 38 | 4. Enable developer mode (top right corner). 39 | 5. Click on `Load unpacked` and select the unzipped folder. 40 | 6. Go to [ChatGPT](https://chat.openai.com/chat/) and enjoy! 41 | 42 | ### Firefox 43 | 1. Download prebuilt firefox zip file from [here](https://github.com/qunash/chatgpt-advanced/tree/main/build). 44 | 45 | #### Temporary installation, in official Release or Beta 46 | 1. Go to `about:debugging#/runtime/this-firefox`. 47 | 2. Click `Load Temporary Add-on` button, then select the zip file you re-zipped. 48 | 49 | #### Persistent installation, in Nightly or Developer Edition 50 | 1. Open Firefox, go to `about:config` and set `xpinstall.signatures.required` to `false`. 51 | 2. Go to `about:addons` 52 | 3. Click on the gear icon in the top right corner of the Add-ons page and select `Install Add-on From File`. 53 | 4. Select the zip file and click open. 54 | 5. Firefox will prompt you to confirm the installation of the addon. Click Install. 55 | 6. The addon will be installed and will appear in the list of installed addons on the Add-ons page. 56 | 7. Go to [ChatGPT](https://chat.openai.com/chat/) and enjoy! 57 |
58 | 59 |
60 |

Build from source

61 | 62 | 1. `git clone https://github.com/qunash/chatgpt-advanced.git` 63 | 2. `npm install` 64 | 3. `npm run build-prod` 65 | 4. Grab your zip extension from `build/` folder 66 |
67 | 68 | ## Contributing 69 | 70 | Contributions are welcome! Please submit pull requests to the `dev` branch. 71 | 72 |


73 | 74 | 75 | Like this free project? Please consider [supporting me](https://www.buymeacoffee.com/anzorq) to keep it running. 76 | 77 | [Buy Me A Coffee](https://www.buymeacoffee.com/anzorq) 78 | 79 | [![visitors](https://visitor-badge.glitch.me/badge?page_id=qunash/chatgpt-advanced)](https://visitor-badge.glitch.me) [![Discord](https://img.shields.io/discord/1060110102188797992?color=green&label=Join%20server&logo=discord)](https://discord.gg/nmCjvyVpnB) [![Twitter Follow](https://img.shields.io/twitter/follow/hahahahohohe?label=follow%20me&style=social)](https://twitter.com/hahahahohohe) 80 | 81 | -------------------------------------------------------------------------------- /chatGPTChromeEnhance/build.mjs: -------------------------------------------------------------------------------- 1 | import esbuild from "esbuild" 2 | import archiver from "archiver" 3 | import fs from "fs-extra" 4 | import tailwindcss from "tailwindcss" 5 | import autoprefixer from "autoprefixer" 6 | import postcssPlugin from "esbuild-style-plugin" 7 | import copyStaticFilesPlugin from "esbuild-copy-files-plugin" 8 | import path from 'path' 9 | 10 | 11 | const buildDir = "build" 12 | const minify = process.argv.includes("--minify") 13 | 14 | async function cleanBuildDir() { 15 | const entries = await fs.readdir(buildDir) 16 | for (const entry of entries) { 17 | if (path.extname(entry) === ".zip") continue 18 | await fs.remove(`${buildDir}/${entry}`) 19 | } 20 | } 21 | 22 | async function runEsbuild() { 23 | await esbuild.build({ 24 | entryPoints: [ 25 | "src/content-scripts/mainUI.tsx", 26 | "src/background/bg.ts", 27 | "src/options/options.tsx", 28 | ], 29 | outdir: buildDir, 30 | bundle: true, 31 | minify, 32 | treeShaking: true, 33 | define: { 34 | "process.env.NODE_ENV": '"production"', 35 | }, 36 | jsxFactory: "h", 37 | jsxFragment: "Fragment", 38 | jsx: "automatic", 39 | loader: { 40 | ".png": "dataurl", 41 | }, 42 | plugins: [ 43 | postcssPlugin({ 44 | postcss: { 45 | plugins: [tailwindcss, autoprefixer], 46 | }, 47 | }), 48 | copyStaticFilesPlugin({ 49 | source: ["src/manifest.json", "src/assets/"], 50 | target: buildDir, 51 | copyWithFolder: false, 52 | }), 53 | copyStaticFilesPlugin({ 54 | source: ["src/options/options.html"], 55 | target: `${buildDir}/options`, 56 | copyWithFolder: false, 57 | }), 58 | copyStaticFilesPlugin({ 59 | source: ["src/_locales/"], 60 | target: buildDir, 61 | copyWithFolder: true, 62 | }), 63 | ], 64 | }) 65 | } 66 | 67 | async function createZipExtensionForBrowser(browser) { 68 | const manifest = await fs.readJson(`${buildDir}/manifest.json`) 69 | const version = manifest.version 70 | let archiveName = `build/webchatgpt-${version}-${browser}.zip` 71 | 72 | const archive = archiver("zip", { zlib: { level: 9 } }) 73 | const stream = fs.createWriteStream(archiveName) 74 | 75 | archive.pipe(stream) 76 | 77 | await addFilesToZip(archive, browser) 78 | 79 | console.log(`Creating ${archiveName}…`) 80 | archive.finalize() 81 | } 82 | 83 | async function addFilesToZip(archive, browser) { 84 | const entries = await fs.readdir("build") 85 | for (const entry of entries) { 86 | const entryStat = await fs.stat(`build/${entry}`) 87 | 88 | if (entryStat.isDirectory()) { 89 | archive.directory(`build/${entry}`, entry) 90 | } else { 91 | if (path.extname(entry) === ".zip") continue 92 | if (entry === "manifest.json") continue 93 | archive.file(`build/${entry}`, { name: entry }) 94 | } 95 | } 96 | if (browser === "firefox") { 97 | archive.file("src/manifest.v2.json", { name: "manifest.json" }) 98 | } else if (browser === "chrome") { 99 | archive.file("build/manifest.json", { name: "manifest.json" }) 100 | } 101 | } 102 | 103 | async function build() { 104 | await cleanBuildDir() 105 | await runEsbuild() 106 | 107 | const createZips = process.argv.includes("--create-zips") 108 | if (createZips) { 109 | try { 110 | await deleteZipsInBuildFolder() 111 | 112 | await createZipExtensionForBrowser("chrome") 113 | await createZipExtensionForBrowser("firefox") 114 | } catch (error) { 115 | console.error(error) 116 | } 117 | } 118 | 119 | console.log("Build complete") 120 | 121 | async function deleteZipsInBuildFolder() { 122 | const entries = await fs.readdir("build") 123 | for (const entry of entries) { 124 | if (path.extname(entry) === ".zip") { 125 | await fs.remove(`build/${entry}`) 126 | } 127 | } 128 | } 129 | } 130 | 131 | build() 132 | -------------------------------------------------------------------------------- /chatGPTChromeEnhance/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "name": "webchatgpt", 4 | "version": "0.0.0", 5 | "license": "MIT", 6 | "scripts": { 7 | "build-dev": "node build.mjs", 8 | "build-prod": "node build.mjs --create-zips", 9 | "build-prod-min": "node build.mjs --create-zips --minify", 10 | "lint": "eslint ./src", 11 | "lint:fix": "eslint ./src --fix", 12 | "watch": "chokidar src -c \"npm run build-dev\"" 13 | }, 14 | "dependencies": { 15 | "fs": "^0.0.1-security", 16 | "lodash-es": "^4.17.21", 17 | "preact": "^10.10.0", 18 | "uuid": "^9.0.0" 19 | }, 20 | "devDependencies": { 21 | "@types/lodash-es": "^4.17.6", 22 | "@types/uuid": "^9.0.0", 23 | "@types/webextension-polyfill": "^0.10.0", 24 | "@typescript-eslint/eslint-plugin": "^5.30.6", 25 | "@typescript-eslint/parser": "^5.52.0", 26 | "archiver": "^5.3.1", 27 | "autoprefixer": "^10.4.13", 28 | "chokidar-cli": "^3.0.0", 29 | "daisyui": "^2.47.0", 30 | "esbuild": "^0.16.17", 31 | "esbuild-copy-files-plugin": "^1.1.0", 32 | "esbuild-style-plugin": "^1.6.1", 33 | "eslint": "^8.20.0", 34 | "eslint-config-preact": "^1.3.0", 35 | "eslint-plugin-tailwindcss": "^3.8.3", 36 | "fs-extra": "^11.1.0", 37 | "jest": "^29.4.3", 38 | "preact-cli": "^2.2.1", 39 | "tailwindcss": "^3.2.4", 40 | "typescript": "^4.5.2", 41 | "webextension-polyfill": "^0.10.0" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /chatGPTChromeEnhance/src/_locales/de/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "appName": { 3 | "message": "WebChatGPT: ChatGPT mit Internetzugang" 4 | }, 5 | "appDesc": { 6 | "message": "Erweitern Sie Ihre ChatGPT-Prompts mit relevanten Ergebnissen aus dem Web." 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /chatGPTChromeEnhance/src/_locales/en/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "appName": { 3 | "message": "WebChatGPT: ChatGPT with internet access" 4 | }, 5 | "appDesc": { 6 | "message": "Augment your ChatGPT prompts with relevant results from the web." 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /chatGPTChromeEnhance/src/_locales/es/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "appName": { 3 | "message": "WebChatGPT: ChatGPT con acceso a internet" 4 | }, 5 | "appDesc": { 6 | "message": "Aumente sus prompts ChatGPT con resultados relevantes de la web." 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /chatGPTChromeEnhance/src/_locales/fr/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "appName": { 3 | "message": "WebChatGPT: ChatGPT avec accès à Internet" 4 | }, 5 | "appDesc": { 6 | "message": "Augmentez vos prompts ChatGPT avec des résultats pertinents provenant du Web." 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /chatGPTChromeEnhance/src/_locales/it/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "appName": { 3 | "message": "WebChatGPT: ChatGPT con accesso a Internet" 4 | }, 5 | "appDesc": { 6 | "message": "Migliora i tuoi prompt di ChatGPT con risultati pertinenti dal web." 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /chatGPTChromeEnhance/src/_locales/ja/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "appName": { 3 | "message": "WebChatGPT: インターネットにアクセスできる ChatGPT" 4 | }, 5 | "appDesc": { 6 | "message": "Webから関連する結果を使用して、ChatGPTのプロンプトを拡張します。" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /chatGPTChromeEnhance/src/_locales/ko/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "appName": { 3 | "message": "WebChatGPT: 인터넷 액세스가 가능한 ChatGPT" 4 | }, 5 | "appDesc": { 6 | "message": "웹에서 관련 결과를 사용하여 ChatGPT 프롬프트를 향상시킵니다." 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /chatGPTChromeEnhance/src/_locales/pt_BR/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "appName": { 3 | "message": "WebChatGPT: ChatGPT com acesso à internet" 4 | }, 5 | "appDesc": { 6 | "message": "Aumente seus prompts do ChatGPT com resultados relevantes da web." 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /chatGPTChromeEnhance/src/_locales/ru/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "appName": { 3 | "message": "WebChatGPT: ChatGPT с доступом в интернет" 4 | }, 5 | "appDesc": { 6 | "message": "Дополните запросы к ChatGPT подходящими результатами из сети Интернет." 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /chatGPTChromeEnhance/src/_locales/zh_CN/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "appName": { 3 | "message": "WebChatGPT:可访问互联网的 ChatGPT" 4 | }, 5 | "appDesc": { 6 | "message": "使用来自网络的相关结果增强您的 ChatGPT 提示。" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /chatGPTChromeEnhance/src/assets/icons/icon128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/circlestarzero/EX-chatGPT/ddfe9c4f410d25d1880b61d149d0ffcbf53371d0/chatGPTChromeEnhance/src/assets/icons/icon128.png -------------------------------------------------------------------------------- /chatGPTChromeEnhance/src/assets/icons/icon16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/circlestarzero/EX-chatGPT/ddfe9c4f410d25d1880b61d149d0ffcbf53371d0/chatGPTChromeEnhance/src/assets/icons/icon16.png -------------------------------------------------------------------------------- /chatGPTChromeEnhance/src/assets/icons/icon48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/circlestarzero/EX-chatGPT/ddfe9c4f410d25d1880b61d149d0ffcbf53371d0/chatGPTChromeEnhance/src/assets/icons/icon48.png -------------------------------------------------------------------------------- /chatGPTChromeEnhance/src/background/bg.ts: -------------------------------------------------------------------------------- 1 | import Browser from 'webextension-polyfill' 2 | 3 | 4 | const manifest_version = Browser.runtime.getManifest().manifest_version 5 | 6 | 7 | Browser.runtime.onInstalled.addListener(async () => openChatGPTWebpage()) 8 | 9 | function openChatGPTWebpage() { 10 | Browser.tabs.create({ 11 | url: "https://chat.openai.com/chat", 12 | }) 13 | } 14 | 15 | // open chatgpt webpage when extension icon is clicked 16 | if (manifest_version == 2) { 17 | Browser.browserAction.onClicked.addListener(openChatGPTWebpage) 18 | } else { 19 | Browser.action.onClicked.addListener(openChatGPTWebpage) 20 | } 21 | 22 | 23 | Browser.runtime.onMessage.addListener((request) => { 24 | if (request === "show_options") { 25 | Browser.runtime.openOptionsPage() 26 | } 27 | if (request === "show_API_options") { 28 | Browser.runtime.openOptionsPage() 29 | } 30 | }) 31 | -------------------------------------------------------------------------------- /chatGPTChromeEnhance/src/components/apiEditor.tsx: -------------------------------------------------------------------------------- 1 | import { h } from 'preact' 2 | import { useState, useEffect, useRef, useLayoutEffect } from 'preact/hooks' 3 | import { getTranslation, localizationKeys } from 'src/util/localization' 4 | import { deleteAPI, getDefaultAPI, getsavedAPIs, API, saveAPI } from 'src/util/apiManager' 5 | const APIEditor = ( 6 | ) => { 7 | const [savedAPIS, setSavedAPIS] = useState([]) 8 | const [api, setAPI] = useState(getDefaultAPI()) 9 | const [deleteBtnText, setDeleteBtnText] = useState("delete") 10 | const [showErrors, setShowErrors] = useState(false) 11 | const [nameError, setNameError] = useState(false) 12 | const [textError, setTextError] = useState(false) 13 | 14 | useLayoutEffect(() => { 15 | updateSavedAPIS() 16 | }, []) 17 | 18 | const updateSavedAPIS = async () => { 19 | const apis = await getsavedAPIs() 20 | setSavedAPIS(apis) 21 | if (api.uuid === 'default') { 22 | setAPI(apis[0]) 23 | } 24 | } 25 | 26 | useEffect(() => { 27 | setNameError(api.name.trim() === '') 28 | setTextError(api.text.trim() === '') 29 | }, [api]) 30 | 31 | async function updateList() { 32 | getsavedAPIs().then(sp => { 33 | setSavedAPIS(sp) 34 | }) 35 | } 36 | 37 | const handleSelect = (api:API) => { 38 | setShowErrors(false) 39 | setAPI(api) 40 | setDeleteBtnText("delete") 41 | } 42 | 43 | const handleAdd = () => { 44 | setShowErrors(false) 45 | setAPI({ name: '', text: '' }) 46 | setDeleteBtnText("delete") 47 | if (nameInputRef.current) { 48 | nameInputRef.current.focus() 49 | } 50 | } 51 | 52 | const handleSave = async () => { 53 | setShowErrors(true) 54 | if (nameError || textError) { 55 | return 56 | } 57 | await saveAPI(api) 58 | await updateList() 59 | } 60 | 61 | const handleDeleteBtnClick = () => { 62 | if (deleteBtnText === "delete") { 63 | setDeleteBtnText("check") 64 | } else { 65 | handleDelete() 66 | } 67 | } 68 | 69 | const handleDelete = async () => { 70 | await deleteAPI(api) 71 | updateList() 72 | handleAdd() 73 | } 74 | 75 | const nameInputRef = useRef(null) 76 | const textareaRef = useRef(null) 77 | const handleTextareaChange = (e: Event) => { 78 | const text = (e.target as HTMLTextAreaElement).value 79 | if (text !== api.text) { 80 | setTextError(false) 81 | setAPI({ ...api, text }) 82 | } 83 | } 84 | const actionToolbar = ( 85 |
88 | 94 |
95 | ) 96 | 97 | const APIList = ( 98 |
99 | 107 | 121 |
122 | ) 123 | 124 | const nameInput = ( 125 | { 133 | setNameError(false) 134 | setAPI({ ...api, name: (e.target as HTMLInputElement).value }) 135 | }} 136 | disabled={api.uuid === 'default'} 137 | /> 138 | ) 139 | 140 | const btnDelete = ( 141 | 151 | ) 152 | 153 | const textArea = ( 154 |