diff --git a/README.md b/README.md index 4ab29e6..9a5bab5 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,46 @@ -# Duck GPT -DuckDuckGo AI Chat Wrapper. +

Duck GPT

+

Unlimited ChatGPT using cloudflare workers and duckchat.


-## ⚙️ Usage: +## 🗜 Features +- **Clear Chat**: Start a new conversation at any time. +- **Settings**: Toggle particle effects and theme settings (light/dark). +- **Open Source Contributions**: Open to community contributions for further improvements. + +
+ +## 📂 Models +- `gpt-4o-mini` +- `claude-3-haiku-20240307` +- `mistralai/Mixtral-8x7B-Instruct-v0.1` +- `meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo` + +
+ +## ⚙️ Deploy +- Create a [Cloudflare](https://www.cloudflare.com/) **account**. +- Navigate to `Workers & Pages > Create > Create Worker`. +- Deploy the worker by clicking **Deploy**. +- Edit the code by clicking **Edit Code**. +- Upload [worker.js](https://github.com/Vauth/duckgpt/blob/main/worker/worker.js) into **Cloudflare**. +- Finally, **Deploy**. + +[![Deploy to Cloudflare Workers](https://deploy.workers.cloudflare.com/button)](https://deploy.workers.cloudflare.com/?url=https://github.com/vauth/duckgpt) + +
+ +## 📡 Live Demo +Check out the live demo [here](https://duck.gpt-api.workers.dev). + +
+ +## 📷 Screenshot + + +
+ +## 📦 Python Usage ([main.py](https://github.com/Vauth/duckgpt/blob/main/main.py)) ```python if __name__ == "__main__": Client = DuckGPT(model="gpt-4o-mini") @@ -17,28 +54,38 @@ if __name__ == "__main__":
-## 📚 Functions: -#### `DuckGPT.Chat` -- Request to duck api using prompt. -#### `DuckGPT.Models` -- Get list of available models. +## 🛠 Credits +- **Front-End Developer**: [Zarox](https://github.com/Zar0x) ([duck-gui](https://github.com/Zar0x/duck-gui)) +- **Back-End Developer & GPT API**: [Vauth](https://github.com/Vauth)
-## 📂 Models: -- `gpt-4o-mini` -- `claude-3-haiku-20240307` -- `mistralai/Mixtral-8x7B-Instruct-v0.1` -- `meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo` +## 🔗 Contributing +Contributions are welcome! Feel free to submit a pull request or report an issue.
-## 🛠 Cloudflare Setup: -### Easy Deploy: +## 🔎 License +``` +MIT License -[![Deploy to Cloudflare Workers](https://deploy.workers.cloudflare.com/button)](https://deploy.workers.cloudflare.com/?url=https://github.com/vauth/duckgpt) -### Manually: -- Upload `worker.js` into [cloudflare workers](https://workers.cloudflare.com/). -- Use `duckgpt.XXXX.workers.dev/chat/?prompt=hi&model=gpt-4o-mini` endpoint. +Copyright (c) 2024 Vauth -**Sample api:** [duck.gpt-api.workers.dev](https://duck.gpt-api.workers.dev/help/) +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +``` diff --git a/worker/worker.js b/worker/worker.js index 2a858ff..f769de6 100644 --- a/worker/worker.js +++ b/worker/worker.js @@ -1,10 +1,22 @@ +// ---------------------------- // // - github.com/Vauth/duckgpt - // +// ---------------------------- // const MODELS = ['gpt-4o-mini', 'claude-3-haiku-20240307', 'meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo', 'mistralai/Mixtral-8x7B-Instruct-v0.1']; +const MAIN_MODEL = 'gpt-4o-mini'; const STATUS_URL = 'https://duckduckgo.com/duckchat/v1/status'; const CHAT_API = 'https://duckduckgo.com/duckchat/v1/chat'; -addEventListener('fetch', event => { +const ERROR_404 = {"action":"error", "status": 404, "usage": "GET /chat/?prompt=&model=&history=", "models": MODELS}; +const ERROR_403 = {"action":"error", "status": 403, "response": "Wrong history syntax", "example":"[{'role': 'user','content': 'Expert python geek'}]"}; + +const HEAD_JSON = { 'content-type': 'application/json', 'Access-Control-Allow-Origin': "*"}; +const HEAD_HTML = { 'content-type': 'text/html', 'Access-Control-Allow-Origin': "*"}; + + +// ---------- Event Listener ---------- // + +addEventListener('fetch', event => { event.respondWith(handleRequest(event.request)) }) @@ -12,16 +24,24 @@ async function handleRequest(request) { let url = new URL(request.url); let prompt = url.searchParams.get('prompt'); let history = url.searchParams.get('history') || '[]'; - let model = url.searchParams.get('model') || 'gpt-4o-mini'; - let headers = { 'content-type': 'application/json', 'Access-Control-Allow-Origin': "*"} + let model = url.searchParams.get('model') || MAIN_MODEL; + + if (url.pathname == "/") { + let response = HTML; + return new Response(response, {headers: HEAD_HTML}); + } - if (!prompt || request.method !== "GET" || url.pathname !== "/chat/") { - return new Response(await Raise(), {status: 400, headers: headers}); + if (prompt && url.pathname == "/chat/") { + let response = JSON.stringify(await Chat(prompt, history, model)); + return new Response(response, {headers: HEAD_JSON}); } else { - return new Response(await Chat(prompt, history, model), {status: 200, headers: headers}); + let response = JSON.stringify(ERROR_404); + return new Response(response, {headers: HEAD_JSON}); } } +// ---------- Duckgpt Function ---------- // + async function Chat(prompt, history, model) { let headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:129.0) Gecko/20100101 Firefox/129.0', @@ -45,16 +65,208 @@ async function Chat(prompt, history, model) { headers['Content-Type'] = 'application/json'; let message; try {message = JSON.parse(history).concat([{ role: 'user', content: prompt }]) - } catch {return JSON.stringify({"action":"error", "status": 403, "response": "Wrong history syntax", "example":"[{'role': 'user','content': 'you are an expert python geek'}]"})} + } catch {return ERROR_403} - let data = JSON.stringify({model: model, messages: message}); - let Response = await (await fetch(CHAT_API, { method: 'POST', headers: headers, body: data })).text(); + let Response = await (await fetch(CHAT_API, { method: 'POST', headers: headers, body: JSON.stringify({model: model, messages: message}) })).text(); let chatMessages = Response.split('\n').filter(line => line.includes('message')).map(line => JSON.parse(line.split('data: ')[1]).message).join(''); if (chatMessages == "") {return Response;} - else {return JSON.stringify({"action":"success", "status": 200, "response": chatMessages, "model": model});} + else {return {"action":"success", "status": 200, "response": chatMessages, "model": model}} } -async function Raise() { - return JSON.stringify({"action":"error", "status": 404, "usage": "GET /chat/?prompt=&model=&history=", "models": MODELS}); +// ----------------------------- // +// - github.com/zar0x/duck-gui - // +// ----------------------------- // + +let CONFIG = { + "scripts": { + "particles": `https://vauth.github.io/duck-gui/scripts/particles.js`, + "script": `https://vauth.github.io/duck-gui/scripts/script.js` + }, + "styles": { + "light": `https://vauth.github.io/duck-gui/styles/light.css`, + "styles": `https://vauth.github.io/duck-gui/styles/styles.css` + }, + "resources": { + "clear": `https://vauth.github.io/duck-gui/assets/clear.png`, + "developer": `https://vauth.github.io/duck-gui/assets/developer.png`, + "help": `https://vauth.github.io/duck-gui/assets/help.png`, + "load": `https://vauth.github.io/duck-gui/assets/load.gif`, + "photo": `https://vauth.github.io/duck-gui/assets/photo.jpg`, + "send": `https://vauth.github.io/duck-gui/assets/send.png`, + "setting": `https://vauth.github.io/duck-gui/assets/setting.png`, + "source": `https://vauth.github.io/duck-gui/assets/source.png`, + "favicon": `https://vauth.github.io/duck-gui/assets/favicon.png`, + "ogcover": `https://vauth.github.io/duck-gui/assets/ogcover.png` + } } + + +// ---------- HTML Website ---------- // + +let HTML = ` + + + + + + + + + DuckGPT Chat + + + + + + + + + + +
+
+
+
+
+
+ +
+
+ +
+
+ +
+ + + +
+
+
+
+ +
+
+
Type your message here...
+ + +
+
+
+ + + + +`