From e5e86a9c9bb7b4faec70f06879868b9f51fe7273 Mon Sep 17 00:00:00 2001 From: chatbung Date: Wed, 19 Feb 2025 13:30:34 +0900 Subject: [PATCH 01/21] feat: chat folder --- src/lib/SideBars/SideChatList.svelte | 541 +++++++++++++++++++-------- src/ts/characters.ts | 5 +- src/ts/storage/database.svelte.ts | 10 + src/ts/util.ts | 3 + 4 files changed, 409 insertions(+), 150 deletions(-) diff --git a/src/lib/SideBars/SideChatList.svelte b/src/lib/SideBars/SideChatList.svelte index 3c2a454e..614be9a2 100644 --- a/src/lib/SideBars/SideChatList.svelte +++ b/src/lib/SideBars/SideChatList.svelte @@ -1,55 +1,116 @@
- -
- {#key sorted} - {#each chara.chats as chat, i} - + +
+ {#if chara.chats.filter(chat => chat.folderId == chara.chatFolders[i].id).length == 0} + Empty +
+ {:else} + {#each chara.chats.filter(chat => chat.folderId == chara.chatFolders[i].id) as chat} + + {/each} + {/if}
- - {/each} - {/key} + {/each} +
+ +
+ {#each chara.chats as chat, i} + {#if chat.folderId == null} + + {/if} + {/each} +
- + {/key} +
+
- {#if DBState.db.characters[$selectedCharID]?.chaId !== '§playground'} - - + {#if DBState.db.characters[$selectedCharID]?.chaId !== '§playground'} {#if parseKeyValue(DBState.db.customPromptTemplateToggle + getModuleToggles()).length > 4}
@@ -268,10 +512,9 @@ {/if} {/if}
- {#if chara.type === 'group'} -
- -
+
+ +
{/if}
\ No newline at end of file diff --git a/src/ts/characters.ts b/src/ts/characters.ts index 8f68dc2d..34906dd8 100644 --- a/src/ts/characters.ts +++ b/src/ts/characters.ts @@ -32,7 +32,9 @@ export function createNewGroup(){ note: '', name: 'Chat 1', localLore: [] - }], chatPage: 0, + }], + chatFolders: [], + chatPage: 0, viewScreen: 'none', globalLore: [], characters: [], @@ -585,6 +587,7 @@ export function createBlankChar():character{ name: 'Chat 1', localLore: [] }], + chatFolders: [], chatPage: 0, emotionImages: [], bias: [], diff --git a/src/ts/storage/database.svelte.ts b/src/ts/storage/database.svelte.ts index 0d8eb46c..12eca435 100644 --- a/src/ts/storage/database.svelte.ts +++ b/src/ts/storage/database.svelte.ts @@ -958,6 +958,7 @@ export interface character{ desc:string notes:string chats:Chat[] + chatFolders: ChatFolder[] chatPage: number viewScreen: 'emotion'|'none'|'imggen'|'vn', bias: [string, number][] @@ -1096,6 +1097,7 @@ export interface groupChat{ image?:string firstMessage:string chats:Chat[] + chatFolders: ChatFolder[] chatPage: number name:string viewScreen: 'single'|'multiple'|'none'|'emp', @@ -1302,6 +1304,14 @@ export interface Chat{ bindedPersona?:string fmIndex?:number hypaV3Data?:SerializableHypaV3Data + folderId?:string +} + +export interface ChatFolder{ + id:string + name?:string + color?:number + folded:boolean } export interface Message{ diff --git a/src/ts/util.ts b/src/ts/util.ts index 865fdfde..fc5267f6 100644 --- a/src/ts/util.ts +++ b/src/ts/util.ts @@ -1015,4 +1015,7 @@ export const sortableOptions = { delay: 300, // time in milliseconds to define when the sorting should start delayOnTouchOnly: true, filter: '.no-sort', + onMove: (event) => { + return event.related.className.indexOf('no-sort') === -1 + } } as const \ No newline at end of file From f9be5d3710f5db7bf5d073fa0a13b8141ac4dc28 Mon Sep 17 00:00:00 2001 From: chatbung Date: Wed, 19 Feb 2025 16:29:57 +0900 Subject: [PATCH 02/21] feat: add folder color --- src/lib/SideBars/SideChatList.svelte | 41 +++++++++++++++++++++++----- src/ts/storage/database.svelte.ts | 3 +- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/src/lib/SideBars/SideChatList.svelte b/src/lib/SideBars/SideChatList.svelte index 614be9a2..9d7dd07d 100644 --- a/src/lib/SideBars/SideChatList.svelte +++ b/src/lib/SideBars/SideChatList.svelte @@ -13,7 +13,7 @@ import TextInput from "../UI/GUI/TextInput.svelte"; import { exportChat, importChat } from "src/ts/characters"; - import { alertChatOptions, alertConfirm, alertError, alertNormal, alertSelect, alertStore } from "src/ts/alert"; + import { alertChatOptions, alertConfirm, alertError, alertInput, alertNormal, alertSelect, alertStore } from "src/ts/alert"; import { findCharacterbyId, parseKeyValue, sleep, sortableOptions } from "src/ts/util"; import { createMultiuserRoom } from "src/ts/sync/multiuser"; import { getChatBranches } from "src/ts/gui/branches"; @@ -164,18 +164,45 @@ {#each chara.chatFolders as folder, i}
-
+{#if DBState.db.useExperimental} +
+ + + +
+{/if} {#if DBState.db?.account?.useSync}
diff --git a/src/ts/storage/database.svelte.ts b/src/ts/storage/database.svelte.ts index 51bf4572..3983fd2e 100644 --- a/src/ts/storage/database.svelte.ts +++ b/src/ts/storage/database.svelte.ts @@ -484,6 +484,7 @@ export function setDatabase(data:Database){ doNotSummarizeUserMessage: data.hypaV3Settings?.doNotSummarizeUserMessage ?? false } data.returnCSSError ??= true + data.useExperimentalGoogleTranslator ??= false changeLanguage(data.language) setDatabaseLite(data) } @@ -905,6 +906,7 @@ export interface Database{ showTranslationLoading: boolean showDeprecatedTriggerV1:boolean returnCSSError:boolean + useExperimentalGoogleTranslator:boolean } interface SeparateParameters{ diff --git a/src/ts/translator/translator.ts b/src/ts/translator/translator.ts index 1194ac4b..aa2fb037 100644 --- a/src/ts/translator/translator.ts +++ b/src/ts/translator/translator.ts @@ -1,7 +1,7 @@ import { get } from "svelte/store" import { translatorPlugin } from "../plugins/plugins" import { getDatabase, type character, type customscript, type groupChat } from "../storage/database.svelte" -import { globalFetch, isTauri } from "../globalApi.svelte" +import { globalFetch, isNodeServer, isTauri } from "../globalApi.svelte" import { alertError } from "../alert" import { requestChatData } from "../process/request" import { doingChat, type OpenAIChat } from "../process/index.svelte" @@ -163,6 +163,30 @@ async function translateMain(text:string, arg:{from:string, to:string, host:stri return f.data.data; } + if(db.useExperimentalGoogleTranslator){ + + const hqAvailable = isTauri || isNodeServer || userScriptFetch + + if(hqAvailable){ + try { + const ua = navigator.userAgent + const d = await globalFetch(`https://translate.google.com/m?tl=${arg.to}&sl=${arg.from}&q=${encodeURIComponent(text)}`, { + headers: { + "User-Agent": ua, + "Accept": "*/*", + } + }) + const parser = new DOMParser() + const dom = parser.parseFromString(d.data, 'text/html') + const result = dom.querySelector('.result-container')?.textContent?.trim() + if(result){ + return result + } + } catch (error) { + + } + } + } const url = `https://${arg.host}/translate_a/single?client=gtx&dt=t&sl=${db.translatorInputLanguage}&tl=${arg.to}&q=` + encodeURIComponent(text) From eba47ab611f65c2435211a1fdeb81dff11ebf336 Mon Sep 17 00:00:00 2001 From: chatbung Date: Thu, 20 Feb 2025 12:16:58 +0900 Subject: [PATCH 05/21] fix: importChat() --- src/ts/characters.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/ts/characters.ts b/src/ts/characters.ts index 34906dd8..30425706 100644 --- a/src/ts/characters.ts +++ b/src/ts/characters.ts @@ -404,6 +404,11 @@ export async function importChat(){ return } + if(db.characters[selectedID].chatFolders + .filter(folder => folder.id === newChat.folderId).length === 0) { + newChat.folderId = null + } + db.characters[selectedID].chats.unshift(newChat) setDatabase(db) alertNormal(language.successImport) From 2af57d3c676a776f3a4e2e83b1bbc4ca02c1a7fb Mon Sep 17 00:00:00 2001 From: Kwaroran Date: Fri, 21 Feb 2025 02:38:55 +0900 Subject: [PATCH 06/21] Add new google translaor --- src/ts/translator/translator.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ts/translator/translator.ts b/src/ts/translator/translator.ts index aa2fb037..4cc79689 100644 --- a/src/ts/translator/translator.ts +++ b/src/ts/translator/translator.ts @@ -174,7 +174,8 @@ async function translateMain(text:string, arg:{from:string, to:string, host:stri headers: { "User-Agent": ua, "Accept": "*/*", - } + }, + method: "GET", }) const parser = new DOMParser() const dom = parser.parseFromString(d.data, 'text/html') From abf4cdda9db88e4955c0cb44582fce12f658ac79 Mon Sep 17 00:00:00 2001 From: bangonicdd <157843588+bangonicdd2@users.noreply.github.com> Date: Sun, 23 Feb 2025 20:35:39 +0900 Subject: [PATCH 07/21] fix: force refresh modules after closing menu --- src/lib/Setting/Pages/Module/ModuleSettings.svelte | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/lib/Setting/Pages/Module/ModuleSettings.svelte b/src/lib/Setting/Pages/Module/ModuleSettings.svelte index a0adcb30..ab48f355 100644 --- a/src/lib/Setting/Pages/Module/ModuleSettings.svelte +++ b/src/lib/Setting/Pages/Module/ModuleSettings.svelte @@ -33,9 +33,7 @@ } onDestroy(() => { - if(DBState.db.moduleIntergration){ - refreshModules() - } + refreshModules() }) {#if mode === 0} From d5841390472274b80c8eb9f0f5cc4f88e355a202 Mon Sep 17 00:00:00 2001 From: bangonicdd <157843588+bangonicdd2@users.noreply.github.com> Date: Sun, 23 Feb 2025 21:39:41 +0900 Subject: [PATCH 08/21] revert: make always deduplicate modules --- src/ts/process/modules.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/ts/process/modules.ts b/src/ts/process/modules.ts index 8b870f6e..a0b7873e 100644 --- a/src/ts/process/modules.ts +++ b/src/ts/process/modules.ts @@ -268,9 +268,7 @@ function getModuleByIds(ids:string[]){ modules.push(module) } } - if(db.moduleIntergration){ - modules = deduplicateModuleById(modules) - } + modules = deduplicateModuleById(modules) return modules } From ed2957fc5041f59bc44db3235447d066decef78a Mon Sep 17 00:00:00 2001 From: Kwaroran Date: Tue, 25 Feb 2025 04:36:58 +0900 Subject: [PATCH 09/21] Upgrade translator playground --- .../Playground/PlaygroundTranslation.svelte | 99 ++++++++++++++++++- src/ts/characterCards.ts | 13 ++- src/ts/process/request.ts | 2 +- src/ts/translator/translator.ts | 18 ++-- 4 files changed, 123 insertions(+), 9 deletions(-) diff --git a/src/lib/Playground/PlaygroundTranslation.svelte b/src/lib/Playground/PlaygroundTranslation.svelte index 61d44731..a57e3f7d 100644 --- a/src/lib/Playground/PlaygroundTranslation.svelte +++ b/src/lib/Playground/PlaygroundTranslation.svelte @@ -7,6 +7,8 @@ import SelectInput from "../UI/GUI/SelectInput.svelte"; import { getLanguageCodes } from "src/ts/globalApi.svelte"; import OptionInput from "../UI/GUI/OptionInput.svelte"; + import CheckInput from "../UI/GUI/CheckInput.svelte"; + import { tokenize } from "src/ts/tokenizer"; const userPreferedLang = navigator.language.split('-')[0] @@ -16,6 +18,9 @@ let output = $state('') let outputLang = $state(userPreferedLang) let loading = $state(false) + let bulk = $state(false) + let keepContext = $state(false) + let bulkProgressText = $state('') @@ -36,7 +41,99 @@ + + Bulk + +{#if bulk} + + Keep Context + +{/if} +
+ +
+
+ + + + + Loading... +
+ Loading RisuAI... +
diff --git a/src/main.ts b/src/main.ts index 7d0b6828..c46c8f25 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,4 +1,3 @@ -import "./styles.css"; import "./ts/polyfill"; import "core-js/actual" import "./ts/storage/database.svelte" @@ -14,5 +13,6 @@ let app = mount(App, { }); loadData() initHotkey() +document.getElementById('preloading').remove() export default app; \ No newline at end of file From 8e00540d6ea345753bd87f087ee0ff6e5fd770ad Mon Sep 17 00:00:00 2001 From: Kwaroran Date: Wed, 26 Feb 2025 08:06:08 +0900 Subject: [PATCH 15/21] Add status on GlobalFetch --- src-tauri/src/main.rs | 8 +++++--- src/ts/globalApi.svelte.ts | 26 ++++++++++++++------------ 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 323a3cf0..26872853 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -66,6 +66,7 @@ async fn native_request(url: String, body: String, header: String, method: Strin Ok(resp) => { let headers = resp.headers(); let header_json = header_map_to_json(headers); + let status = resp.status().as_u16().to_string(); let bytes = match resp.bytes().await { Ok(b) => b, Err(e) => return format!(r#"{{"success":false,"body":"{}"}}"#, e.to_string()), @@ -73,11 +74,12 @@ async fn native_request(url: String, body: String, header: String, method: Strin let encoded = general_purpose::STANDARD.encode(&bytes); format!( - r#"{{"success":true,"body":"{}","headers":{}}}"#, - encoded, header_json + // r#"{{"success":true,"body":"{}","headers":{}}}"#, + r#"{{"success":true,"body":"{}","headers":{},"status":{}}}"#, + encoded, header_json, status ) } - Err(e) => format!(r#"{{"success":false,"body":"{}"}}"#, e.to_string()), + Err(e) => format!(r#"{{"success":false,"body":"{}","status":400}}"#, e.to_string()), } } diff --git a/src/ts/globalApi.svelte.ts b/src/ts/globalApi.svelte.ts index a0a3104c..168dafe1 100644 --- a/src/ts/globalApi.svelte.ts +++ b/src/ts/globalApi.svelte.ts @@ -756,6 +756,7 @@ interface GlobalFetchResult { ok: boolean; data: any; headers: { [key: string]: string }; + status: number; } /** @@ -806,13 +807,13 @@ export async function globalFetch(url: string, arg: GlobalFetchArgs = {}): Promi const method = arg.method ?? "POST"; db.requestmet = "normal"; - if (arg.abortSignal?.aborted) { return { ok: false, data: 'aborted', headers: {} }; } + if (arg.abortSignal?.aborted) { return { ok: false, data: 'aborted', headers: {}, status: 400 }; } const urlHost = new URL(url).hostname const forcePlainFetch = ((knownHostes.includes(urlHost) && !isTauri) || db.usePlainFetch || arg.plainFetchForce) && !arg.plainFetchDeforce if (knownHostes.includes(urlHost) && !isTauri && !isNodeServer) { - return { ok: false, headers: {}, data: 'You are trying local request on web version. This is not allowed due to browser security policy. Use the desktop version instead, or use a tunneling service like ngrok and set the CORS to allow all.' }; + return { ok: false, headers: {}, status:400, data: 'You are trying local request on web version. This is not allowed due to browser security policy. Use the desktop version instead, or use a tunneling service like ngrok and set the CORS to allow all.' }; } if (forcePlainFetch) { @@ -832,7 +833,7 @@ export async function globalFetch(url: string, arg: GlobalFetchArgs = {}): Promi } catch (error) { console.error(error); - return { ok: false, data: `${error}`, headers: {} }; + return { ok: false, data: `${error}`, headers: {}, status: 400 }; } } @@ -887,9 +888,9 @@ async function fetchWithPlainFetch(url: string, arg: GlobalFetchArgs): Promise= 200 && response.status < 300; addFetchLogInGlobalFetch(data, ok, url, arg); - return { ok, data, headers: Object.fromEntries(response.headers) }; + return { ok, data, headers: Object.fromEntries(response.headers), status: response.status }; } catch (error) { - return { ok: false, data: `${error}`, headers: {} }; + return { ok: false, data: `${error}`, headers: {}, status: 400 }; } } @@ -907,9 +908,9 @@ async function fetchWithUSFetch(url: string, arg: GlobalFetchArgs): Promise= 200 && response.status < 300; addFetchLogInGlobalFetch(data, ok, url, arg); - return { ok, data, headers: Object.fromEntries(response.headers) }; + return { ok, data, headers: Object.fromEntries(response.headers), status: response.status }; } catch (error) { - return { ok: false, data: `${error}`, headers: {} }; + return { ok: false, data: `${error}`, headers: {}, status: 400 }; } } @@ -927,7 +928,7 @@ async function fetchWithTauri(url: string, arg: GlobalFetchArgs): Promise= 200 && response.status < 300; addFetchLogInGlobalFetch(data, ok, url, arg); - return { ok, data, headers: Object.fromEntries(response.headers) }; + return { ok, data, headers: Object.fromEntries(response.headers), status: response.status }; } catch (error) { } @@ -946,6 +947,7 @@ async function fetchWithCapacitor(url: string, arg: GlobalFetchArgs): Promise Date: Wed, 26 Feb 2025 09:14:32 +0900 Subject: [PATCH 16/21] Add anti server overload --- src/lang/en.ts | 1 + src/lib/Setting/Pages/AdvancedSettings.svelte | 9 +- src/ts/process/request.ts | 336 +++++++++++------- src/ts/storage/database.svelte.ts | 5 + 4 files changed, 227 insertions(+), 124 deletions(-) diff --git a/src/lang/en.ts b/src/lang/en.ts index ae7c9ab6..e5a4c8d5 100644 --- a/src/lang/en.ts +++ b/src/lang/en.ts @@ -1058,4 +1058,5 @@ export const languageEnglish = { depth: "Depth", returnCSSError: "Return CSS Error", thinkingTokens: "Thinking Tokens", + antiServerOverload: "Anti-Server Overload", } diff --git a/src/lib/Setting/Pages/AdvancedSettings.svelte b/src/lib/Setting/Pages/AdvancedSettings.svelte index 77d6e87e..8f65b62a 100644 --- a/src/lib/Setting/Pages/AdvancedSettings.svelte +++ b/src/lib/Setting/Pages/AdvancedSettings.svelte @@ -150,11 +150,6 @@ {#if DBState.db.useExperimental} -
- - - -
@@ -200,6 +195,10 @@
+
+ + +
{#if DBState.db.useExperimental}
diff --git a/src/ts/process/request.ts b/src/ts/process/request.ts index 10575bf2..768886c8 100644 --- a/src/ts/process/request.ts +++ b/src/ts/process/request.ts @@ -15,7 +15,6 @@ import { supportsInlayImage } from "./files/inlays"; import { Capacitor } from "@capacitor/core"; import { getFreeOpenRouterModel } from "../model/openrouter"; import { runTransformers } from "./transformers"; -import {createParser} from 'eventsource-parser' import {Ollama} from 'ollama/dist/browser.mjs' import { applyChatTemplate } from "./templates/chatTemplate"; import { OobaParams } from "./prompt"; @@ -59,7 +58,8 @@ type requestDataResponse = { noRetry?: boolean, special?: { emotion?: string - } + }, + failByServerError?: boolean }|{ type: "streaming", result: ReadableStream, @@ -329,6 +329,13 @@ export async function requestChatData(arg:requestDataArgument, model:ModelModeEx if(da.type !== 'fail' || da.noRetry){ return da } + + if(da.failByServerError){ + await sleep(1000) + if(db.antiServerOverloads){ + trys -= 0.5 // reduce trys by 0.5, so that it will retry twice as much + } + } trys += 1 if(trys > db.requestRetrys){ @@ -1909,6 +1916,101 @@ async function requestGoogleCloudVertex(arg:RequestDataArgumentExtended):Promise url = `https://generativelanguage.googleapis.com/v1beta/models/${arg.modelInfo.internalID}:generateContent?key=${db.google.accessToken}` } + const fallBackGemini = async (originalError:string):Promise => { + if(!db.antiServerOverloads){ + return { + type: 'fail', + result: originalError, + failByServerError: true + } + } + + if(arg?.abortSignal?.aborted){ + return { + type: 'fail', + result: originalError, + failByServerError: true + } + } + if(arg.modelInfo.format === LLMFormat.VertexAIGemini){ + return { + type: 'fail', + result: originalError, + failByServerError: true + } + } + try { + const OAIMessages:OpenAIChat[] = body.contents.map((v) => { + return { + role: v.role === 'USER' ? 'user' : 'assistant', + content: v.parts.map((v) => { + return v.text ?? '' + }).join('\n') + } + }) + if(body?.systemInstruction?.parts?.[0]?.text){ + OAIMessages.unshift({ + role: 'system', + content: body.systemInstruction.parts[0].text + }) + } + await sleep(2000) + const res = await fetch('https://generativelanguage.googleapis.com/v1beta/openai/chat/completions', { + body: JSON.stringify({ + model: arg.modelInfo.internalID, + messages: OAIMessages, + max_tokens: maxTokens, + temperature: body.generation_config?.temperature, + top_p: body.generation_config?.topP, + presence_penalty: body.generation_config?.presencePenalty, + frequency_penalty: body.generation_config?.frequencyPenalty, + }), + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${db.google.accessToken}` + }, + signal: arg.abortSignal + }) + + if(!res.ok){ + return { + type: 'fail', + result: originalError, + failByServerError: true + } + } + + if(arg?.abortSignal?.aborted){ + return { + type: 'fail', + result: originalError + } + } + + const d = await res.json() + + if(d?.choices?.[0]?.message?.content){ + return { + type: 'success', + result: d.choices[0].message.content + } + } + else{ + return { + type: 'fail', + result: originalError, + failByServerError: true + } + } + } catch (error) { + return { + type: 'fail', + result: originalError, + failByServerError: true + } + } + } if(arg.modelInfo.format === LLMFormat.GoogleCloud && arg.useStreaming){ headers['Content-Type'] = 'application/json' @@ -1920,9 +2022,13 @@ async function requestGoogleCloudVertex(arg:RequestDataArgumentExtended):Promise }) if(f.status !== 200){ + const text = await textifyReadableStream(f.body) + if(text.includes('RESOURCE_EXHAUSTED')){ + return fallBackGemini(text) + } return { type: 'fail', - result: await textifyReadableStream(f.body) + result: text } } @@ -1987,8 +2093,13 @@ async function requestGoogleCloudVertex(arg:RequestDataArgumentExtended):Promise chatId: arg.chatId, abortSignal: arg.abortSignal, }) + if(!res.ok){ + const text = JSON.stringify(res.data) + if(text.includes('RESOURCE_EXHAUSTED')){ + return fallBackGemini(text) + } return { type: 'fail', result: `${JSON.stringify(res.data)}` @@ -2700,7 +2811,6 @@ async function requestClaude(arg:RequestDataArgumentExtended):Promise { + const parseEvent = (async (e:string) => { try { - if(e.type === 'event'){ - switch(e.event){ - case 'content_block_delta': { - if(e.data){ - const parsedData = JSON.parse(e.data) - if(parsedData.delta?.type === 'text' || parsedData.delta?.type === 'text_delta'){ - if(thinking){ - text += "\n\n" - thinking = false - } - text += parsedData.delta?.text ?? '' - controller.enqueue({ - "0": text - }) - } + const parsedData = JSON.parse(e) - if(parsedData.delta?.type === 'thinking' || parsedData.delta?.type === 'thinking_delta'){ - if(!thinking){ - text += "\n" - thinking = true - } - text += parsedData.delta?.thinking ?? '' - controller.enqueue({ - "0": text - }) - } - - if(parsedData?.delta?.type === 'redacted_thinking'){ - if(!thinking){ - text += "\n" - thinking = true - } - text += '\n{{redacted_thinking}}\n' - controller.enqueue({ - "0": text - }) - } - } - break + if(parsedData?.type === 'content_block_delta'){ + if(parsedData?.delta?.type === 'text' || parsedData.delta?.type === 'text_delta'){ + if(thinking){ + text += "\n\n" + thinking = false } - case 'error': { - if(e.data){ - const errormsg:string = JSON.parse(e.data).error?.message - if(errormsg && errormsg.toLocaleLowerCase().includes('overload') && db.antiClaudeOverload){ - console.log('Overload detected, retrying...') - reader.cancel() - rerequesting = true - await sleep(2000) - body.max_tokens -= await tokenize(text) - if(body.max_tokens < 0){ - body.max_tokens = 0 - } - if(body.messages.at(-1)?.role !== 'assistant'){ - body.messages.push({ - role: 'assistant', - content: [{ - type: 'text', - text: '' - }] - }) - } - let block = body.messages[body.messages.length-1].content - if(typeof block === 'string'){ - body.messages[body.messages.length-1].content += text - } - else if(block[0].type === 'text'){ - block[0].text += text - } - const res = await fetchNative(replacerURL, { - body: JSON.stringify(body), - headers: { - "Content-Type": "application/json", - "x-api-key": apiKey, - "anthropic-version": "2023-06-01", - "accept": "application/json", - }, - method: "POST", - chatId: arg.chatId - }) - if(res.status !== 200){ - breakError = 'Error: ' + await textifyReadableStream(res.body) - break - } - reader = res.body.getReader() - rerequesting = false - break - } - text += "Error:" + JSON.parse(e.data).error?.message - if(arg.extractJson && (db.jsonSchemaEnabled || arg.schema)){ - controller.enqueue({ - "0": extractJSON(text, db.jsonSchema) - }) - } - else{ - controller.enqueue({ - "0": text - }) - } - } - break + text += parsedData.delta?.text ?? '' + controller.enqueue({ + "0": text + }) + } + + if(parsedData?.delta?.type === 'thinking' || parsedData.delta?.type === 'thinking_delta'){ + if(!thinking){ + text += "\n" + thinking = true } + text += parsedData.delta?.thinking ?? '' + controller.enqueue({ + "0": text + }) + } + + if(parsedData?.delta?.type === 'redacted_thinking'){ + if(!thinking){ + text += "\n" + thinking = true + } + text += '\n{{redacted_thinking}}\n' + controller.enqueue({ + "0": text + }) } } - } catch (error) {} + + if(parsedData?.type === 'error'){ + const errormsg:string = parsedData?.error?.message + if(errormsg && errormsg.toLocaleLowerCase().includes('overload') && db.antiServerOverloads){ + // console.log('Overload detected, retrying...') + controller.enqueue({ + "0": "Overload detected, retrying..." + }) + + return 'overload' + } + text += "Error:" + parsedData?.error?.message + if(arg.extractJson && (db.jsonSchemaEnabled || arg.schema)){ + controller.enqueue({ + "0": extractJSON(text, db.jsonSchema) + }) + } + else{ + controller.enqueue({ + "0": text + }) + } + + } + + } + catch (error) { + } + + + }) + let breakWhile = false while(true){ - if(rerequesting){ - if(breakError){ - controller.enqueue({ - "0": breakError - }) + try { + if(arg?.abortSignal?.aborted || breakWhile){ break } - await sleep(1000) - continue - } - try { const {done, value} = await reader.read() if(done){ - if(rerequesting){ - continue - } break } - parser.feed(decoder.decode(value)) + parserData += (decoder.decode(value)) + let parts = parserData.split('\n') + for(let i=0;i { const formated = arg.formated const db = getDatabase() diff --git a/src/ts/storage/database.svelte.ts b/src/ts/storage/database.svelte.ts index 537dbe2b..17c0c174 100644 --- a/src/ts/storage/database.svelte.ts +++ b/src/ts/storage/database.svelte.ts @@ -485,6 +485,10 @@ export function setDatabase(data:Database){ } data.returnCSSError ??= true data.useExperimentalGoogleTranslator ??= false + if(data.antiClaudeOverload){ //migration + data.antiClaudeOverload = false + data.antiServerOverloads = true + } changeLanguage(data.language) setDatabaseLite(data) } @@ -908,6 +912,7 @@ export interface Database{ returnCSSError:boolean useExperimentalGoogleTranslator:boolean thinkingTokens: number + antiServerOverloads: boolean } interface SeparateParameters{ From 429022ba6f409e1aadcd83b54fa85d4d0be0a672 Mon Sep 17 00:00:00 2001 From: Kwaroran Date: Wed, 26 Feb 2025 09:35:00 +0900 Subject: [PATCH 17/21] bump version to 150.4.0 --- src-tauri/tauri.conf.json | 2 +- src/ts/storage/database.svelte.ts | 2 +- version.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 784053af..ec2cfdd3 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -29,7 +29,7 @@ }, "productName": "RisuAI", "mainBinaryName": "RisuAI", - "version": "150.3.0", + "version": "150.4.0", "identifier": "co.aiclient.risu", "plugins": { "updater": { diff --git a/src/ts/storage/database.svelte.ts b/src/ts/storage/database.svelte.ts index 17c0c174..899fe56c 100644 --- a/src/ts/storage/database.svelte.ts +++ b/src/ts/storage/database.svelte.ts @@ -12,7 +12,7 @@ import { defaultColorScheme, type ColorScheme } from '../gui/colorscheme'; import type { PromptItem, PromptSettings } from '../process/prompt'; import type { OobaChatCompletionRequestParams } from '../model/ooba'; -export let appVer = "150.3.0" +export let appVer = "150.4.0" export let webAppSubVer = '' diff --git a/version.json b/version.json index 9319891f..b35b2568 100644 --- a/version.json +++ b/version.json @@ -1 +1 @@ -{"version":"150.3.0"} \ No newline at end of file +{"version":"150.4.0"} \ No newline at end of file From 4e69ee64451b604a90ff83ada390a487178a4d2e Mon Sep 17 00:00:00 2001 From: Kwaroran Date: Wed, 26 Feb 2025 12:19:34 +0900 Subject: [PATCH 18/21] refactor: remove unnecessary controller.enqueue calls and optimize text handling --- src/ts/process/request.ts | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/src/ts/process/request.ts b/src/ts/process/request.ts index 768886c8..0b51cd60 100644 --- a/src/ts/process/request.ts +++ b/src/ts/process/request.ts @@ -2831,9 +2831,6 @@ async function requestClaude(arg:RequestDataArgumentExtended):Promise Date: Wed, 26 Feb 2025 12:20:15 +0900 Subject: [PATCH 19/21] bump version to 150.4.1 --- src-tauri/tauri.conf.json | 2 +- src/ts/storage/database.svelte.ts | 2 +- version.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index ec2cfdd3..8add7b31 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -29,7 +29,7 @@ }, "productName": "RisuAI", "mainBinaryName": "RisuAI", - "version": "150.4.0", + "version": "150.4.1", "identifier": "co.aiclient.risu", "plugins": { "updater": { diff --git a/src/ts/storage/database.svelte.ts b/src/ts/storage/database.svelte.ts index 899fe56c..77a921f6 100644 --- a/src/ts/storage/database.svelte.ts +++ b/src/ts/storage/database.svelte.ts @@ -12,7 +12,7 @@ import { defaultColorScheme, type ColorScheme } from '../gui/colorscheme'; import type { PromptItem, PromptSettings } from '../process/prompt'; import type { OobaChatCompletionRequestParams } from '../model/ooba'; -export let appVer = "150.4.0" +export let appVer = "150.4.1" export let webAppSubVer = '' diff --git a/version.json b/version.json index b35b2568..db3e0eb5 100644 --- a/version.json +++ b/version.json @@ -1 +1 @@ -{"version":"150.4.0"} \ No newline at end of file +{"version":"150.4.1"} \ No newline at end of file From 929108def359fe05c5a9a2cb8e8c67672f01a9ff Mon Sep 17 00:00:00 2001 From: Kwaroran Date: Wed, 26 Feb 2025 12:22:10 +0900 Subject: [PATCH 20/21] Add error handling --- src/ts/process/request.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ts/process/request.ts b/src/ts/process/request.ts index 0b51cd60..8cc4e985 100644 --- a/src/ts/process/request.ts +++ b/src/ts/process/request.ts @@ -2887,10 +2887,12 @@ async function requestClaude(arg:RequestDataArgumentExtended):Promise Date: Thu, 27 Feb 2025 23:27:50 +0900 Subject: [PATCH 21/21] feat: add support for OpenAI-compatible embedding API --- src/lib/Setting/Pages/OtherBotSettings.svelte | 10 +++++++++ src/ts/process/memory/hypamemory.ts | 21 ++++++++++++------- src/ts/storage/database.svelte.ts | 12 ++++++++++- 3 files changed, 34 insertions(+), 9 deletions(-) diff --git a/src/lib/Setting/Pages/OtherBotSettings.svelte b/src/lib/Setting/Pages/OtherBotSettings.svelte index 88003e0e..836748e4 100644 --- a/src/lib/Setting/Pages/OtherBotSettings.svelte +++ b/src/lib/Setting/Pages/OtherBotSettings.svelte @@ -594,6 +594,7 @@ OpenAI text-embedding-3-small OpenAI text-embedding-3-large OpenAI Ada + Custom (OpenAI-compatible) {#if DBState.db.hypaModel === 'openai3small' || DBState.db.hypaModel === 'openai3large' || DBState.db.hypaModel === 'ada'} @@ -601,5 +602,14 @@ {/if} + {#if DBState.db.hypaModel === 'custom'} + URL + + Key/Password + + Request Model + + {/if} + {/if} \ No newline at end of file diff --git a/src/ts/process/memory/hypamemory.ts b/src/ts/process/memory/hypamemory.ts index deb2735c..5dd8efc9 100644 --- a/src/ts/process/memory/hypamemory.ts +++ b/src/ts/process/memory/hypamemory.ts @@ -37,14 +37,14 @@ export class HypaProcesser{ name: "hypaVector" }) this.vectors = [] + const db = getDatabase() if(model === 'auto'){ - const db = getDatabase() this.model = db.hypaModel || 'MiniLM' } else{ this.model = model } - this.customEmbeddingUrl = customEmbeddingUrl + this.customEmbeddingUrl = customEmbeddingUrl || db.hypaCustomSettings.url } async embedDocuments(texts: string[]): Promise { @@ -77,12 +77,17 @@ export class HypaProcesser{ } const {customEmbeddingUrl} = this const replaceUrl = customEmbeddingUrl.endsWith('/embeddings')?customEmbeddingUrl:appendLastPath(customEmbeddingUrl,'embeddings') - - gf = await globalFetch(replaceUrl.toString(), { - body:{ - "input": input - }, - }) + + const db = getDatabase() + const fetchArgs = { + ...(db.hypaCustomSettings.key ? {headers: {"Authorization": "Bearer " + db.hypaCustomSettings.key}} : {}), + body: { + "input": input, + ...(db.hypaCustomSettings.model ? {"model": db.hypaCustomSettings.model} : {}) + } + }; + + gf = await globalFetch(replaceUrl.toString(), fetchArgs) } if(this.model === 'ada' || this.model === 'openai3small' || this.model === 'openai3large'){ const db = getDatabase() diff --git a/src/ts/storage/database.svelte.ts b/src/ts/storage/database.svelte.ts index 77a921f6..cb9846a4 100644 --- a/src/ts/storage/database.svelte.ts +++ b/src/ts/storage/database.svelte.ts @@ -489,6 +489,11 @@ export function setDatabase(data:Database){ data.antiClaudeOverload = false data.antiServerOverloads = true } + data.hypaCustomSettings = { + url: data.hypaCustomSettings?.url ?? "", + key: data.hypaCustomSettings?.key ?? "", + model: data.hypaCustomSettings?.model ?? "", + } changeLanguage(data.language) setDatabaseLite(data) } @@ -902,7 +907,7 @@ export interface Database{ preserveOrphanedMemory: boolean processRegexScript: boolean doNotSummarizeUserMessage: boolean - }, + } OaiCompAPIKeys: {[key:string]:string} inlayErrorResponse:boolean reasoningEffort:number @@ -913,6 +918,11 @@ export interface Database{ useExperimentalGoogleTranslator:boolean thinkingTokens: number antiServerOverloads: boolean + hypaCustomSettings: { + url: string, + key: string, + model: string, + } } interface SeparateParameters{