From 8de92e6cd3beae43db8968593047c9cae253bc21 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Thu, 18 May 2023 04:43:54 +0900 Subject: [PATCH] [feat] added streaming --- package.json | 3 +- pnpm-lock.yaml | 7 +++++ src-tauri/tauri.conf.json | 2 +- src/lang/en.ts | 2 +- src/lang/ko.ts | 11 ++++++- src/lib/SideBars/Settings.svelte | 6 +++- src/main.ts | 9 ++++-- src/ts/database.ts | 2 +- src/ts/process/index.ts | 21 +++++++++++-- src/ts/process/request.ts | 54 ++++++++++++++++++++++++++++---- src/ts/update.ts | 2 +- version.json | 2 +- 12 files changed, 103 insertions(+), 18 deletions(-) diff --git a/package.json b/package.json index 682358c7..a682d838 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,8 @@ "rollup": "^3.21.3", "showdown": "^2.1.0", "sweetalert2": "^11.7.3", - "uuid": "^9.0.0" + "uuid": "^9.0.0", + "web-streams-polyfill": "^3.2.1" }, "devDependencies": { "@sveltejs/vite-plugin-svelte": "^2.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8ac62480..e64679e5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -48,6 +48,7 @@ specifiers: vite: ^4.2.1 vite-plugin-top-level-await: ^1.3.0 vite-plugin-wasm: ^3.2.2 + web-streams-polyfill: ^3.2.1 dependencies: '@dqbd/tiktoken': 1.0.4 @@ -71,6 +72,7 @@ dependencies: showdown: 2.1.0 sweetalert2: 11.7.3 uuid: 9.0.0 + web-streams-polyfill: 3.2.1 devDependencies: '@sveltejs/vite-plugin-svelte': 2.0.4_svelte@3.58.0+vite@4.2.1 @@ -2275,6 +2277,11 @@ packages: xml-name-validator: 4.0.0 dev: false + /web-streams-polyfill/3.2.1: + resolution: {integrity: sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==} + engines: {node: '>= 8'} + dev: false + /webidl-conversions/7.0.0: resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} engines: {node: '>=12'} diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index e83f4217..6930cf6e 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -8,7 +8,7 @@ }, "package": { "productName": "RisuAI", - "version": "1.10.1" + "version": "1.11.0" }, "tauri": { "allowlist": { diff --git a/src/lang/en.ts b/src/lang/en.ts index 34378231..74702aa8 100644 --- a/src/lang/en.ts +++ b/src/lang/en.ts @@ -248,5 +248,5 @@ export const languageEnglish = { useExperimental: "Able Experimental Features", showMemoryLimit: "Show Memory Limit", roundIcons: "Round Icons", - useStreaming: "Use Streaming" + streaming: "Streaming" } diff --git a/src/lang/ko.ts b/src/lang/ko.ts index 6e4f47a4..d2d2e31c 100644 --- a/src/lang/ko.ts +++ b/src/lang/ko.ts @@ -225,5 +225,14 @@ export const languageKorean = { selective: "멀티플 키", SecondaryKeys: '두번째 키', useGlobalSettings: "글로벌 설정 사용", - recursiveScanning: "재귀 검색" + recursiveScanning: "재귀 검색", + creator: "제작자", + CharVersion: "캐릭터 버전", + Speech: "음성", + ToggleSuperMemory: "SupaMemory 토글", + SuperMemory:"SupaMemory", + useExperimental: "실험적 요소 보이기", + showMemoryLimit: "기억 한계치 보이기", + roundIcons: "둥근 아이콘", + streaming: "스트리밍" } \ No newline at end of file diff --git a/src/lib/SideBars/Settings.svelte b/src/lib/SideBars/Settings.svelte index 31478f47..a1a4dab2 100644 --- a/src/lib/SideBars/Settings.svelte +++ b/src/lib/SideBars/Settings.svelte @@ -121,7 +121,11 @@ {/if} {#if $DataBase.aiModel === 'gpt35' || $DataBase.aiModel === 'gpt4' || $DataBase.subModel === 'gpt4' || $DataBase.subModel === 'gpt35'} OpenAI {language.apiKey} - + +
+ + OpenAI {language.streaming} +
{/if} {#if $DataBase.aiModel === 'custom'} {language.plugin} diff --git a/src/main.ts b/src/main.ts index 02ce43c0..8d7eabe6 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,12 +1,17 @@ import "./styles.css"; import App from "./App.svelte"; import { loadData } from "./ts/globalApi"; - +import { ReadableStream, WritableStream, TransformStream } from "web-streams-polyfill/ponyfill/es2018"; import { Buffer as BufferPolyfill } from 'buffer' import { initHotkey } from "./ts/hotkey"; + +//Polyfills declare var Buffer: typeof BufferPolyfill; globalThis.Buffer = BufferPolyfill - +//@ts-ignore +globalThis.WritableStream = globalThis.WritableStream ?? WritableStream +globalThis.ReadableStream = globalThis.ReadableStream ?? ReadableStream +globalThis.TransformStream = globalThis.TransformStream ?? TransformStream const app = new App({ target: document.getElementById("app"), diff --git a/src/ts/database.ts b/src/ts/database.ts index ce356b4c..533515e5 100644 --- a/src/ts/database.ts +++ b/src/ts/database.ts @@ -7,7 +7,7 @@ import { cloneDeep } from 'lodash'; export const DataBase = writable({} as any as Database) export const loadedStore = writable(false) -export let appVer = '1.10.1' +export let appVer = '1.11.0' export function setDatabase(data:Database){ diff --git a/src/ts/process/index.ts b/src/ts/process/index.ts index 9c7f778c..2355805b 100644 --- a/src/ts/process/index.ts +++ b/src/ts/process/index.ts @@ -328,7 +328,8 @@ export async function sendChat(chatProcessIndex = -1):Promise { const req = await requestChatData({ formated: formated, bias: bias, - currentChar: currentChar + currentChar: currentChar, + useStreaming: true }, 'model') let result = '' @@ -339,7 +340,23 @@ export async function sendChat(chatProcessIndex = -1):Promise { return false } else if(req.type === 'streaming'){ - + const reader = req.result.getReader() + const msgIndex = db.characters[selectedChar].chats[selectedChat].message.length + db.characters[selectedChar].chats[selectedChat].message.push({ + role: 'char', + data: "", + saying: currentChar.chaId + }) + while(true){ + const readed = (await reader.read()) + if(readed.value){ + db.characters[selectedChar].chats[selectedChat].message[msgIndex].data =readed.value + setDatabase(db) + } + if(readed.done){ + break + } + } } else{ const result2 = processScriptFull(currentChar, reformatContent(req.result), 'editoutput') diff --git a/src/ts/process/request.ts b/src/ts/process/request.ts index 20e47578..7fe46d66 100644 --- a/src/ts/process/request.ts +++ b/src/ts/process/request.ts @@ -13,7 +13,8 @@ interface requestDataArgument{ temperature?: number maxTokens?:number PresensePenalty?: number - frequencyPenalty?: number + frequencyPenalty?: number, + useStreaming?:boolean } type requestDataResponse = { @@ -21,7 +22,7 @@ type requestDataResponse = { result: string }|{ type: "streaming", - result: ReadableStreamDefaultReader + result: ReadableStream } export async function requestChatData(arg:requestDataArgument, model:'model'|'submodel'):Promise { @@ -60,6 +61,7 @@ export async function requestChatDataMain(arg:requestDataArgument, model:'model' presence_penalty: arg.PresensePenalty ?? (db.PresensePenalty / 100), frequency_penalty: arg.frequencyPenalty ?? (db.frequencyPenalty / 100), logit_bias: bias, + stream: false }) let replacerURL = replacer === '' ? 'https://api.openai.com/v1/chat/completions' : replacer @@ -71,19 +73,59 @@ export async function requestChatDataMain(arg:requestDataArgument, model:'model' replacerURL += 'chat/completions' } - if(db.useStreaming){ + if(db.useStreaming && arg.useStreaming){ + body.stream = true const da = await fetch(replacerURL, { body: JSON.stringify(body), + method: "POST", headers: { - "Authorization": "Bearer " + db.openAIKey + "Authorization": "Bearer " + db.openAIKey, + "Content-Type": "application/json" }, }) - const reader = da.body.getReader() + if(da.status !== 200){ + return { + type: "fail", + result: await da.text() + } + } + + let dataUint = new Uint8Array([]) + + const transtream = new TransformStream( { + async transform(chunk, control) { + dataUint = Buffer.from(new Uint8Array([...dataUint, ...chunk])) + try { + const datas = dataUint.toString().split('\n') + let readed = '' + for(const data of datas){ + if(data.startsWith("data: ")){ + try { + const rawChunk = data.replace("data: ", "") + if(rawChunk === "[DONE]"){ + control.enqueue(readed) + return + } + const chunk = JSON.parse(rawChunk).choices[0].delta.content + if(chunk){ + readed += chunk + } + } catch (error) {} + } + } + control.enqueue(readed) + } catch (error) { + + } + } + },) + + da.body.pipeTo(transtream.writable) return { type: 'streaming', - result: reader + result: transtream.readable } } diff --git a/src/ts/update.ts b/src/ts/update.ts index d64f0e87..6528761d 100644 --- a/src/ts/update.ts +++ b/src/ts/update.ts @@ -46,7 +46,7 @@ function versionStringToNumber(versionString:string):number { return Number( versionString .split(".") - .map((component) => component.padStart(2, "0")) + .map((component) => component.padStart(4, "0")) .join("") ); } diff --git a/version.json b/version.json index 7d2f17cb..25e6454d 100644 --- a/version.json +++ b/version.json @@ -1 +1 @@ -{"version":"1.10.1"} \ No newline at end of file +{"version":"1.11.0"} \ No newline at end of file