From a9c5e353e4adc4fb6889fc91792474907a99b8f8 Mon Sep 17 00:00:00 2001 From: zachey <63107653+zachey01@users.noreply.github.com> Date: Wed, 17 Jul 2024 02:00:44 +0500 Subject: [PATCH] Add streaming --- dist/gpt4js.min.js | 2 +- src/Providers/ChatCompletion/Alibaba.js | 12 +++++-- src/Providers/ChatCompletion/ChatBotRu.js | 11 ++++-- src/Utils/stream.js | 43 +++++++++++++++++++++++ 4 files changed, 63 insertions(+), 5 deletions(-) create mode 100644 src/Utils/stream.js diff --git a/dist/gpt4js.min.js b/dist/gpt4js.min.js index 728e227..f6d9b44 100644 --- a/dist/gpt4js.min.js +++ b/dist/gpt4js.min.js @@ -1 +1 @@ -(()=>{"use strict";const e=class{async chatCompletion(e,t){throw new Error("Method 'chatCompletion()' must be implemented.")}},t=function(e){return{options,accept:"application/json, text/event-stream","accept-language":"ru,en;q=0.9","content-type":"application/json",priority:"u=1, i","sec-ch-ua":'"Chromium";v="124", "YaBrowser";v="24.6", "Not-A.Brand";v="99", "Yowser";v="2.5"',"sec-ch-ua-mobile":"?0","sec-ch-ua-platform":'"Windows"',"sec-fetch-dest":"empty","sec-fetch-mode":"cors","sec-fetch-site":"same-origin",Referer:e,"Referrer-Policy":"strict-origin-when-cross-origin",usesearch:"false"}},a=class extends e{async chatCompletion(e,a){try{const r=await fetch("https://nexra.aryahcr.cc/api/chat/gpt",{method:"POST",headers:t("https://nexra.aryahcr.cc/api/chat/gpt"),body:JSON.stringify({messages:e,model:a.model||"gpt-4",temperature:a.temperature||.5,stream:a.stream||!1})});if(!r.ok)throw new Error(`HTTP error! status: ${r.status}`);const o=await r.json();if(o.status&&o.gpt)return o.gpt;throw new Error("Unexpected response format")}catch(e){throw console.error("Error:",e),e}}},r=class extends e{async chatCompletion(e,a={}){const r={messages:e,id:()=>[...Array(7)].map((()=>"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"[Math.floor(36*Math.random())])).join(""),previewToken:null,userId:Math.random().toString(16).substring(2,8)+"-"+Math.random().toString(16).substring(2,4)+"-"+Math.random().toString(16).substring(2,4)+"-"+Math.random().toString(16).substring(2,4)+"-"+Math.random().toString(16).substring(2,12),codeModelMode:a.codeModelMode||!0,agentMode:{},trendingAgentMode:{},isMicMode:!1,isChromeExt:a.isChromeExt||!1,githubToken:null,clickedAnswer2:!1,clickedAnswer3:!1,clickedForceWebSearch:a.webSearch||!1,visitFromDelta:a.visitFromDelta||null};let o;o="undefined"!=typeof window?"https://proxy.zachey.space/?url=http://www.blackbox.ai/api/chat":"https://www.blackbox.ai/api/chat";const s=await fetch(o,{headers:t("https://www.blackbox.ai/api/chat"),body:JSON.stringify(r),method:"POST",mode:"cors",credentials:"omit"});if(!s.ok)throw new Error(`HTTP error! status: ${s.status}`);const n=await s.text();let c=n.lastIndexOf("$");return n.slice(c+1)}},o=class extends e{async chatCompletion(e,a){const r=a.use_proxy?"https://proxy.zachey.space/?url=https://chat.eqing.tech/api/openai/v1/chat/completions":"https://chat.eqing.tech/api/openai/v1/chat/completions",o=await fetch(r,{headers:t("https://chat.eqing.tech/api/openai/v1/chat/completions"),body:JSON.stringify({messages:e,stream:a.stream,model:a.model||"gpt-4o-free",temperature:a.temperature,captchaToken:"P1_"+btoa(JSON.stringify({typ:"JWT",alg:"HS256"}))+"."+btoa("hashedkey")+"."+btoa("signature")}),method:"POST"});if(o.ok)try{const e=await o.json();if(e.choices&&e.choices.length>0&&e.choices[0].message&&e.choices[0].message.content)return e.choices[0].message.content.trim()}catch(e){console.error("Failed to parse JSON:",e)}else console.error("Network response was not ok")}},s=class extends e{async chatCompletion(e){let t=e[0].content;const a=ai.createTextSession(),r=await a;return await r.prompt(t)}},n=class extends e{async chatCompletion(e,a){try{const r=await fetch(`${a.ollama_url||"http://localhost:11434"}/api/chat`,{headers:t(`${a.ollama_url||"http://localhost:11434"}`),body:JSON.stringify({messages:e,stream:a.stream||!1,model:a.model}),method:"POST"});if(!r.ok)throw new Error("Network response was not ok");return(await r.json()).message.content}catch(e){console.error("Error fetching data:",e.message)}}},c=class extends e{async chatCompletion(e,a){try{const r=await fetch("https://chat.chatgpt.org.uk/api/openai/v1/chat/completions",{headers:t("https://chat.chatgpt.org.uk/api/openai/v1/chat/completions"),body:JSON.stringify({messages:e,stream:a.stream||!1,model:a.model||"gpt-3.5-turbo",temperature:a.temperature||.5,presence_penalty:a.presence_penalty||0,frequency_penalty:a.frequency_penalty||0,top_p:a.top_p||1}),method:"POST"});return(await r.json()).choices[0].message.content}catch(e){throw console.error("Error:",e),e}}},i=class extends e{async chatCompletion(e,a){try{const r={"gpt-4o":"gpt-4o-2024-05-13","gpt-4":"gpt-4-32k","gpt-4-turbo":"gpt-4-32k-0613"},o=r[a.model]||r["gpt-4o"],s=await fetch("https://gpt-chatbotru-chat-main.ru/api/openai/v1/chat/completions",{headers:t("https://gpt-chatbotru-chat-main.ru/api/openai/v1/chat/completions"),body:JSON.stringify({messages:e,stream:a.stream||!1,model:o,temperature:a.temperature||.5,presence_penalty:a.presence_penalty||0,frequency_penalty:a.frequency_penalty||0,top_p:a.top_p||1}),method:"POST"});return(await s.json()).choices[0].message.content}catch(e){throw console.error("Error:",e),e}}},p=class{async imageGeneration(e,t){throw new Error("Method 'imageGeneration()' must be implemented.")}},h=class extends p{async imageGeneration(e){try{const t=await fetch("https://nexra.aryahcr.cc/api/image/complements",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({prompt:e,model:"dalle"})});if(!t.ok)throw new Error("Failed to fetch data.");const a=(await t.text()).trim().replace(/^_+/,""),r=JSON.parse(a);if(200===r.code&&r.status)return r.images;throw new Error("Server returned unsuccessful response.")}catch(e){throw console.error("Error fetching data:",e),new Error("Failed to fetch data. Please try again later.")}}},l=class extends p{async imageGeneration(e,t){try{const a=await fetch("https://nexra.aryahcr.cc/api/image/complements",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({prompt:e,model:"stablediffusion-2.1",data:{prompt_negative:t.prompt_negative||"",width:t.width||512,height:t.height||512,sampling_method:t.sampling_method||"default",sampling_steps:t.sampling_steps||1,cfg_scale:t.cfg_scale||1}})});if(!a.ok)throw new Error("Failed to fetch data.");const r=(await a.text()).trim().replace(/^_+/,""),o=JSON.parse(r);if(200===o.code&&o.status)return o.images;throw new Error("Server returned unsuccessful response.")}catch(e){throw console.error("Error fetching data:",e),new Error("Failed to fetch data. Please try again later.")}}};"undefined"!=typeof window&&(window.GPT4js=class{static createProvider(e){switch(e){case"Aryahcr":return new a;case"BlackBox":return new r;case"Nextway":return new o;case"Chrome":return new s;case"Ollama":return new n;case"Alibaba":return new c;case"ChatBotRu":return new i;case"DALLE2":return new h;case"StableDiffusion":return new l;default:throw new Error(`Provider ${e} is not supported.`)}}})})(); \ No newline at end of file +(()=>{"use strict";const e=class{async chatCompletion(e,t){throw new Error("Method 'chatCompletion()' must be implemented.")}},t=function(e){return{accept:"application/json, text/event-stream","accept-language":"ru,en;q=0.9","content-type":"application/json",priority:"u=1, i","sec-ch-ua":'"Chromium";v="124", "YaBrowser";v="24.6", "Not-A.Brand";v="99", "Yowser";v="2.5"',"sec-ch-ua-mobile":"?0","sec-ch-ua-platform":'"Windows"',"sec-fetch-dest":"empty","sec-fetch-mode":"cors","sec-fetch-site":"same-origin",Referer:e,"Referrer-Policy":"strict-origin-when-cross-origin",usesearch:"false"}},r=class extends e{async chatCompletion(e,r){try{const a=await fetch("https://nexra.aryahcr.cc/api/chat/gpt",{method:"POST",headers:t("https://nexra.aryahcr.cc/api/chat/gpt"),body:JSON.stringify({messages:e,model:r.model||"gpt-4",temperature:r.temperature||.5,stream:r.stream||!1})});if(!a.ok)throw new Error(`HTTP error! status: ${a.status}`);const o=await a.json();if(o.status&&o.gpt)return o.gpt;throw new Error("Unexpected response format")}catch(e){throw console.error("Error:",e),e}}},a=class extends e{async chatCompletion(e,r={}){const a={messages:e,id:()=>[...Array(7)].map((()=>"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"[Math.floor(36*Math.random())])).join(""),previewToken:null,userId:Math.random().toString(16).substring(2,8)+"-"+Math.random().toString(16).substring(2,4)+"-"+Math.random().toString(16).substring(2,4)+"-"+Math.random().toString(16).substring(2,4)+"-"+Math.random().toString(16).substring(2,12),codeModelMode:r.codeModelMode||!0,agentMode:{},trendingAgentMode:{},isMicMode:!1,isChromeExt:r.isChromeExt||!1,githubToken:null,clickedAnswer2:!1,clickedAnswer3:!1,clickedForceWebSearch:r.webSearch||!1,visitFromDelta:r.visitFromDelta||null};let o;o="undefined"!=typeof window?"https://proxy.zachey.space/?url=http://www.blackbox.ai/api/chat":"https://www.blackbox.ai/api/chat";const s=await fetch(o,{headers:t("https://www.blackbox.ai/api/chat"),body:JSON.stringify(a),method:"POST",mode:"cors",credentials:"omit"});if(!s.ok)throw new Error(`HTTP error! status: ${s.status}`);const n=await s.text();let c=n.lastIndexOf("$");return n.slice(c+1)}},o=class extends e{async chatCompletion(e,r){const a=r.use_proxy?"https://proxy.zachey.space/?url=https://chat.eqing.tech/api/openai/v1/chat/completions":"https://chat.eqing.tech/api/openai/v1/chat/completions",o=await fetch(a,{headers:t("https://chat.eqing.tech/api/openai/v1/chat/completions"),body:JSON.stringify({messages:e,stream:r.stream,model:r.model||"gpt-4o-free",temperature:r.temperature,captchaToken:"P1_"+btoa(JSON.stringify({typ:"JWT",alg:"HS256"}))+"."+btoa("hashedkey")+"."+btoa("signature")}),method:"POST"});if(o.ok)try{const e=await o.json();if(e.choices&&e.choices.length>0&&e.choices[0].message&&e.choices[0].message.content)return e.choices[0].message.content.trim()}catch(e){console.error("Failed to parse JSON:",e)}else console.error("Network response was not ok")}},s=class extends e{async chatCompletion(e){let t=e[0].content;const r=ai.createTextSession(),a=await r;return await a.prompt(t)}},n=class extends e{async chatCompletion(e,r){try{const a=await fetch(`${r.ollama_url||"http://localhost:11434"}/api/chat`,{headers:t(`${r.ollama_url||"http://localhost:11434"}`),body:JSON.stringify({messages:e,stream:r.stream||!1,model:r.model}),method:"POST"});if(!a.ok)throw new Error("Network response was not ok");return(await a.json()).message.content}catch(e){console.error("Error fetching data:",e.message)}}},c=class extends e{async chatCompletion(e,r){try{const a=await fetch("https://chat.chatgpt.org.uk/api/openai/v1/chat/completions",{headers:t("https://chat.chatgpt.org.uk/api/openai/v1/chat/completions"),body:JSON.stringify({messages:e,stream:r.stream||!1,model:r.model||"gpt-3.5-turbo",temperature:r.temperature||.5,presence_penalty:r.presence_penalty||0,frequency_penalty:r.frequency_penalty||0,top_p:r.top_p||1}),method:"POST"});return(await a.json()).choices[0].message.content}catch(e){throw console.error("Error:",e),e}}},i=class extends e{async chatCompletion(e,r){try{const a={"gpt-4o":"gpt-4o-2024-05-13","gpt-4":"gpt-4-32k","gpt-4-turbo":"gpt-4-32k-0613"},o=a[r.model]||a["gpt-4o"],s=await fetch("https://gpt-chatbotru-chat-main.ru/api/openai/v1/chat/completions",{headers:t("https://gpt-chatbotru-chat-main.ru/api/openai/v1/chat/completions"),body:JSON.stringify({messages:e,stream:r.stream||!1,model:o,temperature:r.temperature||.5,presence_penalty:r.presence_penalty||0,frequency_penalty:r.frequency_penalty||0,top_p:r.top_p||1}),method:"POST"});if(!0!==r.stream)return(await s.json()).choices[0].delta.content;(async function(e){if(!e.ok)throw new Error(`HTTP error! Status: ${e.status}`);const t=e.body.getReader(),r=new TextDecoder("utf-8"),a=[],o=new Set;for(;;){const{done:e,value:s}=await t.read();if(e)break;a.push(r.decode(s,{stream:!0}));let n=a.join("");a.length=0,n.split("\n").forEach((e=>{if(""!==(e=e.replace(/^data: /,"")).trim()&&!o.has(e)){if(o.add(e),"[DONE]"===e.trim())return;try{let t=JSON.parse(e);console.log(t.choices[0].delta.content)}catch(e){console.error("Error parsing chunk:",e)}}}))}return"Streaming finished"})(s).then((e=>e)).catch((e=>console.error("Streaming error:",e)))}catch(e){throw console.error("Error:",e),e}}},h=class{async imageGeneration(e,t){throw new Error("Method 'imageGeneration()' must be implemented.")}},p=class extends h{async imageGeneration(e){try{const t=await fetch("https://nexra.aryahcr.cc/api/image/complements",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({prompt:e,model:"dalle"})});if(!t.ok)throw new Error("Failed to fetch data.");const r=(await t.text()).trim().replace(/^_+/,""),a=JSON.parse(r);if(200===a.code&&a.status)return a.images;throw new Error("Server returned unsuccessful response.")}catch(e){throw console.error("Error fetching data:",e),new Error("Failed to fetch data. Please try again later.")}}},l=class extends h{async imageGeneration(e,t){try{const r=await fetch("https://nexra.aryahcr.cc/api/image/complements",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({prompt:e,model:"stablediffusion-2.1",data:{prompt_negative:t.prompt_negative||"",width:t.width||512,height:t.height||512,sampling_method:t.sampling_method||"default",sampling_steps:t.sampling_steps||1,cfg_scale:t.cfg_scale||1}})});if(!r.ok)throw new Error("Failed to fetch data.");const a=(await r.text()).trim().replace(/^_+/,""),o=JSON.parse(a);if(200===o.code&&o.status)return o.images;throw new Error("Server returned unsuccessful response.")}catch(e){throw console.error("Error fetching data:",e),new Error("Failed to fetch data. Please try again later.")}}};"undefined"!=typeof window&&(window.GPT4js=class{static createProvider(e){switch(e){case"Aryahcr":return new r;case"BlackBox":return new a;case"Nextway":return new o;case"Chrome":return new s;case"Ollama":return new n;case"Alibaba":return new c;case"ChatBotRu":return new i;case"DALLE2":return new p;case"StableDiffusion":return new l;default:throw new Error(`Provider ${e} is not supported.`)}}})})(); \ No newline at end of file diff --git a/src/Providers/ChatCompletion/Alibaba.js b/src/Providers/ChatCompletion/Alibaba.js index 977d15d..fbef791 100644 --- a/src/Providers/ChatCompletion/Alibaba.js +++ b/src/Providers/ChatCompletion/Alibaba.js @@ -1,6 +1,7 @@ "use strict"; import Provider from "./provider.js"; import baseHeaders from "../../Utils/baseHeaders.js"; +import startStreaming from "../../Utils/stream.js"; class AlibabaProvider extends Provider { async chatCompletion(messages, options) { @@ -23,8 +24,15 @@ class AlibabaProvider extends Provider { method: "POST", } ); - const text = await response.json(); - return text.choices[0].message.content; + + if (options.stream === true) { + startStreaming(response).then((chunk) => { + return chunk; + }); + } else { + const text = await response.json(); + return text.choices[0].message.content; + } } catch (error) { console.error("Error:", error); throw error; diff --git a/src/Providers/ChatCompletion/ChatBotRu.js b/src/Providers/ChatCompletion/ChatBotRu.js index 5ad68df..0b2608b 100644 --- a/src/Providers/ChatCompletion/ChatBotRu.js +++ b/src/Providers/ChatCompletion/ChatBotRu.js @@ -1,6 +1,7 @@ "use strict"; import Provider from "./provider.js"; import baseHeaders from "../../Utils/baseHeaders.js"; +import startStreaming from "../../Utils/stream.js"; class ChatBotRuProvider extends Provider { async chatCompletion(messages, options) { @@ -32,8 +33,14 @@ class ChatBotRuProvider extends Provider { } ); - const text = await response.json(); - return text.choices[0].message.content; + if (options.stream === true) { + startStreaming(response).then((chunk) => { + return chunk; + }); + } else { + const text = await response.json(); + return text.choices[0].delta.content; + } } catch (error) { console.error("Error:", error); throw error; diff --git a/src/Utils/stream.js b/src/Utils/stream.js new file mode 100644 index 0000000..d6a466b --- /dev/null +++ b/src/Utils/stream.js @@ -0,0 +1,43 @@ +async function startStreaming(response) { + if (!response.ok) { + throw new Error(`HTTP error! Status: ${response.status}`); + } + + const reader = response.body.getReader(); + const decoder = new TextDecoder("utf-8"); + const buffer = []; + const seenChunks = new Set(); + + while (true) { + const { done, value } = await reader.read(); + if (done) { + break; + } + + buffer.push(decoder.decode(value, { stream: true })); + let combinedChunks = buffer.join(""); + buffer.length = 0; // Clear the buffer + + let chunks = combinedChunks.split("\n"); + + chunks.forEach((chunk) => { + chunk = chunk.replace(/^data: /, ""); + if (chunk.trim() !== "" && !seenChunks.has(chunk)) { + seenChunks.add(chunk); + if (chunk.trim() === "[DONE]") { + return; // Skip processing [DONE] responses + } + try { + let chunkObj = JSON.parse(chunk); + console.log(chunkObj.choices[0].delta.content); + } catch (error) { + console.error("Error parsing chunk:", error); + } + } + }); + } + + return ""; +} + +export default startStreaming;